refactored everything
This commit is contained in:
parent
0e79b5f4ae
commit
8f61c23e62
@ -6,7 +6,7 @@ GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceC
|
||||
CookieIF *comCookie):
|
||||
DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||
dataset(this) {
|
||||
#if L3GD20_GYRO_DEBUG == 1
|
||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
||||
debugDivider = new PeriodicOperationDivider(5);
|
||||
#endif
|
||||
}
|
||||
@ -28,11 +28,12 @@ void GyroHandlerL3GD20H::doStartUp() {
|
||||
if(internalState == InternalState::CHECK_REGS) {
|
||||
if(commandExecuted) {
|
||||
internalState = InternalState::NORMAL;
|
||||
#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1
|
||||
setMode(MODE_NORMAL);
|
||||
#else
|
||||
setMode(_MODE_TO_ON);
|
||||
#endif
|
||||
if(goNormalModeImmediately) {
|
||||
setMode(MODE_NORMAL);
|
||||
}
|
||||
else {
|
||||
setMode(_MODE_TO_ON);
|
||||
}
|
||||
commandExecuted = false;
|
||||
}
|
||||
}
|
||||
@ -85,9 +86,7 @@ ReturnValue_t GyroHandlerL3GD20H::buildCommandFromCommand(
|
||||
size_t commandDataLen) {
|
||||
switch(deviceCommand) {
|
||||
case(L3GD20H::READ_REGS): {
|
||||
commandBuffer[0] = L3GD20H::READ_START | L3GD20H::AUTO_INCREMENT_MASK |
|
||||
L3GD20H::READ_MASK;
|
||||
|
||||
commandBuffer[0] = L3GD20H::READ_START | L3GD20H::AUTO_INCREMENT_MASK | L3GD20H::READ_MASK;
|
||||
std::memset(commandBuffer + 1, 0, L3GD20H::READ_LEN);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = L3GD20H::READ_LEN + 1;
|
||||
@ -196,7 +195,7 @@ ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id,
|
||||
|
||||
int8_t temperaturOffset = (-1) * packet[L3GD20H::TEMPERATURE_IDX];
|
||||
float temperature = 25.0 + temperaturOffset;
|
||||
#if L3GD20_GYRO_DEBUG == 1
|
||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
||||
if(debugDivider->checkAndIncrement()) {
|
||||
/* Set terminal to utf-8 if there is an issue with micro printout. */
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -235,6 +234,10 @@ uint32_t GyroHandlerL3GD20H::getTransitionDelayMs(Mode_t from, Mode_t to) {
|
||||
return 10000;
|
||||
}
|
||||
|
||||
void GyroHandlerL3GD20H::setGoNormalModeAtStartup() {
|
||||
this->goNormalModeImmediately = true;
|
||||
}
|
||||
|
||||
ReturnValue_t GyroHandlerL3GD20H::initializeLocalDataPool(
|
||||
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_X,
|
||||
|
@ -7,9 +7,9 @@
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||
|
||||
#ifndef L3GD20_GYRO_DEBUG
|
||||
#define L3GD20_GYRO_DEBUG 1
|
||||
#endif
|
||||
#ifndef FSFW_HAL_L3GD20_GYRO_DEBUG
|
||||
#define FSFW_HAL_L3GD20_GYRO_DEBUG 1
|
||||
#endif /* FSFW_HAL_L3GD20_GYRO_DEBUG */
|
||||
|
||||
/**
|
||||
* @brief Device Handler for the L3GD20H gyroscope sensor
|
||||
@ -26,6 +26,7 @@ public:
|
||||
CookieIF* comCookie);
|
||||
virtual ~GyroHandlerL3GD20H();
|
||||
|
||||
void setGoNormalModeAtStartup();
|
||||
protected:
|
||||
|
||||
/* DeviceHandlerBase overrides */
|
||||
@ -62,6 +63,7 @@ private:
|
||||
bool commandExecuted = false;
|
||||
|
||||
uint8_t statusReg = 0;
|
||||
bool goNormalModeImmediately = false;
|
||||
|
||||
uint8_t ctrlReg1Value = L3GD20H::CTRL_REG_1_VAL;
|
||||
uint8_t ctrlReg2Value = L3GD20H::CTRL_REG_2_VAL;
|
||||
@ -74,7 +76,7 @@ private:
|
||||
// Set default value
|
||||
float sensitivity = L3GD20H::SENSITIVITY_00;
|
||||
|
||||
#if L3GD20_GYRO_DEBUG == 1
|
||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
||||
PeriodicOperationDivider* debugDivider = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
@ -3,5 +3,5 @@ add_subdirectory(gpio)
|
||||
add_subdirectory(devicetest)
|
||||
|
||||
target_sources(${LIB_FSFW_HAL_NAME} PRIVATE
|
||||
dmaInterrupts.cpp
|
||||
dma.cpp
|
||||
)
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "../spi/mspInit.h"
|
||||
#include "../spi/spiDefinitions.h"
|
||||
#include "../spi/spiCore.h"
|
||||
#include "../spi/spiInterrupts.h"
|
||||
#include "../spi/stm32h743ziSpi.h"
|
||||
|
||||
#include "fsfw/tasks/TaskFactory.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
@ -20,24 +22,32 @@ GyroL3GD20H::txBuffer __attribute__((section(".dma_buffer")));
|
||||
TransferStates transferState = TransferStates::IDLE;
|
||||
spi::TransferModes GyroL3GD20H::transferMode = spi::TransferModes::POLLING;
|
||||
|
||||
DMA_HandleTypeDef txDmaHandle;
|
||||
DMA_HandleTypeDef rxDmaHandle;
|
||||
|
||||
GyroL3GD20H::GyroL3GD20H(SPI_HandleTypeDef *spiHandle, spi::TransferModes transferMode_):
|
||||
spiHandle(spiHandle) {
|
||||
spiHandle(spiHandle) {
|
||||
txDmaHandle = new DMA_HandleTypeDef();
|
||||
rxDmaHandle = new DMA_HandleTypeDef();
|
||||
spi::setSpiHandle(spiHandle);
|
||||
transferMode = transferMode_;
|
||||
if(transferMode == spi::TransferModes::DMA) {
|
||||
spi::setDmaHandles(&txDmaHandle, &rxDmaHandle);
|
||||
spi::setSpiMspFunctions(&spi::halMspInitDma, spiHandle,
|
||||
&spi::halMspDeinitDma, spiHandle);
|
||||
mspCfg = new spi::MspDmaConfigStruct();
|
||||
auto typedCfg = dynamic_cast<spi::MspDmaConfigStruct*>(mspCfg);
|
||||
spi::setDmaHandles(txDmaHandle, rxDmaHandle);
|
||||
spi::h743zi::standardDmaCfg(*typedCfg, IrqPriorities::HIGHEST_FREERTOS,
|
||||
IrqPriorities::HIGHEST_FREERTOS, IrqPriorities::HIGHEST_FREERTOS);
|
||||
spi::setSpiDmaMspFunctions(typedCfg);
|
||||
}
|
||||
else if(transferMode == spi::TransferModes::INTERRUPT) {
|
||||
spi::setSpiMspFunctions(&spi::halMspInitInterrupt, spiHandle,
|
||||
&spi::halMspDeinitInterrupt, spiHandle);
|
||||
mspCfg = new spi::MspIrqConfigStruct();
|
||||
auto typedCfg = dynamic_cast<spi::MspIrqConfigStruct*>(mspCfg);
|
||||
spi::h743zi::standardInterruptCfg(*typedCfg, IrqPriorities::HIGHEST_FREERTOS);
|
||||
spi::setSpiIrqMspFunctions(typedCfg);
|
||||
}
|
||||
else if(transferMode == spi::TransferModes::POLLING) {
|
||||
spi::setSpiMspFunctions(&spi::halMspInitPolling, spiHandle,
|
||||
&spi::halMspDeinitPolling, spiHandle);
|
||||
mspCfg = new spi::MspPollingConfigStruct();
|
||||
auto typedCfg = dynamic_cast<spi::MspPollingConfigStruct*>(mspCfg);
|
||||
spi::h743zi::standardPollingCfg(*typedCfg);
|
||||
spi::setSpiPollingMspFunctions(typedCfg);
|
||||
}
|
||||
|
||||
spi::assignTransferRxTxCompleteCallback(&spiTransferCompleteCallback, nullptr);
|
||||
@ -51,6 +61,12 @@ GyroL3GD20H::GyroL3GD20H(SPI_HandleTypeDef *spiHandle, spi::TransferModes transf
|
||||
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
GyroL3GD20H::~GyroL3GD20H() {
|
||||
delete txDmaHandle;
|
||||
delete rxDmaHandle;
|
||||
delete mspCfg;
|
||||
}
|
||||
|
||||
ReturnValue_t GyroL3GD20H::initialize() {
|
||||
// Configure the SPI peripheral
|
||||
spiHandle->Instance = SPI1;
|
||||
|
@ -3,8 +3,9 @@
|
||||
|
||||
#include "stm32h7xx_hal.h"
|
||||
#include "stm32h7xx_hal_spi.h"
|
||||
|
||||
#include "../spi/mspInit.h"
|
||||
#include "../spi/spiDefinitions.h"
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
#include <cstdint>
|
||||
@ -20,6 +21,7 @@ enum class TransferStates {
|
||||
class GyroL3GD20H {
|
||||
public:
|
||||
GyroL3GD20H(SPI_HandleTypeDef* spiHandle, spi::TransferModes transferMode);
|
||||
~GyroL3GD20H();
|
||||
|
||||
ReturnValue_t initialize();
|
||||
ReturnValue_t performOperation();
|
||||
@ -58,6 +60,11 @@ private:
|
||||
|
||||
void prepareConfigRegs(uint8_t* configRegs);
|
||||
void handleSensorReadout();
|
||||
|
||||
|
||||
DMA_HandleTypeDef* txDmaHandle = {};
|
||||
DMA_HandleTypeDef* rxDmaHandle = {};
|
||||
spi::MspCfgBase* mspCfg = {};
|
||||
};
|
||||
|
||||
#endif /* FSFW_HAL_STM32H7_DEVICETEST_GYRO_L3GD20H_H_ */
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "dmaInterrupts.h"
|
||||
|
||||
#include <fsfw_hal/stm32h7/dma.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
@ -1,18 +1,24 @@
|
||||
#ifndef FSFW_HAL_STM32H7_DMAINTERRUPTS_H_
|
||||
#define FSFW_HAL_STM32H7_DMAINTERRUPTS_H_
|
||||
#ifndef FSFW_HAL_STM32H7_DMA_H_
|
||||
#define FSFW_HAL_STM32H7_DMA_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "interrupts.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace dma {
|
||||
|
||||
enum DMAIndexes {
|
||||
DMA_1 = 0,
|
||||
DMA_2 = 1
|
||||
} ;
|
||||
enum DMAType {
|
||||
TX = 0,
|
||||
RX = 1
|
||||
};
|
||||
|
||||
enum DMAIndexes: uint8_t {
|
||||
DMA_1 = 1,
|
||||
DMA_2 = 2
|
||||
};
|
||||
|
||||
enum DMAStreams {
|
||||
STREAM_0 = 0,
|
||||
@ -40,4 +46,4 @@ void assignDmaUserHandler(DMAIndexes dma_idx, DMAStreams stream_idx,
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FSFW_HAL_STM32H7_DMAINTERRUPTS_H_ */
|
||||
#endif /* FSFW_HAL_STM32H7_DMA_H_ */
|
@ -1,6 +1,8 @@
|
||||
#ifndef FSFW_HAL_STM32H7_INTERRUPTS_H_
|
||||
#define FSFW_HAL_STM32H7_INTERRUPTS_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -13,6 +15,12 @@ extern void Default_Handler();
|
||||
typedef void (*user_handler_t) (void*);
|
||||
typedef void* user_args_t;
|
||||
|
||||
enum IrqPriorities: uint8_t {
|
||||
HIGHEST = 0,
|
||||
HIGHEST_FREERTOS = 6,
|
||||
LOWEST = 15
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -5,4 +5,5 @@ target_sources(${LIB_FSFW_HAL_NAME} PRIVATE
|
||||
mspInit.cpp
|
||||
SpiCookie.cpp
|
||||
SpiComIF.cpp
|
||||
stm32h743ziSpi.cpp
|
||||
)
|
||||
|
@ -83,8 +83,16 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) {
|
||||
SPI_HandleTypeDef& spiHandle = spiCookie->getSpiHandle();
|
||||
|
||||
if(transferMode == spi::TransferModes::POLLING) {
|
||||
spi::setSpiMspFunctions(&spi::halMspInitPolling, &spiHandle,
|
||||
&spi::halMspDeinitPolling, &spiHandle);
|
||||
// spi::setSpiMspFunctions(&spi::halMspInitPolling, &spiHandle,
|
||||
// &spi::halMspDeinitPolling, &spiHandle);
|
||||
}
|
||||
else if(transferMode == spi::TransferModes::INTERRUPT) {
|
||||
// spi::setSpiMspFunctions(&spi::halMspInitInterrupt, &spiHandle,
|
||||
// &spi::halMspDeinitPolling, &spiHandle);
|
||||
}
|
||||
else if(transferMode == spi::TransferModes::DMA) {
|
||||
// spi::setSpiMspFunctions(&spi::halMspInitDma, &spiHandle,
|
||||
// &spi::halMspDeinitDma, &spiHandle);
|
||||
}
|
||||
|
||||
gpio::initializeGpioClock(gpioPort);
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <fsfw_hal/stm32h7/dmaInterrupts.h>
|
||||
#include <fsfw_hal/stm32h7/dma.h>
|
||||
#include "mspInit.h"
|
||||
#include "spiConf.h"
|
||||
#include "spiCore.h"
|
||||
@ -10,6 +10,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
spi::msp_func_t mspInitFunc = nullptr;
|
||||
spi::MspCfgBase* mspInitArgs = nullptr;
|
||||
|
||||
spi::msp_func_t mspDeinitFunc = nullptr;
|
||||
spi::MspCfgBase* mspDeinitArgs = nullptr;
|
||||
|
||||
/**
|
||||
* @brief SPI MSP Initialization
|
||||
* This function configures the hardware resources used in this example:
|
||||
@ -20,38 +26,44 @@
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void spi::halMspInitDma(void *spi_handle) {
|
||||
SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef*) spi_handle;
|
||||
if(hspi == NULL) {
|
||||
return;
|
||||
}
|
||||
if(hspi == NULL) {
|
||||
printf("HAL_SPI_MspInit: Invalid SPI handle!\n");
|
||||
void spi::halMspInitDma(SPI_HandleTypeDef* hspi, MspCfgBase* cfgBase) {
|
||||
auto cfg = dynamic_cast<MspDmaConfigStruct*>(cfgBase);
|
||||
if(hspi == nullptr or cfg == nullptr) {
|
||||
return;
|
||||
}
|
||||
setSpiHandle(hspi);
|
||||
|
||||
DMA_HandleTypeDef* hdma_tx = NULL;
|
||||
DMA_HandleTypeDef* hdma_rx = NULL;
|
||||
DMA_HandleTypeDef* hdma_tx = nullptr;
|
||||
DMA_HandleTypeDef* hdma_rx = nullptr;
|
||||
spi::getDmaHandles(&hdma_tx, &hdma_rx);
|
||||
if(hdma_tx == NULL || hdma_rx == NULL) {
|
||||
printf("HAL_SPI_MspInit: Invalid DMA handles. Make sure to call setDmaHandles!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
spi::halMspInitPolling(spi_handle);
|
||||
if (hspi->Instance == SPI1) {
|
||||
// DMA setup
|
||||
DMAx_CLK_ENABLE();
|
||||
spi::halMspInitInterrupt(hspi, cfg);
|
||||
|
||||
// Configure the DMA
|
||||
/* Configure the DMA handler for Transmission process */
|
||||
// DMA setup
|
||||
if(cfg->dmaClkEnableWrapper == nullptr) {
|
||||
mspErrorHandler("spi::halMspInitDma", "DMA Clock init invalid");
|
||||
}
|
||||
cfg->dmaClkEnableWrapper();
|
||||
|
||||
// Configure the DMA
|
||||
/* Configure the DMA handler for Transmission process */
|
||||
if(hdma_tx->Instance == nullptr) {
|
||||
// Assume it was not configured properly
|
||||
mspErrorHandler("spi::halMspInitDma", "DMA TX handle invalid");
|
||||
}
|
||||
hdma_tx->Instance = SPIx_TX_DMA_STREAM;
|
||||
|
||||
hdma_tx->Init.Request = SPIx_TX_DMA_REQUEST;
|
||||
|
||||
// offer function to configure this..
|
||||
hdma_tx->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
hdma_tx->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
hdma_tx->Init.MemBurst = DMA_MBURST_INC4;
|
||||
hdma_tx->Init.PeriphBurst = DMA_PBURST_INC4;
|
||||
hdma_tx->Init.Request = SPIx_TX_DMA_REQUEST;
|
||||
hdma_tx->Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_tx->Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_tx->Init.MemInc = DMA_MINC_ENABLE;
|
||||
@ -60,53 +72,204 @@ void spi::halMspInitDma(void *spi_handle) {
|
||||
hdma_tx->Init.Mode = DMA_NORMAL;
|
||||
hdma_tx->Init.Priority = DMA_PRIORITY_LOW;
|
||||
|
||||
HAL_DMA_Init(hdma_tx);
|
||||
HAL_DMA_Init(hdma_tx);
|
||||
|
||||
/* Associate the initialized DMA handle to the the SPI handle */
|
||||
__HAL_LINKDMA(hspi, hdmatx, *hdma_tx);
|
||||
/* Associate the initialized DMA handle to the the SPI handle */
|
||||
__HAL_LINKDMA(hspi, hdmatx, *hdma_tx);
|
||||
|
||||
/* Configure the DMA handler for Transmission process */
|
||||
hdma_rx->Instance = SPIx_RX_DMA_STREAM;
|
||||
/* Configure the DMA handler for Transmission process */
|
||||
hdma_rx->Instance = SPIx_RX_DMA_STREAM;
|
||||
|
||||
hdma_rx->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
hdma_rx->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
hdma_rx->Init.MemBurst = DMA_MBURST_INC4;
|
||||
hdma_rx->Init.PeriphBurst = DMA_PBURST_INC4;
|
||||
hdma_rx->Init.Request = SPIx_RX_DMA_REQUEST;
|
||||
hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_rx->Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_rx->Init.Mode = DMA_NORMAL;
|
||||
hdma_rx->Init.Priority = DMA_PRIORITY_HIGH;
|
||||
hdma_rx->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
hdma_rx->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
hdma_rx->Init.MemBurst = DMA_MBURST_INC4;
|
||||
hdma_rx->Init.PeriphBurst = DMA_PBURST_INC4;
|
||||
hdma_rx->Init.Request = SPIx_RX_DMA_REQUEST;
|
||||
hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_rx->Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_rx->Init.Mode = DMA_NORMAL;
|
||||
hdma_rx->Init.Priority = DMA_PRIORITY_HIGH;
|
||||
|
||||
HAL_DMA_Init(hdma_rx);
|
||||
HAL_DMA_Init(hdma_rx);
|
||||
|
||||
/* Associate the initialized DMA handle to the the SPI handle */
|
||||
__HAL_LINKDMA(hspi, hdmarx, *hdma_rx);
|
||||
/* Associate the initialized DMA handle to the the SPI handle */
|
||||
__HAL_LINKDMA(hspi, hdmarx, *hdma_rx);
|
||||
|
||||
/*##-4- Configure the NVIC for DMA #########################################*/
|
||||
/* NVIC configuration for DMA transfer complete interrupt (SPI1_RX) */
|
||||
// Assign the interrupt handler
|
||||
dma::assignDmaUserHandler(dma::DMAIndexes::DMA_2, dma::DMAStreams::STREAM_2,
|
||||
&spi::dmaRxIrqHandler, hdma_rx);
|
||||
HAL_NVIC_SetPriority(SPIx_DMA_RX_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(SPIx_DMA_RX_IRQn);
|
||||
/*##-4- Configure the NVIC for DMA #########################################*/
|
||||
/* NVIC configuration for DMA transfer complete interrupt (SPI1_RX) */
|
||||
// Assign the interrupt handler
|
||||
dma::assignDmaUserHandler(cfg->rxDmaIndex, cfg->rxDmaStream, &spi::dmaRxIrqHandler, hdma_rx);
|
||||
HAL_NVIC_SetPriority(cfg->rxDmaIrqNumber, cfg->rxPreEmptPriority, cfg->rxSubpriority);
|
||||
HAL_NVIC_EnableIRQ(cfg->rxDmaIrqNumber);
|
||||
|
||||
/* NVIC configuration for DMA transfer complete interrupt (SPI1_TX) */
|
||||
// Assign the interrupt handler
|
||||
dma::assignDmaUserHandler(dma::DMAIndexes::DMA_2, dma::DMAStreams::STREAM_3,
|
||||
&spi::dmaTxIrqHandler, hdma_tx);
|
||||
HAL_NVIC_SetPriority(SPIx_DMA_TX_IRQn, 1, 1);
|
||||
HAL_NVIC_EnableIRQ(SPIx_DMA_TX_IRQn);
|
||||
/* NVIC configuration for DMA transfer complete interrupt (SPI1_TX) */
|
||||
// Assign the interrupt handler
|
||||
dma::assignDmaUserHandler(cfg->txDmaIndex, cfg->txDmaStream,
|
||||
&spi::dmaTxIrqHandler, hdma_tx);
|
||||
HAL_NVIC_SetPriority(cfg->txDmaIrqNumber, cfg->txPreEmptPriority, cfg->txSubpriority);
|
||||
HAL_NVIC_EnableIRQ(cfg->txDmaIrqNumber);
|
||||
|
||||
/*##-5- Configure the NVIC for SPI #########################################*/
|
||||
/* NVIC configuration for SPI transfer complete interrupt (SPI1) */
|
||||
// Assign the interrupt handler
|
||||
spi::assignSpiUserHandler(spi::SPI_1, &spi::spi1IrqHandler, hspi);
|
||||
HAL_NVIC_SetPriority(SPIx_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(SPIx_IRQn);
|
||||
/*##-5- Configure the NVIC for SPI #########################################*/
|
||||
/* NVIC configuration for SPI transfer complete interrupt (SPI1) */
|
||||
// Assign the interrupt handler
|
||||
spi::assignSpiUserHandler(spi::SPI_1, &spi::spiIrqHandler, hspi);
|
||||
HAL_NVIC_SetPriority(SPIx_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(SPIx_IRQn);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI MSP De-Initialization
|
||||
* This function frees the hardware resources used in this example:
|
||||
* - Disable the Peripheral's clock
|
||||
* - Revert GPIO, DMA and NVIC configuration to their default state
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void spi::halMspDeinitDma(SPI_HandleTypeDef* hspi, MspCfgBase* cfgBase) {
|
||||
auto cfg = dynamic_cast<MspDmaConfigStruct*>(cfgBase);
|
||||
if(hspi == nullptr or cfg == nullptr) {
|
||||
return;
|
||||
}
|
||||
spi::halMspDeinitInterrupt(hspi, cfgBase);
|
||||
DMA_HandleTypeDef* hdma_tx = NULL;
|
||||
DMA_HandleTypeDef* hdma_rx = NULL;
|
||||
spi::getDmaHandles(&hdma_tx, &hdma_rx);
|
||||
if(hdma_tx == NULL || hdma_rx == NULL) {
|
||||
printf("HAL_SPI_MspInit: Invalid DMA handles. Make sure to call setDmaHandles!\n");
|
||||
}
|
||||
else {
|
||||
// Disable the DMA
|
||||
/* De-Initialize the DMA associated to transmission process */
|
||||
HAL_DMA_DeInit(hdma_tx);
|
||||
/* De-Initialize the DMA associated to reception process */
|
||||
HAL_DMA_DeInit(hdma_rx);
|
||||
}
|
||||
|
||||
// Disable the NVIC for DMA
|
||||
HAL_NVIC_DisableIRQ(cfg->txDmaIrqNumber);
|
||||
HAL_NVIC_DisableIRQ(cfg->rxDmaIrqNumber);
|
||||
|
||||
}
|
||||
|
||||
void spi::halMspInitPolling(SPI_HandleTypeDef* hspi, MspCfgBase* cfgBase) {
|
||||
auto cfg = dynamic_cast<MspPollingConfigStruct*>(cfgBase);
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {};
|
||||
/*##-1- Enable peripherals and GPIO Clocks #################################*/
|
||||
/* Enable GPIO TX/RX clock */
|
||||
cfg->setupMacroWrapper();
|
||||
|
||||
/*##-2- Configure peripheral GPIO ##########################################*/
|
||||
/* SPI SCK GPIO pin configuration */
|
||||
GPIO_InitStruct.Pin = cfg->sckPin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = cfg->sckAlternateFunction;
|
||||
HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* SPI MISO GPIO pin configuration */
|
||||
GPIO_InitStruct.Pin = cfg->misoPin;
|
||||
GPIO_InitStruct.Alternate = cfg->misoAlternateFunction;
|
||||
HAL_GPIO_Init(cfg->misoPort, &GPIO_InitStruct);
|
||||
|
||||
/* SPI MOSI GPIO pin configuration */
|
||||
GPIO_InitStruct.Pin = cfg->mosiPin;
|
||||
GPIO_InitStruct.Alternate = cfg->mosiAlternateFunction;
|
||||
HAL_GPIO_Init(cfg->mosiPort, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
void spi::halMspDeinitPolling(SPI_HandleTypeDef* hspi, MspCfgBase* cfgBase) {
|
||||
auto cfg = reinterpret_cast<MspPollingConfigStruct*>(cfgBase);
|
||||
// Reset peripherals
|
||||
cfg->cleanUpMacroWrapper();
|
||||
|
||||
// Disable peripherals and GPIO Clocks
|
||||
/* Configure SPI SCK as alternate function */
|
||||
HAL_GPIO_DeInit(cfg->sckPort, cfg->sckPin);
|
||||
/* Configure SPI MISO as alternate function */
|
||||
HAL_GPIO_DeInit(cfg->misoPort, cfg->misoPin);
|
||||
/* Configure SPI MOSI as alternate function */
|
||||
HAL_GPIO_DeInit(cfg->mosiPort, cfg->mosiPin);
|
||||
}
|
||||
|
||||
void spi::halMspInitInterrupt(SPI_HandleTypeDef* hspi, MspCfgBase* cfgBase) {
|
||||
auto cfg = dynamic_cast<MspIrqConfigStruct*>(cfgBase);
|
||||
if(cfg == nullptr or hspi == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
spi::halMspInitPolling(hspi, cfg);
|
||||
// Configure the NVIC for SPI
|
||||
spi::assignSpiUserHandler(cfg->spiBus, cfg->spiIrqHandler, cfg->spiUserArgs);
|
||||
HAL_NVIC_SetPriority(cfg->spiIrqNumber, cfg->preEmptPriority, cfg->subpriority);
|
||||
HAL_NVIC_EnableIRQ(cfg->spiIrqNumber);
|
||||
}
|
||||
|
||||
void spi::halMspDeinitInterrupt(SPI_HandleTypeDef* hspi, MspCfgBase* cfgBase) {
|
||||
auto cfg = dynamic_cast<MspIrqConfigStruct*>(cfgBase);
|
||||
spi::halMspDeinitPolling(hspi, cfg);
|
||||
// Disable the NVIC for SPI
|
||||
HAL_NVIC_DisableIRQ(cfg->spiIrqNumber);
|
||||
}
|
||||
|
||||
void spi::getMspInitFunction(msp_func_t* init_func, MspCfgBase** args) {
|
||||
if(init_func != NULL && args != NULL) {
|
||||
*init_func = mspInitFunc;
|
||||
*args = mspInitArgs;
|
||||
}
|
||||
}
|
||||
|
||||
void spi::getMspDeinitFunction(msp_func_t* deinit_func, MspCfgBase** args) {
|
||||
if(deinit_func != NULL && args != NULL) {
|
||||
*deinit_func = mspDeinitFunc;
|
||||
*args = mspDeinitArgs;
|
||||
}
|
||||
}
|
||||
|
||||
void spi::setSpiDmaMspFunctions(MspDmaConfigStruct* cfg,
|
||||
msp_func_t initFunc, msp_func_t deinitFunc) {
|
||||
mspInitFunc = initFunc;
|
||||
mspDeinitFunc = deinitFunc;
|
||||
mspInitArgs = cfg;
|
||||
mspDeinitArgs = cfg;
|
||||
}
|
||||
|
||||
void spi::setSpiIrqMspFunctions(MspIrqConfigStruct *cfg, msp_func_t initFunc,
|
||||
msp_func_t deinitFunc) {
|
||||
mspInitFunc = initFunc;
|
||||
mspDeinitFunc = deinitFunc;
|
||||
mspInitArgs = cfg;
|
||||
mspDeinitArgs = cfg;
|
||||
}
|
||||
|
||||
void spi::setSpiPollingMspFunctions(MspPollingConfigStruct *cfg, msp_func_t initFunc,
|
||||
msp_func_t deinitFunc) {
|
||||
mspInitFunc = initFunc;
|
||||
mspDeinitFunc = deinitFunc;
|
||||
mspInitArgs = cfg;
|
||||
mspDeinitArgs = cfg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI MSP Initialization
|
||||
* This function configures the hardware resources used in this example:
|
||||
* - Peripheral's clock enable
|
||||
* - Peripheral's GPIO Configuration
|
||||
* - DMA configuration for transmission request by peripheral
|
||||
* - NVIC configuration for DMA interrupt request enable
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
extern "C" void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) {
|
||||
if(mspInitFunc != NULL) {
|
||||
mspInitFunc(hspi, mspInitArgs);
|
||||
}
|
||||
else {
|
||||
printf("HAL_SPI_MspInit: Please call set_msp_functions to assign SPI MSP functions\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,91 +281,15 @@ void spi::halMspInitDma(void *spi_handle) {
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void spi::halMspDeinitDma(void *spi_handle)
|
||||
{
|
||||
SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef*) spi_handle;
|
||||
if(hspi == NULL) {
|
||||
return;
|
||||
extern "C" void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) {
|
||||
if(mspDeinitFunc != NULL) {
|
||||
mspDeinitFunc(hspi, mspDeinitArgs);
|
||||
}
|
||||
spi::halMspDeinitPolling(spi_handle);
|
||||
if(hspi->Instance == SPIx) {
|
||||
DMA_HandleTypeDef* hdma_tx = NULL;
|
||||
DMA_HandleTypeDef* hdma_rx = NULL;
|
||||
spi::getDmaHandles(&hdma_tx, &hdma_rx);
|
||||
if(hdma_tx == NULL || hdma_rx == NULL) {
|
||||
printf("HAL_SPI_MspInit: Invalid DMA handles. Make sure to call setDmaHandles!\n");
|
||||
}
|
||||
else {
|
||||
/*##-3- Disable the DMA ####################################################*/
|
||||
/* De-Initialize the DMA associated to transmission process */
|
||||
HAL_DMA_DeInit(hdma_tx);
|
||||
/* De-Initialize the DMA associated to reception process */
|
||||
HAL_DMA_DeInit(hdma_rx);
|
||||
}
|
||||
|
||||
/*##-4- Disable the NVIC for DMA ###########################################*/
|
||||
HAL_NVIC_DisableIRQ(SPIx_DMA_TX_IRQn);
|
||||
HAL_NVIC_DisableIRQ(SPIx_DMA_RX_IRQn);
|
||||
|
||||
/*##-5- Disable the NVIC for SPI ###########################################*/
|
||||
HAL_NVIC_EnableIRQ(SPIx_IRQn);
|
||||
else {
|
||||
printf("HAL_SPI_MspDeInit: Please call set_msp_functions to assign SPI MSP functions\n");
|
||||
}
|
||||
}
|
||||
|
||||
void spi::halMspInitPolling(void *hspi) {
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {};
|
||||
/*##-1- Enable peripherals and GPIO Clocks #################################*/
|
||||
/* Enable GPIO TX/RX clock */
|
||||
SPIx_SCK_GPIO_CLK_ENABLE();
|
||||
SPIx_MISO_GPIO_CLK_ENABLE();
|
||||
SPIx_MOSI_GPIO_CLK_ENABLE();
|
||||
/* Enable SPI clock */
|
||||
SPIx_CLK_ENABLE();
|
||||
|
||||
/*##-2- Configure peripheral GPIO ##########################################*/
|
||||
/* SPI SCK GPIO pin configuration */
|
||||
GPIO_InitStruct.Pin = SPIx_SCK_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Alternate = SPIx_SCK_AF;
|
||||
HAL_GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* SPI MISO GPIO pin configuration */
|
||||
GPIO_InitStruct.Pin = SPIx_MISO_PIN;
|
||||
GPIO_InitStruct.Alternate = SPIx_MISO_AF;
|
||||
HAL_GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* SPI MOSI GPIO pin configuration */
|
||||
GPIO_InitStruct.Pin = SPIx_MOSI_PIN;
|
||||
GPIO_InitStruct.Alternate = SPIx_MOSI_AF;
|
||||
HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
void spi::halMspDeinitPolling(void *hspi) {
|
||||
/*##-1- Reset peripherals ##################################################*/
|
||||
SPIx_FORCE_RESET();
|
||||
SPIx_RELEASE_RESET();
|
||||
|
||||
/*##-2- Disable peripherals and GPIO Clocks ################################*/
|
||||
/* Configure SPI SCK as alternate function */
|
||||
HAL_GPIO_DeInit(SPIx_SCK_GPIO_PORT, SPIx_SCK_PIN);
|
||||
/* Configure SPI MISO as alternate function */
|
||||
HAL_GPIO_DeInit(SPIx_MISO_GPIO_PORT, SPIx_MISO_PIN);
|
||||
/* Configure SPI MOSI as alternate function */
|
||||
HAL_GPIO_DeInit(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_PIN);
|
||||
}
|
||||
|
||||
void spi::halMspInitInterrupt(void *hspi) {
|
||||
spi::halMspInitPolling(hspi);
|
||||
// Configure the NVIC for SPI
|
||||
spi::assignSpiUserHandler(spi::SPI_1, &spi::spi1IrqHandler, hspi);
|
||||
HAL_NVIC_SetPriority(SPIx_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(SPIx_IRQn);
|
||||
}
|
||||
|
||||
void spi::halMspDeinitInterrupt(void *hspi) {
|
||||
spi::halMspDeinitPolling(hspi);
|
||||
// Disable the NVIC for SPI
|
||||
HAL_NVIC_DisableIRQ(SPIx_IRQn);
|
||||
void spi::mspErrorHandler(const char* const function, const char *const message) {
|
||||
printf("%s failure: %s\n", function, message);
|
||||
}
|
||||
|
@ -1,20 +1,103 @@
|
||||
#ifndef FSFW_HAL_STM32H7_SPI_MSPINIT_H_
|
||||
#define FSFW_HAL_STM32H7_SPI_MSPINIT_H_
|
||||
|
||||
#include "spiDefinitions.h"
|
||||
#include "../dma.h"
|
||||
#include "stm32h7xx_hal_spi.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
namespace spi {
|
||||
|
||||
void halMspInitDma(void *hspi);
|
||||
void halMspDeinitDma(void *hspi);
|
||||
struct MspCfgBase {
|
||||
virtual ~MspCfgBase() = default;
|
||||
|
||||
void halMspInitPolling(void *hspi);
|
||||
void halMspDeinitPolling(void *hspi);
|
||||
void (* cleanUpMacroWrapper) (void) = nullptr;
|
||||
void (* setupMacroWrapper) (void) = nullptr;
|
||||
|
||||
void halMspInitInterrupt(void *hspi);
|
||||
void halMspDeinitInterrupt(void *hspi);
|
||||
GPIO_TypeDef* sckPort = nullptr;
|
||||
uint32_t sckPin = 0;
|
||||
uint8_t sckAlternateFunction = 0;
|
||||
GPIO_TypeDef* mosiPort = nullptr;
|
||||
uint32_t mosiPin = 0;
|
||||
uint8_t mosiAlternateFunction = 0;
|
||||
GPIO_TypeDef* misoPort = nullptr;
|
||||
uint32_t misoPin = 0;
|
||||
uint8_t misoAlternateFunction = 0;
|
||||
};
|
||||
|
||||
struct MspPollingConfigStruct: public MspCfgBase {};
|
||||
|
||||
/* A valid instance of this struct must be passed to the MSP initialization function as a void*
|
||||
argument */
|
||||
struct MspIrqConfigStruct: public MspPollingConfigStruct {
|
||||
SpiBus spiBus = SpiBus::SPI_1;
|
||||
user_handler_t spiIrqHandler = nullptr;
|
||||
user_args_t spiUserArgs = nullptr;
|
||||
IRQn_Type spiIrqNumber = SPI1_IRQn;
|
||||
// Priorities for NVIC
|
||||
// Pre-Empt priority ranging from 0 to 15. If FreeRTOS calls are used, only 5-15 are allowed
|
||||
IrqPriorities preEmptPriority = IrqPriorities::LOWEST;
|
||||
IrqPriorities subpriority = IrqPriorities::LOWEST;
|
||||
};
|
||||
|
||||
/* A valid instance of this struct must be passed to the MSP initialization function as a void*
|
||||
argument */
|
||||
struct MspDmaConfigStruct: public MspIrqConfigStruct {
|
||||
void (* dmaClkEnableWrapper) (void) = nullptr;
|
||||
dma::DMAIndexes txDmaIndex;
|
||||
dma::DMAIndexes rxDmaIndex;
|
||||
dma::DMAStreams txDmaStream;
|
||||
dma::DMAStreams rxDmaStream;
|
||||
IRQn_Type txDmaIrqNumber = DMA1_Stream0_IRQn;
|
||||
IRQn_Type rxDmaIrqNumber = DMA1_Stream1_IRQn;
|
||||
// Priorities for NVIC
|
||||
IrqPriorities txPreEmptPriority = IrqPriorities::LOWEST;
|
||||
IrqPriorities rxPreEmptPriority = IrqPriorities::LOWEST;
|
||||
IrqPriorities txSubpriority = IrqPriorities::LOWEST;
|
||||
IrqPriorities rxSubpriority = IrqPriorities::LOWEST;
|
||||
};
|
||||
|
||||
using msp_func_t = void (*) (SPI_HandleTypeDef* hspi, MspCfgBase* cfg);
|
||||
|
||||
|
||||
void getMspInitFunction(msp_func_t* init_func, MspCfgBase **args);
|
||||
void getMspDeinitFunction(msp_func_t* deinit_func, MspCfgBase **args);
|
||||
|
||||
void halMspInitDma(SPI_HandleTypeDef* hspi, MspCfgBase* cfg);
|
||||
void halMspDeinitDma(SPI_HandleTypeDef* hspi, MspCfgBase* cfg);
|
||||
|
||||
void halMspInitInterrupt(SPI_HandleTypeDef* hspi, MspCfgBase* cfg);
|
||||
void halMspDeinitInterrupt(SPI_HandleTypeDef* hspi, MspCfgBase* cfg);
|
||||
|
||||
void halMspInitPolling(SPI_HandleTypeDef* hspi, MspCfgBase* cfg);
|
||||
void halMspDeinitPolling(SPI_HandleTypeDef* hspi, MspCfgBase* cfg);
|
||||
|
||||
/**
|
||||
* Assign MSP init functions. Important for SPI configuration
|
||||
* @param init_func
|
||||
* @param init_args
|
||||
* @param deinit_func
|
||||
* @param deinit_args
|
||||
*/
|
||||
void setSpiDmaMspFunctions(MspDmaConfigStruct* cfg,
|
||||
msp_func_t initFunc = &spi::halMspInitDma,
|
||||
msp_func_t deinitFunc= &spi::halMspDeinitDma
|
||||
);
|
||||
void setSpiIrqMspFunctions(MspIrqConfigStruct* cfg,
|
||||
msp_func_t initFunc = &spi::halMspInitInterrupt,
|
||||
msp_func_t deinitFunc= &spi::halMspDeinitInterrupt
|
||||
);
|
||||
void setSpiPollingMspFunctions(MspPollingConfigStruct* cfg,
|
||||
msp_func_t initFunc = &spi::halMspInitPolling,
|
||||
msp_func_t deinitFunc= &spi::halMspDeinitPolling
|
||||
);
|
||||
|
||||
void mspErrorHandler(const char* const function, const char *const message);
|
||||
|
||||
}
|
||||
|
||||
|
@ -5,12 +5,6 @@ SPI_HandleTypeDef* spiHandle = nullptr;
|
||||
DMA_HandleTypeDef* hdmaTx = nullptr;
|
||||
DMA_HandleTypeDef* hdmaRx = nullptr;
|
||||
|
||||
msp_func_t mspInitFunc = nullptr;
|
||||
void* mspInitArgs = nullptr;
|
||||
|
||||
msp_func_t mspDeinitFunc = nullptr;
|
||||
void* mspDeinitArgs = nullptr;
|
||||
|
||||
spi_transfer_cb_t rxTxCb = nullptr;
|
||||
void* rxTxArgs = nullptr;
|
||||
spi_transfer_cb_t txCb = nullptr;
|
||||
@ -20,6 +14,200 @@ void* rxArgs = nullptr;
|
||||
spi_transfer_cb_t errorCb = nullptr;
|
||||
void* errorArgs = nullptr;
|
||||
|
||||
void spi::configureDmaHandle(DMA_HandleTypeDef *handle, dma::DMAType dmaType,
|
||||
dma::DMAIndexes dmaIdx, dma::DMAStreams dmaStream, IRQn_Type* dmaIrqNumber,
|
||||
uint32_t dmaMode, uint32_t dmaPriority) {
|
||||
using namespace dma;
|
||||
if(dmaIdx == DMAIndexes::DMA_1) {
|
||||
#ifdef DMA1
|
||||
switch(dmaStream) {
|
||||
case(DMAStreams::STREAM_0): {
|
||||
#ifdef DMA1_Stream0
|
||||
handle->Instance = DMA1_Stream0;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA1_Stream0_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_1): {
|
||||
#ifdef DMA1_Stream1
|
||||
handle->Instance = DMA1_Stream1;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA1_Stream1_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_2): {
|
||||
#ifdef DMA1_Stream2
|
||||
handle->Instance = DMA1_Stream2;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA1_Stream2_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_3): {
|
||||
#ifdef DMA1_Stream3
|
||||
handle->Instance = DMA1_Stream3;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA1_Stream3_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_4): {
|
||||
#ifdef DMA1_Stream4
|
||||
handle->Instance = DMA1_Stream4;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA1_Stream4_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_5): {
|
||||
#ifdef DMA1_Stream5
|
||||
handle->Instance = DMA1_Stream5;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA1_Stream5_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_6): {
|
||||
#ifdef DMA1_Stream6
|
||||
handle->Instance = DMA1_Stream6;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA1_Stream6_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_7): {
|
||||
#ifdef DMA1_Stream7
|
||||
handle->Instance = DMA1_Stream7;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA1_Stream7_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(dmaType == DMAType::TX) {
|
||||
handle->Init.Request = DMA_REQUEST_SPI1_TX;
|
||||
}
|
||||
else {
|
||||
handle->Init.Request = DMA_REQUEST_SPI1_RX;
|
||||
}
|
||||
#endif /* DMA1 */
|
||||
}
|
||||
if(dmaIdx == DMAIndexes::DMA_2) {
|
||||
#ifdef DMA2
|
||||
switch(dmaStream) {
|
||||
case(DMAStreams::STREAM_0): {
|
||||
#ifdef DMA1_Stream0
|
||||
handle->Instance = DMA2_Stream0;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA2_Stream0_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_1): {
|
||||
#ifdef DMA1_Stream1
|
||||
handle->Instance = DMA2_Stream1;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA2_Stream1_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_2): {
|
||||
#ifdef DMA1_Stream2
|
||||
handle->Instance = DMA2_Stream2;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA2_Stream2_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_3): {
|
||||
#ifdef DMA1_Stream3
|
||||
handle->Instance = DMA2_Stream3;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA2_Stream3_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_4): {
|
||||
#ifdef DMA1_Stream4
|
||||
handle->Instance = DMA1_Stream4;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA2_Stream4_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_5): {
|
||||
#ifdef DMA1_Stream5
|
||||
handle->Instance = DMA1_Stream5;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA2_Stream5_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_6): {
|
||||
#ifdef DMA1_Stream6
|
||||
handle->Instance = DMA1_Stream6;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA2_Stream6_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case(DMAStreams::STREAM_7): {
|
||||
#ifdef DMA1_Stream7
|
||||
handle->Instance = DMA1_Stream7;
|
||||
if(dmaIrqNumber != nullptr) {
|
||||
*dmaIrqNumber = DMA2_Stream7_IRQn;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(dmaType == DMAType::TX) {
|
||||
handle->Init.Request = DMA_REQUEST_SPI2_TX;
|
||||
}
|
||||
else {
|
||||
handle->Init.Request = DMA_REQUEST_SPI2_RX;
|
||||
}
|
||||
#endif /* DMA2 */
|
||||
}
|
||||
|
||||
if(dmaType == DMAType::TX) {
|
||||
handle->Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
}
|
||||
else {
|
||||
handle->Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
}
|
||||
|
||||
handle->Init.Priority = dmaPriority;
|
||||
handle->Init.Mode = dmaMode;
|
||||
|
||||
// Standard settings for the rest for now
|
||||
handle->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
handle->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
handle->Init.MemBurst = DMA_MBURST_INC4;
|
||||
handle->Init.PeriphBurst = DMA_PBURST_INC4;
|
||||
handle->Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
handle->Init.MemInc = DMA_MINC_ENABLE;
|
||||
handle->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
handle->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
}
|
||||
|
||||
void spi::setDmaHandles(DMA_HandleTypeDef* txHandle, DMA_HandleTypeDef* rxHandle) {
|
||||
hdmaTx = txHandle;
|
||||
hdmaRx = rxHandle;
|
||||
@ -61,63 +249,7 @@ SPI_HandleTypeDef* spi::getSpiHandle() {
|
||||
return spiHandle;
|
||||
}
|
||||
|
||||
void spi::setSpiMspFunctions(msp_func_t init_func, void* init_args, msp_func_t deinit_func,
|
||||
void* deinit_args) {
|
||||
mspInitFunc = init_func;
|
||||
mspInitArgs = init_args;
|
||||
mspDeinitFunc = deinit_func;
|
||||
mspDeinitArgs = deinit_args;
|
||||
}
|
||||
|
||||
void spi::getMspInitFunction(msp_func_t* init_func, void **args) {
|
||||
if(init_func != NULL && args != NULL) {
|
||||
*init_func = mspInitFunc;
|
||||
*args = mspInitArgs;
|
||||
}
|
||||
}
|
||||
|
||||
void spi::getMspDeinitFunction(msp_func_t* deinit_func, void **args) {
|
||||
if(deinit_func != NULL && args != NULL) {
|
||||
*deinit_func = mspDeinitFunc;
|
||||
*args = mspDeinitArgs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI MSP Initialization
|
||||
* This function configures the hardware resources used in this example:
|
||||
* - Peripheral's clock enable
|
||||
* - Peripheral's GPIO Configuration
|
||||
* - DMA configuration for transmission request by peripheral
|
||||
* - NVIC configuration for DMA interrupt request enable
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
extern "C" void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) {
|
||||
if(mspInitFunc != NULL) {
|
||||
mspInitFunc(mspInitArgs);
|
||||
}
|
||||
else {
|
||||
printf("HAL_SPI_MspInit: Please call set_msp_functions to assign SPI MSP functions\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI MSP De-Initialization
|
||||
* This function frees the hardware resources used in this example:
|
||||
* - Disable the Peripheral's clock
|
||||
* - Revert GPIO, DMA and NVIC configuration to their default state
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
extern "C" void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) {
|
||||
if(mspDeinitFunc != NULL) {
|
||||
mspDeinitFunc(mspDeinitArgs);
|
||||
}
|
||||
else {
|
||||
printf("HAL_SPI_MspDeInit: Please call set_msp_functions to assign SPI MSP functions\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TxRx Transfer completed callback.
|
||||
@ -173,4 +305,3 @@ extern "C" void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) {
|
||||
printf("HAL_SPI_ErrorCallback: No user callback specified\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,27 +1,22 @@
|
||||
#ifndef FSFW_HAL_STM32H7_SPI_SPICORE_H_
|
||||
#define FSFW_HAL_STM32H7_SPI_SPICORE_H_
|
||||
|
||||
#include <fsfw_hal/stm32h7/dma.h>
|
||||
#include "stm32h7xx_hal.h"
|
||||
#include "stm32h7xx_hal_dma.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
using msp_func_t = void (*) (void* args);
|
||||
using spi_transfer_cb_t = void (*) (SPI_HandleTypeDef *hspi, void* userArgs);
|
||||
|
||||
namespace spi {
|
||||
|
||||
/**
|
||||
* Assign MSP init functions. Important for SPI configuration
|
||||
* @param init_func
|
||||
* @param init_args
|
||||
* @param deinit_func
|
||||
* @param deinit_args
|
||||
*/
|
||||
void setSpiMspFunctions(msp_func_t init_func, void* init_args, msp_func_t deinit_func,
|
||||
void* deinit_args);
|
||||
void configureDmaHandle(DMA_HandleTypeDef* Handle, dma::DMAType dmaType, dma::DMAIndexes dmaIdx,
|
||||
dma::DMAStreams dmaStream, IRQn_Type* dmaIrqNumber, uint32_t dmaMode = DMA_NORMAL,
|
||||
uint32_t dmaPriority = DMA_PRIORITY_LOW);
|
||||
|
||||
/**
|
||||
* Assign DMA handles. Required to use DMA for SPI transfers.
|
||||
@ -31,9 +26,6 @@ void setSpiMspFunctions(msp_func_t init_func, void* init_args, msp_func_t deinit
|
||||
void setDmaHandles(DMA_HandleTypeDef* txHandle, DMA_HandleTypeDef* rxHandle);
|
||||
void getDmaHandles(DMA_HandleTypeDef** txHandle, DMA_HandleTypeDef** rxHandle);
|
||||
|
||||
void getMspInitFunction(msp_func_t* init_func, void **args);
|
||||
void getMspDeinitFunction(msp_func_t* deinit_func, void **args);
|
||||
|
||||
/**
|
||||
* Assign SPI handle. Needs to be done before using the SPI
|
||||
* @param spiHandle
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "spiInterrupts.h"
|
||||
#include "spiCore.h"
|
||||
|
||||
#include "stm32h7xx_hal.h"
|
||||
#include "stm32h7xx_hal_dma.h"
|
||||
@ -6,10 +7,10 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
user_handler_t spi1UserHandler = nullptr;
|
||||
user_handler_t spi1UserHandler = &spi::spiIrqHandler;
|
||||
user_args_t spi1UserArgs = nullptr;
|
||||
|
||||
user_handler_t spi2UserHandler = nullptr;
|
||||
user_handler_t spi2UserHandler = &spi::spiIrqHandler;
|
||||
user_args_t spi2UserArgs = nullptr;
|
||||
|
||||
/**
|
||||
@ -35,9 +36,10 @@ void spi::dmaTxIrqHandler(void* dmaHandle) {
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void spi::spi1IrqHandler(void* spiHandle)
|
||||
void spi::spiIrqHandler(void* spiHandle)
|
||||
{
|
||||
HAL_SPI_IRQHandler((SPI_HandleTypeDef *) spiHandle);
|
||||
auto currentSpiHandle = spi::getSpiHandle();
|
||||
HAL_SPI_IRQHandler((SPI_HandleTypeDef *) currentSpiHandle);
|
||||
}
|
||||
|
||||
void spi::assignSpiUserHandler(spi::SpiBus spiIdx, user_handler_t userHandler,
|
||||
@ -52,6 +54,30 @@ void spi::assignSpiUserHandler(spi::SpiBus spiIdx, user_handler_t userHandler,
|
||||
}
|
||||
}
|
||||
|
||||
void spi::getSpiUserHandler(spi::SpiBus spiBus, user_handler_t *userHandler,
|
||||
user_args_t *userArgs) {
|
||||
if(userHandler == nullptr or userArgs == nullptr) {
|
||||
return;
|
||||
}
|
||||
if(spiBus == spi::SpiBus::SPI_1) {
|
||||
*userArgs = spi1UserArgs;
|
||||
*userHandler = spi1UserHandler;
|
||||
}
|
||||
else {
|
||||
*userArgs = spi2UserArgs;
|
||||
*userHandler = spi2UserHandler;
|
||||
}
|
||||
}
|
||||
|
||||
void assignSpiUserArgs(spi::SpiBus spiBus, user_args_t userArgs) {
|
||||
if(spiBus == spi::SpiBus::SPI_1) {
|
||||
spi1UserArgs = userArgs;
|
||||
}
|
||||
else {
|
||||
spi2UserArgs = userArgs;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do not change these function names! They need to be exactly equal to the name of the functions
|
||||
defined in the startup_stm32h743xx.s files! */
|
||||
|
||||
@ -70,5 +96,3 @@ extern "C" void SPI2_IRQHandler() {
|
||||
}
|
||||
Default_Handler();
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,6 +10,8 @@ extern "C" {
|
||||
|
||||
namespace spi {
|
||||
|
||||
void assignSpiUserArgs(spi::SpiBus spiBus, user_args_t userArgs);
|
||||
|
||||
/**
|
||||
* Assign a user interrupt handler for SPI bus 1, allowing to pass an arbitrary argument as well.
|
||||
* Generally, this argument will be the related SPI handle.
|
||||
@ -18,6 +20,8 @@ namespace spi {
|
||||
*/
|
||||
void assignSpiUserHandler(spi::SpiBus spiBus, user_handler_t user_handler,
|
||||
user_args_t user_args);
|
||||
void getSpiUserHandler(spi::SpiBus spiBus, user_handler_t* user_handler,
|
||||
user_args_t* user_args);
|
||||
|
||||
/**
|
||||
* Generic interrupt handlers supplied for convenience. Do not call these directly! Set them
|
||||
@ -26,7 +30,7 @@ void assignSpiUserHandler(spi::SpiBus spiBus, user_handler_t user_handler,
|
||||
*/
|
||||
void dmaRxIrqHandler(void* dma_handle);
|
||||
void dmaTxIrqHandler(void* dma_handle);
|
||||
void spi1IrqHandler(void* spi_handle);
|
||||
void spiIrqHandler(void* spi_handle);
|
||||
|
||||
}
|
||||
|
||||
|
81
stm32h7/spi/stm32h743ziSpi.cpp
Normal file
81
stm32h7/spi/stm32h743ziSpi.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include "stm32h743ziSpi.h"
|
||||
#include "spiCore.h"
|
||||
#include "spiInterrupts.h"
|
||||
#include "stm32h7xx_hal.h"
|
||||
#include "stm32h7xx_hal_rcc.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
void spiSetupWrapper() {
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
}
|
||||
|
||||
void spiCleanUpWrapper() {
|
||||
__HAL_RCC_SPI1_FORCE_RESET();
|
||||
__HAL_RCC_SPI1_RELEASE_RESET();
|
||||
}
|
||||
|
||||
void spiDmaClockEnableWrapper() {
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
}
|
||||
|
||||
void spi::h743zi::standardPollingCfg(MspPollingConfigStruct& cfg) {
|
||||
cfg.setupMacroWrapper = &spiSetupWrapper;
|
||||
cfg.cleanUpMacroWrapper = &spiCleanUpWrapper;
|
||||
cfg.sckPort = GPIOA;
|
||||
cfg.sckPin = GPIO_PIN_5;
|
||||
cfg.misoPort = GPIOA;
|
||||
cfg.misoPin = GPIO_PIN_6;
|
||||
cfg.mosiPort = GPIOA;
|
||||
cfg.mosiPin = GPIO_PIN_7;
|
||||
cfg.sckAlternateFunction = GPIO_AF5_SPI1;
|
||||
cfg.mosiAlternateFunction = GPIO_AF5_SPI1;
|
||||
cfg.misoAlternateFunction = GPIO_AF5_SPI1;
|
||||
}
|
||||
|
||||
void spi::h743zi::standardInterruptCfg(MspIrqConfigStruct& cfg, IrqPriorities spiIrqPrio,
|
||||
IrqPriorities spiSubprio) {
|
||||
// High, but works on FreeRTOS as well (priorities range from 0 to 15)
|
||||
cfg.preEmptPriority = spiIrqPrio;
|
||||
cfg.subpriority = spiSubprio;
|
||||
cfg.spiIrqNumber = SPI1_IRQn;
|
||||
cfg.spiBus = SpiBus::SPI_1;
|
||||
user_handler_t spiUserHandler = nullptr;
|
||||
user_args_t spiUserArgs = nullptr;
|
||||
getSpiUserHandler(spi::SpiBus::SPI_1, &spiUserHandler, &spiUserArgs);
|
||||
if(spiUserHandler == nullptr) {
|
||||
printf("spi::h743zi::standardInterruptCfg: Invalid SPI user handlers\n");
|
||||
return;
|
||||
}
|
||||
cfg.spiUserArgs = spiUserArgs;
|
||||
cfg.spiIrqHandler = spiUserHandler;
|
||||
standardPollingCfg(cfg);
|
||||
}
|
||||
|
||||
void spi::h743zi::standardDmaCfg(MspDmaConfigStruct& cfg, IrqPriorities spiIrqPrio,
|
||||
IrqPriorities txIrqPrio, IrqPriorities rxIrqPrio, IrqPriorities spiSubprio,
|
||||
IrqPriorities txSubprio, IrqPriorities rxSubprio) {
|
||||
cfg.dmaClkEnableWrapper = &spiDmaClockEnableWrapper;
|
||||
cfg.rxDmaIndex = dma::DMAIndexes::DMA_1;
|
||||
cfg.txDmaIndex = dma::DMAIndexes::DMA_1;
|
||||
cfg.txDmaStream = dma::DMAStreams::STREAM_3;
|
||||
cfg.rxDmaStream = dma::DMAStreams::STREAM_2;
|
||||
DMA_HandleTypeDef* txHandle;
|
||||
DMA_HandleTypeDef* rxHandle;
|
||||
spi::getDmaHandles(&txHandle, &rxHandle);
|
||||
if(txHandle == nullptr or rxHandle == nullptr) {
|
||||
printf("spi::h743zi::standardDmaCfg: Invalid DMA handles");
|
||||
return;
|
||||
}
|
||||
spi::configureDmaHandle(txHandle, dma::DMAType::TX, cfg.txDmaIndex, cfg.txDmaStream,
|
||||
&cfg.txDmaIrqNumber);
|
||||
spi::configureDmaHandle(rxHandle, dma::DMAType::RX, cfg.rxDmaIndex, cfg.rxDmaStream,
|
||||
&cfg.rxDmaIrqNumber);
|
||||
cfg.txPreEmptPriority = txIrqPrio;
|
||||
cfg.rxPreEmptPriority = txSubprio;
|
||||
cfg.txSubpriority = rxIrqPrio;
|
||||
cfg.rxSubpriority = rxSubprio;
|
||||
standardInterruptCfg(cfg, spiIrqPrio, spiSubprio);
|
||||
}
|
23
stm32h7/spi/stm32h743ziSpi.h
Normal file
23
stm32h7/spi/stm32h743ziSpi.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef FSFW_HAL_STM32H7_SPI_STM32H743ZISPI_H_
|
||||
#define FSFW_HAL_STM32H7_SPI_STM32H743ZISPI_H_
|
||||
|
||||
#include "mspInit.h"
|
||||
|
||||
namespace spi {
|
||||
|
||||
namespace h743zi {
|
||||
|
||||
void standardPollingCfg(MspPollingConfigStruct& cfg);
|
||||
void standardInterruptCfg(MspIrqConfigStruct& cfg, IrqPriorities spiIrqPrio,
|
||||
IrqPriorities spiSubprio = HIGHEST);
|
||||
void standardDmaCfg(MspDmaConfigStruct& cfg, IrqPriorities spiIrqPrio,
|
||||
IrqPriorities txIrqPrio, IrqPriorities rxIrqPrio,
|
||||
IrqPriorities spiSubprio = HIGHEST, IrqPriorities txSubPrio = HIGHEST,
|
||||
IrqPriorities rxSubprio = HIGHEST);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_HAL_STM32H7_SPI_STM32H743ZISPI_H_ */
|
Loading…
Reference in New Issue
Block a user