fsfw/src/fsfw_hal/stm32h7/spi/spiCore.cpp

330 lines
8.6 KiB
C++
Raw Normal View History

2021-08-02 20:58:56 +02:00
#include "fsfw_hal/stm32h7/spi/spiCore.h"
2021-07-15 19:23:12 +02:00
2021-07-13 19:19:25 +02:00
#include <cstdio>
2022-02-02 10:29:30 +01:00
#include "fsfw_hal/stm32h7/spi/spiDefinitions.h"
2021-07-13 19:19:25 +02:00
SPI_HandleTypeDef* spiHandle = nullptr;
DMA_HandleTypeDef* hdmaTx = nullptr;
DMA_HandleTypeDef* hdmaRx = nullptr;
spi_transfer_cb_t rxTxCb = nullptr;
void* rxTxArgs = nullptr;
spi_transfer_cb_t txCb = nullptr;
void* txArgs = nullptr;
spi_transfer_cb_t rxCb = nullptr;
void* rxArgs = nullptr;
spi_transfer_cb_t errorCb = nullptr;
void* errorArgs = nullptr;
void mapIndexAndStream(DMA_HandleTypeDef* handle, dma::DMAType dmaType, dma::DMAIndexes dmaIdx,
2022-02-02 10:29:30 +01:00
dma::DMAStreams dmaStream, IRQn_Type* dmaIrqNumber);
void mapSpiBus(DMA_HandleTypeDef* handle, dma::DMAType dmaType, spi::SpiBus spiBus);
2021-07-13 19:19:25 +02:00
2022-02-02 10:29:30 +01:00
void spi::configureDmaHandle(DMA_HandleTypeDef* handle, spi::SpiBus spiBus, dma::DMAType dmaType,
dma::DMAIndexes dmaIdx, dma::DMAStreams dmaStream,
IRQn_Type* dmaIrqNumber, uint32_t dmaMode, uint32_t dmaPriority) {
using namespace dma;
mapIndexAndStream(handle, dmaType, dmaIdx, dmaStream, dmaIrqNumber);
mapSpiBus(handle, dmaType, spiBus);
2021-07-13 19:19:25 +02:00
2022-02-02 10:29:30 +01:00
if (dmaType == DMAType::TX) {
handle->Init.Direction = DMA_MEMORY_TO_PERIPH;
} else {
handle->Init.Direction = DMA_PERIPH_TO_MEMORY;
}
2021-07-13 19:19:25 +02:00
2022-02-02 10:29:30 +01:00
handle->Init.Priority = dmaPriority;
handle->Init.Mode = dmaMode;
2021-07-13 19:19:25 +02:00
2022-02-02 10:29:30 +01:00
// Standard settings for the rest for now
handle->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
handle->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
handle->Init.MemBurst = DMA_MBURST_INC4;
handle->Init.PeriphBurst = DMA_PBURST_INC4;
handle->Init.PeriphInc = DMA_PINC_DISABLE;
handle->Init.MemInc = DMA_MINC_ENABLE;
handle->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
handle->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
2021-07-13 19:19:25 +02:00
}
void spi::setDmaHandles(DMA_HandleTypeDef* txHandle, DMA_HandleTypeDef* rxHandle) {
2022-02-02 10:29:30 +01:00
hdmaTx = txHandle;
hdmaRx = rxHandle;
2021-07-13 19:19:25 +02:00
}
void spi::getDmaHandles(DMA_HandleTypeDef** txHandle, DMA_HandleTypeDef** rxHandle) {
2022-02-02 10:29:30 +01:00
*txHandle = hdmaTx;
*rxHandle = hdmaRx;
2021-07-13 19:19:25 +02:00
}
2022-02-02 10:29:30 +01:00
void spi::setSpiHandle(SPI_HandleTypeDef* spiHandle_) {
if (spiHandle_ == NULL) {
return;
}
spiHandle = spiHandle_;
2021-07-13 19:19:25 +02:00
}
2022-02-02 10:29:30 +01:00
void spi::assignTransferRxTxCompleteCallback(spi_transfer_cb_t callback, void* userArgs) {
rxTxCb = callback;
rxTxArgs = userArgs;
2021-07-13 19:19:25 +02:00
}
2022-02-02 10:29:30 +01:00
void spi::assignTransferRxCompleteCallback(spi_transfer_cb_t callback, void* userArgs) {
rxCb = callback;
rxArgs = userArgs;
2021-07-13 19:19:25 +02:00
}
2022-02-02 10:29:30 +01:00
void spi::assignTransferTxCompleteCallback(spi_transfer_cb_t callback, void* userArgs) {
txCb = callback;
txArgs = userArgs;
2021-07-13 19:19:25 +02:00
}
2022-02-02 10:29:30 +01:00
void spi::assignTransferErrorCallback(spi_transfer_cb_t callback, void* userArgs) {
errorCb = callback;
errorArgs = userArgs;
2021-07-13 19:19:25 +02:00
}
2022-02-02 10:29:30 +01:00
SPI_HandleTypeDef* spi::getSpiHandle() { return spiHandle; }
2021-07-13 19:19:25 +02:00
/**
* @brief TxRx Transfer completed callback.
* @param hspi: SPI handle
*/
2022-02-02 10:29:30 +01:00
extern "C" void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef* hspi) {
if (rxTxCb != NULL) {
rxTxCb(hspi, rxTxArgs);
} else {
printf("HAL_SPI_TxRxCpltCallback: No user callback specified\n");
}
2021-07-13 19:19:25 +02:00
}
/**
* @brief TxRx Transfer completed callback.
* @param hspi: SPI handle
*/
2022-02-02 10:29:30 +01:00
extern "C" void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef* hspi) {
if (txCb != NULL) {
txCb(hspi, txArgs);
} else {
printf("HAL_SPI_TxCpltCallback: No user callback specified\n");
}
2021-07-13 19:19:25 +02:00
}
/**
* @brief TxRx Transfer completed callback.
* @param hspi: SPI handle
*/
2022-02-02 10:29:30 +01:00
extern "C" void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef* hspi) {
if (rxCb != nullptr) {
rxCb(hspi, rxArgs);
} else {
printf("HAL_SPI_RxCpltCallback: No user callback specified\n");
}
2021-07-13 19:19:25 +02:00
}
/**
* @brief SPI error callbacks.
* @param hspi: SPI handle
* @note This example shows a simple way to report transfer error, and you can
* add your own implementation.
* @retval None
*/
2022-02-02 10:29:30 +01:00
extern "C" void HAL_SPI_ErrorCallback(SPI_HandleTypeDef* hspi) {
if (errorCb != nullptr) {
errorCb(hspi, rxArgs);
} else {
printf("HAL_SPI_ErrorCallback: No user callback specified\n");
}
2021-07-13 19:19:25 +02:00
}
void mapIndexAndStream(DMA_HandleTypeDef* handle, dma::DMAType dmaType, dma::DMAIndexes dmaIdx,
2022-02-02 10:29:30 +01:00
dma::DMAStreams dmaStream, IRQn_Type* dmaIrqNumber) {
using namespace dma;
if (dmaIdx == DMAIndexes::DMA_1) {
2021-07-13 19:19:25 +02:00
#ifdef DMA1
2022-02-02 10:29:30 +01:00
switch (dmaStream) {
case (DMAStreams::STREAM_0): {
2021-07-13 19:19:25 +02:00
#ifdef DMA1_Stream0
2022-02-02 10:29:30 +01:00
handle->Instance = DMA1_Stream0;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA1_Stream0_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_1): {
#ifdef DMA1_Stream1
handle->Instance = DMA1_Stream1;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA1_Stream1_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_2): {
#ifdef DMA1_Stream2
handle->Instance = DMA1_Stream2;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA1_Stream2_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_3): {
#ifdef DMA1_Stream3
handle->Instance = DMA1_Stream3;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA1_Stream3_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_4): {
#ifdef DMA1_Stream4
handle->Instance = DMA1_Stream4;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA1_Stream4_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_5): {
#ifdef DMA1_Stream5
handle->Instance = DMA1_Stream5;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA1_Stream5_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_6): {
#ifdef DMA1_Stream6
handle->Instance = DMA1_Stream6;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA1_Stream6_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_7): {
#ifdef DMA1_Stream7
handle->Instance = DMA1_Stream7;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA1_Stream7_IRQn;
2021-07-13 19:19:25 +02:00
}
2022-02-02 10:29:30 +01:00
#endif
break;
}
2021-07-13 19:19:25 +02:00
}
2022-02-02 10:29:30 +01:00
if (dmaType == DMAType::TX) {
handle->Init.Request = DMA_REQUEST_SPI1_TX;
} else {
handle->Init.Request = DMA_REQUEST_SPI1_RX;
}
#endif /* DMA1 */
}
if (dmaIdx == DMAIndexes::DMA_2) {
2021-07-13 19:19:25 +02:00
#ifdef DMA2
2022-02-02 10:29:30 +01:00
switch (dmaStream) {
case (DMAStreams::STREAM_0): {
2021-07-13 19:19:25 +02:00
#ifdef DMA2_Stream0
2022-02-02 10:29:30 +01:00
handle->Instance = DMA2_Stream0;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA2_Stream0_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_1): {
#ifdef DMA2_Stream1
handle->Instance = DMA2_Stream1;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA2_Stream1_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_2): {
#ifdef DMA2_Stream2
handle->Instance = DMA2_Stream2;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA2_Stream2_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_3): {
#ifdef DMA2_Stream3
handle->Instance = DMA2_Stream3;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA2_Stream3_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_4): {
#ifdef DMA2_Stream4
handle->Instance = DMA2_Stream4;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA2_Stream4_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_5): {
#ifdef DMA2_Stream5
handle->Instance = DMA2_Stream5;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA2_Stream5_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_6): {
#ifdef DMA2_Stream6
handle->Instance = DMA2_Stream6;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA2_Stream6_IRQn;
2021-07-13 19:19:25 +02:00
}
#endif
2022-02-02 10:29:30 +01:00
break;
}
case (DMAStreams::STREAM_7): {
#ifdef DMA2_Stream7
handle->Instance = DMA2_Stream7;
if (dmaIrqNumber != nullptr) {
*dmaIrqNumber = DMA2_Stream7_IRQn;
2021-07-13 19:19:25 +02:00
}
2022-02-02 10:29:30 +01:00
#endif
break;
}
2021-07-13 19:19:25 +02:00
}
2022-02-02 10:29:30 +01:00
#endif /* DMA2 */
}
2021-07-13 19:19:25 +02:00
}
2022-02-02 10:29:30 +01:00
void mapSpiBus(DMA_HandleTypeDef* handle, dma::DMAType dmaType, spi::SpiBus spiBus) {
if (dmaType == dma::DMAType::TX) {
if (spiBus == spi::SpiBus::SPI_1) {
2021-07-13 19:19:25 +02:00
#ifdef DMA_REQUEST_SPI1_TX
2022-02-02 10:29:30 +01:00
handle->Init.Request = DMA_REQUEST_SPI1_TX;
2021-07-13 19:19:25 +02:00
#endif
2022-02-02 10:29:30 +01:00
} else if (spiBus == spi::SpiBus::SPI_2) {
2021-07-13 19:19:25 +02:00
#ifdef DMA_REQUEST_SPI2_TX
2022-02-02 10:29:30 +01:00
handle->Init.Request = DMA_REQUEST_SPI2_TX;
2021-07-13 19:19:25 +02:00
#endif
}
2022-02-02 10:29:30 +01:00
} else {
if (spiBus == spi::SpiBus::SPI_1) {
2021-07-13 19:19:25 +02:00
#ifdef DMA_REQUEST_SPI1_RX
2022-02-02 10:29:30 +01:00
handle->Init.Request = DMA_REQUEST_SPI1_RX;
2021-07-13 19:19:25 +02:00
#endif
2022-02-02 10:29:30 +01:00
} else if (spiBus == spi::SpiBus::SPI_2) {
2021-07-13 19:19:25 +02:00
#ifdef DMA_REQUEST_SPI2_RX
2022-02-02 10:29:30 +01:00
handle->Init.Request = DMA_REQUEST_SPI2_RX;
2021-07-13 19:19:25 +02:00
#endif
}
2022-02-02 10:29:30 +01:00
}
2021-07-13 19:19:25 +02:00
}