Some GPIO manipulations in matrix.c change to atomic. (#10491)

* Changed the processing of select_xxx()/unselect_xxx() in quantum/matrix.c to be atomic.

* Changed the processing of select_xxx()/unselect_xxx() in quantum/split_common/matrix.c to be atomic.

* update matrix.c

* add ATOMIC_BLOCK_FORCEON macro to quantum/quantum_atomic_extend.h

* quantum_atomic_extend.h's contents move into quantum.h

* update ATOMIC_BLOCK_xxx for unknown platform

* ATOMIC_BLOCK macro support PROTOCOL_ARM_ATSAM

* Add Atomic Operation section in docs/internals_gpio_control.md
This commit is contained in:
Takeshi ISHII 2020-10-26 12:11:14 +09:00 committed by James Young
parent 69d8bbf1f4
commit 75a18e69f9
No known key found for this signature in database
GPG key ID: 8E1085BF6FCFBD74
4 changed files with 124 additions and 20 deletions

View file

@ -220,6 +220,61 @@ typedef ioline_t pin_t;
# define togglePin(pin) palToggleLine(pin)
#endif
// Atomic macro to help make GPIO and other controls atomic.
#ifdef IGNORE_ATOMIC_BLOCK
/* do nothing atomic macro */
# define ATOMIC_BLOCK for (uint8_t __ToDo = 1; __ToDo; __ToDo = 0)
# define ATOMIC_BLOCK_RESTORESTATE ATOMIC_BLOCK
# define ATOMIC_BLOCK_FORCEON ATOMIC_BLOCK
#elif defined(__AVR__)
/* atomic macro for AVR */
# include <util/atomic.h>
# define ATOMIC_BLOCK_RESTORESTATE ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
# define ATOMIC_BLOCK_FORCEON ATOMIC_BLOCK(ATOMIC_FORCEON)
#elif defined(PROTOCOL_CHIBIOS) || defined(PROTOCOL_ARM_ATSAM)
/* atomic macro for ChibiOS / ARM ATSAM */
# if defined(PROTOCOL_ARM_ATSAM)
# include "arm_atsam_protocol.h"
# endif
static __inline__ uint8_t __interrupt_disable__(void) {
# if defined(PROTOCOL_CHIBIOS)
chSysLock();
# endif
# if defined(PROTOCOL_ARM_ATSAM)
__disable_irq();
# endif
return 1;
}
static __inline__ void __interrupt_enable__(const uint8_t *__s) {
# if defined(PROTOCOL_CHIBIOS)
chSysUnlock();
# endif
# if defined(PROTOCOL_ARM_ATSAM)
__enable_irq();
# endif
__asm__ volatile("" ::: "memory");
(void)__s;
}
# define ATOMIC_BLOCK(type) for (type, __ToDo = __interrupt_disable__(); __ToDo; __ToDo = 0)
# define ATOMIC_FORCEON uint8_t sreg_save __attribute__((__cleanup__(__interrupt_enable__))) = 0
# define ATOMIC_BLOCK_RESTORESTATE _Static_assert(0, "ATOMIC_BLOCK_RESTORESTATE dose not implement")
# define ATOMIC_BLOCK_FORCEON ATOMIC_BLOCK(ATOMIC_FORCEON)
/* Other platform */
#else
# define ATOMIC_BLOCK_RESTORESTATE _Static_assert(0, "ATOMIC_BLOCK_RESTORESTATE dose not implement")
# define ATOMIC_BLOCK_FORCEON _Static_assert(0, "ATOMIC_BLOCK_FORCEON dose not implement")
#endif
#define SEND_STRING(string) send_string_P(PSTR(string))
#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval)