The gpio and FIFO synchronization operations have been explained earlier. Let's take a look at an SPI read/write example. It is the main program command to read and write some data from SPI.
SPI transmission Subroutine: page address, byte count, buffer, read/write flag
Because only one page can be read or written, the read and write operations always start from the page address.
/* SPI read/writefor programmer application .*/
Cyu3preturnstatus_t
Cyfxspitransfer (
Uint16_t pageaddress, // page address
Uint16_t bytecount, // Byte Count
Uint8_t * buffer, // Buffer
Cybool_t isread) // read/write flag
{
Cyu3pdmabuffer_t buf_p; // DMA Buffer
Uint8_t location [4];
Uint32_t byteaddress = 0;
Uint16_t pagecount = (bytecount/glspipagesize );
Cyu3preturnstatus_t status = cy_u3p_success;
If (bytecount = 0)
{
Return cy_u3p_success;
}
If (bytecount % glspipagesize )! = 0)
{
Pagecount ++; // if there are not all, read and write by one page
}
Buf_p.buffer = buffer; // address overload
Buf_p.status = 0;
Byteaddress = pageaddress * glspipagesize; // page address * size = actual address
Cyu3pdebuuplint (2, "SPI access-ADDR: 0x % x, size: 0x % x, pages: 0x % x. \ r \ n ",
Byteaddress, bytecount, pagecount );
While (pagecount! = 0)
{
// High byte
Location [1] = (byteaddress> 16) & 0xff;/* MS byte */
Location [2] = (byteaddress> 8) & 0xff;
// Low byte
Location [3] = byteaddress & 0xff;/* ls byte */
If (isread)
{
Location [0] = 0x03;/* read command. * // READ command
Buf_p.size = glspipagesize;
Buf_p.count = glspipagesize;
Status = cyfxspiwaitforstatus ();
If (status! = Cy_u3p_success)
Return status;
Cyu3pspisetssnline (cyfalse );
Status = cyu3pspitransmitwords (location, 4 );
If (status! = Cy_u3p_success)
{
Cyu3pdebuuplint (2, "spiread command failed \ r \ n ");
Cyu3pspisetssnline (cytrue );
Return status;
}
Cyu3pspisetblockxfer (0, glspipagesize); // you can specify the transmission size.
/// This subroutine allows DMA. Two parameters: Tx and Rx
Status = cyu3pdmachannelsetuprecvbuffer (& glspirxhandle,
& Buf_p );
If (status! = Cy_u3p_success)
{
Cyu3pspisetssnline (cytrue );
Return status;
}
Status = cyu3pdmachannelwaitforcompletion (& glspirxhandle,
Cy_fx_usb_spi_timeout );
If (status! = Cy_u3p_success)
{
Cyu3pspisetssnline (cytrue );
Return status;
}
Cyu3pspisetssnline (cytrue );
Cyu3pspidisableblockxfer (cyfalse, cytrue );
}
Else/* write */
{
Location [0] = 0x02;/* writecommand */
Buf_p.size = glspipagesize;
Buf_p.count = glspipagesize;
Status = cyfxspiwaitforstatus ();
If (status! = Cy_u3p_success)
Return status;
Cyu3pspisetssnline (cyfalse );
Status = cyu3pspitransmitwords (location, 4 );
If (status! = Cy_u3p_success)
{
Cyu3pdebuuplint (2, "spiwrite command failed \ r \ n ");
Cyu3pspisetssnline (cytrue );
Return status;
}
Cyu3pspisetblockxfer (glspipagesize, 0 );
Status = cyu3pdmachannelsetupsendbuffer (& glspitxhandle,
& Buf_p );
If (status! = Cy_u3p_success)
{
Cyu3pspisetssnline (cytrue );
Return status;
}
Status = cyu3pdmachannelwaitforcompletion (& glspitxhandle,
Cy_fx_usb_spi_timeout );
If (status! = Cy_u3p_success)
{
Cyu3pspisetssnline (cytrue );
Return status;
}
Cyu3pspisetssnline (cytrue );
Cyu3pspidisableblockxfer (cytrue, cyfalse );
}
/* Update the parameters */
Byteaddress + = glspipagesize;
Buf_p.buffer + = glspipagesize;
Pagecount --;
Cyu3pthreadsleep (10 );
}
Return cy_u3p_success;
}
In the USB setup callback (Cyfxusbsetupcb). There are two parameters: setupdat0 and setupdat1.
These two parameters are classes, and the callback function is used when the vendor is called.
If it is a request ID, a string is written directly to ep0.
If Flash write is requested, the corresponding array is obtained from ep0. And write it to SPI.
For read requests, read the specified length from SPI and send it to ep0.
If the request is erased or named. If the name is named, the status will be sent. If it is erased, an ACK package will be sent to USB.
You need to know the format of the class/vendor request.