Skip to content

Commit 5374625

Browse files
committed
Fixed some RTC alarm setup issues; tick interrupts now function as expected.
1 parent 04720ec commit 5374625

6 files changed

Lines changed: 83 additions & 96 deletions

File tree

ports/analog/boards/APARD/mpconfigboard.mk

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,26 @@
44
#
55
# SPDX-License-Identifier: MIT
66

7+
MCU_SERIES=max32
8+
MCU_VARIANT=max32690
9+
710
INTERNAL_FLASH_FILESYSTEM=1
811
# FLASH: 0x10000000 to 0x10300000 (ARM)
912
# SRAM: 0x20000000 to 0x20100000
1013

14+
#### USB CONFIGURATION
1115
# Use 0x0456 for Analog Devices, Inc.; 0B6A for Maxim
1216
USB_VID=0x0456
1317
# USB_VID=0x0B6A
1418
USB_PID=0x003C
1519
USB_MANUFACTURER="Analog Devices, Inc."
1620
USB_PRODUCT="MAX32690 APARD"
17-
# Num endpt pairs for a given device
1821
USB_NUM_ENDPOINT_PAIRS=12
1922
USB_HIGHSPEED=1
23+
###
24+
25+
# define UID len for memory safety (buffer gets passed as a raw ptr)
26+
COMMON_HAL_MCU_PROCESSOR_UID_LENGTH=30
2027

2128
# NOTE: Not implementing external flash for now
2229
# CFLAGS+=-DEXT_FLASH_MX25
23-
24-
# define 13 bytes UID for memory safety (buffer gets passed as a raw ptr)
25-
COMMON_HAL_MCU_PROCESSOR_UID_LENGTH=13
26-
27-
MCU_SERIES=max32
28-
MCU_VARIANT=max32690
29-
30-
CFLAGS += -DHAS_TRNG=1

ports/analog/max32_port.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
#include "gpio.h"
1414

15-
#ifdef MQAX32690
15+
#ifdef MAX32690
1616
#include "system_max32690.h"
1717
#include "max32690.h"
1818
#endif
@@ -33,7 +33,8 @@ extern uint32_t SystemCoreClock;
3333
#define TICKS_PER_SEC 1024
3434

3535
#ifdef MAX32690
36-
#define SUBSEC_PER_TICK 8 // 12-bit ssec register, ticks @ 4096 Hz
36+
// 12-bit ssec register, ticks @ 4096 Hz
37+
#define SUBSEC_PER_TICK 4
3738
#endif
3839

3940
#endif //MAX32_PORT_H

ports/analog/mpconfigport.mk

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ CHIP_FAMILY ?= max32
1010
LONGINT_IMPL ?= MPZ
1111
INTERNAL_LIBM ?= 1
1212

13+
# Req'd for OS; all max32 have TRNG
14+
CFLAGS += -DHAS_TRNG=1
15+
1316
INTERNAL_FLASH_FILESYSTEM = 1
1417
SPI_FLASH_FILESYSTEM = 0
1518
QSPI_FLASH_FILESYSTEM = 0
@@ -18,7 +21,6 @@ QSPI_FLASH_FILESYSTEM = 0
1821
DISABLE_FILESYSTEM = 0
1922

2023
# TODO: Test/Debug TinyUSB!
21-
# Builds clean; need to test
2224
CIRCUITPY_TINYUSB = 1
2325
CIRCUITPY_USB_DEVICE ?= 1
2426
CIRCUITPY_USB_CDC ?= 1

ports/analog/supervisor/port.c

Lines changed: 69 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@
4747
#include "mxc_delay.h"
4848
#include "rtc.h"
4949

50+
// msec to RTC subsec ticks (4 kHz)
51+
#define MSEC_TO_SS_ALARM(x) \
52+
(0 - ((x * 4096) / \
53+
1000)) /* Converts a time in milleseconds to the equivalent RSSA register value. */
54+
5055
// Externs defined by linker .ld file
5156
extern uint32_t _stack, _heap, _estack, _eheap;
5257
extern uint32_t _ebss;
@@ -60,8 +65,9 @@ extern const int num_leds;
6065
//todo: define an LED HAL
6166
// #include "peripherals/led.h"
6267

63-
// For caching rtc data for ticks
68+
// For saving rtc data for ticks
6469
static uint32_t subsec, sec = 0;
70+
static uint32_t tick_flag = 0;
6571

6672
// defined by cmsis core files
6773
extern void NVIC_SystemReset(void) NORETURN;
@@ -91,20 +97,43 @@ safe_mode_t port_init(void) {
9197
// Turn on one LED to indicate Sign of Life
9298
MXC_GPIO_OutSet(led_pin[2].port, led_pin[2].mask);
9399

100+
// Enable clock to RTC peripheral
101+
MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_ERTCO_EN;
102+
while(!(MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_ERTCO_RDY));
103+
104+
NVIC_EnableIRQ(RTC_IRQn);
105+
NVIC_EnableIRQ(USB_IRQn);
106+
94107
// Init RTC w/ 0sec, 0subsec
95108
// Driven by 32.768 kHz ERTCO, with ssec= 1/4096 s
96-
err = MXC_RTC_Init(0, 0);
97-
if (err) {
98-
return SAFE_MODE_SDK_FATAL_ERROR;
99-
}
100-
NVIC_EnableIRQ(RTC_IRQn);
109+
while( MXC_RTC_Init(0,0) != E_SUCCESS ) {};
101110

102-
// todo: init periph clocks / console here when ready
111+
// enable 1 sec RTC SSEC alarm
112+
MXC_RTC_DisableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE);
113+
MXC_RTC_SetSubsecondAlarm(MSEC_TO_SS_ALARM(1000));
114+
MXC_RTC_EnableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE);
115+
116+
// Enable RTC
117+
while ( MXC_RTC_Start() != E_SUCCESS ) {};
103118

104-
MXC_RTC_Start();
105119
return SAFE_MODE_NONE;
106120
}
107121

122+
void RTC_IRQHandler(void) {
123+
// Read flags to clear
124+
int flags = MXC_RTC_GetFlags();
125+
126+
if (flags & MXC_F_RTC_CTRL_SSEC_ALARM) {
127+
MXC_RTC_ClearFlags(MXC_F_RTC_CTRL_SSEC_ALARM);
128+
}
129+
130+
if (flags & MXC_F_RTC_CTRL_TOD_ALARM) {
131+
MXC_RTC_ClearFlags(MXC_F_RTC_CTRL_TOD_ALARM);
132+
}
133+
134+
tick_flag = 1;
135+
}
136+
108137
// Reset the MCU completely
109138
void reset_cpu(void) {
110139
// includes MCU reset request + awaits on memory bus
@@ -114,18 +143,15 @@ void reset_cpu(void) {
114143
// Reset MCU state
115144
void reset_port(void) {
116145
reset_all_pins();
117-
118-
// todo: may need rtc-related resets here later
119146
}
120147

121148
// Reset to the bootloader
122149
// note: not implemented since max32 requires external stim ignals to
123150
// activate bootloaders
124-
// todo: check if there's a method to jump to it
125151
void reset_to_bootloader(void) {
126152
NVIC_SystemReset();
127153
while (true) {
128-
asm ("nop;");
154+
__NOP();
129155
}
130156
}
131157

@@ -169,7 +195,14 @@ uint64_t port_get_raw_ticks(uint8_t *subticks) {
169195
// Ensure we can read from ssec register as soon as we can
170196
// MXC function does cross-tick / busy checking of RTC controller
171197
__disable_irq();
172-
MXC_RTC_GetTime(&sec, &subsec);
198+
if (MXC_RTC->ctrl & MXC_F_RTC_CTRL_EN) {
199+
// NOTE: RTC_GetTime always returns BUSY if RTC is not running
200+
while( (MXC_RTC_GetTime(&sec, &subsec)) != E_NO_ERROR );
201+
}
202+
else {
203+
sec = MXC_RTC->sec;
204+
subsec = MXC_RTC->ssec;
205+
}
173206
__enable_irq();
174207

175208
// Return ticks given total subseconds
@@ -197,71 +230,44 @@ void port_disable_tick(void) {
197230

198231
// Wake the CPU after a given # of ticks or sooner
199232
void port_interrupt_after_ticks(uint32_t ticks) {
233+
uint32_t ticks_msec = 0;
200234
// Stop RTC & store current time & ticks
201235
port_disable_tick();
202236
port_get_raw_ticks(NULL);
203237

204-
uint32_t target_sec = (ticks / TICKS_PER_SEC);
205-
uint32_t target_ssec = (ticks - (target_sec * TICKS_PER_SEC)) * SUBSEC_PER_TICK;
206-
207-
// Set up alarm configuration
208-
// if alarm is greater than 1 s,
209-
// use the ToD alarm --> resol. to closest second
210-
// else
211-
// use Ssec alarm --> resn. to 1/1024 s. (down to a full tick)
212-
if (target_sec > 0) {
213-
if (MXC_RTC_DisableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE |
214-
MXC_F_RTC_CTRL_TOD_ALARM_IE) == E_BUSY) {
215-
// todo: signal some RTC error!
216-
}
238+
ticks_msec = 1000 * ticks / TICKS_PER_SEC;
217239

218-
if (MXC_RTC_SetTimeofdayAlarm(target_sec) != E_NO_ERROR) {
219-
// todo: signal some RTC error!
220-
}
221-
if (MXC_RTC_EnableInt(MXC_F_RTC_CTRL_TOD_ALARM_IE) == E_BUSY) {
222-
// todo: signal some RTC error!
223-
}
224-
}
225-
else {
226-
if (MXC_RTC_DisableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE |
227-
MXC_F_RTC_CTRL_TOD_ALARM_IE) == E_BUSY) {
228-
// todo: signal some RTC error!
229-
}
240+
while (MXC_RTC_DisableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE |
241+
MXC_F_RTC_CTRL_TOD_ALARM_IE) == E_BUSY) {};
230242

231-
if (MXC_RTC_SetSubsecondAlarm(target_ssec) != E_NO_ERROR) {
232-
// todo: signal some RTC error!
233-
}
234-
235-
if (MXC_RTC_EnableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE) == E_BUSY) {
236-
// todo: signal some RTC error!
237-
}
238-
}
239-
port_enable_tick();
240-
}
243+
// Clear the flag to be set by the RTC Handler
244+
tick_flag = 0;
241245

242-
void RTC_IRQHandler(void) {
243-
// Read flags to clear
244-
int flags = MXC_RTC_GetFlags();
246+
// Subsec alarm is the starting/reload value of the SSEC counter.
247+
// ISR triggered when SSEC rolls over from 0xFFFF_FFFF to 0x0
248+
while ( MXC_RTC_SetSubsecondAlarm(MSEC_TO_SS_ALARM(ticks_msec) ) == E_BUSY) {}
249+
while (MXC_RTC_EnableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE) == E_BUSY) {}
245250

246-
if (flags & MXC_F_RTC_CTRL_TOD_ALARM) {
247-
MXC_RTC_ClearFlags(MXC_F_RTC_CTRL_TOD_ALARM);
248-
while (MXC_RTC_DisableInt(MXC_F_RTC_CTRL_TOD_ALARM_IE) == E_BUSY) {}
249-
}
251+
NVIC_EnableIRQ(RTC_IRQn);
250252

251-
if (flags & MXC_F_RTC_CTRL_SSEC_ALARM) {
252-
MXC_RTC_ClearFlags(MXC_F_RTC_CTRL_SSEC_ALARM);
253-
while (MXC_RTC_DisableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE) == E_BUSY) {}
254-
}
253+
port_enable_tick();
255254
}
256255

257256
void port_idle_until_interrupt(void) {
258-
// Check if alarm triggers before we even got here
259-
if (MXC_RTC_GetFlags() == (MXC_F_RTC_CTRL_TOD_ALARM | MXC_F_RTC_CTRL_SSEC_ALARM)) {
260-
return;
261-
}
257+
#if CIRCUITPY_RTC
258+
// Check if alarm triggers before we even got here
259+
if (MXC_RTC_GetFlags() == (MXC_F_RTC_CTRL_TOD_ALARM | MXC_F_RTC_CTRL_SSEC_ALARM)) {
260+
return;
261+
}
262+
#endif
262263

264+
// Interrupts should be disabled to ensure the ISR queue is flushed
265+
// WFI still returns as long as the interrupt flag toggles;
266+
// only when we re-enable interrupts will the ISR function trigger
263267
common_hal_mcu_disable_interrupts();
264268
if (!background_callback_pending()) {
269+
__DSB();
270+
/** DEBUG: may comment out WFI for debugging port functions */
265271
__WFI();
266272
}
267273
common_hal_mcu_enable_interrupts();

ports/analog/tools/connect-gdb.txt

Lines changed: 0 additions & 16 deletions
This file was deleted.

ports/analog/tools/flash-halt-openocd.bat

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)