From 65fccdd55a04c4a4b7b7d6eae87350cdc6f8f3ce Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 6 Feb 2023 14:15:45 +0100 Subject: [PATCH 1/3] tests/driver_dac_dds: fix output of sine and saw functions --- tests/driver_dac_dds/main.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/tests/driver_dac_dds/main.c b/tests/driver_dac_dds/main.c index 43e9f93b18f1..ac8adcb1db12 100644 --- a/tests/driver_dac_dds/main.c +++ b/tests/driver_dac_dds/main.c @@ -98,24 +98,17 @@ typedef void (*sample_gen_t)(uint8_t *dst, size_t len, uint16_t period); static void _fill_saw_samples_8(uint8_t *buf, size_t len, uint16_t period) { - uint8_t x = 0; - unsigned step = 0xFF / period; - for (uint16_t i = 0; i < len; ++i) { - x += step; - buf[i] = x; + buf[i] = (i * 0xFFUL) / period; } } static void _fill_saw_samples_16(uint8_t *buf, size_t len, uint16_t period) { - uint16_t x = 0; - unsigned step = 0xFFFF / period; - for (uint16_t i = 0; i < len; ++i) { - x += step; - buf[i] = x; - buf[++i] = x >> 8; + uint16_t y = (i * 0xFFFFUL) / period; + buf[i] = y; + buf[++i] = y >> 8; } } @@ -126,8 +119,7 @@ static void _fill_sine_samples_8(uint8_t *buf, size_t len, uint16_t period) for (uint16_t i = 0; i < period; ++i) { x += step; - buf[i] = isin(x) >> 5; - buf[i] += INT8_MAX + 1; + buf[i] = (isin(x) + 4096) >> 6; } for (uint16_t i = period; i < len; i += period) { @@ -145,8 +137,7 @@ static void _fill_sine_samples_16(uint8_t *buf, size_t len, uint16_t period) for (uint16_t i = 0; i < period; ++i) { x += step; - uint16_t y = isin(x); - y += INT16_MAX + 1; + uint16_t y = (isin(x) + 4096) << 2; buf[i] = y; buf[++i] = y >> 8; } From f0f9a026fcf8edfb1d6cd5dcc46b19e64899bae6 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Mon, 6 Feb 2023 22:21:19 +0100 Subject: [PATCH 2/3] tests/periph_rtt: replace fixed buffer by riot_msg size --- tests/periph_rtt/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/periph_rtt/main.c b/tests/periph_rtt/main.c index 7095a9f7f035..57fe6082925e 100644 --- a/tests/periph_rtt/main.c +++ b/tests/periph_rtt/main.c @@ -65,7 +65,7 @@ static void _set_rtc_mem(void) static void _get_rtc_mem(void) { - char buf[4]; + char buf[sizeof(riot_msg) - 1]; rtc_mem_read(riot_msg_offset, buf, sizeof(buf)); if (memcmp(buf, riot_msg, sizeof(buf))) { From dc5a1e9db0f77b5b92710bf6e981ac9495fa8f28 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Mon, 6 Feb 2023 22:22:01 +0100 Subject: [PATCH 3/3] cpu/gd32v: add periph_rtc_mem support --- cpu/gd32v/Kconfig | 1 + cpu/gd32v/Makefile.features | 1 + cpu/gd32v/periph/rtc_mem.c | 107 ++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 cpu/gd32v/periph/rtc_mem.c diff --git a/cpu/gd32v/Kconfig b/cpu/gd32v/Kconfig index 4caf73dc7a47..809ba86e63f8 100644 --- a/cpu/gd32v/Kconfig +++ b/cpu/gd32v/Kconfig @@ -18,6 +18,7 @@ config CPU_FAM_GD32V select HAS_PERIPH_FLASHPAGE_PAGEWISE select HAS_PERIPH_PM select HAS_PERIPH_RTC + select HAS_PERIPH_RTC_MEM select HAS_PERIPH_RTT select HAS_PERIPH_TIMER select HAS_PERIPH_TIMER_PERIODIC diff --git a/cpu/gd32v/Makefile.features b/cpu/gd32v/Makefile.features index d7a4e16adcb3..e2134f9062fe 100644 --- a/cpu/gd32v/Makefile.features +++ b/cpu/gd32v/Makefile.features @@ -5,6 +5,7 @@ FEATURES_PROVIDED += periph_clic FEATURES_PROVIDED += periph_gpio FEATURES_PROVIDED += periph_gpio_irq FEATURES_PROVIDED += periph_rtc +FEATURES_PROVIDED += periph_rtc_mem FEATURES_PROVIDED += periph_rtt FEATURES_PROVIDED += periph_timer FEATURES_PROVIDED += periph_timer_periodic diff --git a/cpu/gd32v/periph/rtc_mem.c b/cpu/gd32v/periph/rtc_mem.c new file mode 100644 index 000000000000..c6ee050c0348 --- /dev/null +++ b/cpu/gd32v/periph/rtc_mem.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2023 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_gd32v + * @{ + * @file + * @brief Low-level RTC backup memory implementation for GD32VF103 + * + * @author Gunar Schorcht + * @} + */ + +#include + +#include "cpu.h" +#include "periph/rtc_mem.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +#define RTC_MEM_SIZE 84 /* RTC data register size in byte */ + +extern void rtc_lock(void); +extern void rtc_unlock(void); + +/* Since the registers are only 16-bit, but 32-bit aligned and not linearly + * addressed, it makes more sense to write and read byte by byte instead of + * using memcpy */ + +static volatile uint16_t *_rtc_mem_data_reg(unsigned addr) +{ + /* This function determines the register address of the 16-bit BKP data + * register which are 32-bit aligned and not addressed linearly. The + * layout is the following: + * + * addr 0, 1, ..., 9 are @0x40006c00 + 0x04, 0x08, ...,0x28 + * addr 10, 11, ..., 41 are @0x40006c00 + 0x40, 0x44, ...,0xbc + */ + + /* 16-bit data register index */ + unsigned reg_index = addr >> 1; + /* 16-bit data register address as multiple of 32 bit */ + return (reg_index < 10) ? &BKP->DATA0 + (reg_index << 1) + : &BKP->DATA10 + ((reg_index - 10) << 1); +} + +static void _rtc_mem_write_byte(unsigned addr, uint8_t byte) +{ + volatile uint16_t *reg = _rtc_mem_data_reg(addr); + if (addr % 2) { + /* high byte */ + *reg &= 0x00ff; + *reg |= (uint16_t)byte << 8; + } + else { + /* low byte */ + *reg &= 0xff00; + *reg |= byte; + } +} + +static uint8_t _rtc_mem_read_byte(unsigned addr) +{ + volatile uint16_t *reg = _rtc_mem_data_reg(addr); + return (addr % 2) ? (*reg & 0xff00) >> 8 : *reg & 0x00ff; +} + +size_t rtc_mem_size(void) +{ + return RTC_MEM_SIZE; +} + +void rtc_mem_write(unsigned offset, const void *data, size_t len) +{ + assert(offset + len <= rtc_mem_size()); + + /* enable APB1 clocks */ + RCU->APB1EN |= RCU_APB1EN_PMUEN_Msk | RCU_APB1EN_BKPIEN_Msk; + + /* enable write access to backup domain registers */ + PMU->CTL |= PMU_CTL_BKPWEN_Msk; + + for (unsigned i = 0; i < len; i++) { + _rtc_mem_write_byte(offset++, ((uint8_t *)data)[i]); + } + + /* disable write access to backup domain registers */ + PMU->CTL &= ~PMU_CTL_BKPWEN_Msk; +} + +void rtc_mem_read(unsigned offset, void *data, size_t len) +{ + assert(offset + len <= rtc_mem_size()); + + /* enable APB1 clocks */ + RCU->APB1EN |= RCU_APB1EN_PMUEN_Msk | RCU_APB1EN_BKPIEN_Msk; + + for (unsigned i = 0; i < len; i++) { + ((uint8_t *)data)[i] = _rtc_mem_read_byte(offset++); + } +}