Almost empty pin of FX3 is abnormal

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
jach_1279971
Level 3
Level 3
25 replies posted 10 replies posted 5 replies posted

Continue to discuss the watermark issue Set DMA watermark of FX3 , the behaviour of "almost empty pin" (DMA_AEMP) is quite abnormal. This pin is configured as logic low in initial state. When slave and master are power up, DMA_AEMP outputs high. Until slave finishes to transmit data to master, DMA_AEMP outputs low.

When I break the connection between slave and master, and just power up the slave, DMA_AEMP outputs low. Please kindly advise.

pastedImage_1.png

pastedImage_2.png

0 Likes
1 Solution

Hi Jackie,

Refer to the 5th response on this thread I would like to suggest you to implement the workaround exactly same as it is mentioned in the flags.doc file in Re: DMA flags Basic doubt thread.

Error code 67 says that "CY_U3P_ERROR_ALREADY_STARTED" that means the state of DMA channel is not set to configured. Once you call CyU3PDmaChannelCreate () API, it will initialize all the variables of the channel and set the state to configured. CyU3PDmaChannelSetupSendBuffer() & CyU3PDmaChannelSetXfer() API's will check for this state and return Error Code 67 if it is not configured. I am not sure why the channel state is changed. Please implement the workaround and check.

Thanks & Regards

Abhinav

View solution in original post

0 Likes
17 Replies
jach_1279971
Level 3
Level 3
25 replies posted 10 replies posted 5 replies posted

Re: DMA flags Basic doubt

I dont' know whether I'm facing the same issue as the above link but I tried to revise the code as below, however, "CyU3PDmaChannelSetXfer Failed, Error code = 67" is printed, please kindly advise.

uint8_t TempBuf[32] __attribute__ ((aligned (32)));

CyU3PDmaBuffer_t Buf;

Buf.buffer = (uint8_t *)TempBuf;

Buf.count = 32;

Buf.size = 32;

Buf.status = 0;

/* Send the Sample Buffer to the PIB Consumer */

apiRetStatus = CyU3PDmaChannelSetupSendBuffer (&glDmaChHandle, &Buf);

if (apiRetStatus != CY_U3P_SUCCESS)

{

CyU3PDebugPrint (4, "Setupsendbuffer failed = %d\n", apiRetStatus);

CyFxAppErrorHandler (apiRetStatus);

}

apiRetStatus = CyU3PDmaChannelSetXfer (&glDmaChHandle, CY_FX_GPIFTOUSB_DMA_TX_SIZE);

if (apiRetStatus != CY_U3P_SUCCESS)

{

CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer failed, Error code = %d\n", apiRetStatus);

CyFxAppErrorHandler(apiRetStatus);

}

0 Likes

Hi Jackie,

You mentiond that DMA_AEMP  flag is working as expected for slave interface, abnormality is happening only for master interface. Can you please share the GPIF SM for master interface. One more thing you are making use of DMA_FULL_FLAG, what is the behavior if you start the communication after monitoring full flag only as mentioned in Re: DMA flags Basic doubt thread.

Thanks & Regards
Abhinav

0 Likes
lock attach
Attachments are accessible only for community members.

There is only one way direction, slave writes data to master. It seems that DMA_AEMP flag is abnormal after master interface provides pclk to slave interface.

Please find the GPIF SM for master interface.

0 Likes

Actually I have 2 pairs of firmware and each pair works in one direction. One pair is slave write/master read and the other is slave read/master write. I checked DMA_AFULL flag worked normally (logic high) in initial state for the slave read/master write pair.

0 Likes

Is it a bug of FX3? I need to solve this issue ASAP, please kindly advise.

0 Likes

Please kindly advise.

0 Likes

Hi Jackie,

You are using Buffer size as 16 and it is 16 byte alinged. but with "CyU3PDmaChannelSetupSendBuffer" API it is advisable to use

32 byte aligned and should be a multiple of 32 bytes in size.

Please refer to the section 5.17.4.16 of FX3_API Guide.

Thanks & Regards
Abhinav

0 Likes

Hi Abhinav,

I have already set the buffer size to 32. But if just running the slave alone, CyU3PDmaChannelSetXfer must be failed. Can you duplicate my problem?

0 Likes

Hi Jackie,

I assume that same modified slave firmware is working fine when master is power up first, then slave. Correct me if my assumption is wrong.

I checked the master GPIF SM, you are not driving the A1 line. Could you please specify any reason for it?

Thanks & RegardsAbhinav Garg

0 Likes

As I know, A0 and A1 are used to select the threads of SLAVE. But I just use 1 direction for each pair, take SLAVE WRITE / MASTER READ as an example.

In slave side, CyU3PGpifSocketConfigure(1, CY_U3P_PIB_SOCKET_1, 2, CyFalse, 1), thread 1 is used for output data. Am I correct?

How to disable the selection of A0 and A1 in slave?

Also, in the final stage of this project, MASTER will be replaced by FPGA and number of pin used is our concern.

0 Likes

Hi,

If you want to read the status of Thread 1 then A1:A0 = 1.

Please use "No of address pins used" box on the left side of GPIF designer tool to mention address lines.

1. You didn't mention that but I assume that FLAG A in the master SM is the AEMT flag from slave.

2. Why are you loading DATA counter when you are not using it.

3. what is the size of DMA buffer? I guess it is 512 * 2 = 1024 bytes?

4. SLWR signal is selected as delayed, is there any specific reason for it?

According to the watermark formula,

When reading into an external master from the synchronous Slave FIFO:

(a) The number of data words available for reading (while keeping SLOE# asserted) after the clock edge at which the partial flag is sampled asserted = watermark x (32/bus width) – 1

(b) There is already two-cycle latency from SLRD# to the data. Hence, the number of cycles for which SLRD# may be kept asserted after the clock edge at which the partial flag is sampled asserted = watermark x (32/bus width) –3.

On the master side you have to keep reading the data for 2 * (32/16) - 1 = 3 more words after receiving Partial Flag signal.

If your final project includes interfacing of FX3 with FPGA kindly use AN65974 as a reference project. This will guide you how to use water marks properly.

http://www.cypress.com/documentation/application-notes/an65974-designing-ez-usb-fx3-slave-fifo-inter...

Thanks & Regards
Abhinav

0 Likes

In GPIF design, thread 1 is configured as the thread number for DR_DATA action, the DMA_flag for use of GPIO_25 (AEMP) is Thread1_DMA_watermark and DMA_flag for use of GPIO_21 (FLAGA) is Thread1_DMA_ready.

In source file, CyU3PGpifSocketConfigure(1, CY_U3P_PIB_SOCKET_1, 2, CyFalse, 1); Thread1 is linked with socket 1.

Why do I need to use address pins?

How to read the status of Thread 1?

Any problem if I don't use the address pins?

Thanks.

0 Likes

Hi Jackie,

Refer to the 5th response on this thread I would like to suggest you to implement the workaround exactly same as it is mentioned in the flags.doc file in Re: DMA flags Basic doubt thread.

Error code 67 says that "CY_U3P_ERROR_ALREADY_STARTED" that means the state of DMA channel is not set to configured. Once you call CyU3PDmaChannelCreate () API, it will initialize all the variables of the channel and set the state to configured. CyU3PDmaChannelSetupSendBuffer() & CyU3PDmaChannelSetXfer() API's will check for this state and return Error Code 67 if it is not configured. I am not sure why the channel state is changed. Please implement the workaround and check.

Thanks & Regards

Abhinav

0 Likes

Please also answer the following questions, thanks.

In GPIF design, thread 1 is configured as the thread number for DR_DATA action, the DMA_flag for use of GPIO_25 (AEMP) is Thread1_DMA_watermark and DMA_flag for use of GPIO_21 (FLAGA) is Thread1_DMA_ready.

In source file, CyU3PGpifSocketConfigure(1, CY_U3P_PIB_SOCKET_1, 2, CyFalse, 1); Thread1 is linked with socket 1.

Why do I need to use address pins?

How to read the status of Thread 1?

Any problem if I don't use the address pins?

0 Likes

  

Please also answer the following questions, thanks.

In GPIF design, thread 1 is configured as the thread number for DR_DATA action, the DMA_flag for use of GPIO_25 (AEMP) is Thread1_DMA_watermark and DMA_flag for use of GPIO_21 (FLAGA) is Thread1_DMA_ready.

In source file, CyU3PGpifSocketConfigure(1, CY_U3P_PIB_SOCKET_1, 2, CyFalse, 1); Thread1 is linked with socket 1.

Why do I need to use address pins?

How to read the status of Thread 1?

Any problem if I don't use the address pins?

Please kindly advise.

0 Likes
lock attach
Attachments are accessible only for community members.

Hi Jackie,

Yes you are right if you are using dedicated thread for INDATA action in GPIF II state machine then there is no need to use address pins.

To know the status of any thread you have to use DMA flags(see Signals section on the left of GPIF designer tool Interface window) then fill appropriate no of flags in the column provided. You will see that new signals will come up in the interface then double click on those signals and in the Flag settings window, change the DMA flag to use section (see the attached image)

Thanks & Regards
Abhinav

0 Likes

Refer to the 2nd reply of this thread, slave's program is modified as below.

apiRetStatus = CyU3PDmaChannelCreate (&glChHandleBulkLpUtoP,  CY_U3P_DMA_TYPE_AUTO, &dmaCfg);
if (apiRetStatus != CY_U3P_SUCCESS)
{
        CyU3PDebugPrint (4, "CyU3PDmaChannelCreate failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
}

    uint8_t TempBuf[16] __attribute__ ((aligned (16)));
    CyU3PDmaBuffer_t Buf;

    memset(TempBuf, 1, 16);
    Buf.buffer = (uint8_t *)TempBuf;
    Buf.count = 16;
    Buf.size = 16;
    Buf.status = 0;

    /* Send the Sample Buffer to the PIB Consumer */

    apiRetStatus = CyU3PDmaChannelSetupSendBuffer (&glChHandleBulkLpUtoP, &Buf);
    if (apiRetStatus != CY_U3P_SUCCESS) {

     CyU3PDebugPrint (4, "Setupsendbuffer failed = %d\n", apiRetStatus);
     CyFxAppErrorHandler (apiRetStatus);
    }

    /* Flush the Endpoint memory */

    CyU3PUsbFlushEp(CY_FX_EP_PRODUCER);
    // CyU3PUsbFlushEp(CY_FX_EP_CONSUMER);  // remove consumer endpoint

    /* Set DMA Channel transfer size */
    apiRetStatus = CyU3PDmaChannelSetXfer (&glChHandleBulkLpUtoP, CY_FX_DMA_TX_SIZE);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyU3PDebugPrint (4, "CyU3PDmaChannelSetXfer Failed, Error code = %d\n", apiRetStatus);
        CyFxAppErrorHandler(apiRetStatus);
    }
    CyU3PDebugPrint (4, "Finish reset DMA channel\r\n");

When master is power up first, then slave, slave's program works perfectly.

pastedImage_12.png

However, when slave is power up first, then master, CyU3PDmaChannelSetXfer is failed to be run.

pastedImage_13.png

When slave invokes the api "CyU3PDmaChannelSetupSendBuffer", does slave need the pclk from master in order to run this api successfully? Thanks.

0 Likes