Persistent storage for STM32 RTCV1 driver.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12438 110e8d01-0319-4d1e-a829-52ad28d1bb01
This commit is contained in:
parent
7a0857aa5d
commit
b8a4c26a9c
|
@ -118,6 +118,17 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
#define getBasePersistentStorage(ip) ((BasePersistentStorage *)&(ip)->vmt)
|
#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.
|
* @brief Read operation.
|
||||||
*
|
*
|
||||||
|
@ -140,7 +151,7 @@ typedef struct {
|
||||||
*
|
*
|
||||||
* @param[in] ip pointer to a @p BasePersistentStorage or derived class
|
* @param[in] ip pointer to a @p BasePersistentStorage or derived class
|
||||||
* @param[in] offset persistent storage offset
|
* @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
|
* @param[in] wp pointer to the data buffer
|
||||||
* @return An error code.
|
* @return An error code.
|
||||||
* @retval PS_NO_ERROR if there is no erase operation in progress.
|
* @retval PS_NO_ERROR if there is no erase operation in progress.
|
||||||
|
|
|
@ -200,33 +200,59 @@ static uint32_t rtc_encode_date(const RTCDateTime *timespec) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if RTC_HAS_STORAGE == TRUE
|
#if RTC_HAS_STORAGE == TRUE
|
||||||
/* TODO: Map on the backup SRAM on devices that have it.*/
|
static size_t _getsize(void *instance) {
|
||||||
static size_t _read(void *instance, ps_offset_t offset,
|
|
||||||
size_t n, uint8_t *rp) {
|
|
||||||
|
|
||||||
(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,
|
static ps_error_t _write(void *instance, ps_offset_t offset,
|
||||||
size_t n, const uint8_t *wp) {
|
size_t n, const uint8_t *wp) {
|
||||||
|
volatile uint32_t *bkpr = &((RTCDriver *)instance)->rtc->BKP0R;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
(void)instance;
|
chDbgCheck((instance != NULL) && (wp != NULL));
|
||||||
(void)offset;
|
chDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE));
|
||||||
(void)n;
|
chDbgCheck((offset < STM32_RTC_STORAGE_SIZE) &&
|
||||||
(void)wp;
|
(offset + n <= STM32_RTC_STORAGE_SIZE));
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PS_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief VMT for the RTC storage file interface.
|
* @brief VMT for the RTC storage file interface.
|
||||||
*/
|
*/
|
||||||
struct RTCDriverVMT _rtc_lld_vmt = {
|
struct RTCDriverVMT _rtc_lld_vmt = {
|
||||||
|
(size_t)0,
|
||||||
_getsize, _read, _write
|
_getsize, _read, _write
|
||||||
};
|
};
|
||||||
#endif /* RTC_HAS_STORAGE == TRUE */
|
#endif /* RTC_HAS_STORAGE == TRUE */
|
||||||
|
@ -494,6 +520,7 @@ void rtc_lld_init(void) {
|
||||||
rtc_enter_init();
|
rtc_enter_init();
|
||||||
|
|
||||||
RTCD1.rtc->CR = STM32_RTC_CR_INIT;
|
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->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->PRER = STM32_RTC_PRER_BITS;
|
RTCD1.rtc->PRER = STM32_RTC_PRER_BITS;
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
/**
|
/**
|
||||||
* @brief Presence of a local persistent storage.
|
* @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__)
|
#if !defined(STM32_RTC_CR_INIT) || defined(__DOXYGEN__)
|
||||||
#define STM32_RTC_CR_INIT 0
|
#define STM32_RTC_CR_INIT 0
|
||||||
#endif
|
#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
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#define STM32_RTC_HAS_SUBSECONDS TRUE
|
#define STM32_RTC_HAS_SUBSECONDS TRUE
|
||||||
#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
|
#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
|
||||||
#define STM32_RTC_NUM_ALARMS 2
|
#define STM32_RTC_NUM_ALARMS 2
|
||||||
|
#define STM32_RTC_STORAGE_SIZE 128
|
||||||
#define STM32_RTC_TAMP_STAMP_HANDLER Vector48
|
#define STM32_RTC_TAMP_STAMP_HANDLER Vector48
|
||||||
#define STM32_RTC_WKUP_HANDLER Vector49
|
#define STM32_RTC_WKUP_HANDLER Vector49
|
||||||
#define STM32_RTC_ALARM_HANDLER VectorE4
|
#define STM32_RTC_ALARM_HANDLER VectorE4
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#define STM32_RTC_HAS_SUBSECONDS TRUE
|
#define STM32_RTC_HAS_SUBSECONDS TRUE
|
||||||
#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
|
#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
|
||||||
#define STM32_RTC_NUM_ALARMS 2
|
#define STM32_RTC_NUM_ALARMS 2
|
||||||
|
#define STM32_RTC_STORAGE_SIZE 128
|
||||||
#define STM32_RTC_TAMP_STAMP_HANDLER Vector48
|
#define STM32_RTC_TAMP_STAMP_HANDLER Vector48
|
||||||
#define STM32_RTC_WKUP_HANDLER Vector49
|
#define STM32_RTC_WKUP_HANDLER Vector49
|
||||||
#define STM32_RTC_ALARM_HANDLER VectorE4
|
#define STM32_RTC_ALARM_HANDLER VectorE4
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
||||||
*** Next ***
|
*** Next ***
|
||||||
|
- NEW: Added persistent storage interface to the STM32 RTCv2 driver.
|
||||||
- NEW: STM32 RTCv2 driver now supports callbacks on events.
|
- NEW: STM32 RTCv2 driver now supports callbacks on events.
|
||||||
- NEW: Added an EXTI helper driver for STM32.
|
- NEW: Added an EXTI helper driver for STM32.
|
||||||
- NEW: Added demo for STM32L4R9I-Discovery board.
|
- NEW: Added demo for STM32L4R9I-Discovery board.
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
|
<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.COREFILE_PATH" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" 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.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.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}"/>
|
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="${selected_resource_loc}"/>
|
||||||
|
|
|
@ -39,7 +39,7 @@ static void cmd_date(BaseSequentialStream *chp, int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
rtcGetTime(&RTCD1, ×pec);
|
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,
|
||||||
(timespec.millisecond % 3600000U) / 60000U,
|
(timespec.millisecond % 3600000U) / 60000U,
|
||||||
(timespec.millisecond % 60000U) / 1000U,
|
(timespec.millisecond % 60000U) / 1000U,
|
||||||
|
@ -49,8 +49,30 @@ static void cmd_date(BaseSequentialStream *chp, int argc, char *argv[]) {
|
||||||
timespec.year + 1980U);
|
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[] = {
|
static const ShellCommand commands[] = {
|
||||||
{"date", cmd_date},
|
{"date", cmd_date},
|
||||||
|
{"storage", cmd_storage},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -140,6 +162,7 @@ int main(void) {
|
||||||
rtcSetAlarm(&RTCD1, 0, &alarm1);
|
rtcSetAlarm(&RTCD1, 0, &alarm1);
|
||||||
rtcSetAlarm(&RTCD1, 1, &alarm2);
|
rtcSetAlarm(&RTCD1, 1, &alarm2);
|
||||||
rtcSetCallback(&RTCD1, alarmcb);
|
rtcSetCallback(&RTCD1, alarmcb);
|
||||||
|
psWrite(&RTCD1, 0U, 12U, (const uint8_t *)"Hello World!");
|
||||||
|
|
||||||
/* Normal main() thread activity, spawning shells.*/
|
/* Normal main() thread activity, spawning shells.*/
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
Loading…
Reference in New Issue