refactored spi components for stm32

This commit is contained in:
2021-06-10 12:05:49 +02:00
parent 499ff5dd12
commit 5c40ca9ae8
13 changed files with 187 additions and 94 deletions

View File

@ -4,34 +4,13 @@
#include "fsfw/tasks/SemaphoreFactory.h"
#include "fsfw/osal/FreeRTOS/TaskManagement.h"
#include "fsfw_hal/stm32h7/spi/spiCore.h"
#include "fsfw_hal/stm32h7/spi/mspInit.h"
#include "fsfw_hal/stm32h7/gpio/gpio.h"
#include "stm32h7xx_hal_gpio.h"
SpiComIF::SpiComIF(object_id_t objectId, SPI_TypeDef* spiInstance, SPI_HandleTypeDef* spiHandle,
spi::TransferModes transferMode): SystemObject(objectId), transferMode(transferMode),
spiHandle(spiHandle) {
if(spiHandle == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "SpiComIF::SpiComIF: Passed SPI handle invalid!" << std::endl;
#else
sif::printError("SpiComIF::SpiComIF: Passed SPI handle invalid!\n");
#endif
return;
}
spiHandle->Instance = spiInstance;
spiHandle->Init.DataSize = SPI_DATASIZE_8BIT;
spiHandle->Init.FirstBit = SPI_FIRSTBIT_MSB;
spiHandle->Init.TIMode = SPI_TIMODE_DISABLE;
spiHandle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spiHandle->Init.CRCPolynomial = 7;
spiHandle->Init.CRCLength = SPI_CRC_LENGTH_8BIT;
spiHandle->Init.NSS = SPI_NSS_SOFT;
spiHandle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
spiHandle->Init.Direction = SPI_DIRECTION_2LINES;
// Recommended setting to avoid glitches
spiHandle->Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE;
spiHandle->Init.Mode = SPI_MODE_MASTER;
SpiComIF::SpiComIF(object_id_t objectId, spi::TransferModes transferMode):
SystemObject(objectId), transferMode(transferMode) {
spi::assignTransferRxTxCompleteCallback(&spiTransferCompleteCallback, this);
spi::assignTransferRxCompleteCallback(&spiTransferRxCompleteCallback, this);
spi::assignTransferTxCompleteCallback(&spiTransferTxCompleteCallback, this);
@ -56,10 +35,7 @@ ReturnValue_t SpiComIF::initialize() {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
if(HAL_SPI_Init(spiHandle) != HAL_OK) {
sif::printWarning("SpiComIF::initialize: Error initializing SPI\n");
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
@ -104,11 +80,24 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) {
auto gpioPin = spiCookie->getChipSelectGpioPin();
auto gpioPort = spiCookie->getChipSelectGpioPort();
SPI_HandleTypeDef& spiHandle = spiCookie->getSpiHandle();
if(transferMode == spi::TransferModes::POLLING) {
spi::setSpiMspFunctions(&spi::halMspInitPolling, &spiHandle,
&spi::halMspDeinitPolling, &spiHandle);
}
gpio::initializeGpioClock(gpioPort);
GPIO_InitTypeDef chipSelect = {};
chipSelect.Pin = gpioPin;
chipSelect.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(gpioPort, &chipSelect);
HAL_GPIO_WritePin(gpioPort, gpioPin, GPIO_PIN_SET);
if(HAL_SPI_Init(&spiHandle) != HAL_OK) {
sif::printWarning("SpiComIF::initialize: Error initializing SPI\n");
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
@ -118,9 +107,8 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s
return NULLPOINTER;
}
spi::assignSpiMode(spiCookie->getSpiMode(), spiHandle);
spiHandle->Init.BaudRatePrescaler = spi::getPrescaler(HAL_RCC_GetHCLKFreq(),
spiCookie->getSpiSpeed());
SPI_HandleTypeDef& spiHandle = spiCookie->getSpiHandle();
auto iter = spiDeviceMap.find(spiCookie->getDeviceAddress());
if(iter == spiDeviceMap.end()) {
return HasReturnvaluesIF::RETURN_FAILED;
@ -129,16 +117,16 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s
switch(transferMode) {
case(spi::TransferModes::POLLING): {
return handlePollingSendOperation(iter->second.replyBuffer.data(), spiCookie, sendData,
sendLen);
return handlePollingSendOperation(iter->second.replyBuffer.data(), spiHandle, *spiCookie,
sendData, sendLen);
}
case(spi::TransferModes::INTERRUPT): {
return handleInterruptSendOperation(iter->second.replyBuffer.data(), spiCookie, sendData,
sendLen);
return handleInterruptSendOperation(iter->second.replyBuffer.data(), spiHandle, *spiCookie,
sendData, sendLen);
}
case(spi::TransferModes::DMA): {
return handleDmaSendOperation(iter->second.replyBuffer.data(), spiCookie, sendData,
sendLen);
return handleDmaSendOperation(iter->second.replyBuffer.data(), spiHandle, *spiCookie,
sendData, sendLen);
}
}
return HasReturnvaluesIF::RETURN_OK;
@ -170,13 +158,13 @@ void SpiComIF::setDefaultPollingTimeout(dur_millis_t timeout) {
this->defaultPollingTimeout = timeout;
}
ReturnValue_t SpiComIF::handlePollingSendOperation(uint8_t* recvPtr, SpiCookie *spiCookie,
const uint8_t *sendData, size_t sendLen) {
auto gpioPort = spiCookie->getChipSelectGpioPort();
auto gpioPin = spiCookie->getChipSelectGpioPin();
ReturnValue_t SpiComIF::handlePollingSendOperation(uint8_t* recvPtr, SPI_HandleTypeDef& spiHandle,
SpiCookie& spiCookie, const uint8_t *sendData, size_t sendLen) {
auto gpioPort = spiCookie.getChipSelectGpioPort();
auto gpioPin = spiCookie.getChipSelectGpioPin();
spiMutex->lockMutex(timeoutType, timeoutMs);
HAL_GPIO_WritePin(gpioPort, gpioPin, GPIO_PIN_RESET);
auto result = HAL_SPI_TransmitReceive(spiHandle, const_cast<uint8_t*>(sendData),
auto result = HAL_SPI_TransmitReceive(&spiHandle, const_cast<uint8_t*>(sendData),
recvPtr, sendLen, defaultPollingTimeout);
HAL_GPIO_WritePin(gpioPort, gpioPin, GPIO_PIN_SET);
spiMutex->unlockMutex();
@ -191,7 +179,7 @@ ReturnValue_t SpiComIF::handlePollingSendOperation(uint8_t* recvPtr, SpiCookie *
spiCookie->getDeviceAddress() << std::endl;
#else
sif::printWarning("SpiComIF::sendMessage: Polling Mode | Timeout for SPI device %d\n",
spiCookie->getDeviceAddress());
spiCookie.getDeviceAddress());
#endif
#endif
return spi::HAL_TIMEOUT_RETVAL;
@ -204,7 +192,7 @@ ReturnValue_t SpiComIF::handlePollingSendOperation(uint8_t* recvPtr, SpiCookie *
spiCookie->getDeviceAddress() << std::endl;
#else
sif::printWarning("SpiComIF::sendMessage: Polling Mode | HAL error for SPI device %d\n",
spiCookie->getDeviceAddress());
spiCookie.getDeviceAddress());
#endif
#endif
return spi::HAL_ERROR_RETVAL;
@ -213,19 +201,19 @@ ReturnValue_t SpiComIF::handlePollingSendOperation(uint8_t* recvPtr, SpiCookie *
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t SpiComIF::handleInterruptSendOperation(uint8_t* recvPtr, SpiCookie* spiCookie,
const uint8_t * sendData, size_t sendLen) {
return handleIrqSendOperation(recvPtr, spiCookie, sendData, sendLen);
ReturnValue_t SpiComIF::handleInterruptSendOperation(uint8_t* recvPtr, SPI_HandleTypeDef& spiHandle,
SpiCookie& spiCookie, const uint8_t * sendData, size_t sendLen) {
return handleIrqSendOperation(recvPtr, spiHandle, spiCookie, sendData, sendLen);
}
ReturnValue_t SpiComIF::handleDmaSendOperation(uint8_t* recvPtr, SpiCookie* spiCookie,
const uint8_t * sendData, size_t sendLen) {
return handleIrqSendOperation(recvPtr, spiCookie, sendData, sendLen);
ReturnValue_t SpiComIF::handleDmaSendOperation(uint8_t* recvPtr, SPI_HandleTypeDef& spiHandle,
SpiCookie& spiCookie, const uint8_t * sendData, size_t sendLen) {
return handleIrqSendOperation(recvPtr, spiHandle, spiCookie, sendData, sendLen);
}
ReturnValue_t SpiComIF::handleIrqSendOperation(uint8_t *recvPtr, SpiCookie *spiCookie,
const uint8_t *sendData, size_t sendLen) {
ReturnValue_t result = genericIrqSendSetup(recvPtr, spiCookie, sendData, sendLen);
ReturnValue_t SpiComIF::handleIrqSendOperation(uint8_t *recvPtr, SPI_HandleTypeDef& spiHandle,
SpiCookie& spiCookie, const uint8_t *sendData, size_t sendLen) {
ReturnValue_t result = genericIrqSendSetup(recvPtr, spiHandle, spiCookie, sendData, sendLen);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
@ -238,11 +226,11 @@ ReturnValue_t SpiComIF::handleIrqSendOperation(uint8_t *recvPtr, SpiCookie *spiC
SCB_CleanDCache_by_Addr((uint32_t*)(((uint32_t) sendData ) & ~(uint32_t)0x1F),
sendLen + 32);
}
status = HAL_SPI_TransmitReceive_DMA(spiHandle, const_cast<uint8_t*>(sendData),
status = HAL_SPI_TransmitReceive_DMA(&spiHandle, const_cast<uint8_t*>(sendData),
currentRecvPtr, sendLen);
}
else {
status = HAL_SPI_TransmitReceive_IT(spiHandle, const_cast<uint8_t*>(sendData),
status = HAL_SPI_TransmitReceive_IT(&spiHandle, const_cast<uint8_t*>(sendData),
currentRecvPtr, sendLen);
}
switch(status) {
@ -283,11 +271,11 @@ ReturnValue_t SpiComIF::halErrorHandler(HAL_StatusTypeDef status) {
}
ReturnValue_t SpiComIF::genericIrqSendSetup(uint8_t *recvPtr, SpiCookie *spiCookie,
const uint8_t *sendData, size_t sendLen) {
ReturnValue_t SpiComIF::genericIrqSendSetup(uint8_t *recvPtr, SPI_HandleTypeDef& spiHandle,
SpiCookie& spiCookie, const uint8_t *sendData, size_t sendLen) {
// These are required by the callback
currentGpioPort = spiCookie->getChipSelectGpioPort();
currentGpioPin = spiCookie->getChipSelectGpioPin();
currentGpioPort = spiCookie.getChipSelectGpioPort();
currentGpioPin = spiCookie.getChipSelectGpioPin();
currentRecvPtr = recvPtr;
currentRecvBuffSize = sendLen;