251 lines
5.4 KiB
C++
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);
|
|
}
|