Files
F407-SX1280-FreeRTOS/Core/Src/Components/SPI_Peripheral_STM32.cpp

251 lines
5.4 KiB
C++

/*
* SPI_Peripheral_STM32.cpp
*
* Created on: Feb 10, 2024
* Author: Gabriel
*/
#include "SPI_Peripheral_STM32.hpp"
SPI_Peripheral_STM32* SPI_Peripheral_STM32::objects[];
SPI_Peripheral_STM32::SPI_Peripheral_STM32(SPI_HandleTypeDef* hspi, uint32_t timeout) :
hspi(hspi), timeout(timeout) {
}
SPI_Peripheral_STM32::~SPI_Peripheral_STM32() {
}
// Public methods
int32_t SPI_Peripheral_STM32::init(){
// TODO Implement self test routine
hSpiMutex = xSemaphoreCreateMutexStatic(&spiMutexBuffer);
vQueueAddToRegistry(hSpiMutex, "spiMutex");
hSpiEventGroup = xEventGroupCreateStatic(&spiEventGroupBuffer);
HAL_SPI_RegisterCallback(hspi, HAL_SPI_TX_COMPLETE_CB_ID, transmitCallbackStatic);
HAL_SPI_RegisterCallback(hspi, HAL_SPI_RX_COMPLETE_CB_ID, receiveCallbackStatic);
HAL_SPI_RegisterCallback(hspi, HAL_SPI_TX_RX_COMPLETE_CB_ID, trxCallbackStatic);
#ifdef SPI1
if(hspi->Instance == SPI1){
objects[0] = this;
}
#endif
#ifdef SPI2
if(hspi->Instance == SPI2){
objects[1] = this;
}
#endif
#ifdef SPI3
if(hspi->Instance == SPI3){
objects[2] = this;
}
#endif
#ifdef SPI4
if(hspi->Instance == SPI4){
objects[3] = this;
}
#endif
#ifdef SPI5
if(hspi->Instance == SPI5){
objects[4] = this;
}
#endif
return 0;
}
int32_t SPI_Peripheral_STM32::take(uint32_t timeout) {
if(xSemaphoreTake(hSpiMutex, timeout)){
// Took
taskLocking = xTaskGetCurrentTaskHandle();
return 0;
}else{
// Timeout
return -1;
}
}
int32_t SPI_Peripheral_STM32::give() {
taskLocking = nullptr;
xSemaphoreGive(hSpiMutex);
return 0;
}
int32_t SPI_Peripheral_STM32::transmit(uint8_t *buffer, uint32_t length) {
if (taskLocking != xTaskGetCurrentTaskHandle()){
// Not taken
return -2;
}
HAL_SPI_Transmit_DMA(hspi, buffer, length);
EventBits_t bits = xEventGroupWaitBits(hSpiEventGroup, (EventBits_t)Event::TX_CPLT, true, true, timeout);
if(!bits){
// Timeout
return -1;
}
return 0;
}
int32_t SPI_Peripheral_STM32::receive(uint8_t *buffer, uint32_t length) {
if (taskLocking != xTaskGetCurrentTaskHandle()){
// Not taken
return -2;
}
HAL_SPI_Receive_DMA(hspi, buffer, length);
EventBits_t bits = xEventGroupWaitBits(hSpiEventGroup, (EventBits_t)Event::RX_CPLT, true, true, timeout);
if(!bits){
// Timeout
return -1;
}
return 0;
}
int32_t SPI_Peripheral_STM32::trx(uint8_t *txBuffer, uint8_t *rxBuffer, uint32_t length) {
if (taskLocking != xTaskGetCurrentTaskHandle()){
// Not taken
return -2;
}
HAL_SPI_TransmitReceive_DMA(hspi, txBuffer, rxBuffer, length);
EventBits_t bits = xEventGroupWaitBits(hSpiEventGroup, (EventBits_t)Event::TRX_CPLT, true, true, timeout);
if(!bits){
// Timeout
return -1;
}
return 0;
}
// Private methods
void SPI_Peripheral_STM32::transmitCallbackStatic(SPI_HandleTypeDef *_hspi) {
#ifdef SPI1
if(_hspi->Instance == SPI1){
if(objects[0]){
objects[0]->transmitCallback();
}
}
#endif
#ifdef SPI2
if(_hspi->Instance == SPI2){
if(objects[1]){
objects[1]->transmitCallback();
}
}
#endif
#ifdef SPI3
if(_hspi->Instance == SPI3){
if(objects[2]){
objects[2]->transmitCallback();
}
}
#endif
#ifdef SPI4
if(_hspi->Instance == SPI4){
if(objects[3]){
objects[3]->transmitCallback();
}
}
#endif
#ifdef SPI5
if(_hspi->Instance == SPI5){
if(objects[4]){
objects[4]->transmitCallback();
}
}
#endif
}
void SPI_Peripheral_STM32::receiveCallbackStatic(SPI_HandleTypeDef *_hspi) {
#ifdef SPI1
if(_hspi->Instance == SPI1){
if(objects[0]){
objects[0]->receiveCallback();
}
}
#endif
#ifdef SPI2
if(_hspi->Instance == SPI2){
if(objects[1]){
objects[1]->receiveCallback();
}
}
#endif
#ifdef SPI3
if(_hspi->Instance == SPI3){
if(objects[2]){
objects[2]->receiveCallback();
}
}
#endif
#ifdef SPI4
if(_hspi->Instance == SPI4){
if(objects[3]){
objects[3]->receiveCallback();
}
}
#endif
#ifdef SPI5
if(_hspi->Instance == SPI5){
if(objects[4]){
objects[4]->receiveCallback();
}
}
#endif
}
void SPI_Peripheral_STM32::trxCallbackStatic(SPI_HandleTypeDef *_hspi) {
#ifdef SPI1
if(_hspi->Instance == SPI1){
if(objects[0]){
objects[0]->trxCallback();
}
}
#endif
#ifdef SPI2
if(_hspi->Instance == SPI2){
if(objects[1]){
objects[1]->trxCallback();
}
}
#endif
#ifdef SPI3
if(_hspi->Instance == SPI3){
if(objects[2]){
objects[2]->trxCallback();
}
}
#endif
#ifdef SPI4
if(_hspi->Instance == SPI4){
if(objects[3]){
objects[3]->trxCallback();
}
}
#endif
#ifdef SPI5
if(_hspi->Instance == SPI5){
if(objects[4]){
objects[4]->trxCallback();
}
}
#endif
}
void SPI_Peripheral_STM32::transmitCallback() {
BaseType_t xHigherPriorityTaskWoken = false;
xEventGroupSetBitsFromISR(hSpiEventGroup, (EventBits_t)Event::TX_CPLT, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void SPI_Peripheral_STM32::receiveCallback() {
BaseType_t xHigherPriorityTaskWoken = false;
xEventGroupSetBitsFromISR(hSpiEventGroup, (EventBits_t)Event::RX_CPLT, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void SPI_Peripheral_STM32::trxCallback() {
BaseType_t xHigherPriorityTaskWoken = false;
xEventGroupSetBitsFromISR(hSpiEventGroup, (EventBits_t)Event::TRX_CPLT, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}