1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2025-07-21 12:28:55 +02:00

STM32: Remove I2C interrupt blocking waveform interrupt

This commit is contained in:
Harald Barth 2025-07-10 12:18:36 +02:00
parent 51c4b4d34a
commit 2e0a596afe
3 changed files with 36 additions and 4 deletions

View File

@ -208,7 +208,7 @@ void DCCTimer::begin(INTERRUPT_CALLBACK callback) {
dcctimer.setOverflow(DCC_SIGNAL_TIME, MICROSEC_FORMAT);
// dcctimer.attachInterrupt(Timer11_Handler);
dcctimer.attachInterrupt(DCCTimer_Handler);
dcctimer.setInterruptPriority(0, 0); // Set highest preemptive priority!
dcctimer.setInterruptPriority(1, 0); // Set second highest preemptive priority!
dcctimer.refresh();
dcctimer.resume();

View File

@ -37,21 +37,42 @@
// it can replace use of noInterrupts/interrupts in other parts of DCC-EX.
//
static inline uint8_t _deferInterrupts(void) {
#if defined(ARDUINO_ARCH_STM32)
NVIC_DisableIRQ(I2C1_EV_IRQn);
NVIC_DisableIRQ(I2C1_ER_IRQn);
#else
noInterrupts();
#endif
return 1;
}
static inline void _conditionalEnableInterrupts(bool *wasEnabled) {
#if defined(ARDUINO_ARCH_STM32)
(void)wasEnabled;
NVIC_EnableIRQ(I2C1_EV_IRQn);
NVIC_EnableIRQ(I2C1_ER_IRQn);
#else
if (*wasEnabled) interrupts();
#endif
}
#define ATOMIC_BLOCK(x) \
for (bool _int_saved __attribute__((__cleanup__(_conditionalEnableInterrupts))) \
=_getInterruptState(),_ToDo=_deferInterrupts(); _ToDo; _ToDo=0)
// The construct of
// "variable __attribute__((__cleanup__(func)))"
// calls the func with *variable when variable goes out of scope
#if defined(__AVR__) // Nano, Uno, Mega2580, NanoEvery, etc.
static inline bool _getInterruptState(void) {
return bitRead(SREG, SREG_I); // true if enabled, false if disabled
}
#elif defined(__arm__) // STM32, SAMD, Teensy
#elif defined(ARDUINO_ARCH_STM32)
static inline bool _getInterruptState( void ) {
// as we do ony mess with the I2C interrupts in the STM32 case,
// we do not care about their previous state
return true;
}
#elif defined(__arm__) // SAMD, Teensy
static inline bool _getInterruptState( void ) {
uint32_t reg;
__asm__ __volatile__ ("MRS %0, primask" : "=r" (reg) );

View File

@ -211,9 +211,19 @@ void I2CManagerClass::I2C_init()
#if defined(I2C_USE_INTERRUPTS)
// Setting NVIC
NVIC_SetPriority(I2C1_EV_IRQn, 1); // Match default priorities
NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); // 4 means that we have all bits for preemptive grouping
// prio scheme:
// systick : 0
// waveform timer : 1
// i2c : 2
// one must call NVIC_EncodePriority() to bitshift the priorities
// according to the active priority grouping and then use that
// value as argument to NVIC_SetPriority().
NVIC_SetPriority(I2C1_EV_IRQn,
NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 2, 0));
NVIC_EnableIRQ(I2C1_EV_IRQn);
NVIC_SetPriority(I2C1_ER_IRQn, 1); // Match default priorities
NVIC_SetPriority(I2C1_ER_IRQn,
NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 2, 0));
NVIC_EnableIRQ(I2C1_ER_IRQn);
// CR2 Interrupt Settings
@ -305,6 +315,7 @@ void I2CManagerClass::I2C_close() {
***************************************************************************/
void I2CManagerClass::I2C_handleInterrupt() {
volatile uint16_t temp_sr1, temp_sr2;
(void) temp_sr2; // only used as target for reads
temp_sr1 = s->SR1;