- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.