Skip to content

Commit d706916

Browse files
dgarskedanielinux
authored andcommitted
Fix sleep_us logic to use RTC. Resolves issue with different optimization levels breaking sleep. Also demonstrates synchronized boot and LED's matching from both cores.
1 parent f6c1283 commit d706916

2 files changed

Lines changed: 79 additions & 28 deletions

File tree

hal/nrf5340.c

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
* Any key size greater than 128 bits must be divided and distributed over multiple key slot instances.
3939
*/
4040

41+
#define USE_RTC 0 /* Use RTC0 for sleep */
42+
4143
/* Network updates can be signed with "--id 2" and placed into the normal update partition,
4244
* or they can be placed into the external flash at offset 0x100000 */
4345
/* Partition ID should be set HDR_IMG_TYPE_APP=2 */
@@ -321,28 +323,38 @@ void ext_flash_unlock(void)
321323

322324
static void clock_init(void)
323325
{
324-
#ifndef TARGET_nrf5340_net
326+
#ifdef TARGET_nrf5340_app
325327
CLOCK_HFCLKSRC = 1; /* use external high frequency clock */
326328
CLOCK_HFCLKSTART = 1;
327329
/* wait for high frequency clock startup */
328330
while (CLOCK_HFCLKSTARTED == 0);
329331
#endif
332+
/* Start low frequency clock - used by RTC */
333+
CLOCK_LFCLKSRC = 0; /* internal low power */
334+
CLOCK_LFCLKSTART = 1;
335+
/* wait for high frequency clock startup */
336+
while (CLOCK_LFCLKSTARTED == 0);
337+
338+
RTC_PRESCALER(USE_RTC) = 0; /* 32768 per second */
330339
}
331340

332-
void sleep_us(unsigned int us)
341+
void sleep_us(uint32_t usec)
333342
{
334-
/* Calculate ops per us (128MHz=128 instructions per 1us */
335-
unsigned long nop_us = (CPU_CLOCK / 1000000);
336-
nop_us *= us;
337-
/* instruction for each iteration */
338-
#ifdef DEBUG
339-
nop_us /= 30;
340-
#else
341-
nop_us /= 5;
342-
#endif
343-
while (nop_us-- > 0) {
344-
NOP();
345-
}
343+
/* Calculate number ticks to wait */
344+
uint32_t comp = ((usec * 32768UL) / 1000000);
345+
if (comp == 0)
346+
comp = 1; /* wait at least 1 tick */
347+
if (comp > RTC_OVERFLOW)
348+
comp = RTC_OVERFLOW; /* max wait (512 seconds with prescaler=0) */
349+
350+
RTC_CLEAR(USE_RTC) = 1;
351+
RTC_EVTENSET(USE_RTC) = RTC_EVTENSET_CC0;
352+
RTC_EVENT_CC(USE_RTC, 0) = 0; /* clear compare event */
353+
RTC_CC(USE_RTC, 0) = comp;
354+
RTC_START(USE_RTC) = 1;
355+
/* wait for compare event */
356+
while (RTC_EVENT_CC(USE_RTC, 0) == 0);
357+
RTC_STOP(USE_RTC) = 1;
346358
}
347359

348360
#ifdef TARGET_nrf5340_app
@@ -427,15 +439,14 @@ static void hal_shm_status_set(ShmInfo_t* info, uint32_t status)
427439
}
428440

429441
static int hal_shm_status_wait(ShmInfo_t* info, uint32_t status,
430-
uint32_t timeout_us)
442+
uint32_t timeout_ms)
431443
{
432444
int ret = 0;
433-
uint32_t timeout = timeout_us;
434445
while ((info->magic != SHAREM_MEM_MAGIC || (info->status & status) == 0)
435-
&& --timeout > 0) {
436-
sleep_us(1);
446+
&& --timeout_ms > 0) {
447+
sleep_us(1000);
437448
};
438-
if (timeout == 0) {
449+
if (timeout_ms == 0) {
439450
wolfBoot_printf("Timeout: status 0x%x\n", status);
440451
ret = -1; /* timeout */
441452
}
@@ -474,8 +485,8 @@ static void hal_net_check_version(void)
474485
/* release network core - issue boot command */
475486
hal_net_core(0);
476487

477-
/* wait for ready status from network core */
478-
ret = hal_shm_status_wait(&shm->net, SHARED_STATUS_READY, 1000000);
488+
/* wait for ready status from network core - 2 seconds */
489+
ret = hal_shm_status_wait(&shm->net, SHARED_STATUS_READY, 2*1000);
479490

480491
/* check if network core can continue booting or needs to wait for update */
481492
if (ret != 0 || shm->app.version <= shm->net.version) {
@@ -505,9 +516,9 @@ static void hal_net_check_version(void)
505516

506517
wolfBoot_printf("Waiting for net core update to finish...\n");
507518

508-
/* wait for update_done - note longer wait */
519+
/* wait for update_done - note longer wait - 10 seconds */
509520
ret = hal_shm_status_wait(&shm->net,
510-
SHARED_STATUS_UPDATE_DONE, 5000000);
521+
SHARED_STATUS_UPDATE_DONE, 10*1000);
511522
if (ret == 0) {
512523
wolfBoot_printf("Network core firmware update done\n");
513524
}
@@ -524,10 +535,10 @@ static void hal_net_check_version(void)
524535
hal_net_get_image(&img, &shm->net);
525536
hal_shm_status_set(&shm->net, SHARED_STATUS_READY);
526537

527-
/* wait for do_boot or update from app core */
538+
/* wait for do_boot or update from app core - 2 seconds */
528539
wolfBoot_printf("Waiting for status from app core...\n");
529540
ret = hal_shm_status_wait(&shm->app,
530-
(SHARED_STATUS_UPDATE_START | SHARED_STATUS_DO_BOOT), 1000000);
541+
(SHARED_STATUS_UPDATE_START | SHARED_STATUS_DO_BOOT), 2*1000);
531542

532543
/* are we updating? */
533544
if (ret == 0 && shm->app.status == SHARED_STATUS_UPDATE_START) {
@@ -601,10 +612,11 @@ void hal_prepare_boot(void)
601612

602613
#ifdef TARGET_nrf5340_app
603614
#ifdef NRF_SYNC_CORES
604-
/* if core synchronization enabled, then wait for update_done or do_boot */
615+
/* if core synchronization enabled,
616+
* then wait for update_done or do_boot (5 seconds) */
605617
wolfBoot_printf("Waiting for network core...\n");
606618
(void)hal_shm_status_wait(&shm->net,
607-
(SHARED_STATUS_UPDATE_DONE | SHARED_STATUS_DO_BOOT), 2000000);
619+
(SHARED_STATUS_UPDATE_DONE | SHARED_STATUS_DO_BOOT), 5*1000);
608620
#endif /* NRF_SYNC_CORES */
609621
#endif /* TARGET_nrf5340_app */
610622
#endif /* !DISABLE_SHARED_MEM */

hal/nrf5340.h

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
#define ISB() __asm__ volatile ("isb")
7171
#define NOP() __asm__ volatile ("nop")
7272

73-
void sleep_us(unsigned int us);
73+
void sleep_us(uint32_t usec);
7474

7575
/* PSEL Port (bit 5) - Used for various PSEL (UART,SPI,QSPI,I2C,NFC) */
7676
#define PSEL_PORT(n) (((n) & 0x1) << 5)
@@ -194,6 +194,16 @@ void sleep_us(unsigned int us);
194194
#define CLOCK_HFCLK192MCTRL_DIV2 1
195195
#define CLOCK_HFCLK192MCTRL_DIV4 2
196196

197+
/* Low frequency: 32.768 kHz */
198+
#define CLOCK_LFCLKSTART *((volatile uint32_t *)(CLOCK_BASE + 0x008))
199+
#define CLOCK_LFCLKSTOP *((volatile uint32_t *)(CLOCK_BASE + 0x00C))
200+
#define CLOCK_LFCLKSTARTED *((volatile uint32_t *)(CLOCK_BASE + 0x104))
201+
#define CLOCK_LFCLKSRC *((volatile uint32_t *)(CLOCK_BASE + 0x518))
202+
#define CLOCK_LFCLKSRC_LFULP 0 /* ultra-low power RC oscillator */
203+
#define CLOCK_LFCLKSRC_LFRC 1 /* RC oscillator */
204+
#define CLOCK_LFCLKSRC_LFXO 2 /* crystal oscillator */
205+
#define CLOCK_LFCLKSRC_LFSYNT 3 /* synthesized from HFCLK */
206+
197207

198208
/* GPIO Port (0-1) */
199209
#ifdef TARGET_nrf5340_app
@@ -387,4 +397,33 @@ void uart_write_sz(const char* c, unsigned int sz);
387397
#define IPC_RECEIVE_CNF(n) *((volatile uint32_t *)(IPC_BASE + 0x590 + (((n) & 0xF) * 0x4)))
388398
#define IPC_GPMEM(n) *((volatile uint32_t *)(IPC_BASE + 0x610 + (((n) & 0x1) * 0x4)))
389399

400+
/* RTC - uses LFCLK - 24-bit counter/compare */
401+
#ifdef TARGET_nrf5340_app
402+
#ifdef TZEN
403+
#define RTC_BASE(n) ((0x50014000) + (((n) & 0x1) * 0x1000))
404+
#else
405+
#define RTC_BASE(n) ((0x40014000) + (((n) & 0x1) * 0x1000))
406+
#endif
407+
#else
408+
#define RTC_BASE(n) (0x41011000) /* network core */
409+
#endif
410+
#define RTC_START(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x000))
411+
#define RTC_STOP(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x004))
412+
#define RTC_CLEAR(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x008))
413+
#define RTC_EVENT_TICK(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x100))
414+
#define RTC_EVENT_OVRFLW(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x104))
415+
#define RTC_EVENT_CC(n,i) *((volatile uint32_t *)(RTC_BASE(n) + 0x140 + ((i) & 0x3) * 0x4))
416+
#define RTC_EVTENSET(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x344))
417+
#define RTC_EVTENSET_TICK (1 << 0)
418+
#define RTC_EVTENSET_OVRFLW (1 << 1)
419+
#define RTC_EVTENSET_CC0 (1 << 16)
420+
#define RTC_EVTENSET_CC1 (1 << 17)
421+
#define RTC_EVTENSET_CC2 (1 << 18)
422+
#define RTC_EVTENSET_CC3 (1 << 19)
423+
#define RTC_COUNTER(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x504))
424+
#define RTC_PRESCALER(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x508)) /* default=0 or 32768 per second (12-bit) up to 0xFFF */
425+
#define RTC_CC(n,i) *((volatile uint32_t *)(RTC_BASE(n) + 0x540 + ((i) & 0x3) * 0x4))
426+
#define RTC_OVERFLOW 0xFFFFFFUL
427+
428+
390429
#endif /* !_HAL_NRF5340_H_ */

0 commit comments

Comments
 (0)