summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/Documentation/NuttX.html33
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32_exti.h20
-rw-r--r--nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rtc.h11
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_lse.c28
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_pwr.c40
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_pwr.h20
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_rcc.h5
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f10xxx_rtc.c3
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f40xxx_rcc.c2
-rw-r--r--nuttx/arch/arm/src/stm32/stm32f40xxx_rtc.c504
-rw-r--r--nuttx/include/debug.h24
11 files changed, 639 insertions, 51 deletions
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index afa7dc3fd..d55c727d2 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -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;
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32_exti.h b/nuttx/arch/arm/src/stm32/chip/stm32_exti.h
index d295b6cb8..31b50136d 100644
--- a/nuttx/arch/arm/src/stm32/chip/stm32_exti.h
+++ b/nuttx/arch/arm/src/stm32/chip/stm32_exti.h
@@ -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 */
diff --git a/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rtc.h b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rtc.h
index eea94b92f..c12698f7f 100644
--- a/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rtc.h
+++ b/nuttx/arch/arm/src/stm32/chip/stm32f40xxx_rtc.h
@@ -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 */
diff --git a/nuttx/arch/arm/src/stm32/stm32_lse.c b/nuttx/arch/arm/src/stm32/stm32_lse.c
index bf9d6d6f2..931199efd 100644
--- a/nuttx/arch/arm/src/stm32/stm32_lse.c
+++ b/nuttx/arch/arm/src/stm32/stm32_lse.c
@@ -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
}
diff --git a/nuttx/arch/arm/src/stm32/stm32_pwr.c b/nuttx/arch/arm/src/stm32/stm32_pwr.c
index 861d32b64..6a4e62d66 100644
--- a/nuttx/arch/arm/src/stm32/stm32_pwr.c
+++ b/nuttx/arch/arm/src/stm32/stm32_pwr.c
@@ -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)
-/** \} */
diff --git a/nuttx/arch/arm/src/stm32/stm32_pwr.h b/nuttx/arch/arm/src/stm32/stm32_pwr.h
index 638d23640..56aee49b6 100644
--- a/nuttx/arch/arm/src/stm32/stm32_pwr.h
+++ b/nuttx/arch/arm/src/stm32/stm32_pwr.h
@@ -63,15 +63,27 @@ extern "C" {
* Public Functions
************************************************************************************/
-/** Disables Write Protection to the Backup Area
- **/
-EXTERN void stm32_pwr_enablebkp(void);
+/************************************************************************************
+ * 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 */
diff --git a/nuttx/arch/arm/src/stm32/stm32_rcc.h b/nuttx/arch/arm/src/stm32/stm32_rcc.h
index b4a1500b7..1e05f9ecb 100644
--- a/nuttx/arch/arm/src/stm32/stm32_rcc.h
+++ b/nuttx/arch/arm/src/stm32/stm32_rcc.h
@@ -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
diff --git a/nuttx/arch/arm/src/stm32/stm32f10xxx_rtc.c b/nuttx/arch/arm/src/stm32/stm32f10xxx_rtc.c
index 659039bf0..a0e616f04 100644
--- a/nuttx/arch/arm/src/stm32/stm32f10xxx_rtc.c
+++ b/nuttx/arch/arm/src/stm32/stm32f10xxx_rtc.c
@@ -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();
diff --git a/nuttx/arch/arm/src/stm32/stm32f40xxx_rcc.c b/nuttx/arch/arm/src/stm32/stm32f40xxx_rcc.c
index 91f362059..e06a84d65 100644
--- a/nuttx/arch/arm/src/stm32/stm32f40xxx_rcc.c
+++ b/nuttx/arch/arm/src/stm32/stm32f40xxx_rcc.c
@@ -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;
diff --git a/nuttx/arch/arm/src/stm32/stm32f40xxx_rtc.c b/nuttx/arch/arm/src/stm32/stm32f40xxx_rtc.c
index c9d23d471..e249dc27b 100644
--- a/nuttx/arch/arm/src/stm32/stm32f40xxx_rtc.c
+++ b/nuttx/arch/arm/src/stm32/stm32f40xxx_rtc.c
@@ -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: 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: stm32_rtc_interrupt
+ * 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;
+
+ /* 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();
- /* Configure RTC interrupt to catch alarm interrupts. */
+ /* 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
diff --git a/nuttx/include/debug.h b/nuttx/include/debug.h
index 24097fa57..5cfe1e601 100644
--- a/nuttx/include/debug.h
+++ b/nuttx/include/debug.h
@@ -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