您的位置:首页 > 其它

CYPEESS USB3.0程序解读之---SPI读写

2015-08-31 15:20 489 查看
前面已经解读了GPIO以及同步FIFO操作,下面我们看一个SPI读写的例子,它是主程序命令从SPI中读写一些数据。

SPI传输子程序看一下: 页地址,字节计数,缓冲区,读写标志

因为只能一页一页的读或写,故读写总是从页地址开始的

/* SPI read / writefor programmer application. */

CyU3PReturnStatus_t

CyFxSpiTransfer (

uint16_t pageAddress, //页地址

uint16_t byteCount, //字节计数

uint8_t *buffer, //缓冲区

CyBool_t isRead) //读写标志

{

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 ++; ///如果除不尽,则按多一页来读写

}



buf_p.buffer = buffer; //地址重载

buf_p.status = 0;



byteAddress = pageAddress * glSpiPageSize; //页地址*尺寸=实际地址

CyU3PDebugPrint (2, "SPI access -addr: 0x%x, size: 0x%x, pages: 0x%x.\r\n",

byteAddress, byteCount, pageCount);



while (pageCount != 0)

{

//高字节

location[1] = (byteAddress >> 16)& 0xFF; /* MS byte */

location[2] = (byteAddress >> 8)& 0xFF;

//低字节

location[3] = byteAddress &0xFF; /* LS byte */



if (isRead)

{

location[0] = 0x03; /* 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); //设置传输尺寸



/// 这个子程序是允许DMA。两个参数一个是TX,一个是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;

}

在USB的SETUP中回调中( CyFxUSBSetupCB ),有两个参数,一个是setupdat0,一个是setupdat1.

这两个参数是类,VENDOR调用时的回调函数。

如果是请求ID号,则直接往EP0中写入一个字符串。

如果是请求FLASH写,则从EP0中得到相应的数组。后写到SPI中。

如果是请求读,则从SPI中读出指定长度的数,再送到EP0中去。

如果是请求擦除或点名。则如果点名,就送状态过去,如果是擦除,就送一个ACK包给USB即可。

那么就要了解一下类/VENDOR请求的格式是什么即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: