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

前面已经解读了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. ",

            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 ");

                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 ");

                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请求的格式是什么即可。

原文地址:https://www.cnblogs.com/Zoran-/p/5819294.html