#include #include "mspInit.h" #include "spiConf.h" #include "spiCore.h" #include "spiInterrupts.h" #include "stm32h743xx.h" #include "stm32h7xx_hal_spi.h" #include "stm32h7xx_hal_dma.h" #include "stm32h7xx_hal_def.h" #include /** * @brief SPI MSP Initialization * This function configures the hardware resources used in this example: * - Peripheral's clock enable * - Peripheral's GPIO Configuration * - DMA configuration for transmission request by peripheral * - NVIC configuration for DMA interrupt request enable * @param hspi: SPI handle pointer * @retval None */ void spi::halMspInitDma(void *spi_handle) { SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef*) spi_handle; if(hspi == NULL) { return; } if(hspi == NULL) { printf("HAL_SPI_MspInit: Invalid SPI handle!\n"); return; } setSpiHandle(hspi); DMA_HandleTypeDef* hdma_tx = NULL; DMA_HandleTypeDef* hdma_rx = NULL; spi::getDmaHandles(&hdma_tx, &hdma_rx); if(hdma_tx == NULL || hdma_rx == NULL) { printf("HAL_SPI_MspInit: Invalid DMA handles. Make sure to call setDmaHandles!\n"); return; } spi::halMspInitPolling(spi_handle); if (hspi->Instance == SPI1) { // DMA setup DMAx_CLK_ENABLE(); // Configure the DMA /* Configure the DMA handler for Transmission process */ hdma_tx->Instance = SPIx_TX_DMA_STREAM; hdma_tx->Init.FIFOMode = DMA_FIFOMODE_DISABLE; hdma_tx->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_tx->Init.MemBurst = DMA_MBURST_INC4; hdma_tx->Init.PeriphBurst = DMA_PBURST_INC4; hdma_tx->Init.Request = SPIx_TX_DMA_REQUEST; hdma_tx->Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_tx->Init.PeriphInc = DMA_PINC_DISABLE; hdma_tx->Init.MemInc = DMA_MINC_ENABLE; hdma_tx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_tx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_tx->Init.Mode = DMA_NORMAL; hdma_tx->Init.Priority = DMA_PRIORITY_LOW; HAL_DMA_Init(hdma_tx); /* Associate the initialized DMA handle to the the SPI handle */ __HAL_LINKDMA(hspi, hdmatx, *hdma_tx); /* Configure the DMA handler for Transmission process */ hdma_rx->Instance = SPIx_RX_DMA_STREAM; hdma_rx->Init.FIFOMode = DMA_FIFOMODE_DISABLE; hdma_rx->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_rx->Init.MemBurst = DMA_MBURST_INC4; hdma_rx->Init.PeriphBurst = DMA_PBURST_INC4; hdma_rx->Init.Request = SPIx_RX_DMA_REQUEST; hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE; hdma_rx->Init.MemInc = DMA_MINC_ENABLE; hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_rx->Init.Mode = DMA_NORMAL; hdma_rx->Init.Priority = DMA_PRIORITY_HIGH; HAL_DMA_Init(hdma_rx); /* Associate the initialized DMA handle to the the SPI handle */ __HAL_LINKDMA(hspi, hdmarx, *hdma_rx); /*##-4- Configure the NVIC for DMA #########################################*/ /* NVIC configuration for DMA transfer complete interrupt (SPI1_RX) */ // Assign the interrupt handler dma::assignDmaUserHandler(dma::DMAIndexes::DMA_2, dma::DMAStreams::STREAM_2, &spi::dmaRxIrqHandler, hdma_rx); HAL_NVIC_SetPriority(SPIx_DMA_RX_IRQn, 1, 0); HAL_NVIC_EnableIRQ(SPIx_DMA_RX_IRQn); /* NVIC configuration for DMA transfer complete interrupt (SPI1_TX) */ // Assign the interrupt handler dma::assignDmaUserHandler(dma::DMAIndexes::DMA_2, dma::DMAStreams::STREAM_3, &spi::dmaTxIrqHandler, hdma_tx); HAL_NVIC_SetPriority(SPIx_DMA_TX_IRQn, 1, 1); HAL_NVIC_EnableIRQ(SPIx_DMA_TX_IRQn); /*##-5- Configure the NVIC for SPI #########################################*/ /* NVIC configuration for SPI transfer complete interrupt (SPI1) */ // Assign the interrupt handler spi::assignSpiUserHandler(spi::SPI_1, &spi::spi1IrqHandler, hspi); HAL_NVIC_SetPriority(SPIx_IRQn, 1, 0); HAL_NVIC_EnableIRQ(SPIx_IRQn); } } /** * @brief SPI MSP De-Initialization * This function frees the hardware resources used in this example: * - Disable the Peripheral's clock * - Revert GPIO, DMA and NVIC configuration to their default state * @param hspi: SPI handle pointer * @retval None */ void spi::halMspDeinitDma(void *spi_handle) { SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef*) spi_handle; if(hspi == NULL) { return; } spi::halMspDeinitPolling(spi_handle); if(hspi->Instance == SPIx) { DMA_HandleTypeDef* hdma_tx = NULL; DMA_HandleTypeDef* hdma_rx = NULL; spi::getDmaHandles(&hdma_tx, &hdma_rx); if(hdma_tx == NULL || hdma_rx == NULL) { printf("HAL_SPI_MspInit: Invalid DMA handles. Make sure to call setDmaHandles!\n"); } else { /*##-3- Disable the DMA ####################################################*/ /* De-Initialize the DMA associated to transmission process */ HAL_DMA_DeInit(hdma_tx); /* De-Initialize the DMA associated to reception process */ HAL_DMA_DeInit(hdma_rx); } /*##-4- Disable the NVIC for DMA ###########################################*/ HAL_NVIC_DisableIRQ(SPIx_DMA_TX_IRQn); HAL_NVIC_DisableIRQ(SPIx_DMA_RX_IRQn); /*##-5- Disable the NVIC for SPI ###########################################*/ HAL_NVIC_EnableIRQ(SPIx_IRQn); } } void spi::halMspInitPolling(void *hspi) { GPIO_InitTypeDef GPIO_InitStruct = {}; /*##-1- Enable peripherals and GPIO Clocks #################################*/ /* Enable GPIO TX/RX clock */ SPIx_SCK_GPIO_CLK_ENABLE(); SPIx_MISO_GPIO_CLK_ENABLE(); SPIx_MOSI_GPIO_CLK_ENABLE(); /* Enable SPI clock */ SPIx_CLK_ENABLE(); /*##-2- Configure peripheral GPIO ##########################################*/ /* SPI SCK GPIO pin configuration */ GPIO_InitStruct.Pin = SPIx_SCK_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = SPIx_SCK_AF; HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct); /* SPI MISO GPIO pin configuration */ GPIO_InitStruct.Pin = SPIx_MISO_PIN; GPIO_InitStruct.Alternate = SPIx_MISO_AF; HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct); /* SPI MOSI GPIO pin configuration */ GPIO_InitStruct.Pin = SPIx_MOSI_PIN; GPIO_InitStruct.Alternate = SPIx_MOSI_AF; HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct); } void spi::halMspDeinitPolling(void *hspi) { /*##-1- Reset peripherals ##################################################*/ SPIx_FORCE_RESET(); SPIx_RELEASE_RESET(); /*##-2- Disable peripherals and GPIO Clocks ################################*/ /* Configure SPI SCK as alternate function */ HAL_GPIO_DeInit(SPIx_SCK_GPIO_PORT, SPIx_SCK_PIN); /* Configure SPI MISO as alternate function */ HAL_GPIO_DeInit(SPIx_MISO_GPIO_PORT, SPIx_MISO_PIN); /* Configure SPI MOSI as alternate function */ HAL_GPIO_DeInit(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_PIN); } void spi::halMspInitInterrupt(void *hspi) { spi::halMspInitPolling(hspi); // Configure the NVIC for SPI spi::assignSpiUserHandler(spi::SPI_1, &spi::spi1IrqHandler, hspi); HAL_NVIC_SetPriority(SPIx_IRQn, 1, 0); HAL_NVIC_EnableIRQ(SPIx_IRQn); } void spi::halMspDeinitInterrupt(void *hspi) { spi::halMspDeinitPolling(hspi); // Disable the NVIC for SPI HAL_NVIC_DisableIRQ(SPIx_IRQn); }