2017年12月16日 星期六

[STM32] SPI slave mode

之前比較常用的是SPI master的功能,到是第一次使用SPI slave的功能,測試的時後,就把SPI1 當作Master,SPI2當作Slave,cube的設定如下





假設要使用interrupt mode的話,在initialize的時後

hspi2.RxISR = SPI2_RXISR;
hspi2.TxISR = SPI2_TXISR;
hspi2.RxXferSize  = 1;
hspi2.RxXferCount = 1;
__HAL_SPI_ENABLE_IT(&hspi2, (  SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
__HAL_SPI_ENABLE(&hspi2);

最後加入interrupt handler 即可
uint8_t abc;
void SPI1_RXISR(struct __SPI_HandleTypeDef *hspi){
abc = *(__IO uint8_t *)&hspi->Instance->DR;
}


void SPI1_TXISR(struct __SPI_HandleTypeDef *hspi){
*(__IO uint8_t *)&hspi->Instance->DR = 0x12;
}

假設要使用DMA的話,和master的用法一樣:

#define COMM_RX_MESSAGE_SIZE  4
uint8_t spiStatus, bufferRx[COMM_RX_MESSAGE_SIZE], bufferTx[COMM_RX_MESSAGE_SIZE];

同master的用法:
HAL_SPI_TransmitReceive_DMA(&hspi2, bufferTx, bufferRx, COMM_RX_MESSAGE_SIZE);              

// spi complete callback function
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi->Instance==SPI2) {
// spi done
}
}

如果要做ping-pong buffer,可以call下面的function
HAL_SPI_TxRxHalfCpltCallback (SPI_HandleTypeDef *hspi)

確認DMA剩餘DATA, return length, 如果DMA是塞4 bytes,  收到4代表沒有資料, 0 代表master撈走了4個bytes。
length = __HAL_DMA_GET_COUNTER(&hdma_spi2_rx);