119 lines
4.5 KiB
C++
119 lines
4.5 KiB
C++
#include "SpiComIF.h"
|
|
#include "SpiCookie.h"
|
|
|
|
#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;
|
|
}
|
|
|
|
ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) {
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t SpiComIF::getSendSuccess(CookieIF *cookie) {
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) {
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|
|
|
|
ReturnValue_t SpiComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) {
|
|
return HasReturnvaluesIF::RETURN_OK;
|
|
}
|