From f7f6e4d520295083818c971c00ffbc4af6d94c76 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 5 Jun 2021 00:04:38 +0200 Subject: [PATCH] continued spi com if --- stm32h7/spi/SpiComIF.cpp | 80 +++++++++++++++++++++++++++++++++++- stm32h7/spi/SpiComIF.h | 15 ++++++- stm32h7/spi/spiDefinitions.h | 7 ++++ 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/stm32h7/spi/SpiComIF.cpp b/stm32h7/spi/SpiComIF.cpp index b47b919..8a185a2 100644 --- a/stm32h7/spi/SpiComIF.cpp +++ b/stm32h7/spi/SpiComIF.cpp @@ -30,8 +30,6 @@ SpiComIF::SpiComIF(object_id_t objectId, SPI_TypeDef* spiInstance, SPI_HandleTyp // Recommended setting to avoid glitches spiHandle->Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; spiHandle->Init.Mode = SPI_MODE_MASTER; - - spiSemaphore = SemaphoreFactory::instance()->createBinarySemaphore(); } void SpiComIF::configureCacheMaintenanceOnTxBuffer(bool enable) { @@ -70,6 +68,13 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { return NULLPOINTER; } + if(transferMode == spi::TransferModes::DMA or transferMode == spi::TransferModes::INTERRUPT) { + spiSemaphore = SemaphoreFactory::instance()->createBinarySemaphore(); + } + else { + spiMutex = MutexFactory::instance()->createMutex(); + } + address_t spiAddress = spiCookie->getDeviceAddress(); auto iter = spiDeviceMap.find(spiAddress); @@ -102,6 +107,29 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { } ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) { + SpiCookie* spiCookie = dynamic_cast(cookie); + if(spiCookie == nullptr) { + return NULLPOINTER; + } + + spi::assignSpiMode(spiCookie->getSpiMode(), spiHandle); + spiHandle->Init.BaudRatePrescaler = spi::getPrescaler(HAL_RCC_GetHCLKFreq(), + spiCookie->getSpiSpeed()); + auto iter = spiDeviceMap.find(spiCookie->getDeviceAddress()); + if(iter == spiDeviceMap.end()) { + return HasReturnvaluesIF::RETURN_FAILED; + } + switch(transferMode) { + case(spi::TransferModes::POLLING): { + return handlePollingSendOperation(iter, spiCookie, sendData, sendLen); + } + case(spi::TransferModes::INTERRUPT): { + break; + } + case(spi::TransferModes::DMA): { + break; + } + } return HasReturnvaluesIF::RETURN_OK; } @@ -113,6 +141,54 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLe return HasReturnvaluesIF::RETURN_OK; } +void SpiComIF::setDefaultPollingTimeout(dur_millis_t timeout) { + this->defaultPollingTimeout = timeout; +} + ReturnValue_t SpiComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) { return HasReturnvaluesIF::RETURN_OK; } + +ReturnValue_t SpiComIF::handlePollingSendOperation(SpiDeviceMapIter iter, 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(sendData), + iter->second.replyBuffer.data(), + sendLen, defaultPollingTimeout); + HAL_GPIO_WritePin(gpioPort, gpioPin, GPIO_PIN_SET); + spiMutex->unlockMutex(); + switch(result) { + case(HAL_OK): { + break; + } + case(HAL_TIMEOUT): { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "SpiComIF::sendMessage: Polling Mode | Timeout for SPI device" << + spiCookie->getDeviceAddress() << std::endl; +#else + sif::printWarning("SpiComIF::sendMessage: Polling Mode | Timeout for SPI device %d\n", + spiCookie->getDeviceAddress()); +#endif +#endif + return spi::HAL_TIMEOUT_RETVAL; + } + case(HAL_ERROR): + default: { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "SpiComIF::sendMessage: Polling Mode | HAL error for SPI device" << + spiCookie->getDeviceAddress() << std::endl; +#else + sif::printWarning("SpiComIF::sendMessage: Polling Mode | HAL error for SPI device %d\n", + spiCookie->getDeviceAddress()); +#endif +#endif + return spi::HAL_ERROR_RETVAL; + } + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/stm32h7/spi/SpiComIF.h b/stm32h7/spi/SpiComIF.h index 040cf4c..0826e8c 100644 --- a/stm32h7/spi/SpiComIF.h +++ b/stm32h7/spi/SpiComIF.h @@ -13,6 +13,8 @@ #include #include +class SpiCookie; + class SpiComIF: public SystemObject, public DeviceCommunicationIF { @@ -36,6 +38,8 @@ public: */ void configureCacheMaintenanceOnTxBuffer(bool enable); + void setDefaultPollingTimeout(dur_millis_t timeout); + /** * Add the DMA handles. These need to be set in the DMA transfer mode is used * @param txHandle @@ -60,16 +64,25 @@ private: struct SpiInstance { std::vector replyBuffer; }; + uint32_t defaultPollingTimeout = 50; spi::TransferModes transferMode; SPI_HandleTypeDef* spiHandle; - SemaphoreIF* spiSemaphore; + + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + dur_millis_t timeoutMs = 20; + + SemaphoreIF* spiSemaphore = nullptr; + MutexIF* spiMutex = nullptr; bool cacheMaintenanceOnTxBuffer = true; using SpiDeviceMap = std::map; using SpiDeviceMapIter = SpiDeviceMap::iterator; SpiDeviceMap spiDeviceMap; + + ReturnValue_t handlePollingSendOperation(SpiDeviceMapIter iter, SpiCookie* spiCookie, + const uint8_t * sendData, size_t sendLen); }; diff --git a/stm32h7/spi/spiDefinitions.h b/stm32h7/spi/spiDefinitions.h index b812c15..db16df4 100644 --- a/stm32h7/spi/spiDefinitions.h +++ b/stm32h7/spi/spiDefinitions.h @@ -3,11 +3,18 @@ #include "../../common/spi/spiCommon.h" +#include "fsfw/returnvalues/FwClassIds.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" + #include "stm32h7xx_hal.h" #include "stm32h7xx_hal_spi.h" namespace spi { +static constexpr uint8_t HAL_SPI_ID = CLASS_ID::HAL_SPI; +static constexpr ReturnValue_t HAL_TIMEOUT_RETVAL = HasReturnvaluesIF::makeReturnCode(HAL_SPI_ID, 0); +static constexpr ReturnValue_t HAL_ERROR_RETVAL = HasReturnvaluesIF::makeReturnCode(HAL_SPI_ID, 1); + enum SpiBus { SPI_1, SPI_2