USB 3 VISION in CX3

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

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hello,

I am developing a usb 3 vision application in a CX3 MCU (using the Denebola board and snesor OV5640). I have encountered some trouble trying to launch download the Genicam XML.

I managed to write a firmware for the CX3 with the help of the FX3 note on the U3V and UVC examples. So far the device starts correctly creating 3 dma channels (DCICommand, DCIRespond and DSIMultichannel). The first 2 as are needed to process any u3v command are enable just before the SET_CONF usb event has been trigger. The third one is only configured and is not started (as it will start once the acquisition start is enabled).

There are 2 threads: one for U3V Commands and respond, and another for streaming.

So, I start the host application which detects the device as a USB 3 VISION. Everything ok.

Then, when I start the application, the host app log tells me that the XML is detected @*MEM_ADDRESS*, but then I got an error saying that a memory reading error. So, using a USB sniffer tool to find the usb packects raw data, I managed to find out that there is NO error during memory reading, but that at some point there is an "Abort Pipe" of the In Bulk Endpoint (DCICommand Channel).

I have debugged the code but I cannot find the code segment where the abort operation is happening. Does anyone have found him/herself with this?

To add some weirdness, the XML download works IF I start everything before the XML request. DSIMultiChannel, MIPI-CSI, and sensor (sleep mode).

But anyway, I cannot find any reference why is happening when the streaming is NOT used during the setup.

Hope I explained good enough.

Thanks.

0 Likes
5 Replies
Anonymous
Not applicable

Hi,

When you see the USB abort on the host side, correspondingly do you see any USB Events on the device side? (In the USBEventCallback)

Please let us know the details of debug logs on the device side.

Regards,

- Madhu Sudhan

0 Likes
Anonymous
Not applicable

Hi there,

Thanks for the reply .

No, there were no USB Events. In fact, yesterday I found out what was causing this problem. I wasn't allocating the EPConfig and DMAConfig vars, so when a context switch or whatever happend it destroyed these ones.

Anyway, now I have another issue. I cannot grab images. When I execute StartAcquisition, the host sends some commands to get the SIRM (which retrieves correctly) and then sends the StartAcquisition which is capture correctly. StartAcq sets an STREAM_EVENT flag which is capture by the second thread, which first restarts and sets the DSI DMA Channelsets, sets MipiConfig (720p_YUV422@30), configures the sensor (using Cypress example library 720p@30), resume the GPIF, starts Mipi, and finally powers up the sensor.

Just as does the example from Cypress (cycx3_uvc_ov5640).

Ok, then as is expected, the host prepares for the Leader packet and payload and trailer, which immeditely are suppose to be transmitted.

Well, is not happening, there is a Image Timeout error. (I'm attaching some screenshots)

stream_1.PNG

    The last Control Cmd reads the SIRM + 0x00 value. (Then the DSI starts, which are the larger size packets: 1024(L/T), 32768(P))

stream_2.PNG

    Here there is an error I am not sure where from. (Below I explained my hypothesis)

stream_3.PNG

    And finally the Timeout error.

So, my theory of what is happening is that the DSI Callback is not sending the Leader/Trailer. Is always sending payload data, until the timeout happends. From the FX3 example, I copy the DMA Callback function. Should I send forcefully the L/T packets? Maybe the implementation is not valid for CX3 GPIF SM?

Br,

Marc J

DMACallback_code:

void

CyCxUSB3VDSIDmaMultiCallback(CyU3PDmaMultiChannel *handle, CyU3PDmaCbType_t type, CyU3PDmaCBInput_t *input)

{

    extern CyBool_t glLpmDisable;

    CyU3PDmaBuffer_t dmaBuffer;

    CyU3PReturnStatus_t status = CY_U3P_SUCCESS;

    if (type == CY_U3P_DMA_CB_PROD_EVENT)

    {

        /* This is a produce event notification to the CPU. This notification is

         * received upon reception of every buffer. The buffer will not be sent

         * out unless it is explicitly committed. The call shall fail if there

         * is a bus reset / usb disconnect or if there is any application error. */

        /* Disable USB 3.0 LPM while Buffer is being transmitted out*/

        if ((CyU3PUsbGetSpeed() == CY_U3P_SUPER_SPEED) && (glLpmDisable))

        {

            CyU3PUsbLPMDisable();

            CyU3PUsbSetLinkPowerState(CyU3PUsbLPM_U0);

            CyU3PBusyWait(200);

            glLpmDisable = CyFalse;

        }

        if(input->buffer_p.count == 0)

        {

            if(header) {

                CyCxU3VUpdateBlockCount();

                CyU3PMemCopy(input->buffer_p.buffer, CyU3VLeader, 52);

                /* Commit Leader to USB */

                status = CyU3PDmaMultiChannelCommitBuffer (handle, 52, 0);

                if(status != CY_U3P_SUCCESS) {

                    CyU3PDebugPrint(4,"\r\n CyU3PDmaChannelCommitBuffer failed for LEADER %x",status);

                    CyCx3AppErrorHandler(status);

                }

                header = CyFalse;

            }

            else {

                CyU3PMemCopy(input->buffer_p.buffer, CyU3VTrailer, 32);

                /* Commit Trailer to USB */

                status = CyU3PDmaMultiChannelCommitBuffer (handle, 32, 0);

                if(status != CY_U3P_SUCCESS) {

                    CyU3PDebugPrint(4,"\r\n CyU3PDmaChannelCommitBuffer failed for TRAILER %x",status);

                    CyCx3AppErrorHandler(status);

                }

                header = CyTrue;

            }

            /* Toggle the Active Socket */

            glActiveSocket ^= 1;

        }

        else

        {

            /* Commit Payload Data */

            status = CyU3PDmaMultiChannelCommitBuffer (handle, input->buffer_p.count, 0);

            if(status != CY_U3P_SUCCESS) {

                CyU3PDebugPrint(4,"\r\n CyU3PDmaChannelCommitBuffer failed for PAYLOAD %x",status);

                CyCx3AppErrorHandler(status);

            }

        }

    }

    else if(type == CY_U3P_DMA_CB_CONS_EVENT) {

        if(isGrabbing)

            dma_packet_counter++;

        /* Check if Frame is completely transferred */

        if (dma_packet_counter == packet_size) {

            dma_packet_counter = 0;

            if (glActiveSocket)

                CyU3PGpifSMSwitch(CX3_INVALID_GPIF_STATE, CX3_START_SCK1, CX3_INVALID_GPIF_STATE, ALPHA_CX3_START_SCK1, CX3_GPIF_SWITCH_TIMEOUT);

            else

                CyU3PGpifSMSwitch(CX3_INVALID_GPIF_STATE, CX3_START_SCK0, CX3_INVALID_GPIF_STATE, ALPHA_CX3_START_SCK0, CX3_GPIF_SWITCH_TIMEOUT);

//            CyU3PUsbLPMEnable ();

//            glLpmDisable = CyTrue;

        }

    }

}

0 Likes
Anonymous
Not applicable

UPDATE!!

I found the issue. I was allocating the DSI endpoint config var after initializing it.

Therefore at this moment I can send payload data. But as there is no commit inside the SM (every commit is done in the CallBack), I am having issues to send the Leader/Trailer packets.

So I am trying to send only ONE frame. Unfortunately, I cannot send Leader/Trailer within the DMACallback, so I decided to create a new DMAChannel that goes from CPU to DSI Endpoint and send the Leader. Then destroy it and create the multichannel from GPIF to DSI Endpoint to send the Payload data. Finally, recreate the other channel and send the Trailer.

I succesfully manage to get the Leader and Payload, but I am unable to send the Trailer. Any ideas?

CODE:

-------------------------------

          status = CyU3PDmaMultiChannelDestroy(&glChHandleUVCStream);

                if (status != CY_U3P_SUCCESS) {

                    CyU3PDebugPrint (4, "CyU3PDmaChannelReset, Error Code = %d\n\r", status);

                    CyCx3AppErrorHandler(status);

                }

                CyU3PUsbFlushEp(CX3_EP_DSI);

                CreateHeadTailSingleStreamingChannel();

                status = CyU3PDmaChannelGetBuffer(&glChHeadTailStream, &dmaBuffer, CYU3P_NO_WAIT);

                if (status != CY_U3P_SUCCESS) {

                    CyU3PDebugPrint(4, "\n\rAplnStrt:SetXfer Err = 0x%x", status);

                    CyCx3AppErrorHandler(status);

                }

                CyU3PMemCopy(dmaBuffer.buffer, CyU3VTrailer, 32);

                dmaBuffer.size = 32;

                dmaBuffer.count = 32;

                dmaBuffer.status = 0;

                status = CyU3PDmaChannelCommitBuffer (&glChHeadTailStream, 32, 0);

                if (status != CY_U3P_SUCCESS) {

                    CyU3PDebugPrint(4, "\n\rAplnStrt:SetXfer Err = 0x%x", status);

                    CyCx3AppErrorHandler(status);

                }

                CyU3PBusyWait (10);

                do{

                    CyU3PDmaChannelGetStatus(&glChHeadTailStream, &state, &prodXferCount, &consXferCount);

                } while(state == CY_U3P_DMA_IN_COMPLETION || state == CY_U3P_DMA_ABORTED);

                status = CyU3PDmaChannelReset(&glChHeadTailStream);

                if (status != CY_U3P_SUCCESS) {

                    CyU3PDebugPrint (4,"\n\rAppInit:MultiChannelReset Err = 0x%x", status);

                    CyCx3AppErrorHandler(status);

                }

                status = CyU3PDmaChannelDestroy(&glChHeadTailStream);

                if (status != CY_U3P_SUCCESS) {

                    CyU3PDebugPrint(4, "\n\rAplnStrt:SetXfer Err = 0x%x", status);

                    CyCx3AppErrorHandler(status);

                }

-------------------------------

Regards.

0 Likes
Anonymous
Not applicable

UPDATE2!!

Good and bad news!

Good first: I was able to grab an image, Leader, Payload and Trailer .

Bad news: The Trailer arrives with 500ms of delay. Meaning that is grabbing @2fps instead of the 60fps; the speed which MIPI-CSI2 block  and sensor are configured.

The implementation is not very different from the last update. At this moment, I use the instruction CyU3PDmaMultiChannelSetupSendBuffer

to send the Leader packet. Then I resume the GPIF machine and start the sensor. Once a frame is grab, I stopped the GPIF machine (from DMACallback consumer event) which swicthes back to the Thread and sends the Trailer.

So the Leader and Payloads are send within 20 to 80 ms, which is not bad, but the Trailer takes 500ms because between the DMACallback (after I had stopped the GPIF) and the first instruction back in the Streaming Thread, takes around 500ms.

Then, again, any ideas how to drastically reduce this delay time?

Thanks people.

0 Likes
Anonymous
Not applicable

Hello there,

Still struggling with this problem, anyone has a clue on it?

Regards

0 Likes