DMA_ready flag seems to do the opposite of what I expect.

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

cross mob
ThAl_4704151
Level 4
Level 4
25 sign-ins 25 replies posted 10 replies posted

I'm using a GPIF-II interface to communicate with another chip, and I have FLAGA set up to be connected to Current_Thread_DMA_ready, initially low and with active high. I'm only using 4 endpoints, so if I understand correctly, each thread corresponds to only one GPIF address and one USB endpoint, so that should hopefully keep things simple.

My chip sets the address pins to 3, and then checks the pin connected to FLAGA. Then I wait a bit to make sure the flags have time to get updated, and FLAGA is 0. This is the first time I've written anything to the endpoint, so I doubt it's full. I'm not sure what else could be making it not ready, but waiting for it more doesn't seem to help at all.

Next, as a test, I negated the check, so it only tries to send the message when the Current_Thread_DMA_ready flag is false, ostensibly meaning that the thread associated with the endpoint is not ready. That said, when I configured it that way I was able to send data to the host without any trouble. What gives?

It's possible that I'm a bit unclear about what exactly the DMA_ready flag in the GPIF-II interface means. I see a couple places in a couple manuals that say things along the lines of "This is true when the DMA is ready to send or receive data." What exactly is the criteria for "ready" though? Does that just mean the buffer has enough space to queue up a message? Does the state machine also need to be in one of the states with the DATA_IN action? Is there some other constraint?

0 Likes
1 Solution

Hello ThAl_4704151,

"When I said I negated the Current_Thread_DMA_ready check, I meant I changed the logic in the legacy microcontroller. I've also tried it by switching the polarity of the signal in the GPIF-II designer, and that works just as well."

=> Please refer to section b. Output pins (when used as DMA Flags): of the following KBA: GPIF Pin Polarity – KBA224208

Since the flag is configured with initial value: LOW and polarity: Active High, this means that initially, the flag would be low, but as soon as the initialization is done, the flag will:

1.) stay LOW, if there is buffer space available for the thread.

2.) go HIGH, if there is no buffer space available for the thread.

So, your understanding of the FLAG is correct.

Regards,

Yashwant

View solution in original post

0 Likes
7 Replies
YashwantK_46
Moderator
Moderator
Moderator
100 solutions authored 50 solutions authored 50 likes received

Hello ThAl_4704151​,


For more info on the GPIF flags, please go through the section 8 Flag Configuration of the app note AN65974 from the following link: https://www.cypress.com/file/136056/download

Also, please share your GPIF state machine so that i can review it on my end.


Regards,

Yashwant

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

Sure thing. Here's the GPIF-II designer project.

0 Likes

Hello ThAl_4704151,

Can you please let me know if you have made any changes to the firmware provided with AN65974?

Also, can you let me know which data path out of the two mentioned is failing in your case:

1.) Host => FX3 => FPGA (Host Write to FPGA)

2.) FPGA => FX3 => Host (Host Read from FPGA)

Also, in the firmware can you let me know what are the 4 data paths between USB endpoints and the GPIF sockets?

"Next, as a test, I negated the check, so it only tries to send the message when the Current_Thread_DMA_ready flag is false, ostensibly meaning that the thread associated with the endpoint is not ready."

=> Can you please let me know how this negation is done? Is it done on the FPGA side?

Regards,

Yashwant

0 Likes
YashwantK_46
Moderator
Moderator
Moderator
100 solutions authored 50 solutions authored 50 likes received

Hello,

"My chip sets the address pins to 3, and then checks the pin connected to FLAGA. Then I wait a bit to make sure the flags have time to get updated, and FLAGA is 0. This is the first time I've written anything to the endpoint, so I doubt it's full. I'm not sure what else could be making it not ready, but waiting for it more doesn't seem to help at all."

=> Does it mean that the FPGA is trying to write data to the FX3 when the FLAGA is going low?

Regards,

Yashwant

0 Likes

Can you please let me know if you have made any changes to the firmware provided with AN65974?

Yes, I'm running my own firmware.

Here's the part of it that configures the DMA and connects the data paths. I'll add comments so you know the constants and what values I parsed out of the descriptor.

// Configure the corresponding endpoint

CyU3PMemSet ((uint8_t *)&epCfg, 0, sizeof (epCfg));

epCfg.enable  = CyTrue;

epCfg.epType  = endpoint->type; // 3, aka interrupt endpoint

epCfg.burstLen = 1;

epCfg.streams  = 0;

epCfg.pcktSize = endpoint->packetSize; // 512 if it enumerates as high speed, 64 if it enumerates as full speed. We've enumerated at high speed.

apiRetStatus = CyU3PSetEpConfig(endpoint->address, &epCfg); // address is 0b10001000, aka 8 | 0b10000000

switch(apiRetStatus){

case CY_U3P_ERROR_NOT_STARTED:

    errorLoop();

    break;

case CY_U3P_ERROR_NULL_POINTER:

    // Should never happen

    errorLoop();

    break;

case CY_U3P_ERROR_BAD_ARGUMENT:

    // We got a bad endpoint number from the descriptor

    return USB_INVALID_ADDRESS;

case CY_U3P_ERROR_INVALID_CONFIGURATION:

    // bursts of more than 1 are only supported on certain endpoints

    // We're hardcoding this to false for now anyway, so this should never happen

    errorLoop();

break;

}

// Set up the DMA buffer for the endpoint

uint8_t epLeadsToHost = endpoint->address & IN_Endpoint;

uint8_t addressNum = endpoint->address & ~IN_Endpoint;

dmaCfg.size          = endpoint->packetSize; //again, 512 if it enumerates as high speed, 64 if it enumerates as full speed

dmaCfg.count          = DMA_CHANNEL_SIZE / endpoint->packetSize; // DMA_CHANNEL_SIZE is 2048

if (epLeadsToHost){

    // Data goes from the device to the host

    // FX3 is the producer

    dmaCfg.notification = CY_U3P_DMA_CB_CONS_EVENT; // Callback on produce event

    dmaCfg.prodSckId = CY_U3P_PIB_SOCKET_0 + USB_ADDRESS_TO_PIB(addressNum); // USB_ADDRESS_TO_PIB maps 2,4,6,8 to 0,1,2,3. addressNum is 8, so producer socket id is PIB socket 3.

    dmaCfg.consSckId = CY_U3P_UIB_SOCKET_CONS_0 + addressNum;

    dmaType = CY_U3P_DMA_TYPE_AUTO_SIGNAL;

}

else {

    //Data goes from the host to the device

    // FX3 is the consumer

    dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT; // Callback on produce event

    dmaCfg.prodSckId = CY_U3P_UIB_SOCKET_PROD_0 + addressNum;

    dmaCfg.consSckId = CY_U3P_PIB_SOCKET_0 + USB_ADDRESS_TO_PIB(addressNum); // USB_ADDRESS_TO_PIB maps 2,4,6,8 to 0,1,2,3. addressNum is 8, so producer socket id is PIB socket 3.

    dmaType = CY_U3P_DMA_TYPE_AUTO_SIGNAL;

}

dmaCfg.dmaMode        = CY_U3P_DMA_MODE_BYTE;

dmaCfg.cb            = CyFxDmaCallback; // Sends off an interrupt when we receive data from the host; does nothing otherwise

dmaCfg.prodHeader    = 0;

dmaCfg.prodFooter    = 0;

dmaCfg.consHeader    = 0;

dmaCfg.prodAvailCount = 0;

apiRetStatus = CyU3PDmaChannelCreate(&endpoint->dmaHandle, dmaType, &dmaCfg);

switch (apiRetStatus){

case CY_U3P_ERROR_BAD_ARGUMENT:

case CY_U3P_ERROR_NULL_POINTER:

    // Shouldn't happen

    errorLoop();

    break;

case CY_U3P_ERROR_MEMORY_ERROR:

    // Could not allocate buffers

    errorLoop();

}

// the 0 tells the DMA not to limit the transfers.

apiRetStatus = CyU3PDmaChannelSetXfer(&endpoint->dmaHandle, 0);

switch (apiRetStatus){

case CY_U3P_ERROR_NULL_POINTER:

case CY_U3P_ERROR_NOT_CONFIGURED:

case CY_U3P_ERROR_NOT_SUPPORTED:

    // we passed a null pointer, which shouldn't happen

    // our configuration was wrong, which shouldn't happen

    // no buffer was allocated, which shouldn't happen

    errorLoop();

}

// Configure endpoint watermarks

endpoint->dmaThreadNum = USB_ADDRESS_TO_PIB(addressNum) % 4;

apiRetStatus = CyU3PGpifSocketConfigure(

    endpoint->dmaThreadNum,

    CY_U3P_PIB_SOCKET_0 + USB_ADDRESS_TO_PIB(addressNum),

    0, // watermark at zero indicates when the buffer has data to read

    CyTrue,

    0);

if (apiRetStatus != CY_U3P_SUCCESS){

    errorLoop();

}

// Flush the endpoint

CyU3PUsbFlushEp(endpoint->address);

Also, can you let me know which data path out of the two mentioned is failing in your case:

The path I'm testing right now is Legacy Microcontroller => FX3 => Host. I will be testing host to the microcontroller next.

Also, in the firmware can you let me know what are the 4 data paths between USB endpoints and the GPIF sockets?

I mentioned it in one of the comments in the code snippet, but the mapping from GPIF sockets to USB endpoints is 0:2, 1:4, 2:6, 3:8. That is, add one to the GPIF socket number, and multiply it by 2 to get the corresponding USB endpoint. This is just to maintain the legacy interface so the app on the host doesn't need to change.

Can you please let me know how this negation is done? Is it done on the FPGA side?

When I said I negated the Current_Thread_DMA_ready check, I meant I changed the logic in the legacy microcontroller. I've also tried it by switching the polarity of the signal in the GPIF-II designer, and that works just as well.

"My chip sets the address pins to 3, and then checks the pin connected to FLAGA. Then I wait a bit to make sure the flags have time to get updated, and FLAGA is 0. This is the first time I've written anything to the endpoint, so I doubt it's full. I'm not sure what else could be making it not ready, but waiting for it more doesn't seem to help at all."

=> Does it mean that the FPGA is trying to write data to the FX3 when the FLAGA is going low?

Initially no, the logic in the legacy microcontroller was that it checked FLAGA to see if it was ready, and because it came back low (meaning that it wasn't ready), it bailed out to try again later. The trouble was that FLAGA never indicated that it was ready, so it always bailed out. Later on, I tried negating the check as an experiment (meaning that it would write data only when FLAGA is low), and that was able to transmit data just fine.

Thanks for your help and patience, and have a nice day!

Thomas

0 Likes

Hello ThAl_4704151,

"When I said I negated the Current_Thread_DMA_ready check, I meant I changed the logic in the legacy microcontroller. I've also tried it by switching the polarity of the signal in the GPIF-II designer, and that works just as well."

=> Please refer to section b. Output pins (when used as DMA Flags): of the following KBA: GPIF Pin Polarity – KBA224208

Since the flag is configured with initial value: LOW and polarity: Active High, this means that initially, the flag would be low, but as soon as the initialization is done, the flag will:

1.) stay LOW, if there is buffer space available for the thread.

2.) go HIGH, if there is no buffer space available for the thread.

So, your understanding of the FLAG is correct.

Regards,

Yashwant

0 Likes

I see, so with the DMA ready flag set to active high, a high signal actually means that it's not ready for new input, and I was thinking it meant that it was ready.

0 Likes