Skip to content

Commit

Permalink
Merge #19251 #19254
Browse files Browse the repository at this point in the history
19251: tests/driver_dac_dds: fix output of sine and saw functions r=benpicco a=benpicco



19254: cpu/gd32v: add periph_rtc_mem support r=benpicco a=gschorcht

### Contribution description

This PR provides the `periph_rtc_mem` support for GD32VF103.

A modified version of this driver could also be used for STM32F1.

### Testing procedure

`tests/periph_rtt` should work on any GD32V board, for example:
```
BOARD=sipeed-longan-nano make -C tests/periph_rtt flash
```
```
Help: Press s to start test, r to print it is ready
START
main(): This is RIOT! (Version: 2023.04-devel-319-gebc86-cpu/gd32v/periph_rtc_mem)

RIOT RTT low-level driver test
RTT configuration:
RTT_MAX_VALUE: 0xffffffff
RTT_FREQUENCY: 32768

Testing the tick conversion
Trying to convert 1 to seconds and back
Trying to convert 256 to seconds and back
Trying to convert 65536 to seconds and back
Trying to convert 16777216 to seconds and back
Trying to convert 2147483648 to seconds and back
All ok

Initializing the RTT driver
RTC mem OK
This test will now display 'Hello' every 5 seconds

RTT now: 1
Setting initial alarm to now + 5 s (163841)
rtt_get_alarm() PASSED
RTC mem OK
```

### Issues/PRs references

Co-authored-by: Benjamin Valentin <benjamin.valentin@ml-pa.com>
Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
  • Loading branch information
3 people authored Feb 7, 2023
3 parents 304245b + 65fccdd + dc5a1e9 commit af39387
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 16 deletions.
1 change: 1 addition & 0 deletions cpu/gd32v/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions cpu/gd32v/Makefile.features
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
107 changes: 107 additions & 0 deletions cpu/gd32v/periph/rtc_mem.c
Original file line number Diff line number Diff line change
@@ -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 <gunar@schorcht.net>
* @}
*/

#include <string.h>

#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++);
}
}
21 changes: 6 additions & 15 deletions tests/driver_dac_dds/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand All @@ -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) {
Expand All @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/periph_rtt/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))) {
Expand Down

0 comments on commit af39387

Please sign in to comment.