refactored spi components for stm32

This commit is contained in:
Robin Müller 2021-06-10 12:05:49 +02:00
parent 499ff5dd12
commit 5c40ca9ae8
No known key found for this signature in database
GPG Key ID: BE6480244DFE612C
13 changed files with 187 additions and 94 deletions

View File

@ -149,11 +149,7 @@ ReturnValue_t GyroHandlerL3GD20H::scanForReply(const uint8_t *start, size_t len,
*foundId = this->getPendingCommand();
*foundLen = this->rawPacketLen;
/* Data with SPI Interface has always this answer */
if (start[0] == 0b11111111) {
return HasReturnvaluesIF::RETURN_OK;
}
return DeviceHandlerIF::INVALID_DATA;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id,

View File

@ -7,6 +7,9 @@
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
#ifndef L3GD20_GYRO_DEBUG
#define L3GD20_GYRO_DEBUG 1
#endif
/**
* @brief Device Handler for the L3GD20H gyroscope sensor

View File

@ -1,4 +1,5 @@
add_subdirectory(spi)
add_subdirectory(gpio)
add_subdirectory(devicetest)
target_sources(${LIB_FSFW_HAL_NAME} PRIVATE

View File

@ -56,7 +56,7 @@ ReturnValue_t GyroL3GD20H::initialize() {
spiHandle->Instance = SPI1;
spiHandle->Init.BaudRatePrescaler = spi::getPrescaler(HAL_RCC_GetHCLKFreq(), 3900000);
spiHandle->Init.Direction = SPI_DIRECTION_2LINES;
spi::assignSpiMode(spi::SpiModes::MODE_3, spiHandle);
spi::assignSpiMode(spi::SpiModes::MODE_3, *spiHandle);
spiHandle->Init.DataSize = SPI_DATASIZE_8BIT;
spiHandle->Init.FirstBit = SPI_FIRSTBIT_MSB;
spiHandle->Init.TIMode = SPI_TIMODE_DISABLE;

View File

@ -0,0 +1,3 @@
target_sources(${LIB_FSFW_HAL_NAME} PRIVATE
gpio.cpp
)

69
stm32h7/gpio/gpio.cpp Normal file
View File

@ -0,0 +1,69 @@
#include "gpio.h"
void gpio::initializeGpioClock(GPIO_TypeDef* gpioPort) {
#ifdef GPIOA
if(gpioPort == GPIOA) {
__HAL_RCC_GPIOA_CLK_ENABLE();
}
#endif
#ifdef GPIOB
if(gpioPort == GPIOB) {
__HAL_RCC_GPIOB_CLK_ENABLE();
}
#endif
#ifdef GPIOC
if(gpioPort == GPIOC) {
__HAL_RCC_GPIOC_CLK_ENABLE();
}
#endif
#ifdef GPIOD
if(gpioPort == GPIOD) {
__HAL_RCC_GPIOD_CLK_ENABLE();
}
#endif
#ifdef GPIOE
if(gpioPort == GPIOE) {
__HAL_RCC_GPIOE_CLK_ENABLE();
}
#endif
#ifdef GPIOF
if(gpioPort == GPIOF) {
__HAL_RCC_GPIOF_CLK_ENABLE();
}
#endif
#ifdef GPIOG
if(gpioPort == GPIOG) {
__HAL_RCC_GPIOG_CLK_ENABLE();
}
#endif
#ifdef GPIOH
if(gpioPort == GPIOH) {
__HAL_RCC_GPIOH_CLK_ENABLE();
}
#endif
#ifdef GPIOI
if(gpioPort == GPIOI) {
__HAL_RCC_GPIOI_CLK_ENABLE();
}
#endif
#ifdef GPIOJ
if(gpioPort == GPIOJ) {
__HAL_RCC_GPIOJ_CLK_ENABLE();
}
#endif
#ifdef GPIOK
if(gpioPort == GPIOK) {
__HAL_RCC_GPIOK_CLK_ENABLE();
}
#endif
}

14
stm32h7/gpio/gpio.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef FSFW_HAL_STM32H7_GPIO_GPIO_H_
#define FSFW_HAL_STM32H7_GPIO_GPIO_H_
#include "stm32h7xx.h"
namespace gpio {
void initializeGpioClock(GPIO_TypeDef* gpioPort);
}
#endif /* FSFW_HAL_STM32H7_GPIO_GPIO_H_ */

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;

View File

@ -35,8 +35,7 @@ public:
* @param spiHandle
* @param transferMode
*/
SpiComIF(object_id_t objectId, SPI_TypeDef* spiInstance, SPI_HandleTypeDef* spiHandle,
spi::TransferModes transferMode);
SpiComIF(object_id_t objectId, spi::TransferModes transferMode);
/**
* Allows the user to disable cache maintenance on the TX buffer. This can be done if the
@ -81,7 +80,6 @@ private:
uint32_t defaultPollingTimeout = 50;
spi::TransferModes transferMode;
SPI_HandleTypeDef* spiHandle;
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
dur_millis_t timeoutMs = 20;
@ -101,16 +99,16 @@ private:
SpiDeviceMap spiDeviceMap;
ReturnValue_t handlePollingSendOperation(uint8_t* recvPtr, SpiCookie* spiCookie,
const uint8_t * sendData, size_t sendLen);
ReturnValue_t handleInterruptSendOperation(uint8_t* recvPtr, SpiCookie* spiCookie,
const uint8_t * sendData, size_t sendLen);
ReturnValue_t handleDmaSendOperation(uint8_t* recvPtr, SpiCookie* spiCookie,
const uint8_t * sendData, size_t sendLen);
ReturnValue_t handleIrqSendOperation(uint8_t* recvPtr, SpiCookie* spiCookie,
const uint8_t * sendData, size_t sendLen);
ReturnValue_t genericIrqSendSetup(uint8_t* recvPtr, SpiCookie* spiCookie,
const uint8_t * sendData, size_t sendLen);
ReturnValue_t handlePollingSendOperation(uint8_t* recvPtr, SPI_HandleTypeDef& spiHandle,
SpiCookie& spiCookie, const uint8_t * sendData, size_t sendLen);
ReturnValue_t handleInterruptSendOperation(uint8_t* recvPtr, SPI_HandleTypeDef& spiHandle,
SpiCookie& spiCookie, const uint8_t * sendData, size_t sendLen);
ReturnValue_t handleDmaSendOperation(uint8_t* recvPtr, SPI_HandleTypeDef& spiHandle,
SpiCookie& spiCookie, const uint8_t * sendData, size_t sendLen);
ReturnValue_t handleIrqSendOperation(uint8_t* recvPtr, SPI_HandleTypeDef& spiHandle,
SpiCookie& spiCookie, const uint8_t * sendData, size_t sendLen);
ReturnValue_t genericIrqSendSetup(uint8_t* recvPtr, SPI_HandleTypeDef& spiHandle,
SpiCookie& spiCookie, const uint8_t * sendData, size_t sendLen);
ReturnValue_t halErrorHandler(HAL_StatusTypeDef status);
static void spiTransferTxCompleteCallback(SPI_HandleTypeDef *hspi, void* args);

View File

@ -1,13 +1,27 @@
#include "SpiCookie.h"
SpiCookie::SpiCookie(address_t deviceAddress, spi::SpiBus spiIdx, uint32_t spiSpeed,
spi::SpiModes spiMode, uint16_t chipSelectGpioPin, GPIO_TypeDef* chipSelectGpioPort,
size_t maxRecvSize):
SpiCookie::SpiCookie(address_t deviceAddress, spi::SpiBus spiIdx, SPI_TypeDef* spiInstance,
uint32_t spiSpeed, spi::SpiModes spiMode, uint16_t chipSelectGpioPin,
GPIO_TypeDef* chipSelectGpioPort, size_t maxRecvSize):
deviceAddress(deviceAddress), spiIdx(spiIdx), spiSpeed(spiSpeed), spiMode(spiMode),
chipSelectGpioPin(chipSelectGpioPin), chipSelectGpioPort(chipSelectGpioPort),
maxRecvSize(maxRecvSize) {
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;
spi::assignSpiMode(spiMode, spiHandle);
spiHandle.Init.BaudRatePrescaler = spi::getPrescaler(HAL_RCC_GetHCLKFreq(), spiSpeed);
}
uint16_t SpiCookie::getChipSelectGpioPin() const {
@ -37,3 +51,7 @@ uint32_t SpiCookie::getSpiSpeed() const {
size_t SpiCookie::getMaxRecvSize() const {
return maxRecvSize;
}
SPI_HandleTypeDef& SpiCookie::getSpiHandle() {
return spiHandle;
}

View File

@ -9,7 +9,8 @@
class SpiCookie: public CookieIF {
public:
SpiCookie(address_t deviceAddress, spi::SpiBus spiIdx, uint32_t spiSpeed, spi::SpiModes spiMode,
SpiCookie(address_t deviceAddress, spi::SpiBus spiIdx, SPI_TypeDef* spiInstance,
uint32_t spiSpeed, spi::SpiModes spiMode,
uint16_t chipSelectGpioPin, GPIO_TypeDef* chipSelectGpioPort, size_t maxRecvSize);
uint16_t getChipSelectGpioPin() const;
@ -19,9 +20,11 @@ public:
spi::SpiModes getSpiMode() const;
uint32_t getSpiSpeed() const;
size_t getMaxRecvSize() const;
SPI_HandleTypeDef& getSpiHandle();
private:
address_t deviceAddress;
SPI_HandleTypeDef spiHandle = {};
spi::SpiBus spiIdx;
uint32_t spiSpeed;
spi::SpiModes spiMode;

View File

@ -1,25 +1,25 @@
#include "spiDefinitions.h"
void spi::assignSpiMode(SpiModes spiMode, SPI_HandleTypeDef *spiHandle) {
void spi::assignSpiMode(SpiModes spiMode, SPI_HandleTypeDef& spiHandle) {
switch(spiMode) {
case(SpiModes::MODE_0): {
spiHandle->Init.CLKPolarity = SPI_POLARITY_LOW;
spiHandle->Init.CLKPhase = SPI_PHASE_1EDGE;
spiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
spiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
break;
}
case(SpiModes::MODE_1): {
spiHandle->Init.CLKPolarity = SPI_POLARITY_LOW;
spiHandle->Init.CLKPhase = SPI_PHASE_2EDGE;
spiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
spiHandle.Init.CLKPhase = SPI_PHASE_2EDGE;
break;
}
case(SpiModes::MODE_2): {
spiHandle->Init.CLKPolarity = SPI_POLARITY_HIGH;
spiHandle->Init.CLKPhase = SPI_PHASE_1EDGE;
spiHandle.Init.CLKPolarity = SPI_POLARITY_HIGH;
spiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
break;
}
case(SpiModes::MODE_3): {
spiHandle->Init.CLKPolarity = SPI_POLARITY_HIGH;
spiHandle->Init.CLKPhase = SPI_PHASE_2EDGE;
spiHandle.Init.CLKPolarity = SPI_POLARITY_HIGH;
spiHandle.Init.CLKPhase = SPI_PHASE_2EDGE;
break;
}
}

View File

@ -27,7 +27,7 @@ enum TransferModes {
DMA
};
void assignSpiMode(SpiModes spiMode, SPI_HandleTypeDef* spiHandle);
void assignSpiMode(SpiModes spiMode, SPI_HandleTypeDef& spiHandle);
/**
* @brief Set SPI frequency to calculate correspondent baud-rate prescaler.