9
0
Fork 0

STM32 F4 RTC driver is fully coded (but not tested)

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4176 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2011-12-14 19:12:00 +00:00
parent e03edf97b6
commit f82bc39fb6
11 changed files with 639 additions and 51 deletions

View File

@ -1689,7 +1689,7 @@
<p>
<b>STATUS:</b>
This is really a vapor ware, pre-announcement.
I have the hardware and the motivation and I expect to announce the availability of support the STM32F4-Discovery with the NuttX 6.13 release.
I have the hardware and the motivation and I expect to announce the availability of support the STM32F4-Discovery in a later NuttX release.
</p>
</td>
</tr>
@ -2728,8 +2728,39 @@ buildroot-1.10 2011-05-06 &lt;gnutt@nuttx.org&gt;
<ul><pre>
nuttx-6.13 2012-xx-xx Gregory Nutt &lt;gnutt@nuttx.org&gt;
* arch/arm/src/stm32/stm32f40xxx_dma.c: Add DMA support for the STM32 F4
family (untested on initial check-in)
* arch/arm/src/armv7-m/up_fpu.c: Add logic for saving an restoring VFP
floating point registers on context switches (but also disable the FPU
because CodeSourcery doesn't support hard flowing point!)
* arch/arm/src/stm32/chip/stm32_eth.h: Add Ethernet register definitions
for the STM32 F4.
* arch/arm/srcm/stm32/stm32_eth.c: Adds an Ethernet driver for the STM32 F4.
* arch/arm/srcm/stm32/stm32_dac.c and stm32_adc.c: &quot;Skeleton&quot; files for STM32
DAC and ADC drivers. The actual logic will come later.
* arch/arm/srcm/stm32/stm32_eth.c: There may be a few more lurking bugs, but
the STM32 Ethernet driver appears to be fully functional on the STM3240G-EVAL.
* arch/arm/srcm/stm32/stm32_eth.c: Fix an error in clearing abnormal interrupt
events.
* configs/stm3240g-eval/dhcpd: Add a DCHP daemon configuration for the
STM3240G-EVAL board.
* configs/stm3240g-eval/nettest: Add a network test configuration for the
STM3240G-EVAL board.
* arch/arm/srcm/stm32/stm32_rtc.c, stm32f10xxx_rtc.c, and stm32f40xxx_rtc:
Broke out separate drivers to handle the very different RTC implementations
in the STM32 F1 and F4 family.
apps-6.13 2012-xx-xx Gregory Nutt &lt;gnutt@nuttx.org&gt;
* apps/examples/dhcpd: May now be built as an NSH built-in application
by setting CONFIG_NSH_BUILTIN_APPS.
* apps/netutils/dhcpd/dhcpd.c: Fix several problems using host order address
where network addresses expected (and vice versa).
* apps/examples/nettest: May now be built as an NSH built-in application
by setting CONFIG_NSH_BUILTIN_APPS.
* apps/examples/nettest: Correct some build issues with the nettest is
built for performance evaluation.
pascal-3.1 2012-xx-xx Gregory Nutt &lt;gnutt@nuttx.org&gt;
buildroot-1.11 2012-xx-xx &lt;gnutt@nuttx.org&gt;

View File

@ -82,6 +82,26 @@
/* Register Bitfield Definitions ****************************************************/
/* EXTI lines > 15 are associated with internal devices: */
#if defined(CONFIG_STM32_STM32F10XX)
# define EXTI_PVD_LINE (1 << 16) /* EXTI line 16 is connected to the PVD output */
# define EXTI_RTC_ALARM (1 << 17) /* EXTI line 17 is connected to the RTC Alarm event */
# define EXTI_USB_WAKEUP (1 << 18) /* EXTI line 18 is connected to the USB Wakeup event */
# ifdef CONFIG_STM32_CONNECTIVITYLINE
# define EXTI_ETH_WAKEUP (1 << 19) /* EXTI line 19 is connected to the Ethernet Wakeup event */
# endif
#elif defined(CONFIG_STM32_STM32F40XX)
# define EXTI_PVD_LINE (1 << 16) /* EXTI line 16 is connected to the PVD output */
# define EXTI_RTC_ALARM (1 << 17) /* EXTI line 17 is connected to the RTC Alarm event */
# define EXTI_OTGFS_WAKEUP (1 << 18) /* EXTI line 18 is connected to the USB OTG FS Wakeup event */
# define EXTI_ETH_WAKEUP (1 << 19) /* EXTI line 19 is connected to the Ethernet Wakeup event */
# define EXTI_OTGHS_WAKEUP (1 << 20) /* EXTI line 20 is connected to the USB OTG HS Wakeup event */
# define EXTI_RTC_TAMPER (1 << 21) /* EXTI line 21 is connected to the RTC Tamper and TimeStamp events */
# define EXTI_RTC_TIMESTAMP (1 << 22) /* EXTI line 21 is connected to the RTC Tamper and TimeStamp events */
# define EXTI_RTC_WAKEUP (1 << 23) /* EXTI line 22 is connected to the RTC Wakeup event
#endif
/* Interrupt mask register */
#define EXTI_IMR_BIT(n) STM32_EXTI_BIT(n) /* 1=Interrupt request from line x is not masked */

View File

@ -133,7 +133,7 @@
#define RTC_TR_SU_SHIFT (0) /* Bits 0-3: Second units in BCD format */
#define RTC_TR_SU_MASK (15 << RTC_TR_SU_SHIFT)
#define RTC_TR_ST_SHIFT (4) /* Bits 4-6: Second tens in BCD format */
#define RTC_TR_ST_MASK (7 << RTC_TR_ST_SHIFT)*
#define RTC_TR_ST_MASK (7 << RTC_TR_ST_SHIFT)
#define RTC_TR_MNU_SHIFT (8) /* Bit 8-11: Minute units in BCD format */
#define RTC_TR_MNU_MASK (15 << RTC_TR_MNU_SHIFT)
#define RTC_TR_MNT_SHIFT (12) /* Bits 12-14: Minute tens in BCD format */
@ -143,10 +143,11 @@
#define RTC_TR_HT_SHIFT (20) /* Bits 20-21: Hour tens in BCD format */
#define RTC_TR_HT_MASK (3 << RTC_TR_HT_SHIFT)
#define RTC_TR_PM (1 << 22) /* Bit 22: AM/PM notation */
#define RTC_TR_RESERVED_BITS (0xff808080)
/* RTC date register */
#define RTC_DR_DU_SHIFT (0) /* Bits 0-3]: Date units in BCD format */
#define RTC_DR_DU_SHIFT (0) /* Bits 0-3: Date units in BCD format */
#define RTC_DR_DU_MASK (15 << RTC_DR_DU_SHIFT)
#define RTC_DR_DT_SHIFT (4) /* Bits 4-5: Date tens in BCD format */
#define RTC_DR_DT_MASK (3 << RTC_DR_DT_SHIFT)
@ -166,6 +167,7 @@
#define RTC_DR_YU_MASK (15 << RTC_DR_YU_SHIFT)
#define RTC_DR_YT_SHIFT (20) /* Bits 20-23: Year tens in BCD format */
#define RTC_DR_YT_MASK (15 << RTC_DR_YT_SHIFT)
#define RTC_DR_RESERVED_BITS (0xff0000c0)
/* RTC control register */
@ -220,13 +222,14 @@
#define RTC_ISR_TSOVF (1 << 12) /* Bit 12: Timestamp overflow flag */
#define RTC_ISR_TAMP1F (1 << 13) /* Bit 13: Tamper detection flag */
#define RTC_ISR_TAMP2F (1 << 14) /* Bit 14: TAMPER2 detection flag */
#define RTC_ISR_RECALPF (1 << 15) /* Bit 16: Recalibration pending Flag */
#define RTC_ISR_RECALPF (1 << 16) /* Bit 16: Recalibration pending Flag */
#define RTC_ISR_ALLFLAGS (0x00017fff)
/* RTC prescaler register */
#define RTC_PRER_PREDIV_S_SHIFT (0) /* Bits 0-14: Synchronous prescaler factor */
#define RTC_PRER_PREDIV_S_MASK (0x7fff << RTC_PRER_PREDIV_S_SHIFT)
#define RTC_PRER_PREDIV_A_SHIFT (22) /* Bits 16-22: Asynchronous prescaler factor */
#define RTC_PRER_PREDIV_A_SHIFT (16) /* Bits 16-22: Asynchronous prescaler factor */
#define RTC_PRER_PREDIV_A_MASK (0x7f << RTC_PRER_PREDIV_A_SHIFT)
/* RTC wakeup timer register */

View File

@ -2,7 +2,7 @@
* arch/arm/src/stm32/stm32_lse.c
*
* Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* Author: Gregory Nutt <gnutt@nuttx.orgr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -63,31 +63,43 @@
/****************************************************************************
* Name: stm32_rcc_enablelse
*
* Description:
* Enable the External Low-Speed (LSE) Oscillator and, if the RTC is
* configured, setup the LSE as the RTC clock source, and enable the RTC.
*
* Todo:
* Check for LSE good timeout and return with -1,
* possible ISR optimization? or at least ISR should be cough in case of\
* failure
*
****************************************************************************/
void stm32_rcc_enablelse(void)
{
/* Enable LSE */
/* Enable the External Low-Speed (LSE) Oscillator by setting the LSEON bit
* the RCC BDCR register.
*/
modifyreg16(STM32_RCC_BDCR, 0, RCC_BDCR_LSEON);
/* We could wait for ISR here ... */
/* Wait for the LSE clock to be ready */
while ((getreg16(STM32_RCC_BDCR) & RCC_BDCR_LSERDY) == 0)
{
up_waste();
}
/* Select LSE as RTC Clock Source */
/* The primariy purpose of the LSE clock is to drive the RTC. The RTC could
* also be driven by the LSI (but that would be very inaccurate) or by the
* HSE (but that would prohibit low-power operation)
*
* Select LSE as RTC Clock Source by setting the RTCSEL field of the RCC BDCR
* register.
*/
#ifdef CONFIG_RTC
modifyreg16(STM32_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSE);
/* Enable Clock */
/* Enable the RTC Clock by setting the RTCEN bit in the RCC BDCR register */
modifyreg16(STM32_RCC_BDCR, 0, RCC_BDCR_RTCEN);
#endif
}

View File

@ -33,13 +33,9 @@
*
************************************************************************************/
/** \file
* \author Uros Platise
* \brief STM32 Power
*
* \addtogroup STM32_PWR
* \{
*/
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include <nuttx/arch.h>
@ -50,7 +46,6 @@
#include "up_arch.h"
#include "stm32_pwr.h"
#if defined(CONFIG_STM32_PWR)
/************************************************************************************
@ -59,32 +54,41 @@
static inline uint16_t stm32_pwr_getreg(uint8_t offset)
{
return getreg32(STM32_PWR_BASE + offset);
return getreg32(STM32_PWR_BASE + offset);
}
static inline void stm32_pwr_putreg(uint8_t offset, uint16_t value)
{
putreg32(value, STM32_PWR_BASE + offset);
putreg32(value, STM32_PWR_BASE + offset);
}
static inline void stm32_pwr_modifyreg(uint8_t offset, uint16_t clearbits, uint16_t setbits)
{
modifyreg32(STM32_PWR_BASE + offset, clearbits, setbits);
modifyreg32(STM32_PWR_BASE + offset, clearbits, setbits);
}
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Public Function - Initialization
* Name: stm32_pwr_enablebkp
*
* Description:
* Enables access to the backup domain (RTC registers, RTC backup data registers
* and backup SRAM).
*
* Input Parameters:
* None
*
* Returned Values:
* None
*
************************************************************************************/
void stm32_pwr_enablebkp(void)
{
stm32_pwr_modifyreg(STM32_PWR_CR_OFFSET, 0, PWR_CR_DBP);
stm32_pwr_modifyreg(STM32_PWR_CR_OFFSET, 0, PWR_CR_DBP);
}
#endif // defined(CONFIG_STM32_PWR)
/** \} */

View File

@ -63,15 +63,27 @@ extern "C" {
* Public Functions
************************************************************************************/
/** Disables Write Protection to the Backup Area
**/
/************************************************************************************
* Name: stm32_pwr_enablebkp
*
* Description:
* Enables access to the backup domain (RTC registers, RTC backup data registers
* and backup SRAM).
*
* Input Parameters:
* None
*
* Returned Values:
* None
*
************************************************************************************/
EXTERN void stm32_pwr_enablebkp(void);
/** \} */
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_STM32_STM32_PWR_H */

View File

@ -2,7 +2,7 @@
* arch/arm/src/stm32/stm32_rcc.h
*
* Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* Author: Gregory Nutt <gnutt@nuttx.orgr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -170,7 +170,8 @@ EXTERN void stm32_clockconfig(void);
* Name: stm32_rcc_enablelse
*
* Description:
* Enable LSE Clock
* Enable the External Low-Speed (LSE) Oscillator and, if the RTC is
* configured, setup the LSE as the RTC clock source, and enable the RTC.
*
* Input Parameters:
* None

View File

@ -354,7 +354,8 @@ static int stm32_rtc_interrupt(int irq, void *context)
int up_rtcinitialize(void)
{
/* Set access to the peripheral, enable the backup domain (BKP) and the lower power
* extern 32,768Hz (Low-Speed External, LSE) oscillator.
* extern 32,768Hz (Low-Speed External, LSE) oscillator. Configure the LSE to
* drive the RTC.
*/
stm32_pwr_enablebkp();

View File

@ -426,7 +426,7 @@ static inline void rcc_enableapb1(void)
#endif
/* Power interface clock enable. The PWR block is always enabled so that
* we can set the internal voltage regulator for maximum performanc.
* we can set the internal voltage regulator for maximum performance.
*/
regval |= RCC_APB1ENR_PWREN;

View File

@ -65,6 +65,14 @@
# error "CONFIG_RTC_HIRES must NOT be set with this driver"
#endif
/* Constants ************************************************************************/
#define SYNCHRO_TIMEOUT (0x00020000)
#define INITMODE_TIMEOUT (0x00010000)
#define RTC_MAGIC (0xfacefeed)
#define RTC_PREDIV_S (0xff)
#define RTC_PREDIV_A (0x7f)
/************************************************************************************
* Private Types
************************************************************************************/
@ -90,9 +98,338 @@ volatile bool g_rtc_enabled = false;
/************************************************************************************
* Private Functions
************************************************************************************/
/************************************************************************************
* Name: rtc_wprunlock
*
* Description:
* Disable RTC write protection
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
static void rtc_wprunlock(void)
{
/* The following steps are required to unlock the write protection on all the
* RTC registers (except for RTC_ISR[13:8], RTC_TAFCR, and RTC_BKPxR).
*
* 1. Write 0xCA into the RTC_WPR register.
* 2. Write 0x53 into the RTC_WPR register.
*
* Writing a wrong key reactivates the write protection.
*/
putreg32(0xca, STM32_RTC_WPR);
putreg32(0x53, STM32_RTC_WPR);
}
/************************************************************************************
* Name: stm32_rtc_interrupt
* Name: rtc_wprunlock
*
* Description:
* Enable RTC write protection
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
************************************************************************************/
static inline void rtc_wprlock(void)
{
/* Writing any wrong key reactivates the write protection. */
putreg32(0xff, STM32_RTC_WPR);
}
/************************************************************************************
* Name: rtc_synchwait
*
* Description:
* Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are
* synchronized with RTC APB clock.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
static int rtc_synchwait(void)
{
volatile uint32_t timeout;
uint32_t regval;
int ret;
/* Disable the write protection for RTC registers */
rtc_wprunlock();
/* Clear Registers synchronization flag (RSF) */
regval = getreg32(STM32_RTC_ISR);
regval &= ~RTC_ISR_RSF;
putreg32(regval, STM32_RTC_ISR);
/* Now wait the registers to become synchronised */
ret = -ETIMEDOUT;
for (timeout = 0; timeout < SYNCHRO_TIMEOUT; timeout++)
{
regval = getreg32(STM32_RTC_ISR);
if ((regval & RTC_ISR_RSF) != 0)
{
/* Synchronized */
ret = OK;
break;
}
}
/* Re-enable the write protection for RTC registers */
rtc_wprlock();
return ret;
}
/************************************************************************************
* Name: rtc_enterinit
*
* Description:
* Enter RTC initialization mode.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
static int rtc_enterinit(void)
{
volatile uint32_t timeout;
uint32_t regval;
int ret;
/* Check if the Initialization mode is already set */
regval = getreg32(STM32_RTC_ISR);
ret = OK;
if ((regval & RTC_ISR_INITF) == 0)
{
/* Set the Initialization mode */
putreg32(RTC_ISR_INIT, STM32_RTC_ISR);
/* Wait until the RTC is in the INIT state (or a timeout occurs) */
ret = -ETIMEDOUT;
for (timeout = 0; timeout < INITMODE_TIMEOUT; timeout++)
{
regval = getreg32(STM32_RTC_ISR);
if ((regval & RTC_ISR_INITF) != 0)
{
ret = OK;
break;
}
}
return ret;
}
/************************************************************************************
* Name: rtc_exitinit
*
* Description:
* Exit RTC initialization mode.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
static void rtc_exitinit(void)
{
uint32_t regval;
regval = getreg32(STM32_RTC_ISR);
regval &= ~(RTC_ISR_INIT);
putreg32(regval, STM32_RTC_ISR);
}
/************************************************************************************
* Name: rtc_bin2bcd
*
* Description:
* Converts a 2 digit binary to BCD format
*
* Input Parameters:
* value - The byte to be converted.
*
* Returned Value:
* The value in BCD representation
*
************************************************************************************/
static uint32_t rtc_bin2bcd(int value)
{
uint32_t msbcd = 0;
while (value >= 10)
{
msbcd++;
value -= 10;
}
return (msbcd << 4) | value;
}
/************************************************************************************
* Name: rtc_bin2bcd
*
* Description:
* Convert from 2 digit BCD to binary.
*
* Input Parameters:
* value - The BCD value to be converted.
*
* Returned Value:
* The value in binary representation
*
************************************************************************************/
static int rtc_bcd2bin(uint32_t value)
{
uint32_t tens = (value >> 4) * 10;
return (int)(tens + (value & 0x0f));
}
/************************************************************************************
* Name: rtc_setup
*
* Description:
* Performs first time configuration of the RTC. A special value written into
* back-up register 0 will prevent this function from being called on sub-sequent
* resets or power up.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
static int rtc_setup(void)
{
uint32_t regval;
int ret;
/* Enable the External Low-Speed (LSE) Oscillator setup the LSE as the RTC clock\
* source, and enable the RTC.
*/
stm32_rcc_enablelse();
/* Wait for the RTC Time and Date registers to be synchronized with RTC APB
* clock.
*/
ret = rtc_synchwait();
if (ret == OK)
{
/* Disable the write protection for RTC registers */
rtc_wprunlock();
/* Set Initialization mode */
ret = rtc_enterinit()
if (ret == OK)
{
/* Set the 24 hour format by clearing the FMT bit in the RTC
* control register
*/
regval = getreg32(STM32_RTC_CR);
regval &= ~RTC_CR_FMT
putreg32(regval, STM32_RTC_CR);
/* Configure RTC pre-scaler to the required, default values for
* use with the 32.768 KHz LSE clock:
*/
putreg32(((uint32_t)0xff << RTC_PRER_PREDIV_S_SHIFT) |
((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT),
STM32_RTC_PRER);
/* Exit RTC initialization mode */
rtc_exitinit();
}
/* Re-enable the write protection for RTC registers */
rtc_wprlock();
}
return ret;
}
/************************************************************************************
* Name: rtc_resume
*
* Description:
* Called when the RTC was already initialized on a previous power cycle. This
* just brings the RTC back into full operation.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
static int rtc_resume(void)
{
uint32_t regval;
int ret;
/* Wait for the RTC Time and Date registers to be syncrhonized with RTC APB
* clock.
*/
ret = rtc_synchwait();
/* Clear the RTC alarm flags */
#ifdef CONFIG_RTC_ALARM
regval = getreg32(STM32_RTC_ISR);
regval &= ~(RTC_ISR_ALRAF|RTC_ISR_ALRBF);
putreg32(regval, STM32_RTC_ISR);
/* Clear the EXTI Line 17 Pending bit (Connected internally to RTC Alarm) */
putreg32((1 << 17), STM32_EXTI_PR);
#endif
return ret;
}
/************************************************************************************
* Name: rtc_interrupt
*
* Description:
* RTC interrupt service routine
@ -107,7 +444,7 @@ volatile bool g_rtc_enabled = false;
************************************************************************************/
#if CONFIG_RTC_ALARM
static int stm32_rtc_interrupt(int irq, void *context)
static int rtc_interrupt(int irq, void *context)
{
#warning "Missing logic"
return OK;
@ -135,13 +472,55 @@ static int stm32_rtc_interrupt(int irq, void *context)
int up_rtcinitialize(void)
{
/* Initialize the RTC */
#warning "Missing logic"
uint32_t regval;
/* Configure RTC interrupt to catch alarm interrupts. */
/* Clocking for the PWR block must be provided. However, this is done
* unconditionally in stm32f40xxx_rcc.c on power up. This done unconditionally
* because the PWR block is also needed to set the internal voltage regulator for
* maximum performance.
*/
/* Enable access to the backup domain (RTC registers, RTC backup data registers
* and backup SRAM).
*/
stm32_pwr_enablebkp();
/* Check if the one-time initialization of the RTC has already been performed.
* We can determine this by checking if the magic number has been writing to
* to back-up date register DR0.
*/
regval = getreg32(STM32_RTC_BK0R);
if (regval != RTC_MAGIC)
{
/* Perform the one-time setup of the LSE clocking to the RTC */
ret = rtc_setup();
}
else
{
/* RTC already set-up, just resume normal operation */
ret = rtc_resume();
}
/* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts are
* connected to the EXTI controller. To enable the RTC Alarm interrupt, the
* following sequence is required:
*
* 1. Configure and enable the EXTI Line 17 in interrupt mode and select the
* rising edge sensitivity.
* 2. Configure and enable the RTC_Alarm IRQ channel in the NVIC.
* 3. Configure the RTC to generate RTC alarms (Alarm A or Alarm B).
*/
#ifdef CONFIG_RTC_ALARM
irq_attach(STM32_IRQ_RTC, stm32_rtc_interrupt);
# warning "Missing logic"
/* Then attach the ALARM interrupt handler */
irq_attach(STM32_IRQ_RTC, rtc_interrupt);
up_enable_irq(STM32_IRQ_RTC);
#endif
@ -174,7 +553,54 @@ int up_rtcinitialize(void)
int up_rtc_getdatetime(FAR const struct tm *tp)
{
#warning "Missing logic"
uint32_t dr;
uint32_t tr;
uint32_t tmp;
/* Sample the data time registers. There is a race condition here... If we sample
* the time just before midnight on December 31, the date could be wrong because
* the day rolled over while were sampling.
*/
do
{
dr = getreg32(STM32_RTC_DR);
tr = getreg32(STM32_RTC_TR);
tmp = getreg32(STM32_RTC_DR);
}
while (tmp != dr);
/* Convert the RTC time to fields in struct tm format. All of the STM32
* All of the ranges of values correspond between struct tm and the time
* register.
*/
tmp = (uint8_t)(tr & (RTC_TR_SU_MASK|RTC_TR_ST_MASK)) >> RTC_TR_SU_SHIFT;
tp->tm_sec = rtc_bcd2bin(tmp);
tmp = (tr & RTC_TR_MNU_MASK|RTC_TR_MNT_MASK) >> RTC_TR_MNU_SHIFT;
tp->tm_min = rtc_bcd2bin(tmp);
tmp = (tr & RTC_TR_HU_MASK|RTC_TR_HT_MASK) >> RTC_TR_HU_SHIFT;
tp->tm_hour = rtc_bcd2bin(tmp);
/* Now convert the RTC date to fields in struct tm format:
* Days: 1-31 match in both cases.
* Month: STM32 is 1-12, struct tm is 0-11.
* Years: STM32 is 00-99, struct tm is years since 1900.
*
* Issue: I am not sure what the STM32 years mean. Are these the
* years 2000-2099? I'll assume so.
*/
tmp = (dr & RTC_DR_DU_MASK|RTC_DR_DT_MASK) >> RTC_DR_DU_SHIFT;
tp->tm_mday = rtc_bcd2bin(tmp);
tmp = (dr & RTC_DR_MU_MASK|RTC_DR_MT) >> RTC_DR_MU_SHIFT;
tp->tm_mon = rtc_bcd2bin(tmp) - 1;
tmp = (dr & RTC_DR_YU_MASK|RTC_DR_YT_MASK) >> RTC_DR_YU_SHIFT; /* Year units, BCD 0-99 */
tp->tm_year = rtc_bcd2bin(tmp) + 100;
return OK;
}
@ -195,20 +621,74 @@ int up_rtc_getdatetime(FAR const struct tm *tp)
int up_rtc_settime(FAR const struct timespec *tp)
{
/* Break out the time values */
#warning "Missing logic"
FAR struct tm newtime;
uint32_t tr;
uint32_t dr;
int ret;
/* Break out the time values (not that the time is set only to units of seconds) */
(void)gmtime_r(&tp->tv_sec, &newtime);
/* Then write the broken out values to the RTC */
#warning "Missing logic"
return OK;
/* Convert the struct tm format to RTC time register fields. All of the STM32
* All of the ranges of values correspond between struct tm and the time
* register.
*/
tr = (rtc_bin2bcd(tp->tm_sec) << RTC_TR_SU_SHIFT) |
(rtc_bin2bcd(tp->tm_min) << RTC_TR_MNU_SHIFT) |
(rtc_bin2bcd(tp->tm_hour) << RTC_TR_HU_SHIFT);
tr &= ~RTC_TR_RESERVED_BITS;
/* Now convert the fields in struct tm format to the RTC date register fields:
* Days: 1-31 match in both cases.
* Month: STM32 is 1-12, struct tm is 0-11.
* Years: STM32 is 00-99, struct tm is years since 1900.
*
* Issue: I am not sure what the STM32 years mean. Are these the
* years 2000-2099? I'll assume so.
*/
dr = (rtc_bin2bcd(tp->tm_mday) << RTC_DR_DU_SHIFT) |
((rtc_bin2bcd(tp->tm_mon) + 1) << RTC_DR_MU_SHIFT) |
((rtc_bin2bcd(tp->tm_year) - 100) << RTC_DR_YU_SHIFT);
dr &= ~RTC_DR_RESERVED_BITS;
/* Disable the write protection for RTC registers */
rtc_wprunlock();
/* Set Initialization mode */
ret = rtc_enterinit()
if (ret == OK)
{
/* Set the RTC TR and DR registers */
putreg32(tr, STM32_RTC_TR);
putreg32(dr, STM32_RTC_DR);
/* Exit Initialization mode and wait for the RTC Time and Date
* registers to be synchronized with RTC APB clock.
*/
rtc_enterinit()
ret = rtc_synchwait();
}
/* Re-enable the write protection for RTC registers */
rtc_wprlock();
return ret;
}
/************************************************************************************
* Name: up_rtc_setalarm
*
* Description:
* Set up an alarm.
* Set up an alarm. Up to two alarms can be supported (ALARM A and ALARM B).
*
* Input Parameters:
* tp - the time to set the alarm

View File

@ -236,6 +236,18 @@
# define illvdbg(x...)
#endif
#ifdef CONFIG_DEBUG_ANALOG
# define adbg(format, arg...) dbg(format, ##arg)
# define alldbg(format, arg...) lldbg(format, ##arg)
# define avdbg(format, arg...) vdbg(format, ##arg)
# define allvdbg(format, arg...) llvdbg(format, ##arg)
#else
# define adbg(x...)
# define alldbg(x...)
# define avdbg(x...)
# define allvdbg(x...)
#endif
#ifdef CONFIG_DEBUG_GRAPHICS
# define gdbg(format, arg...) dbg(format, ##arg)
# define glldbg(format, arg...) lldbg(format, ##arg)
@ -393,6 +405,18 @@
# define illvdbg (void)
#endif
#ifdef CONFIG_DEBUG_ANALOG
# define adbg dbg
# define alldbg lldbg
# define avdbg vdbg
# define allvdbg llvdbg
#else
# define adbg (void)
# define alldbg (void)
# define avdbg (void)
# define allvdbg (void)
#endif
#ifdef CONFIG_DEBUG_GRAPHICS
# define gdbg dbg
# define glldbg lldbg