RP2040 RTC driver WIP

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14142 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
cinsights 2021-04-06 20:58:04 +00:00
parent 22c741835d
commit c2fd099efc
5 changed files with 373 additions and 0 deletions

View File

@ -230,6 +230,21 @@ typedef struct {
__I uint32_t UARTPCELLID2; __I uint32_t UARTPCELLID2;
__I uint32_t UARTPCELLID3; __I uint32_t UARTPCELLID3;
} UART_TypeDef; } UART_TypeDef;
typedef struct {
__IO uint32_t CLKDIVM1;
__IO uint32_t SETUP0;
__IO uint32_t SETUP1;
__IO uint32_t CTRL;
__IO uint32_t IRQSETUP0;
__IO uint32_t IRQSETUP1;
__IO uint32_t RTC1;
__IO uint32_t RTC0;
__IO uint32_t INTR;
__IO uint32_t INTE;
__IO uint32_t INTF;
__IO uint32_t INTS;
} RTC_TypeDef;
/** @} */ /** @} */
/** /**
@ -248,6 +263,7 @@ typedef struct {
#define __UART0_BASE (__APBPERIPH_BASE + 0x00034000U) #define __UART0_BASE (__APBPERIPH_BASE + 0x00034000U)
#define __UART1_BASE (__APBPERIPH_BASE + 0x00038000U) #define __UART1_BASE (__APBPERIPH_BASE + 0x00038000U)
#define __SIO_BASE (__IOPORT_BASE + 0x00000000U) #define __SIO_BASE (__IOPORT_BASE + 0x00000000U)
#define __RTC_BASE (__APBPERIPH_BASE + 0x0005c000U)
/** @} */ /** @} */
/** /**
@ -263,6 +279,7 @@ typedef struct {
#define TIMER ((TIMER_TypeDef *) __TIMER_BASE) #define TIMER ((TIMER_TypeDef *) __TIMER_BASE)
#define UART0 ((UART_TypeDef *) __UART0_BASE) #define UART0 ((UART_TypeDef *) __UART0_BASE)
#define UART1 ((UART_TypeDef *) __UART1_BASE) #define UART1 ((UART_TypeDef *) __UART1_BASE)
#define RTC ((RTC_TypeDef *) __RTC_BASE)
/** @} */ /** @} */
/** /**

View File

@ -0,0 +1,9 @@
ifeq ($(USE_SMART_BUILD),yes)
ifneq ($(findstring HAL_USE_RTC TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/RP/LLD/RTCv1/hal_rtc_lld.c
endif
else
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/RP/LLD/RTCv1/hal_rtc_lld.c
endif
PLATFORMINC += $(CHIBIOS)/os/hal/ports/RP/LLD/RTCv1

View File

@ -0,0 +1,196 @@
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_rtc_lld.c
* @brief RP2040 RTC subsystem low level driver source.
*
* @addtogroup RTC
* @{
*/
#include "hal.h"
#include "hardware/rtc.h"
#if (HAL_USE_RTC == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief RTC driver identifier.
*/
RTCDriver RTCD1;
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Enable access to registers.
*
* @notapi
*/
void rtc_lld_init(void) {
/* RTC object initialization.*/
rtcObjectInit(&RTCD1);
/* RTC pointer initialization.*/
RTCD1.rtc = RTC;
clock = hal_lld_get_clock(clk_rtc);
osalDbgAssert(clock > 0U, "no clock");
/* Take RTC out of reset. */
hal_lld_peripheral_unreset(RESETS_ALLREG_RTC);
clock -= 1;
osalDbgAssert(clock <= RTC_CLKDIV_M1_BITS, "invalid divide");
RTCD1.rtc.CLKDIVM1 = clock;
/* Callback initially disabled.*/
RTCD1.callback = NULL;
/* IRQ vector permanently assigned to this driver.*/
//nvicEnableVector(STM32_RTC1_NUMBER, STM32_RTC_IRQ_PRIORITY);
}
/**
* @brief Set current time.
* @note Fractional part will be silently ignored. There is no possibility
* to set it on RP2040 platform.
* @note The function can be called from any context.
*
* @param[in] rtcp pointer to RTC driver structure
* @param[in] timespec pointer to a @p RTCDateTime structure
*
* @notapi
*/
void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) {
uint32_t sec = (uint32_t)timespec->millisecond / 1000;
uint32_t hour = sec / 3600;
sec %= 3600;
uint32_t min = sec / 60;
sec %= 60;
/* Disable RTC. */
rtcp->rtc->CTRL = 0;
/* Wait for RTC to become inactive. */
while (rtccp->rtc->CTRL & RTC_CTRL_RTC_ACTIVE_BITS != 0)
;
/* Write to setup registers. */
rtcp->rtc->SETUP0 =
(timespec->year) << RTC_SETUP_0_YEAR_LSB ) |
(timespec->month) << RTC_SETUP_0_MONTH_LSB) |
(timespec->day) << RTC_SETUP_0_DAY_LSB);
rtcp->rtc->SETUP1 =
(timespec->dayofweek) << RTC_SETUP_1_DOTW_LSB) |
(hour) << RTC_SETUP_1_HOUR_LSB) |
(min) << RTC_SETUP_1_MIN_LSB) |
(sec) << RTC_SETUP_1_SEC_LSB);
/* Load setup values into RTC clock domain. */
rtcp->rtc->CTRL = RTC_CTRL_LOAD_BITS;
/* Enable RTC and wait for it to be active. */
rtcp->rtc->CTRL = RTC_CTRL_RTC_ENABLE_BITS;
while (rtccp->rtc->CTRL & RTC_CTRL_RTC_ACTIVE_BITS == 0)
;
}
/**
* @brief Get current time.
* @note The function can be called from any context.
*
* @param[in] rtcp pointer to RTC driver structure
* @param[out] timespec pointer to a @p RTCDateTime structure
*
* @notapi
*/
void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) {
(void)rtcp;
(void)timespec;
}
#if (RTC_ALARMS > 0) || defined(__DOXYGEN__)
/**
* @brief Set alarm time.
* @note Default value after BKP domain reset for both comparators is 0.
* @note Function does not performs any checks of alarm time validity.
* @note The function can be called from any context.
*
* @param[in] rtcp pointer to RTC driver structure.
* @param[in] alarm alarm identifier. Can be 1 or 2.
* @param[in] alarmspec pointer to a @p RTCAlarm structure.
*
* @notapi
*/
void rtc_lld_set_alarm(RTCDriver *rtcp,
rtcalarm_t alarm,
const RTCAlarm *alarmspec) {
(void)rtcp;
(void)alarm;
(void)alarmspec;
}
/**
* @brief Get alarm time.
* @note The function can be called from any context.
*
* @param[in] rtcp pointer to RTC driver structure
* @param[in] alarm alarm identifier
* @param[out] alarmspec pointer to a @p RTCAlarm structure
*
* @notapi
*/
void rtc_lld_get_alarm(RTCDriver *rtcp,
rtcalarm_t alarm,
RTCAlarm *alarmspec) {
(void)rtcp;
(void)alarm;
(void)alarmspec;
}
#endif /* RTC_ALARMS > 0 */
#endif /* HAL_USE_RTC */
/** @} */

View File

@ -0,0 +1,148 @@
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_rtc_lld.h
* @brief RP2040 RTC subsystem low level driver header.
*
* @addtogroup RTC
* @{
*/
#ifndef HAL_RTC_LLD_H
#define HAL_RTC_LLD_H
#if (HAL_USE_RTC == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @name Implementation capabilities
* @{
*/
/**
* @brief Callback support int the driver.
*/
#define RTC_SUPPORTS_CALLBACKS TRUE
/**
* @brief Number of alarms available.
*/
#define RTC_ALARMS 1
/**
* @brief Presence of a local persistent storage.
*/
#define RTC_HAS_STORAGE FALSE
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name PLATFORM configuration options
* @{
*/
/**
* @brief RTCD1 driver enable switch.
* @details If set to @p TRUE the support for RTC1 is included.
* @note The default is @p FALSE.
*/
#if !defined(PLATFORM_RTC_USE_RTC1) || defined(__DOXYGEN__)
#define PLATFORM_RTC_USE_RTC1 FALSE
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
#if (RTC_SUPPORTS_CALLBACKS == TRUE) || defined(__DOXYGEN__)
/**
* @brief Type of an RTC event.
*/
typedef enum {
RTC_EVENT_SECOND = 0 /** Triggered every second. */
} rtcevent_t;
/**
* @brief Type of a generic RTC callback.
*/
typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event);
#endif
/**
* @brief Type of a structure representing an RTC alarm time stamp.
*/
typedef struct {
/* End of the mandatory fields.*/
uint32_t dummy;
} RTCAlarm;
/**
* @brief Implementation-specific @p RTCDriver fields.
*/
#define rtc_lld_driver_fields \
/* Pointer to the RTC registers block.*/ \
RTC_TypeDef *rtc; \
/* Callback pointer.*/ \
rtccb_t callback
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if (PLATFORM_RTC_USE_RTC1 == TRUE) && !defined(__DOXYGEN__)
extern RTCDriver RTCD1;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void rtc_lld_init(void);
void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec);
void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec);
#if RTC_ALARMS > 0
void rtc_lld_set_alarm(RTCDriver *rtcp,
rtcalarm_t alarm,
const RTCAlarm *alarmspec);
void rtc_lld_get_alarm(RTCDriver *rtcp,
rtcalarm_t alarm,
RTCAlarm *alarmspec);
#endif
#if RTC_SUPPORTS_CALLBACKS == TRUE
void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback);
#endif
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_RTC == TRUE */
#endif /* HAL_RTC_LLD_H */
/** @} */

View File

@ -49,6 +49,9 @@
/* TIMER attributes.*/ /* TIMER attributes.*/
#define RP_HAS_TIMER TRUE #define RP_HAS_TIMER TRUE
/* RTC attributes.*/
#define RP_HAS_RTC TRUE
/** @} */ /** @} */
#endif /* RP_REGISTRY_H */ #endif /* RP_REGISTRY_H */