mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 19:12:45 +01:00
cpu/gd32v: add periph_rtc_mem support
This commit is contained in:
parent
f0f9a026fc
commit
dc5a1e9db0
@ -18,6 +18,7 @@ config CPU_FAM_GD32V
|
|||||||
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||||
select HAS_PERIPH_PM
|
select HAS_PERIPH_PM
|
||||||
select HAS_PERIPH_RTC
|
select HAS_PERIPH_RTC
|
||||||
|
select HAS_PERIPH_RTC_MEM
|
||||||
select HAS_PERIPH_RTT
|
select HAS_PERIPH_RTT
|
||||||
select HAS_PERIPH_TIMER
|
select HAS_PERIPH_TIMER
|
||||||
select HAS_PERIPH_TIMER_PERIODIC
|
select HAS_PERIPH_TIMER_PERIODIC
|
||||||
|
@ -5,6 +5,7 @@ FEATURES_PROVIDED += periph_clic
|
|||||||
FEATURES_PROVIDED += periph_gpio
|
FEATURES_PROVIDED += periph_gpio
|
||||||
FEATURES_PROVIDED += periph_gpio_irq
|
FEATURES_PROVIDED += periph_gpio_irq
|
||||||
FEATURES_PROVIDED += periph_rtc
|
FEATURES_PROVIDED += periph_rtc
|
||||||
|
FEATURES_PROVIDED += periph_rtc_mem
|
||||||
FEATURES_PROVIDED += periph_rtt
|
FEATURES_PROVIDED += periph_rtt
|
||||||
FEATURES_PROVIDED += periph_timer
|
FEATURES_PROVIDED += periph_timer
|
||||||
FEATURES_PROVIDED += periph_timer_periodic
|
FEATURES_PROVIDED += periph_timer_periodic
|
||||||
|
107
cpu/gd32v/periph/rtc_mem.c
Normal file
107
cpu/gd32v/periph/rtc_mem.c
Normal 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++);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user