continued spi com if
This commit is contained in:
parent
cb121b9faf
commit
c50868c9dc
@ -1,10 +1,103 @@
|
||||
#include "SpiComIF.h"
|
||||
#include "SpiCookie.h"
|
||||
|
||||
SpiComIF::SpiComIF(object_id_t objectId, SPI_TypeDef* spiInstance,
|
||||
spi::TransferModes transferMode): SystemObject(objectId) {
|
||||
#include "fsfw/tasks/SemaphoreFactory.h"
|
||||
#include "fsfw_hal/stm32h7/spi/spiCore.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;
|
||||
|
||||
spiSemaphore = SemaphoreFactory::instance()->createBinarySemaphore();
|
||||
}
|
||||
|
||||
void SpiComIF::configureCacheMaintenanceOnTxBuffer(bool enable) {
|
||||
this->cacheMaintenanceOnTxBuffer = enable;
|
||||
}
|
||||
|
||||
void SpiComIF::addDmaHandles(DMA_HandleTypeDef *txHandle, DMA_HandleTypeDef *rxHandle) {
|
||||
set_dma_handles(txHandle, rxHandle);
|
||||
}
|
||||
|
||||
ReturnValue_t SpiComIF::initialize() {
|
||||
if(transferMode == spi::TransferModes::DMA) {
|
||||
DMA_HandleTypeDef *txHandle = nullptr;
|
||||
DMA_HandleTypeDef *rxHandle = nullptr;
|
||||
get_dma_handles(&txHandle, &rxHandle);
|
||||
if(txHandle == nullptr or rxHandle == nullptr) {
|
||||
sif::printError("SpiComIF::initialize: DMA handles not set!\n");
|
||||
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;
|
||||
}
|
||||
|
||||
ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) {
|
||||
SpiCookie* spiCookie = dynamic_cast<SpiCookie*>(cookie);
|
||||
if(spiCookie == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error < "SpiComIF::initializeInterface: Invalid cookie" << std::endl;
|
||||
#else
|
||||
sif::printError("SpiComIF::initializeInterface: Invalid cookie\n");
|
||||
#endif
|
||||
return NULLPOINTER;
|
||||
}
|
||||
|
||||
address_t spiAddress = spiCookie->getDeviceAddress();
|
||||
|
||||
auto iter = spiDeviceMap.find(spiAddress);
|
||||
if(iter == spiDeviceMap.end()) {
|
||||
size_t bufferSize = spiCookie->getMaxRecvSize();
|
||||
SpiInstance spiInstance = {std::vector<uint8_t>(bufferSize)};
|
||||
auto statusPair = spiDeviceMap.emplace(spiAddress, spiInstance);
|
||||
if (not statusPair.second) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "SpiComIF::initializeInterface: Failed to insert device with address " <<
|
||||
spiAddress << "to SPI device map" << std::endl;
|
||||
#else
|
||||
sif::printError("SpiComIF::initializeInterface: Failed to insert device with address "
|
||||
"%lu to SPI device map\n", static_cast<unsigned long>(spiAddress));
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
#endif /* FSFW_VERBOSE_LEVEL >= 1 */
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
auto gpioPin = spiCookie->getChipSelectGpioPin();
|
||||
auto gpioPort = spiCookie->getChipSelectGpioPort();
|
||||
|
||||
GPIO_InitTypeDef chipSelect = {};
|
||||
chipSelect.Pin = GPIO_PIN_14;
|
||||
chipSelect.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
HAL_GPIO_Init(gpioPort, &chipSelect);
|
||||
HAL_GPIO_WritePin(gpioPort, gpioPin, GPIO_PIN_SET);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define FSFW_HAL_STM32H7_SPI_SPICOMIF_H_
|
||||
|
||||
|
||||
#include "fsfw/tasks/SemaphoreIF.h"
|
||||
#include "fsfw/devicehandlers/DeviceCommunicationIF.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
|
||||
@ -9,11 +10,40 @@
|
||||
#include "stm32h7xx_hal_spi.h"
|
||||
#include "stm32h743xx.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class SpiComIF:
|
||||
public SystemObject,
|
||||
public DeviceCommunicationIF {
|
||||
public:
|
||||
SpiComIF(object_id_t objectId, SPI_TypeDef* spiInstance, spi::TransferModes transferMode);
|
||||
/**
|
||||
* Create a SPI communication interface for the given SPI peripheral (spiInstance)
|
||||
* @param objectId
|
||||
* @param spiInstance
|
||||
* @param spiHandle
|
||||
* @param transferMode
|
||||
*/
|
||||
SpiComIF(object_id_t objectId, SPI_TypeDef* spiInstance, SPI_HandleTypeDef* spiHandle,
|
||||
spi::TransferModes transferMode);
|
||||
|
||||
/**
|
||||
* Allows the user to disable cache maintenance on the TX buffer. This can be done if the
|
||||
* TX buffers are places and MPU protected properly like specified in this link:
|
||||
* https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices
|
||||
* The cache maintenace is enabled by default.
|
||||
* @param enable
|
||||
*/
|
||||
void configureCacheMaintenanceOnTxBuffer(bool enable);
|
||||
|
||||
/**
|
||||
* Add the DMA handles. These need to be set in the DMA transfer mode is used
|
||||
* @param txHandle
|
||||
* @param rxHandle
|
||||
*/
|
||||
void addDmaHandles(DMA_HandleTypeDef* txHandle, DMA_HandleTypeDef* rxHandle);
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
protected:
|
||||
|
||||
// DeviceCommunicationIF overrides
|
||||
@ -25,8 +55,21 @@ protected:
|
||||
size_t requestLen) override;
|
||||
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie,
|
||||
uint8_t **buffer, size_t *size) override;
|
||||
|
||||
private:
|
||||
SPI_HandleTypeDef spiHandle;
|
||||
struct SpiInstance {
|
||||
std::vector<uint8_t> replyBuffer;
|
||||
};
|
||||
|
||||
spi::TransferModes transferMode;
|
||||
SPI_HandleTypeDef* spiHandle;
|
||||
SemaphoreIF* spiSemaphore;
|
||||
bool cacheMaintenanceOnTxBuffer = true;
|
||||
|
||||
using SpiDeviceMap = std::map<address_t, SpiInstance>;
|
||||
using SpiDeviceMapIter = SpiDeviceMap::iterator;
|
||||
|
||||
SpiDeviceMap spiDeviceMap;
|
||||
};
|
||||
|
||||
|
||||
|
@ -3,7 +3,37 @@
|
||||
|
||||
|
||||
SpiCookie::SpiCookie(address_t deviceAddress, spi::SpiBus spiIdx, uint32_t spiSpeed,
|
||||
spi::SpiModes spiMode, uint16_t chipSelectGpioPin, GPIO_TypeDef* chipSelectGpioPort):
|
||||
spi::SpiModes spiMode, uint16_t chipSelectGpioPin, GPIO_TypeDef* chipSelectGpioPort,
|
||||
size_t maxRecvSize):
|
||||
deviceAddress(deviceAddress), spiIdx(spiIdx), spiSpeed(spiSpeed), spiMode(spiMode),
|
||||
chipSelectGpioPin(chipSelectGpioPin), chipSelectGpioPort(chipSelectGpioPort) {
|
||||
chipSelectGpioPin(chipSelectGpioPin), chipSelectGpioPort(chipSelectGpioPort),
|
||||
maxRecvSize(maxRecvSize) {
|
||||
}
|
||||
|
||||
uint16_t SpiCookie::getChipSelectGpioPin() const {
|
||||
return chipSelectGpioPin;
|
||||
}
|
||||
|
||||
GPIO_TypeDef* SpiCookie::getChipSelectGpioPort() {
|
||||
return chipSelectGpioPort;
|
||||
}
|
||||
|
||||
address_t SpiCookie::getDeviceAddress() const {
|
||||
return deviceAddress;
|
||||
}
|
||||
|
||||
spi::SpiBus SpiCookie::getSpiIdx() const {
|
||||
return spiIdx;
|
||||
}
|
||||
|
||||
spi::SpiModes SpiCookie::getSpiMode() const {
|
||||
return spiMode;
|
||||
}
|
||||
|
||||
uint32_t SpiCookie::getSpiSpeed() const {
|
||||
return spiSpeed;
|
||||
}
|
||||
|
||||
size_t SpiCookie::getMaxRecvSize() const {
|
||||
return maxRecvSize;
|
||||
}
|
||||
|
@ -10,7 +10,16 @@
|
||||
class SpiCookie: public CookieIF {
|
||||
public:
|
||||
SpiCookie(address_t deviceAddress, spi::SpiBus spiIdx, uint32_t spiSpeed, spi::SpiModes spiMode,
|
||||
uint16_t chipSelectGpioPin, GPIO_TypeDef* chipSelectGpioPort);
|
||||
uint16_t chipSelectGpioPin, GPIO_TypeDef* chipSelectGpioPort, size_t maxRecvSize);
|
||||
|
||||
uint16_t getChipSelectGpioPin() const;
|
||||
GPIO_TypeDef* getChipSelectGpioPort();
|
||||
address_t getDeviceAddress() const;
|
||||
spi::SpiBus getSpiIdx() const;
|
||||
spi::SpiModes getSpiMode() const;
|
||||
uint32_t getSpiSpeed() const;
|
||||
size_t getMaxRecvSize() const;
|
||||
|
||||
private:
|
||||
address_t deviceAddress;
|
||||
spi::SpiBus spiIdx;
|
||||
@ -18,6 +27,7 @@ private:
|
||||
spi::SpiModes spiMode;
|
||||
uint16_t chipSelectGpioPin;
|
||||
GPIO_TypeDef* chipSelectGpioPort;
|
||||
const size_t maxRecvSize;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user