its working
This commit is contained in:
@ -4,13 +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/spiInterrupts.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::TransferModes transferMode):
|
||||
SystemObject(objectId), transferMode(transferMode) {
|
||||
SpiComIF::SpiComIF(object_id_t objectId): SystemObject(objectId) {
|
||||
spi::assignTransferRxTxCompleteCallback(&spiTransferCompleteCallback, this);
|
||||
spi::assignTransferRxCompleteCallback(&spiTransferRxCompleteCallback, this);
|
||||
spi::assignTransferTxCompleteCallback(&spiTransferTxCompleteCallback, this);
|
||||
@ -26,16 +26,6 @@ void SpiComIF::addDmaHandles(DMA_HandleTypeDef *txHandle, DMA_HandleTypeDef *rxH
|
||||
}
|
||||
|
||||
ReturnValue_t SpiComIF::initialize() {
|
||||
if(transferMode == spi::TransferModes::DMA) {
|
||||
DMA_HandleTypeDef *txHandle = nullptr;
|
||||
DMA_HandleTypeDef *rxHandle = nullptr;
|
||||
spi::getDmaHandles(&txHandle, &rxHandle);
|
||||
if(txHandle == nullptr or rxHandle == nullptr) {
|
||||
sif::printError("SpiComIF::initialize: DMA handles not set!\n");
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -49,15 +39,20 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) {
|
||||
#endif
|
||||
return NULLPOINTER;
|
||||
}
|
||||
auto transferMode = spiCookie->getTransferMode();
|
||||
|
||||
if(transferMode == spi::TransferModes::DMA or transferMode == spi::TransferModes::INTERRUPT) {
|
||||
spiSemaphore = dynamic_cast<BinarySemaphore*>(
|
||||
SemaphoreFactory::instance()->createBinarySemaphore());
|
||||
if(transferMode == spi::TransferModes::DMA) {
|
||||
DMA_HandleTypeDef *txHandle = nullptr;
|
||||
DMA_HandleTypeDef *rxHandle = nullptr;
|
||||
spi::getDmaHandles(&txHandle, &rxHandle);
|
||||
if(txHandle == nullptr or rxHandle == nullptr) {
|
||||
sif::printError("SpiComIF::initialize: DMA handles not set!\n");
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
spiMutex = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
|
||||
// This semaphore ensures thread-safety for a given bus
|
||||
spiSemaphore = dynamic_cast<BinarySemaphore*>(
|
||||
SemaphoreFactory::instance()->createBinarySemaphore());
|
||||
address_t spiAddress = spiCookie->getDeviceAddress();
|
||||
|
||||
auto iter = spiDeviceMap.find(spiAddress);
|
||||
@ -82,17 +77,55 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) {
|
||||
|
||||
SPI_HandleTypeDef& spiHandle = spiCookie->getSpiHandle();
|
||||
|
||||
auto spiIdx = spiCookie->getSpiIdx();
|
||||
if(spiIdx == spi::SpiBus::SPI_1) {
|
||||
#ifdef SPI1
|
||||
spiHandle.Instance = SPI1;
|
||||
#endif
|
||||
}
|
||||
else if(spiIdx == spi::SpiBus::SPI_2) {
|
||||
#ifdef SPI2
|
||||
spiHandle.Instance = SPI2;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
printCfgError("SPI Bus Index");
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
auto mspCfg = spiCookie->getMspCfg();
|
||||
|
||||
if(transferMode == spi::TransferModes::POLLING) {
|
||||
// spi::setSpiMspFunctions(&spi::halMspInitPolling, &spiHandle,
|
||||
// &spi::halMspDeinitPolling, &spiHandle);
|
||||
auto typedCfg = dynamic_cast<spi::MspPollingConfigStruct*>(mspCfg);
|
||||
if(typedCfg == nullptr) {
|
||||
printCfgError("Polling MSP");
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
spi::setSpiPollingMspFunctions(typedCfg);
|
||||
}
|
||||
else if(transferMode == spi::TransferModes::INTERRUPT) {
|
||||
// spi::setSpiMspFunctions(&spi::halMspInitInterrupt, &spiHandle,
|
||||
// &spi::halMspDeinitPolling, &spiHandle);
|
||||
auto typedCfg = dynamic_cast<spi::MspIrqConfigStruct*>(mspCfg);
|
||||
if(typedCfg == nullptr) {
|
||||
printCfgError("IRQ MSP");
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
spi::setSpiIrqMspFunctions(typedCfg);
|
||||
}
|
||||
else if(transferMode == spi::TransferModes::DMA) {
|
||||
// spi::setSpiMspFunctions(&spi::halMspInitDma, &spiHandle,
|
||||
// &spi::halMspDeinitDma, &spiHandle);
|
||||
auto typedCfg = dynamic_cast<spi::MspDmaConfigStruct*>(mspCfg);
|
||||
if(typedCfg == nullptr) {
|
||||
printCfgError("DMA MSP");
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
// Check DMA handles
|
||||
DMA_HandleTypeDef* txHandle = nullptr;
|
||||
DMA_HandleTypeDef* rxHandle = nullptr;
|
||||
spi::getDmaHandles(&txHandle, &rxHandle);
|
||||
if(txHandle == nullptr or rxHandle == nullptr) {
|
||||
printCfgError("DMA Handle");
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
spi::setSpiDmaMspFunctions(typedCfg);
|
||||
}
|
||||
|
||||
gpio::initializeGpioClock(gpioPort);
|
||||
@ -106,6 +139,9 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) {
|
||||
sif::printWarning("SpiComIF::initialize: Error initializing SPI\n");
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
// The MSP configuration struct is not required anymore
|
||||
spiCookie->deleteMspCfg();
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -123,6 +159,8 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s
|
||||
}
|
||||
iter->second.currentTransferLen = sendLen;
|
||||
|
||||
auto transferMode = spiCookie->getTransferMode();
|
||||
|
||||
switch(transferMode) {
|
||||
case(spi::TransferModes::POLLING): {
|
||||
return handlePollingSendOperation(iter->second.replyBuffer.data(), spiHandle, *spiCookie,
|
||||
@ -170,12 +208,15 @@ ReturnValue_t SpiComIF::handlePollingSendOperation(uint8_t* recvPtr, SPI_HandleT
|
||||
SpiCookie& spiCookie, const uint8_t *sendData, size_t sendLen) {
|
||||
auto gpioPort = spiCookie.getChipSelectGpioPort();
|
||||
auto gpioPin = spiCookie.getChipSelectGpioPin();
|
||||
spiMutex->lockMutex(timeoutType, timeoutMs);
|
||||
auto returnval = spiSemaphore->acquire(timeoutType, timeoutMs);
|
||||
if(returnval != HasReturnvaluesIF::RETURN_OK) {
|
||||
return returnval;
|
||||
}
|
||||
HAL_GPIO_WritePin(gpioPort, gpioPin, GPIO_PIN_RESET);
|
||||
auto result = HAL_SPI_TransmitReceive(&spiHandle, const_cast<uint8_t*>(sendData),
|
||||
recvPtr, sendLen, defaultPollingTimeout);
|
||||
HAL_GPIO_WritePin(gpioPort, gpioPin, GPIO_PIN_SET);
|
||||
spiMutex->unlockMutex();
|
||||
spiSemaphore->release();
|
||||
switch(result) {
|
||||
case(HAL_OK): {
|
||||
break;
|
||||
@ -227,6 +268,7 @@ ReturnValue_t SpiComIF::handleIrqSendOperation(uint8_t *recvPtr, SPI_HandleTypeD
|
||||
}
|
||||
// yet another HAL driver which is not const-correct..
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
auto transferMode = spiCookie.getTransferMode();
|
||||
if(transferMode == spi::TransferModes::DMA) {
|
||||
if(cacheMaintenanceOnTxBuffer) {
|
||||
/* Clean D-cache. Make sure the address is 32-byte aligned and add 32-bytes to length,
|
||||
@ -246,13 +288,13 @@ ReturnValue_t SpiComIF::handleIrqSendOperation(uint8_t *recvPtr, SPI_HandleTypeD
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return halErrorHandler(status);
|
||||
return halErrorHandler(status, transferMode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t SpiComIF::halErrorHandler(HAL_StatusTypeDef status) {
|
||||
ReturnValue_t SpiComIF::halErrorHandler(HAL_StatusTypeDef status, spi::TransferModes transferMode) {
|
||||
char modeString[10];
|
||||
if(transferMode == spi::TransferModes::DMA) {
|
||||
std::snprintf(modeString, sizeof(modeString), "Dma");
|
||||
@ -291,10 +333,14 @@ ReturnValue_t SpiComIF::genericIrqSendSetup(uint8_t *recvPtr, SPI_HandleTypeDef&
|
||||
ReturnValue_t result = spiSemaphore->acquire(SemaphoreIF::TimeoutType::WAITING, timeoutMs);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
// Configuration error
|
||||
sif::printWarning("SpiComIF::handleInterruptSendOperation: Semaphore"
|
||||
sif::printWarning("SpiComIF::handleInterruptSendOperation: Semaphore "
|
||||
"could not be acquired after %d ms\n", timeoutMs);
|
||||
return result;
|
||||
}
|
||||
// Cache the current SPI handle in any case
|
||||
spi::setSpiHandle(&spiHandle);
|
||||
// The SPI handle is passed to the default SPI callback as a void argument
|
||||
spi::assignSpiUserArgs(spiCookie.getSpiIdx(), reinterpret_cast<void*>(&spiHandle));
|
||||
HAL_GPIO_WritePin(currentGpioPort, currentGpioPin, GPIO_PIN_RESET);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
@ -341,13 +387,13 @@ void SpiComIF::genericIrqHandler(SpiComIF *spiComIF, TransferStates targetState)
|
||||
BaseType_t taskWoken = pdFALSE;
|
||||
ReturnValue_t result = BinarySemaphore::releaseFromISR(spiComIF->spiSemaphore->getSemaphore(),
|
||||
&taskWoken);
|
||||
if(result != HasReturnvaluesIF::RETURN_FAILED) {
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
// Configuration error
|
||||
printf("SpiComIF::genericIrqHandler: Failure releasing Semaphore!\n");
|
||||
}
|
||||
|
||||
// Perform cache maintenance operation for DMA transfers
|
||||
if(spiComIF->transferMode == spi::TransferModes::DMA) {
|
||||
if(spiComIF->currentTransferMode == spi::TransferModes::DMA) {
|
||||
// Invalidate cache prior to access by CPU
|
||||
SCB_InvalidateDCache_by_Addr ((uint32_t *) spiComIF->currentRecvPtr,
|
||||
spiComIF->currentRecvBuffSize);
|
||||
@ -358,3 +404,12 @@ void SpiComIF::genericIrqHandler(SpiComIF *spiComIF, TransferStates targetState)
|
||||
TaskManagement::requestContextSwitch(CallContext::ISR);
|
||||
}
|
||||
}
|
||||
|
||||
void SpiComIF::printCfgError(const char *const type) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "SpiComIF::initializeInterface: Invalid " << type << " configuration"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning("SpiComIF::initializeInterface: Invalid %s configuration\n", type);
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue
Block a user