diff options
-rw-r--r-- | os/hal/include/hal_persistent.h | 13 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c | 61 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h | 11 | ||||
-rw-r--r-- | os/hal/ports/STM32/STM32L4xx+/stm32_registry.h | 1 | ||||
-rw-r--r-- | os/hal/ports/STM32/STM32L4xx/stm32_registry.h | 1 | ||||
-rw-r--r-- | readme.txt | 1 | ||||
-rw-r--r-- | testhal/STM32/multi/RTC/debug/STM32-RTC (Select ELF file)(OpenOCD, Just Run).launch | 2 | ||||
-rw-r--r-- | testhal/STM32/multi/RTC/main.c | 25 |
8 files changed, 94 insertions, 21 deletions
diff --git a/os/hal/include/hal_persistent.h b/os/hal/include/hal_persistent.h index f0aed89b9..f6ba14e82 100644 --- a/os/hal/include/hal_persistent.h +++ b/os/hal/include/hal_persistent.h @@ -119,6 +119,17 @@ typedef struct { #define getBasePersistentStorage(ip) ((BasePersistentStorage *)&(ip)->vmt)
/**
+ * @brief Get storage size.
+ *
+ * @param[in] ip pointer to a @p BasePersistentStorage or derived class
+ * @return The storage size in bytes.
+ *
+ * @api
+ */
+#define psGetStorageSize(ip) \
+ (ip)->vmt->getsize(ip)
+
+/**
* @brief Read operation.
*
* @param[in] ip pointer to a @p BasePersistentStorage or derived class
@@ -140,7 +151,7 @@ typedef struct { *
* @param[in] ip pointer to a @p BasePersistentStorage or derived class
* @param[in] offset persistent storage offset
- * @param[in] n number of bytes to be programmed
+ * @param[in] n number of bytes to be written
* @param[in] wp pointer to the data buffer
* @return An error code.
* @retval PS_NO_ERROR if there is no erase operation in progress.
diff --git a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c index a7c212b00..763ebf851 100644 --- a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c +++ b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c @@ -200,33 +200,59 @@ static uint32_t rtc_encode_date(const RTCDateTime *timespec) { }
#if RTC_HAS_STORAGE == TRUE
-/* TODO: Map on the backup SRAM on devices that have it.*/
-static size_t _read(void *instance, ps_offset_t offset,
- size_t n, uint8_t *rp) {
+static size_t _getsize(void *instance) {
(void)instance;
- (void)offset;
- (void)n;
- (void)rp;
- return 0;
+ return (size_t)STM32_RTC_STORAGE_SIZE;
+}
+
+static ps_error_t _read(void *instance, ps_offset_t offset,
+ size_t n, uint8_t *rp) {
+ volatile uint32_t *bkpr = &((RTCDriver *)instance)->rtc->BKP0R;
+ unsigned i;
+
+ chDbgCheck((instance != NULL) && (rp != NULL));
+ chDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE));
+ chDbgCheck((offset < STM32_RTC_STORAGE_SIZE) &&
+ (offset + n <= STM32_RTC_STORAGE_SIZE));
+
+ for (i = 0; i < (unsigned)n; i++) {
+ unsigned index = ((unsigned)offset + i) / sizeof (uint32_t);
+ unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t);
+ *rp++ = (uint8_t)(bkpr[index] >> (shift * 8U));
+ }
+
+ return PS_NO_ERROR;
}
static ps_error_t _write(void *instance, ps_offset_t offset,
size_t n, const uint8_t *wp) {
+ volatile uint32_t *bkpr = &((RTCDriver *)instance)->rtc->BKP0R;
+ unsigned i;
+
+ chDbgCheck((instance != NULL) && (wp != NULL));
+ chDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE));
+ chDbgCheck((offset < STM32_RTC_STORAGE_SIZE) &&
+ (offset + n <= STM32_RTC_STORAGE_SIZE));
+
+ for (i = 0; i < (unsigned)n; i++) {
+ unsigned index = ((unsigned)offset + i) / sizeof (uint32_t);
+ unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t);
+ uint32_t regval = bkpr[index];
+ regval &= ~(0xFFU << (shift * 8U));
+ regval |= (uint32_t)*wp++ << (shift * 8U);
+ bkpr[index] = regval;
+ }
- (void)instance;
- (void)offset;
- (void)n;
- (void)wp;
-
- return 0;
+ return PS_NO_ERROR;
}
/**
* @brief VMT for the RTC storage file interface.
*/
struct RTCDriverVMT _rtc_lld_vmt = {
+ (size_t)0,
_getsize, _read, _write
};
#endif /* RTC_HAS_STORAGE == TRUE */
@@ -493,10 +519,11 @@ void rtc_lld_init(void) { rtc_enter_init();
- RTCD1.rtc->CR = STM32_RTC_CR_INIT;
- RTCD1.rtc->ISR = RTC_ISR_INIT; /* Clearing all but RTC_ISR_INIT. */
- RTCD1.rtc->PRER = STM32_RTC_PRER_BITS;
- RTCD1.rtc->PRER = STM32_RTC_PRER_BITS;
+ RTCD1.rtc->CR = STM32_RTC_CR_INIT;
+ RTCD1.rtc->TAMPCR = STM32_RTC_TAMPCR_INIT;
+ RTCD1.rtc->ISR = RTC_ISR_INIT; /* Clearing all but RTC_ISR_INIT. */
+ RTCD1.rtc->PRER = STM32_RTC_PRER_BITS;
+ RTCD1.rtc->PRER = STM32_RTC_PRER_BITS;
rtc_exit_init();
}
diff --git a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h index 5aae1ab99..3badc3d1d 100644 --- a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h +++ b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h @@ -51,7 +51,7 @@ /**
* @brief Presence of a local persistent storage.
*/
-#define RTC_HAS_STORAGE FALSE
+#define RTC_HAS_STORAGE TRUE
/** @} */
/**
@@ -115,6 +115,15 @@ #if !defined(STM32_RTC_CR_INIT) || defined(__DOXYGEN__)
#define STM32_RTC_CR_INIT 0
#endif
+
+/**
+ * @brief RTC TAMPCR register initialization value.
+ * @note Use this value to initialize features not directly handled by
+ * the RTC driver.
+ */
+#if !defined(STM32_RTC_TAMPCR_INIT) || defined(__DOXYGEN__)
+#define STM32_RTC_TAMPCR_INIT 0
+#endif
/** @} */
/*===========================================================================*/
diff --git a/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h b/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h index 590db30f0..735af3781 100644 --- a/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h +++ b/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h @@ -46,6 +46,7 @@ #define STM32_RTC_HAS_SUBSECONDS TRUE
#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 128
#define STM32_RTC_TAMP_STAMP_HANDLER Vector48
#define STM32_RTC_WKUP_HANDLER Vector49
#define STM32_RTC_ALARM_HANDLER VectorE4
diff --git a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h index a6c8ac5c8..9c22b96f2 100644 --- a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h +++ b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h @@ -46,6 +46,7 @@ #define STM32_RTC_HAS_SUBSECONDS TRUE
#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 128
#define STM32_RTC_TAMP_STAMP_HANDLER Vector48
#define STM32_RTC_WKUP_HANDLER Vector49
#define STM32_RTC_ALARM_HANDLER VectorE4
diff --git a/readme.txt b/readme.txt index 5180ee598..6ee109cd1 100644 --- a/readme.txt +++ b/readme.txt @@ -75,6 +75,7 @@ *****************************************************************************
*** Next ***
+- NEW: Added persistent storage interface to the STM32 RTCv2 driver.
- NEW: STM32 RTCv2 driver now supports callbacks on events.
- NEW: Added an EXTI helper driver for STM32.
- NEW: Added demo for STM32L4R9I-Discovery board.
diff --git a/testhal/STM32/multi/RTC/debug/STM32-RTC (Select ELF file)(OpenOCD, Just Run).launch b/testhal/STM32/multi/RTC/debug/STM32-RTC (Select ELF file)(OpenOCD, Just Run).launch index 835e7d705..3bd927aff 100644 --- a/testhal/STM32/multi/RTC/debug/STM32-RTC (Select ELF file)(OpenOCD, Just Run).launch +++ b/testhal/STM32/multi/RTC/debug/STM32-RTC (Select ELF file)(OpenOCD, Just Run).launch @@ -33,7 +33,7 @@ <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/> <stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/> <stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/> -<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="xPSR-(format)" val="4"/><content id="ISR-rtc-rtcp-rtc_lld_get_time-(format)" val="4"/></contentList>"/> +<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="xPSR-(format)" val="4"/><content id="ISR-rtc-rtcp-rtc_lld_get_time-(format)" val="4"/><content id="regval-_write-(format)" val="4"/><content id="*bkpr-bkpr-_read-(format)" val="4"/></contentList>"/> <stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/> <stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList> <memoryBlockExpressionItem> <expression text="0x40021004"/> </memoryBlockExpressionItem> </memoryBlockExpressionList> "/> <stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="${selected_resource_loc}"/> diff --git a/testhal/STM32/multi/RTC/main.c b/testhal/STM32/multi/RTC/main.c index 3c273c238..f4dfb5334 100644 --- a/testhal/STM32/multi/RTC/main.c +++ b/testhal/STM32/multi/RTC/main.c @@ -39,7 +39,7 @@ static void cmd_date(BaseSequentialStream *chp, int argc, char *argv[]) { }
rtcGetTime(&RTCD1, ×pec);
- chprintf(chp, "%02d:%02d:%02d (%02d) - %02d-%02d-%04d\r\n",
+ chprintf(chp, "%02d:%02d:%02d:%03d - %02d-%02d-%04d\r\n",
timespec.millisecond / 3600000U,
(timespec.millisecond % 3600000U) / 60000U,
(timespec.millisecond % 60000U) / 1000U,
@@ -49,8 +49,30 @@ static void cmd_date(BaseSequentialStream *chp, int argc, char *argv[]) { timespec.year + 1980U);
}
+static void cmd_storage(BaseSequentialStream *chp, int argc, char *argv[]) {
+ size_t storage_size = psGetStorageSize(&RTCD1);
+ ps_offset_t i;
+
+ (void)argv;
+
+ if (argc > 0) {
+ chprintf(chp, "Usage: storage\r\n");
+ return;
+ }
+
+ for (i = 0U; i < (ps_offset_t)storage_size; i++) {
+ uint8_t val;
+ psRead(&RTCD1, i, 1U, &val);
+ chprintf(chp, "%02x ", val);
+ if (((i + 1) & 15) == 0U) {
+ chprintf(chp, "\r\n");
+ }
+ }
+}
+
static const ShellCommand commands[] = {
{"date", cmd_date},
+ {"storage", cmd_storage},
{NULL, NULL}
};
@@ -140,6 +162,7 @@ int main(void) { rtcSetAlarm(&RTCD1, 0, &alarm1);
rtcSetAlarm(&RTCD1, 1, &alarm2);
rtcSetCallback(&RTCD1, alarmcb);
+ psWrite(&RTCD1, 0U, 12U, (const uint8_t *)"Hello World!");
/* Normal main() thread activity, spawning shells.*/
while (true) {
|