1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
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>
This commit is contained in:
bors[bot] 2023-02-07 07:33:48 +00:00 committed by GitHub
commit af393878d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 116 additions and 16 deletions

View File

@ -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

View File

@ -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

107
cpu/gd32v/periph/rtc_mem.c Normal file
View File

@ -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++);
}
}

View File

@ -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;
}

View File

@ -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))) {