From 2831954309ffcbe06477409c515e9eaa7104cdb3 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sun, 24 Nov 2024 15:19:48 +0100 Subject: [PATCH] feat: atomic register modifications --- include/registers.h | 52 +++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/include/registers.h b/include/registers.h index ccaf2ac..6b131bf 100644 --- a/include/registers.h +++ b/include/registers.h @@ -1,43 +1,45 @@ #include +#include #ifndef REGISTERS_H #define REGISTERS_H /** - * @brief Writes data on the given position in register. + * @brief Writes data into the register. * @param[in,out] reg The address to change. - * @param[in] data The data to write on pos. - * @param[in] pos The position to start writing to. First @see data param is shifted by this. + * @param[in] data The data to write to the whole register. * @param[in] mask The mask to and the data with, ie. if you want only two bits, set to 0x3. */ -inline void __attribute__((always_inline)) -reg_write_bits_pos(volatile uint32_t *reg, uint32_t data, uint8_t pos, - uint32_t mask) { - *reg &= ~(mask << pos); - *reg |= (data & mask) << pos; +static inline void __attribute__((always_inline)) reg_write_bits(volatile uint32_t *reg, uint32_t data, + uint32_t mask) { + uint32_t set = data & mask; + uint32_t clear = (~data) & mask; + ATOMIC_MODIFY_REG(reg, clear, set); } /** - * @brief Writes data into the register. + * @brief Writes data on the given position in register. * @param[in,out] reg The address to change. - * @param[in] data The data to write to the whole register. + * @param[in] data The data to write on pos. + * @param[in] pos The position to start writing to. First @see data param is shifted by this. * @param[in] mask The mask to and the data with, ie. if you want only two bits, set to 0x3. */ -inline void __attribute__((always_inline)) reg_write_bits(volatile uint32_t *reg, uint32_t data, - uint32_t mask) { - *reg &= ~(mask); - *reg |= (data & mask); +static inline void __attribute__((always_inline)) +reg_write_bits_pos(volatile uint32_t *reg, uint32_t data, uint8_t pos, + uint32_t mask) { + reg_write_bits(reg, data, mask << pos); } + /** * @brief Write ones on the given position in register. * @param[in,out] reg The address to change. * @param[in] pos The position to start writing to. First @see mask param is shifted by this. * @param[in] mask The mask of bits to write ones to, ie. if you want only two bits, set to 0x3. */ -inline void __attribute__((always_inline)) reg_set_bits_pos(volatile uint32_t *reg, uint8_t pos, +static inline void __attribute__((always_inline)) reg_set_bits_pos(volatile uint32_t *reg, uint8_t pos, uint32_t mask) { - *reg |= mask << pos; + ATOMIC_SET_BIT(reg, mask << pos); } /** @@ -45,9 +47,9 @@ inline void __attribute__((always_inline)) reg_set_bits_pos(volatile uint32_t *r * @param[in,out] reg The address to change. * @param[in] mask The mask of bits to write ones to. */ -inline void __attribute__((always_inline)) reg_set_bits(volatile uint32_t *reg, +static inline void __attribute__((always_inline)) reg_set_bits(volatile uint32_t *reg, uint32_t mask) { - *reg |= mask; + ATOMIC_SET_BIT(reg, mask); } /** @@ -57,7 +59,7 @@ inline void __attribute__((always_inline)) reg_set_bits(volatile uint32_t *reg, * @param[in] pos The position to shift the @see mask by. * @param[in] mask The mask saying what bits to toggle (1), from the @see pos. */ -inline void __attribute__((always_inline)) reg_toggle_bits_pos(volatile uint32_t *reg, uint8_t pos, +static inline void __attribute__((always_inline)) reg_toggle_bits_pos(volatile uint32_t *reg, uint8_t pos, uint32_t mask) { *reg ^= (mask << pos); } @@ -68,7 +70,7 @@ inline void __attribute__((always_inline)) reg_toggle_bits_pos(volatile uint32_t * @param[in,out] reg Address of the register to toggle bits in. * @param[in] mask The mask saying what bits to toggle (1). */ -inline void __attribute__((always_inline)) +static inline void __attribute__((always_inline)) reg_toggle_bits(volatile uint32_t *reg, uint32_t mask) { *reg ^= mask; } @@ -79,9 +81,9 @@ reg_toggle_bits(volatile uint32_t *reg, uint32_t mask) { * @param[in] pos The position to start writing to. First the mask is shifted by this. * @param[in] mask The mask of bits to write ones to, ie. if you want only two bits, set to 0x3. */ -inline void __attribute__((always_inline)) +static inline void __attribute__((always_inline)) reg_clear_bits_pos(volatile uint32_t *reg, uint8_t pos, uint32_t mask) { - *reg ^= ~(mask << pos); + ATOMIC_CLEAR_BIT(reg, mask << pos); } /** @@ -89,9 +91,9 @@ reg_clear_bits_pos(volatile uint32_t *reg, uint8_t pos, uint32_t mask) { * @param[in,out] reg The address to change. * @param[in] mask The mask of bits to write ones to. */ -inline void __attribute__((always_inline)) +static inline void __attribute__((always_inline)) reg_clear_bits(volatile uint32_t *reg, uint32_t mask) { - *reg &= ~mask; + ATOMIC_CLEAR_BIT(reg, mask); } /** @@ -102,7 +104,7 @@ reg_clear_bits(volatile uint32_t *reg, uint32_t mask) { * @param[in] mask The mask to apply on the resulting data * @return The read data. */ -inline uint32_t __attribute__((always_inline)) +static inline uint32_t __attribute__((always_inline)) reg_read_bits_pos(volatile uint32_t *reg, uint8_t pos, uint32_t mask) { return ((*reg) >> pos) & mask; } -- 2.48.1