3 Replies Latest reply on Apr 16, 2020 1:16 AM by SaMe_4645651

    FX3S storage write in override mode

    SaMe_4645651

      Hi everyone,

       

      I'm developing an application based on the MSC example for the FX3S. In some cases, I need to manually read/write data to the storage.

       

      This is the DMA configuration:

      CyU3PDmaChannelConfig_t dmaConfig;
      dmaConfig.size = 512;
      dmaConfig.count = CY_FX_MSC_DMA_BUF_COUNT;
      dmaConfig.prodSckId = (CyU3PDmaSocketId_t) (CY_U3P_UIB_SOCKET_PROD_0 | CY_FX_MSC_EP_BULK_OUT_SOCKET);
      dmaConfig.consSckId = CY_U3P_SIB_SOCKET_0;
      dmaConfig.dmaMode = CY_U3P_DMA_MODE_BYTE;
      dmaConfig.notification = CY_U3P_DMA_CB_RECV_CPLT | CY_U3P_DMA_CB_SEND_CPLT | CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_CONS_EVENT;
      dmaConfig.cb = UsbStorage_DmaStorageWriteCb;
      dmaConfig.prodHeader = 0;
      dmaConfig.prodFooter = 0;
      dmaConfig.consHeader = 0;
      dmaConfig.prodAvailCount = 0;
      status = CyU3PDmaChannelCreate(&glChHandleMscOut, CY_U3P_DMA_TYPE_MANUAL, &dmaConfig);
      
      dmaConfig.prodSckId = CY_U3P_SIB_SOCKET_1;
      dmaConfig.consSckId = (CyU3PDmaSocketId_t) (CY_U3P_UIB_SOCKET_CONS_0 | CY_FX_MSC_EP_BULK_IN_SOCKET);
      dmaConfig.notification = CY_U3P_DMA_CB_RECV_CPLT | CY_U3P_DMA_CB_SEND_CPLT | CY_U3P_DMA_CB_PROD_EVENT | CY_U3P_DMA_CB_CONS_EVENT;
      dmaConfig.cb = UsbStorage_DmaStorageReadCb;
      status = CyU3PDmaChannelCreate(&glChHandleMscIn, CY_U3P_DMA_TYPE_MANUAL, &dmaConfig);
      

       

       

      I am using the following command sequence to initiate a read/write request. (Each return status check here is omitted for brevity: every call returns SUCCESS until WaitForCompletion).

       

      // Prepare the DMA Buffer
      CyU3PDmaBuffer_t dmaBuf;
      dmaBuf.buffer = buf;
      dmaBuf.status = 0;
      dmaBuf.size = (len + 15) & 0xFFF0; // Round up to a multiple of 16.
      dmaBuf.count = len;
      
      CyU3PDmaChannel *handle = (isRead) ? &glChHandleMscIn : &glChHandleMscOut;
      if(isRead)
          CyU3PDmaChannelSetupRecvBuffer(handle, &dmaBuf);
      else
          CyU3PDmaChannelSetupSendBuffer(handle, &dmaBuf);
      
      CyU3PSibReadWriteRequest(isRead, ((lun >= CY_FX_SIB_PARTITIONS) ? 1 : 0), glLunUnit[lun], len / CY_FX_SIB_MAX_BLOCK_SIZE, startAddr, 1);
      ret = CyU3PDmaChannelWaitForCompletion(handle, CYU3P_WAIT_FOREVER); // ret == "ABORTED" when trying to write!
      

       

      Reads are successful. When trying to WRITE, the DmaStorageWriteCb callback is not called and the WaitForCompletion function returns ABORTED.

       

      I've checked the docs and the forums and couldn't find an answer. Can you help me?

       

      Thanks,
      Salvatore

        • 1. Re: FX3S storage write in override mode
          YashwantK_46

          Hello Salvatore,

           

          The CyU3PDmaChannelWaitForCompletion() API returns CY_U3P_ERROR_ABORTED in these cases:

          1.) /* Wait for the normal transaction to complete */

          2.) /* Wait for the producer socket override transaction to complete */

          3.) /* Wait for the consumer socket override transaction to complete */

           

          So, is the manual transfer only happening when the AUTO channel is not being used?

           

          Also, for the manual channel, what is the 2nd parameter passed to the CyU3PDmaChannelSetXfer() API? Is it a finite value or set to 0?

           

          Please share your firmware so that i can review the modifications done and get a better understanding of the issue.


          Regards,

          Yashwant

          • 2. Re: FX3S storage write in override mode
            SaMe_4645651

            Hello Yashwant,

             

            unfortunately I cannot share the firmware at the moment. The first post contains what I think to be the relevant parts. The DMA channels are created ONCE (at the startup), then never recreated again. This way, both reads and writes in AUTO mode (USB HOST <--> MMC) work correctly. Also the Read in MANUAL mode work.

             

            Yes the manual transfer is being used when no other request is being made by the Host. No other API is invoked before/after the second function.
            I've currently setup a Timer that sets a event flag which is waited upon in the HandleMSCTask() thread. So this function is called in the HandleMSCTask() thread.


            As indicated by the documentation, CyU3PDmaChannelSetXfer() must not be called when using CyU3PDmaChannelSetupSendBuffer() / CyU3PDmaChannelSetupRecvBuffer() so I did not call it.


            Regards,
            Salvatore

            • 3. Re: FX3S storage write in override mode
              SaMe_4645651

              Hello everyone,

               

              I've solved it. I've added a check before the CyU3PDmaChannelSetupRecvBuffer()/CyU3PDmaChannelSetupSendBuffer() calls:

               

              CyU3PDmaState_t state; uint32_t prodCount, consCount;
              CyU3PDmaChannelGetStatus(handle, &state, &prodCount, &consCount);
              while(state != CY_U3P_DMA_CONFIGURED && state != CY_U3P_DMA_RECV_COMPLETED && state != CY_U3P_DMA_SEND_COMPLETED)
              {
                  CyU3PThreadSleep(10);
                  CyU3PDmaChannelGetStatus(handle, &state, &prodCount, &consCount);
              }
              

               

              Thanks for the help.

               

              Regards,
              Salvatore.