Skip to content

Commit f1d400f

Browse files
Rework atomic primitives to allow for shorter interrupt disable code segments
1 parent a0db3e8 commit f1d400f

File tree

10 files changed

+404
-534
lines changed

10 files changed

+404
-534
lines changed

system/STM32L0xx/Include/armv6m_atomic.h

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -208,28 +208,6 @@ static inline __attribute__((optimize("O3"),always_inline)) uint32_t __armv6m_at
208208
return data_return;
209209
}
210210

211-
static inline __attribute__((optimize("O3"),always_inline)) uint32_t __armv6m_atomic_modify(volatile uint32_t *p_data, uint32_t mask, uint32_t data)
212-
{
213-
uint32_t data_return;
214-
215-
mask = ~mask;
216-
217-
__asm__ volatile (
218-
" mrs r12, PRIMASK \n"
219-
" cpsid i \n"
220-
" ldr %0, [%2] \n"
221-
" and %1, %0 \n"
222-
" eor %1, %3 \n"
223-
" str %1, [%2] \n"
224-
"1: msr PRIMASK, r12 \n"
225-
: "=&l" (data_return), "+&l" (mask)
226-
: "l" (p_data), "l" (data)
227-
: "r12", "memory"
228-
);
229-
230-
return data_return;
231-
}
232-
233211
static inline __attribute__((optimize("O3"),always_inline)) uint32_t __armv6m_atomic_addh(volatile uint16_t *p_data, uint32_t data)
234212
{
235213
uint32_t data_return;
@@ -580,6 +558,76 @@ static inline __attribute__((optimize("O3"),always_inline)) uint32_t __armv6m_at
580558
return data_return;
581559
}
582560

561+
static inline __attribute__((optimize("O3"),always_inline)) uint32_t __armv6m_atomic_modify(volatile uint32_t *p_data, uint32_t mask, uint32_t data)
562+
{
563+
uint32_t data_return;
564+
565+
mask = ~mask;
566+
567+
__asm__ volatile (
568+
" mrs r12, PRIMASK \n"
569+
" cpsid i \n"
570+
" ldr %0, [%2] \n"
571+
" and %1, %0 \n"
572+
" eor %1, %3 \n"
573+
" str %1, [%2] \n"
574+
"1: msr PRIMASK, r12 \n"
575+
: "=&l" (data_return), "+&l" (mask)
576+
: "l" (p_data), "l" (data)
577+
: "r12", "memory"
578+
);
579+
580+
return data_return;
581+
}
582+
583+
static inline __attribute__((optimize("O3"),always_inline)) uint32_t __armv6m_atomic_andzb(volatile uint32_t *p_data, uint32_t data, volatile uint8_t *p_zero)
584+
{
585+
uint32_t data_return;
586+
587+
__asm__ volatile (
588+
" mrs r12, PRIMASK \n"
589+
" cpsid i \n"
590+
" ldr %0, [%3] \n"
591+
" ldrb %2, [%2] \n"
592+
" cmp %2, #0 \n"
593+
" beq 1f \n"
594+
" mov %1, %0 \n"
595+
" b 2f \n"
596+
"1: and %1, %0 \n"
597+
"2: str %1, [%3] \n"
598+
" msr PRIMASK, r12 \n"
599+
: "=&l" (data_return), "+&l" (data), "+&l" (p_zero)
600+
: "l" (p_data)
601+
: "r12", "memory"
602+
);
603+
604+
return data_return;
605+
}
606+
607+
static inline __attribute__((optimize("O3"),always_inline)) uint32_t __armv6m_atomic_andzh(volatile uint32_t *p_data, uint32_t data, volatile uint16_t *p_zero, uint32_t mask)
608+
{
609+
uint32_t data_return;
610+
611+
__asm__ volatile (
612+
" mrs r12, PRIMASK \n"
613+
" cpsid i \n"
614+
" ldr %0, [%3] \n"
615+
" ldrh %2, [%2] \n"
616+
" and %2, %4 \n"
617+
" beq 1f \n"
618+
" mov %1, %0 \n"
619+
" b 2f \n"
620+
"1: and %1, %0 \n"
621+
"2: str %1, [%3] \n"
622+
" msr PRIMASK, r12 \n"
623+
: "=&l" (data_return), "+&l" (data), "+&l" (p_zero)
624+
: "l" (p_data), "l" (mask)
625+
: "r12", "memory"
626+
);
627+
628+
return data_return;
629+
}
630+
583631
extern uint32_t armv6m_atomic_add(volatile uint32_t *p_data, uint32_t data);
584632
extern uint32_t armv6m_atomic_sub(volatile uint32_t *p_data, uint32_t data);
585633
extern uint32_t armv6m_atomic_and(volatile uint32_t *p_data, uint32_t data);
@@ -604,6 +652,10 @@ extern uint32_t armv6m_atomic_casb(volatile uint8_t *p_data, uint32_t data_expec
604652
/* *p_data = (*p_data & ~mask) ^ data */
605653
extern uint32_t armv6m_atomic_modify(volatile uint32_t *p_data, uint32_t mask, uint32_t data);
606654

655+
/* *p_data = (*p_zero == 0) ? (*p_data & mask) : *p_data */
656+
extern uint32_t armv6m_atomic_andzb(volatile uint32_t *p_data, uint32_t data, volatile uint8_t *p_zero);
657+
extern uint32_t armv6m_atomic_andzh(volatile uint32_t *p_data, uint32_t data, volatile uint16_t *p_zero, uint32_t mask);
658+
607659
#ifdef __cplusplus
608660
}
609661
#endif

system/STM32L0xx/Include/stm32l0_dma.h

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017-2019 Thomas Roell. All rights reserved.
2+
* Copyright (c) 2017-2020 Thomas Roell. All rights reserved.
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to
@@ -33,20 +33,20 @@
3333
#include "stm32l0xx.h"
3434

3535
#ifdef __cplusplus
36-
extern "C" {
36+
extern "C" {
3737
#endif
3838

3939
#define STM32L0_DMA_CHANNEL_NONE 0x0000
4040
#define STM32L0_DMA_CHANNEL_UNDEFINED 0x0fff
4141
#define STM32L0_DMA_CHANNEL_MASK 0x0fff
4242

43-
#define STM32L0_DMA_CHANNEL_DMA1_CH1_INDEX 0x0800
44-
#define STM32L0_DMA_CHANNEL_DMA1_CH2_INDEX 0x0801
45-
#define STM32L0_DMA_CHANNEL_DMA1_CH3_INDEX 0x0802
46-
#define STM32L0_DMA_CHANNEL_DMA1_CH4_INDEX 0x0803
47-
#define STM32L0_DMA_CHANNEL_DMA1_CH5_INDEX 0x0804
48-
#define STM32L0_DMA_CHANNEL_DMA1_CH6_INDEX 0x0805
49-
#define STM32L0_DMA_CHANNEL_DMA1_CH7_INDEX 0x0806
43+
#define STM32L0_DMA_CHANNEL_DMA1_CH1_INDEX 0
44+
#define STM32L0_DMA_CHANNEL_DMA1_CH2_INDEX 1
45+
#define STM32L0_DMA_CHANNEL_DMA1_CH3_INDEX 2
46+
#define STM32L0_DMA_CHANNEL_DMA1_CH4_INDEX 3
47+
#define STM32L0_DMA_CHANNEL_DMA1_CH5_INDEX 4
48+
#define STM32L0_DMA_CHANNEL_DMA1_CH6_INDEX 5
49+
#define STM32L0_DMA_CHANNEL_DMA1_CH7_INDEX 6
5050

5151

5252
#if defined(STM32L052xx)
@@ -263,17 +263,18 @@
263263

264264
typedef void (*stm32l0_dma_callback_t)(void *context, uint32_t events);
265265

266-
extern void stm32l0_dma_configure(unsigned int priority_1, unsigned int priority_2_3, unsigned int priority_4_5_6_7);
267-
extern unsigned int stm32l0_dma_priority(unsigned int channel);
268-
extern unsigned int stm32l0_dma_channel(unsigned int channel);
269-
extern bool stm32l0_dma_lock(unsigned int channel);
270-
extern void stm32l0_dma_unlock(unsigned int channel);
271-
extern bool stm32l0_dma_enable(unsigned int channel, stm32l0_dma_callback_t callback, void *context);
272-
extern void stm32l0_dma_disable(unsigned int channel);
273-
extern void stm32l0_dma_start(unsigned int channel, uint32_t tx_data, uint32_t rx_data, uint16_t xf_count, uint32_t option);
274-
extern uint16_t stm32l0_dma_stop(unsigned int channel);
275-
extern uint16_t stm32l0_dma_count(unsigned int channel);
276-
extern bool stm32l0_dma_done(unsigned int channel);
266+
extern void __stm32l0_dma_initialize(void);
267+
extern void stm32l0_dma_configure(uint8_t priority_1, uint8_t priority_2_3, uint8_t priority_4_5_6_7);
268+
extern uint8_t stm32l0_dma_priority(uint16_t channel);
269+
extern uint16_t stm32l0_dma_channel(uint16_t channel);
270+
extern bool stm32l0_dma_lock(uint16_t channel);
271+
extern void stm32l0_dma_unlock(uint16_t channel);
272+
extern bool stm32l0_dma_enable(uint16_t channel, stm32l0_dma_callback_t callback, void *context);
273+
extern void stm32l0_dma_disable(uint16_t channel);
274+
extern void stm32l0_dma_start(uint16_t channel, uint32_t tx_data, uint32_t rx_data, uint16_t xf_count, uint32_t option);
275+
extern uint16_t stm32l0_dma_stop(uint16_t channel);
276+
extern uint16_t stm32l0_dma_count(uint16_t channel);
277+
extern bool stm32l0_dma_done(uint16_t channel);
277278

278279
#ifdef __cplusplus
279280
}

system/STM32L0xx/Include/stm32l0_gpio.h

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017-2018 Thomas Roell. All rights reserved.
2+
* Copyright (c) 2017-2020 Thomas Roell. All rights reserved.
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to
@@ -904,20 +904,19 @@ typedef struct _stm32l0_gpio_stop_state_t {
904904
#define STM32L0_GPIO_PIN_MASK(_pin) (1ul << ((_pin) & 15))
905905

906906
extern void __stm32l0_gpio_initialize(void);
907-
extern void __stm32l0_gpio_stop_enter(stm32l0_gpio_stop_state_t *state);
908-
extern void __stm32l0_gpio_stop_leave(stm32l0_gpio_stop_state_t *state);
909907
extern void __stm32l0_gpio_swd_enable(void);
910908
extern void __stm32l0_gpio_swd_disable(void);
911-
extern void stm32l0_gpio_pin_configure(unsigned int pin, unsigned int mode);
912-
extern void stm32l0_gpio_pin_input(unsigned int pin);
913-
extern void stm32l0_gpio_pin_output(unsigned int pin);
914-
extern void stm32l0_gpio_pin_alternate(unsigned int pin);
915-
extern void stm32l0_gpio_pin_analog(unsigned int pin);
916-
917-
extern unsigned int __stm32l0_gpio_pin_read(unsigned int pin);
918-
extern void __stm32l0_gpio_pin_write(unsigned int pin, unsigned int data);
919-
920-
static inline unsigned int stm32l0_gpio_pin_read(unsigned int pin)
909+
extern void __stm32l0_gpio_stop_enter(stm32l0_gpio_stop_state_t *state);
910+
extern void __stm32l0_gpio_stop_leave(stm32l0_gpio_stop_state_t *state);
911+
extern uint32_t __stm32l0_gpio_pin_read(uint32_t pin);
912+
extern void __stm32l0_gpio_pin_write(uint32_t pin, uint32_t data);
913+
extern void stm32l0_gpio_pin_configure(uint32_t pin, uint32_t mode);
914+
extern void stm32l0_gpio_pin_input(uint32_t pin);
915+
extern void stm32l0_gpio_pin_output(uint32_t pin);
916+
extern void stm32l0_gpio_pin_alternate(uint32_t pin);
917+
extern void stm32l0_gpio_pin_analog(uint32_t pin);
918+
919+
static inline uint32_t stm32l0_gpio_pin_read(uint32_t pin)
921920
{
922921
if (__builtin_constant_p(pin))
923922
{
@@ -937,7 +936,7 @@ static inline unsigned int stm32l0_gpio_pin_read(unsigned int pin)
937936
}
938937
}
939938

940-
static inline void stm32l0_gpio_pin_write(unsigned int pin, unsigned int data)
939+
static inline void stm32l0_gpio_pin_write(uint32_t pin, uint32_t data)
941940
{
942941
if (__builtin_constant_p(pin))
943942
{
@@ -949,9 +948,12 @@ static inline void stm32l0_gpio_pin_write(unsigned int pin, unsigned int data)
949948

950949
GPIO = (GPIO_TypeDef *)(GPIOA_BASE + (GPIOB_BASE - GPIOA_BASE) * group);
951950

952-
if (data) {
951+
if (data)
952+
{
953953
GPIO->BSRR = (1ul << index);
954-
} else {
954+
}
955+
else
956+
{
955957
GPIO->BRR = (1ul << index);
956958
}
957959
}

system/STM32L0xx/Lib/libstm32l052xx.a

5.74 KB
Binary file not shown.

system/STM32L0xx/Lib/libstm32l072xx.a

5.65 KB
Binary file not shown.

system/STM32L0xx/Lib/libstm32l082xx.a

5.97 KB
Binary file not shown.

system/STM32L0xx/Source/armv6m_atomic.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,12 @@ uint32_t armv6m_atomic_modify(volatile uint32_t *p_data, uint32_t mask, uint32_t
128128
return __armv6m_atomic_modify(p_data, mask, data);
129129
}
130130

131+
uint32_t armv6m_atomic_andzb(volatile uint32_t *p_data, uint32_t data, volatile uint8_t *p_zero)
132+
{
133+
return __armv6m_atomic_andzb(p_data, data, p_zero);
134+
}
135+
136+
uint32_t armv6m_atomic_andzh(volatile uint32_t *p_data, uint32_t data, volatile uint16_t *p_zero, uint32_t mask)
137+
{
138+
return __armv6m_atomic_andzh(p_data, data, p_zero, mask);
139+
}

0 commit comments

Comments
 (0)