Hello all,
With some help from the forum, I was able to get the chip to enumerate the other day, and now that that's working, I'm trying to send data through it using DMA to get the data from the host. I've tried to copy the USBBulkLoopManualInOut project.
To configure the endpoint, I:
So far so good. Nothing returns an error code.
When I go to get data, I:
I'll include my source code, but does anyone know what I'm missing, or what I've done wrong?
Thank you for your help!
Solved! Go to Solution.
Hello,
I tried to reproduce the issue at my end and was successful in that. After debugging the firmware I realized that the configureEndpoints() is called just after the CyU3PConnectState API.
configureEndpoints() which is equivalent to CyFxBulkLpApplnStart of the Manual IN OUT example should be called when the CY_U3P_USB_EVENT_SETCONF event occurs. For this USB event call back needs to be registered and events needs to be handled.
********************************************************************
CyU3PUsbRegisterEventCallback(usbEventCallback);
void usbEventCallback(
CyU3PUsbEventType_t evtype, /**< The event type. */
uint16_t evdata /**< Event specific data. */
){
switch (evtype)
{
case CY_U3P_USB_EVENT_SETCONF:
/* Disable the low power entry to optimize USB throughput */
CyU3PUsbLPMDisable();
/* Stop the application before re-starting. */
if (glIsApplnActive)
{
disableendpoint();
}
/* Start the loop back function. */
configureEndpoints ();
break;
case CY_U3P_USB_EVENT_RESET:
case CY_U3P_USB_EVENT_DISCONNECT:
/* Stop the loop back function. */
if (glIsApplnActive)
{
disableendpoint(); //equivalent to AppStop
}
break;
default:
break;
}
***************************************************************
Please find the attached modified firmware and test results. Now, you can try calling the CyU3PDmaChannelGetBuffer as done in the SDK example.
Please let me know if any queries on this
Regards,
Rashi
Hello,
From the source code that you shared i understand that only one channel is created at a time i.e. either Manual In (USB>CPU) or Manual OUT (CPU>USB) unlike USBBulklpManualnOut which has both the channels created.
To check if the data is received by the USB socket you can add the callback to the DMA channel configuration and register for the PROD and CONS event.
***************For the MANUAL IN channel only****************
/* Create a DMA MANUAL_IN channel for the producer socket. */
dmaCfg.size = size;
dmaCfg.count = CY_FX_BULKLP_DMA_BUF_COUNT;
dmaCfg.prodSckId = CY_FX_EP_PRODUCER_SOCKET;
dmaCfg.consSckId = CY_U3P_CPU_SOCKET_CONS;
dmaCfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT;
dmaCfg.cb = CyFxDmaCallback;
dmaCfg.prodHeader = 0;
dmaCfg.prodFooter = 0;
dmaCfg.consHeader = 0;
dmaCfg.prodAvailCount = 0;
In the CyFxDmaCallback function CY_U3P_DMA_CB_PROD_EVENT can be tracked using a variable and then later the value of the variable can be printed.
void CyFxDmaCallback (
CyU3PDmaChannel *chHandle, /* Handle to the DMA channel. */
CyU3PDmaCbType_t type, /* Callback type. */
CyU3PDmaCBInput_t *input) /* Callback status. */
{
if (type == CY_U3P_DMA_CB_PROD_EVENT)
{
glDMARxCount ++;
}
}
Get the variable printed in the for{} to check if the data is received at USB socket
for (;;)
{
CyU3PDebugPrint (4, "\n\n glDMARxCount = %d", glDMARxCount);
.....
}
*********************************************************************
>> If from the above test you get CY_U3P_DMA_CB_PROD_EVENT for MANUAL_IN channel try calling CyU3PDmaChannelGetBuffer inside the callback under CY_U3P_DMA_CB_PROD_EVENT and let me know the results.
Q1 call a function I've written to get the CyU3PDmaChannel pointer for the address 2.
>> Please confirm that the UIB socket used in DMA channel and the endpoint used are same (for example if UIB socket is PROD_1 then EP number should also be OUT endpoint 1 (0x01)
Q2 I've tried calling CyU3PDmaChannelResume here with that pointer to enable both producer and consumer, but it doesn't seem to do anything.
>> Please comment out these CyU3PDmaChannelGetBuffer &CyU3PDmaChannelResume API for the above mentioned test.
Q3 call CyU3PDmaChannelGetBuffer(<the previously mentioned pointer>, the address of a buffer struct, either CYU3P_WAIT_FOREVER or CYU3P_NO_WAIT)
>> CYU3P_WAIT_FOREVER will wait for buffer till infinite timer ticks
>> CYU3P_NO_WAIT will not wait for buffer and return immediately
Regards,
Rashi
Hi Rashi,
First off, thanks for your help. You're a life saver.
I was able to try to use the callback like you suggested, but it doesn't seem to ever get called when I try to send data. I attached the callback in usb.c in the configureEndpoints function.
I was able to determine which sockets were being used with which endpoints (out 2 with PROD_2, out 4 with PROD_4, in 6 with CONS_6, and in 8 with CONS_8). By printing out the addresses of the CyU3PDmaChannels, I was able to verify that when I pass my function an endpoint address, I get the CyU3PDmaChannel associated with the correct UIB socket.
I made a couple other changes too. I was originally not using the UART logging, and instead just relying on the debugger and blinking the LED on the demo board. It turns out the LED was attached to one of the pins needed for UART, and by configuring it as GPIO, I broke UART, so I fixed that. I'm attaching the new code to this reply.
Again, thanks for your help.
Hello,
I tried to reproduce the issue at my end and was successful in that. After debugging the firmware I realized that the configureEndpoints() is called just after the CyU3PConnectState API.
configureEndpoints() which is equivalent to CyFxBulkLpApplnStart of the Manual IN OUT example should be called when the CY_U3P_USB_EVENT_SETCONF event occurs. For this USB event call back needs to be registered and events needs to be handled.
********************************************************************
CyU3PUsbRegisterEventCallback(usbEventCallback);
void usbEventCallback(
CyU3PUsbEventType_t evtype, /**< The event type. */
uint16_t evdata /**< Event specific data. */
){
switch (evtype)
{
case CY_U3P_USB_EVENT_SETCONF:
/* Disable the low power entry to optimize USB throughput */
CyU3PUsbLPMDisable();
/* Stop the application before re-starting. */
if (glIsApplnActive)
{
disableendpoint();
}
/* Start the loop back function. */
configureEndpoints ();
break;
case CY_U3P_USB_EVENT_RESET:
case CY_U3P_USB_EVENT_DISCONNECT:
/* Stop the loop back function. */
if (glIsApplnActive)
{
disableendpoint(); //equivalent to AppStop
}
break;
default:
break;
}
***************************************************************
Please find the attached modified firmware and test results. Now, you can try calling the CyU3PDmaChannelGetBuffer as done in the SDK example.
Please let me know if any queries on this
Regards,
Rashi
That did the trick. Thank you!