Before we have read the Gpio and synchronous FIFO operation, let's look at an example of SPI read and write, which is the main program command reads and writes some data from the SPI.
SPI Transfer subroutine look at: page address, byte count, buffer, read-write flag
Because only one page of read or write, so read and write 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 + +; Read and write on more than one page, if not endless
}
Buf_p.buffer = buffer; Address overloading
Buf_p.status = 0;
byteaddress = pageaddress * glspipagesize; Page address * size = actual address
Cyu3pdebugprint (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 >>) & 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)
{
Cyu3pdebugprint (2, "Spiread command failed\r\n");
Cyu3pspisetssnline (cytrue);
return status;
}
Cyu3pspisetblockxfer (0,glspipagesize); Set Transfer dimensions
This subroutine is to allow DMA. Two parameters one is TX, the other is the number of 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)
{
Cyu3pdebugprint (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, one is Setupdat0, the other is SETUPDAT1.
These two parameters are the callback functions of the class, vendor when called.
If the ID number is requested, a string is written directly to the EP0.
If the flash write is requested, the corresponding array is obtained from the EP0. And then write to the SPI.
If the request is read, the number of the specified length is read from the SPI and sent to the EP0.
If it is a request erase or roll call. If the name, send the status of the past, if it is erased, send an ACK packet to the USB.
Then you need to know what the format of the class/vendor request is.