continued spi com if

This commit is contained in:
Robin Müller 2021-06-05 00:04:38 +02:00
parent c50868c9dc
commit f7f6e4d520
No known key found for this signature in database
GPG Key ID: BE6480244DFE612C
3 changed files with 99 additions and 3 deletions

View File

@ -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<SpiCookie*>(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<uint8_t*>(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;
}

View File

@ -13,6 +13,8 @@
#include <vector>
#include <map>
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<uint8_t> 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<address_t, SpiInstance>;
using SpiDeviceMapIter = SpiDeviceMap::iterator;
SpiDeviceMap spiDeviceMap;
ReturnValue_t handlePollingSendOperation(SpiDeviceMapIter iter, SpiCookie* spiCookie,
const uint8_t * sendData, size_t sendLen);
};

View File

@ -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