我的开发环境MPLAB X v5.50,XC32版本为v2.40,用Harmony生成了一个SPI的程序。
生成的SPI读写函数如下:
- // *****************************************************************************
- /* Function:
- bool SERCOM6_SPI_WriteRead (void* pTransmitData, size_t txSize
- void* pReceiveData, size_t rxSize);
- Summary:
- Write and Read data on SERCOM SERCOM6 SPI peripheral.
- Description:
- This function transmits "txSize" number of bytes and receives "rxSize"
- number of bytes on SERCOM SERCOM6 SPI module. Data pointed by pTransmitData is
- transmitted and received data is saved in the location pointed by
- pReceiveData. The function will transfer the maximum of "txSize" or "rxSize"
- data units towards completion.
- When "Interrupt Mode" option is unchecked in MHC, this function will be
- blocking in nature. In this mode, the function will not return until all
- the requested data is transferred. The function returns true after
- transferring all the data. This indicates that the operation has been
- completed.
- When "Interrupt Mode" option is selected in MHC, the function will be
- non-blocking in nature. The function returns immediately. The data transfer
- process continues in the peripheral interrupt. The application specified
- transmit and receive buffer are ownerd by the library until the data
- transfer is complete and should not be modified by the application till the
- transfer is complete. Only one transfer is allowed at any time. The
- Application can use a callback function or a polling function to check for
- completion of the transfer. If a callback is required, this should be
- registered prior to calling the SERCOM6_SPI_WriteRead() function. The
- application can use the SERCOM6_SPI_IsBusy() to poll for completion.
- Remarks:
- Refer plib_sercom6_spi.h file for more information.
- */
- bool SERCOM6_SPI_WriteRead (void* pTransmitData, size_t txSize, void* pReceiveData, size_t rxSize)
- {
- bool isRequestAccepted = false;
- uint32_t dummyData = 0U;
- /* Verify the request */
- if((((txSize > 0U) && (pTransmitData != NULL)) || ((rxSize > 0U) && (pReceiveData != NULL))) && (sercom6SPIObj.transferIsBusy == false))
- {
- if((SERCOM6_REGS->SPIM.SERCOM_CTRLB & SERCOM_SPIM_CTRLB_CHSIZE_Msk) == (uint32_t)SPI_DATA_BITS_9)
- {
- /* For 9-bit transmission, the txSize and rxSize must be an even number. */
- if(((txSize > 0U) && ((txSize & 0x01U) != 0U)) || ((rxSize > 0U) && ((rxSize & 0x01U) != 0U)))
- {
- return isRequestAccepted;
- }
- }
- isRequestAccepted = true;
- sercom6SPIObj.txBuffer = pTransmitData;
- sercom6SPIObj.rxBuffer = pReceiveData;
- sercom6SPIObj.rxCount = 0U;
- sercom6SPIObj.txCount = 0U;
- sercom6SPIObj.dummySize = 0U;
- if(pTransmitData != NULL)
- {
- sercom6SPIObj.txSize = txSize;
- }
- else
- {
- sercom6SPIObj.txSize = 0U;
- }
- if(pReceiveData != NULL)
- {
- sercom6SPIObj.rxSize = rxSize;
- }
- else
- {
- sercom6SPIObj.rxSize = 0U;
- }
- sercom6SPIObj.transferIsBusy = true;
- /* Flush out any unread data in SPI read buffer */
- while((SERCOM6_REGS->SPIM.SERCOM_INTFLAG & SERCOM_SPIM_INTFLAG_RXC_Msk) == SERCOM_SPIM_INTFLAG_RXC_Msk)
- {
- dummyData = SERCOM6_REGS->SPIM.SERCOM_DATA;
- (void)dummyData;
- }
- SERCOM6_REGS->SPIM.SERCOM_STATUS |= SERCOM_SPIM_STATUS_BUFOVF_Msk;
- SERCOM6_REGS->SPIM.SERCOM_INTFLAG |= (uint8_t)SERCOM_SPIM_INTFLAG_ERROR_Msk;
- if(sercom6SPIObj.rxSize > sercom6SPIObj.txSize)
- {
- sercom6SPIObj.dummySize = sercom6SPIObj.rxSize - sercom6SPIObj.txSize;
- }
- /* Start the first write here itself, rest will happen in ISR context */
- if((SERCOM6_REGS->SPIM.SERCOM_CTRLB & SERCOM_SPIM_CTRLB_CHSIZE_Msk) == (uint32_t)SPI_DATA_BITS_8)
- {
- if(sercom6SPIObj.txCount < sercom6SPIObj.txSize)
- {
- SERCOM6_REGS->SPIM.SERCOM_DATA = *((uint8_t*)sercom6SPIObj.txBuffer);
- sercom6SPIObj.txCount++;
- }
- else if(sercom6SPIObj.dummySize > 0U)
- {
- SERCOM6_REGS->SPIM.SERCOM_DATA = 0xFFU;
- sercom6SPIObj.dummySize--;
- }
- else
- {
- /* Do nothing */
- }
- }
- else
- {
- sercom6SPIObj.txSize >>= 1U;
- sercom6SPIObj.dummySize >>= 1U;
- sercom6SPIObj.rxSize >>= 1U;
- if(sercom6SPIObj.txCount < sercom6SPIObj.txSize)
- {
- SERCOM6_REGS->SPIM.SERCOM_DATA = *((uint16_t*)sercom6SPIObj.txBuffer) & SERCOM_SPIM_DATA_Msk;
- sercom6SPIObj.txCount++;
- }
- else if(sercom6SPIObj.dummySize > 0U)
- {
- SERCOM6_REGS->SPIM.SERCOM_DATA = 0xFFFFU & SERCOM_SPIM_DATA_Msk;
- sercom6SPIObj.dummySize--;
- }
- else
- {
- /* Do nothing */
- }
- }
- if(rxSize > 0U)
- {
- /* Enable ReceiveComplete */
- SERCOM6_REGS->SPIM.SERCOM_INTENSET = (uint8_t)SERCOM_SPIM_INTENSET_RXC_Msk;
- }
- else
- {
- /* Enable the DataRegisterEmpty */
- SERCOM6_REGS->SPIM.SERCOM_INTENSET = (uint8_t)SERCOM_SPIM_INTENSET_DRE_Msk;
- }
- }
- return isRequestAccepted;
- }
我不知道它搞得这么复杂,弄得我不知道怎么调用了。
下面还有:
- bool SERCOM6_SPI_Write(void* pTransmitData, size_t txSize)
- {
- return SERCOM6_SPI_WriteRead(pTransmitData, txSize, NULL, 0U);
- }
- bool SERCOM6_SPI_Read(void* pReceiveData, size_t rxSize)
- {
- return SERCOM6_SPI_WriteRead(NULL, 0U, pReceiveData, rxSize);
- }
|