Please let me know if my understanding is wrong about your application.
Your microcontroller is interfaced to GPIF II of FX3. These two together (uC + FX3) acting as a mass storage device.
So the role of FX3 here is to just pass the information between your microcontroller and PC.
Whenever PC sends a CBW then your microcontroller reads that data from the FX3 and it will return back with CSW.
So you are able to recieve the CBW from FX3 but you are not able to send CSW through FX3.
Can you check whether FX3 got the CSW data into it or leftout at GPIF interface itself. You can use UART for debugging the firmware.
Hi Sai Krishna,
What You have written is absolutely right.
(Our MC+ Cypress FX3 SDK) to be used as a Mass Storage device.
For this purpose the example application(firmware), I selected in FX3 SDK is "slave async fifo". And I selected "async slave fifo 2 bit" mode and "8 bit data bus" with GPIF2 programmer.
I further did experiments on this and observed the following.
1) regarding function CyFxSlFifoPtoUDmaCallback() ( Tested with Cypress Control Center )
When a partial packet is transferred from Our MC to Cypress FX3 SDK ( from P port to U port ), the call back function CyFxSlFifoPtoUDmaCallback() is executed Two times. Both times "commit" is performed.
For eg: I seleced Full Speed. So the maximum buffer size is 64. When 64 bytes packet is transferred from P port to U port, only One time, the commit is performed by the call back function. But when a 36 byte packet ( or any short packet which is having bytes less than 64 ), the "commit" is performed Two times.
And also I observed the input->buffer_p.count for this function with serial port. For the first commit, input->buffer_p.count Is 36 and the for the second commit it is Zero.
I think this is the basic reason for the problem.
When CBW of 31 bytes is received from PC, Our MC sends 36 bytes of Inquiry Data. But then PtoU call back function is executed Two times and commit happens Two times. So at first a buffer of 36 bytes is transferred to PC and then a 0byte buffer (or ZLP) is transferred to PC. So this 0byte buffer is misunderstood by the PC as CSW. Even though 13bytes of CSW is sent from Our MC, after Inquiry data transfer, this is not considered as CSW by the PC. That is why, in the USBlyzer, in the place of CSW, "0 bytes received" is appeared.
Would it will be like this only with this example application or is there any thing wrong I am doing.
Please advice me, how to come out of this problem.
I have seen this problem earlier. Please look at the following thread:
Following changes are required in the firmware, if you are going to use CyU3PDmaChannelSetWrapUp API.
/* Load the GPIF configuration for Master mode. */
apiRetStatus = CyU3PGpifLoad (&CyFxGpifConfig);
/* Register a callback function as shown below: */
CyU3PGpifEventType event, /* Event type that is being notified. */
uint8_t currentState /* Current state of the State Machine. */
Hi Sai Krishna,
Thank You very much for Your timely reply.
From Your reply, what I understood is given below. (PLease correct if I am wrong).
To solve this problem there are Two methods.
1) to do IN_DATA action along with the COMMIT action
2) do INT_CPU action
The method 1) is not very perfect. There shall be some extra data appearing with this method.
For method 2), I am having the following doubts.
1) Which example application( firmware ) to be selected for this? Is it possible with "Slavefioasync"? Or Is it possible with any other cypress provided example applications?
2) In the reply it is mentioned that, for implementing this we have to load GPIF configuration for master mode. But in the Cypress supplied interfaces ( for GPIF2 Designer ), there is not any master modes. Is Cypress providing any specific Interfaces for implementing this?
For method 1) also I am having the same doubts.
Also for method 1) how IN_DATA action can be performed with the COMMIT action?
Thank You in advance for Your reply.
First of all, sorry for confusing you regarding the comment "/* Load the GPIF configuration for Master mode. */". My intention here is just to show you where to register a callback function. I wanted to tell you that you need to register a callback function after loading the GPIF descriptors. Please ignore the comment "/* Load the GPIF configuration for Master mode. */". You can do the suggested changes in your SlaveFIFOasync example itslef.
Coming to your next question:
Open the GPIF II project that is developed for SlaveFIFOasync interface.
Go to the SHORT_PKT state and look if you have IN_DATA action added in that state. If not, please add IN_DATA action to that state. You need to build that prject after doing the change and there will be a .h file as a result. Copy the contents of the .h file into cyfxgpif_asyncsf.h file of SlaveFIFOasync example project.
Hi Sai Krishna,
As You told, I modified the software.
What I observed is, now even the 36 bytes of Inquiry data is not observed in USBLyzer. (USBlyzer and UART messages showing 0 bytes of data for Inquiry data ).
Also in the callback function, newly written "CyFxBulkSrcSinkApplnGPIFEventCB ", I put some UART messages. But it is not getting executed.
As You suggested the changes done are
1) registering the call back function
2) adding the call back function definition
3) adding the variable definition for glChHandleBulkLpPtoU
One doubt I am having is the variable "glChHandleBulkLpPtoU" appears only in One place( In call back function CyFxBulkSrcSinkApplnGPIFEventCB ). There is not any initialization. Is this OK?
I think some thing, some where is wrong.
Please forward Your valuable suggestions for the solution.
It looks like you have not added the INT_CPU action to the state which handles short packets.
You might be doing COMMIT and IN_DATA action in a state to commit the short packet. Now you need to delete those actions and you need to add INT_CPU action.
Hi Sai Krishna,
As You mentioned, I opened GPIF programmer, changed the actions in SHORT_PKT state, performed building and the resulting header file copied to example appliocation folder.
Now the Inquiry Data is getting appeared in USBlyzer, but CSW data is still not appeared.
That is, the state is now as old only.
How I can check whether this newly added call function is working?
Still I am keeping the PtoUcallback function and UtoP callback function. Is that OK?
Another doubt I am having is about PKTEND signal. In the documents, it is mentioned that along with last data and WR signal PKTEND to be asserted.
But when doing so the last byte is not transmitted (or received). So PKTEND assertion is done for a dummy byte, after the transmission of all bytes. Is it OK?
Expecting Your valid response,
Hi Sai Krishna,
I have One more query regarding the same issue.
Now I am using only Two dedicated flags.
FLAGA to know the staus ( BUFFER FULL or BUFFER NOT FULL ) of PtoU In Transfer and
FLAGB for UtoP Out Transfer (BUFFER EMPTY or BUFFER NOT EMPTY ).
There are some remarks about water mark flags in some documents and User mails.
Can this be implemented for "slave async fifo 2 bit" mode ?
And would this solve Our issue?
Hi Sai Krishna,
The following two solutions suggested by You have been tried to solve this problem.
1) with the actions COMMIT and IN_DATA in SHORT_PKT state in "slavefifoasync" application example without any change in it. ( I got the kit with this condition only )
2) with the action INTR_CPU in SHORT_PKT state, with the changes suggested by You in the application example "slavefifoasync".
But in both of these cases, in the PtoU call back function, Two times the "commit" happens, whenever an IN packet is getting transferred. First time the bytes count is the packet length and the second time the bytes count is Zero.
I tried so many possible ways of doing it. But the result is same.
It seems like a permanent error.
Had the Interface between an external Processor and FX3 SDK through GPIF2 been tested, with "slave fifo async 2 bit" gpif2 configuration, in Cypress Lab?
Would You please suggest an already tested and proved way for interfacing an external processor with FX3 SDK for developing an (External Processor + Cypress FX3 SDK ) mass storage device?
I have tested the method that I suggested to you and it worked at my end without any issue.
I would reccomend you to do the following: create a tech support case by attaching your project files so that one of our engineer will look into this and help you to come out of this issue.
Hi Sai Krishna,
I got a solution for the Short Packet problem.
It is solved by keeping the actions COMMIT and IN_DATA in SHORT_PKT state and doing the following changes in the state diagram for slave fifo async 2 bit.
1) The transition equation for the transition from IDLE state to PKT_END state is changed from (!PKEND) | (!SLCS & !SLWR) to (!SLCS & !SLWR)
2) The transition equation for the WRITE state to IDLE state is changed from ( SLWR | SLCS ) to ( SLWR & SLCS )
This changes is required, may be because of the Test setup changes in Cypress Lab and Our Lab. With Our Test setup, we are using Micro controller WR and RD signals directly as SLRD and SLWR signals. (Instead of using some port pins).
With the above changes now SCSI commands are getting executed fine.
But now I am facing problem in handling Long Packet. I have configured the FX3 SDK for FULL SPEED operation. So packet length is 64 bytes. When the Host PC requests 512 bytes of data through SCSI READ 10 command, I need to send Eight 64bytes packets. But after sending One 64bytes Packet there is not any changes in the FLAGB which I assigned for IN Operations.(I am using dedicated flag for IN and OUT operations). The FLAG is continously showing BUFFER NOT FULL.
Without considering this, when I attempt to write the remaining 64bytes packets, during the transmission of 4th or 5th packet, BUFFER FULL state appears.
So Long packet writting is getting failed.
Kindly provide a solution for this problem. How generally a Long packet cab be written?
Expecting Your valuable reply,
Good to know that the short packet issue has been resolved.
Coming to the other one, I would like to know the dmaCfg paramters that you are using in your firmware. Also the type of channel that you are creating.
Hi Sai Krishna,
The DMA Configuration is same as used in the Application example slave async fifo. I have not done any change in that.
In the function CyFxSlFifoApplnInit(), the DMA channels are created as follows.
/* Create a MANUAL channel for UtoP transfer */
dmaCfg.count = 64 ; /* 64 for FS,512 for HS and 1024 for SS */
dmaCfg.ProdSckId = 0x0401 ;
dmaCfg.ConsSckId = 0x0103 ;
dmaCfg.dmaMode = 0 ;
dmaCfg.notification = CY_U3P_DMA_CB_PROD_EVENT ;
dmaCfg.cb = CyFxSlFifoUtoPDmaCallback ;
dmaCfg.ProdHeader = 0 ;
dmaCfg.ProdFooter = 0 ;
dmaCfg.ConsHeader = 0 ;
dmaCfg.ProdAvailCount = 0 ;
apiRetStatus = CyU3PDmaChannelCreate(&glChHandleSlFifoUtoP, CY_U3P_DMA_TYPE_MANUAL,&dmaCfg) ;
/* Create a MANUAL channel for PtoU transfer */
dmaCfg.ProdSckId = 0x0100 ;
dmaCfg.ConsSckId = 0x0301 ;
dmaCfg.cb =CyFxSlFifoPtoUDmaCallback ;
apiRetStatus = CyU3PDmaChannelCreate(&glChHandleSlFifoPtoU, CY_U3P_DMA_TYPE_MANUAL,&dmaCfg) ;
/* Flush the endpoint memory */
CyU3PUsbFlushEp (CY_FX_EP_PRODUCER) ;
CyU3PUsbFlushEp (CY_FX_EP_CONSUMER) ;
/* Set DMA channel transfer size */
apiRetStatus = CyU3PDmaChannelSetXfer(&glChHandleSlFifoUtoP, 0) ;
apiRetStatus = CyU3PDmaChannelSetXfer(&glChHandleSlFifoPtoU, 0) ;
In both UtoP and PtoU call back functions, commit is performed if type == CY_U3P_DMA_CB_PROD_EVENT
1) Fast enumeration is used.
2) The function CyU3PRegisterSetupCallback() is called from the function CyFxSlFifoApplnInit()
3) The function CyU3PRegisterEventCallback() is called from the function CyFxSlFifoApplnInit()
4) The function CyU3PRegisterLPMRequestCallback() is called from the function CyFxSlFifoApplnInit()
5) FLAGA is dedicated for UtoP transfer status
6) FLAGB is dedicated for PtoU transfer status
7) The type of DMA channel is MANUAL for both P to U and U to P transfers