Skip to content

Commit

Permalink
Fix sleep_us logic to use RTC. Resolves issue with different optimi…
Browse files Browse the repository at this point in the history
…zation levels breaking sleep. Also demonstrates synchronized boot and LED's matching from both cores.
  • Loading branch information
dgarske committed Oct 4, 2024
1 parent f04d36f commit 0319028
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 28 deletions.
66 changes: 39 additions & 27 deletions hal/nrf5340.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
* Any key size greater than 128 bits must be divided and distributed over multiple key slot instances.
*/

#define USE_RTC 0 /* Use RTC0 for sleep */

/* Network updates can be signed with "--id 2" and placed into the normal update partition,
* or they can be placed into the external flash at offset 0x100000 */
/* Partition ID should be set HDR_IMG_TYPE_APP=2 */
Expand Down Expand Up @@ -321,28 +323,38 @@ void ext_flash_unlock(void)

static void clock_init(void)
{
#ifndef TARGET_nrf5340_net
#ifdef TARGET_nrf5340_app
CLOCK_HFCLKSRC = 1; /* use external high frequency clock */
CLOCK_HFCLKSTART = 1;
/* wait for high frequency clock startup */
while (CLOCK_HFCLKSTARTED == 0);
#endif
/* Start low frequency clock - used by RTC */
CLOCK_LFCLKSRC = 0; /* internal low power */
CLOCK_LFCLKSTART = 1;
/* wait for high frequency clock startup */
while (CLOCK_LFCLKSTARTED == 0);

RTC_PRESCALER(USE_RTC) = 0; /* 32768 per second */
}

void sleep_us(unsigned int us)
void sleep_us(uint32_t usec)
{
/* Calculate ops per us (128MHz=128 instructions per 1us */
unsigned long nop_us = (CPU_CLOCK / 1000000);
nop_us *= us;
/* instruction for each iteration */
#ifdef DEBUG
nop_us /= 30;
#else
nop_us /= 5;
#endif
while (nop_us-- > 0) {
NOP();
}
/* Calculate number ticks to wait */
uint32_t comp = ((usec * 32768UL) / 1000000);
if (comp == 0)
comp = 1; /* wait at least 1 tick */
if (comp > RTC_OVERFLOW)
comp = RTC_OVERFLOW; /* max wait (512 seconds with prescaler=0) */

RTC_CLEAR(USE_RTC) = 1;
RTC_EVTENSET(USE_RTC) = RTC_EVTENSET_CC0;
RTC_EVENT_CC(USE_RTC, 0) = 0; /* clear compare event */
RTC_CC(USE_RTC, 0) = comp;
RTC_START(USE_RTC) = 1;
/* wait for compare event */
while (RTC_EVENT_CC(USE_RTC, 0) == 0);
RTC_STOP(USE_RTC) = 1;
}

#ifdef TARGET_nrf5340_app
Expand Down Expand Up @@ -427,15 +439,14 @@ static void hal_shm_status_set(ShmInfo_t* info, uint32_t status)
}

static int hal_shm_status_wait(ShmInfo_t* info, uint32_t status,
uint32_t timeout_us)
uint32_t timeout_ms)
{
int ret = 0;
uint32_t timeout = timeout_us;
while ((info->magic != SHAREM_MEM_MAGIC || (info->status & status) == 0)
&& --timeout > 0) {
sleep_us(1);
&& --timeout_ms > 0) {
sleep_us(1000);
};
if (timeout == 0) {
if (timeout_ms == 0) {
wolfBoot_printf("Timeout: status 0x%x\n", status);
ret = -1; /* timeout */
}
Expand Down Expand Up @@ -474,8 +485,8 @@ static void hal_net_check_version(void)
/* release network core - issue boot command */
hal_net_core(0);

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

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

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

/* wait for update_done - note longer wait */
/* wait for update_done - note longer wait - 10 seconds */
ret = hal_shm_status_wait(&shm->net,
SHARED_STATUS_UPDATE_DONE, 5000000);
SHARED_STATUS_UPDATE_DONE, 10*1000);
if (ret == 0) {
wolfBoot_printf("Network core firmware update done\n");
}
Expand All @@ -524,10 +535,10 @@ static void hal_net_check_version(void)
hal_net_get_image(&img, &shm->net);
hal_shm_status_set(&shm->net, SHARED_STATUS_READY);

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

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

#ifdef TARGET_nrf5340_app
#ifdef NRF_SYNC_CORES
/* if core synchronization enabled, then wait for update_done or do_boot */
/* if core synchronization enabled,
* then wait for update_done or do_boot (5 seconds) */
wolfBoot_printf("Waiting for network core...\n");
(void)hal_shm_status_wait(&shm->net,
(SHARED_STATUS_UPDATE_DONE | SHARED_STATUS_DO_BOOT), 2000000);
(SHARED_STATUS_UPDATE_DONE | SHARED_STATUS_DO_BOOT), 5*1000);
#endif /* NRF_SYNC_CORES */
#endif /* TARGET_nrf5340_app */
#endif /* !DISABLE_SHARED_MEM */
Expand Down
41 changes: 40 additions & 1 deletion hal/nrf5340.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
#define ISB() __asm__ volatile ("isb")
#define NOP() __asm__ volatile ("nop")

void sleep_us(unsigned int us);
void sleep_us(uint32_t usec);

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

/* Low frequency: 32.768 kHz */
#define CLOCK_LFCLKSTART *((volatile uint32_t *)(CLOCK_BASE + 0x008))
#define CLOCK_LFCLKSTOP *((volatile uint32_t *)(CLOCK_BASE + 0x00C))
#define CLOCK_LFCLKSTARTED *((volatile uint32_t *)(CLOCK_BASE + 0x104))
#define CLOCK_LFCLKSRC *((volatile uint32_t *)(CLOCK_BASE + 0x518))
#define CLOCK_LFCLKSRC_LFULP 0 /* ultra-low power RC oscillator */
#define CLOCK_LFCLKSRC_LFRC 1 /* RC oscillator */
#define CLOCK_LFCLKSRC_LFXO 2 /* crystal oscillator */
#define CLOCK_LFCLKSRC_LFSYNT 3 /* synthesized from HFCLK */


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

/* RTC - uses LFCLK - 24-bit counter/compare */
#ifdef TARGET_nrf5340_app
#ifdef TZEN
#define RTC_BASE(n) ((0x50014000) + (((n) & 0x1) * 0x1000))
#else
#define RTC_BASE(n) ((0x40014000) + (((n) & 0x1) * 0x1000))
#endif
#else
#define RTC_BASE(n) (0x41011000) /* network core */
#endif
#define RTC_START(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x000))
#define RTC_STOP(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x004))
#define RTC_CLEAR(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x008))
#define RTC_EVENT_TICK(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x100))
#define RTC_EVENT_OVRFLW(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x104))
#define RTC_EVENT_CC(n,i) *((volatile uint32_t *)(RTC_BASE(n) + 0x140 + ((i) & 0x3) * 0x4))
#define RTC_EVTENSET(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x344))
#define RTC_EVTENSET_TICK (1 << 0)
#define RTC_EVTENSET_OVRFLW (1 << 1)
#define RTC_EVTENSET_CC0 (1 << 16)
#define RTC_EVTENSET_CC1 (1 << 17)
#define RTC_EVTENSET_CC2 (1 << 18)
#define RTC_EVTENSET_CC3 (1 << 19)
#define RTC_COUNTER(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x504))
#define RTC_PRESCALER(n) *((volatile uint32_t *)(RTC_BASE(n) + 0x508)) /* default=0 or 32768 per second (12-bit) up to 0xFFF */
#define RTC_CC(n,i) *((volatile uint32_t *)(RTC_BASE(n) + 0x540 + ((i) & 0x3) * 0x4))
#define RTC_OVERFLOW 0xFFFFFFUL


#endif /* !_HAL_NRF5340_H_ */

0 comments on commit 0319028

Please sign in to comment.