diff --git a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Intern.h b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Intern.h index 82e9a3c..a8b452e 100644 --- a/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Intern.h +++ b/AMS_Master_Code/Core/Lib/ADBMS6830B_Driver/Inc/ADBMS_Intern.h @@ -13,6 +13,16 @@ typedef enum { ADBMS_TIMEOUT, } ADBMS_Internal_Status; +#define CRITICAL_SECTION_VAR(counter) bool primask_##counter = (__get_PRIMASK() == 0) +#define CRITICAL_SECTION_ENTER(counter) do { __disable_irq(); } while(0) +#define CRITICAL_SECTION_EXIT(counter) ({do { if (primask_##counter) __enable_irq(); } while(0);}) + +#define CRITICAL_SECTION() \ + CRITICAL_SECTION_VAR(__COUNTER__); \ + asm volatile ("dmb"); \ + CRITICAL_SECTION_ENTER(__COUNTER__); \ + for(int _cs_flag_##__COUNTER__ = 1; _cs_flag_##__COUNTER__; _cs_flag_##__COUNTER__ = 0, CRITICAL_SECTION_EXIT(__COUNTER__)) + [[maybe_unused, gnu::always_inline]] static inline void mcuAdbmsCSLow() { HAL_GPIO_WritePin(AMS_CS_GPIO_Port, AMS_CS_Pin, GPIO_PIN_RESET); @@ -29,20 +39,32 @@ static inline void mcuAdbmsCSHigh() { [[maybe_unused, gnu::always_inline, gnu::access(read_only, 2, 3), gnu::nonnull(1)]] static inline ADBMS_Internal_Status mcuSPITransmit(USER_PTR_TYPE user_ptr, const uint8_t* buffer, uint8_t buffersize, uint32_t timeout) { - const HAL_StatusTypeDef status = HAL_SPI_Transmit(user_ptr, buffer, buffersize, timeout); - return (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR; + ADBMS_Internal_Status adbms_status; + CRITICAL_SECTION() { + const HAL_StatusTypeDef status = HAL_SPI_Transmit(user_ptr, buffer, buffersize, timeout); + adbms_status = (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR; + } + return adbms_status; } [[maybe_unused, gnu::always_inline, gnu::access(read_write, 2, 3), gnu::nonnull(1)]] static inline ADBMS_Internal_Status mcuSPIReceive(USER_PTR_TYPE user_ptr, uint8_t* buffer, uint8_t buffersize, uint32_t timeout) { - const HAL_StatusTypeDef status = HAL_SPI_Receive(user_ptr, buffer, buffersize, timeout); - return (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR; + ADBMS_Internal_Status adbms_status; + CRITICAL_SECTION() { + const HAL_StatusTypeDef status = HAL_SPI_Receive(user_ptr, buffer, buffersize, timeout); + adbms_status = (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR; + } + return adbms_status; } [[maybe_unused, gnu::always_inline, gnu::access(read_write, 2, 4), gnu::access(read_only, 3, 4), gnu::nonnull(1, 2)]] static inline ADBMS_Internal_Status mcuSPITransmitReceive(USER_PTR_TYPE user_ptr, uint8_t* rxbuffer, const uint8_t* txbuffer, uint8_t buffersize, uint32_t timeout) { - const HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(user_ptr, txbuffer, rxbuffer, buffersize, timeout); - return (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR; + ADBMS_Internal_Status adbms_status; + CRITICAL_SECTION() { + const HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(user_ptr, txbuffer, rxbuffer, buffersize, timeout); + adbms_status = (status == HAL_OK) ? ADBMS_OK : ADBMS_ERROR; + } + return adbms_status; } // Delay by `delay` milliseconds