Skip to content

Commit 8608024

Browse files
committed
ports: analog: Improve supervisor portability
- *usb.c*: Place USB hardware clock / power into separate init_usb functions. - *internal_flash.c*: Move Flash and Instruction Cache Controller operations into different functions for different targets. - *port.c*: Create macros abstracting RTC alarms & enables for different register structures. Signed-off-by: Brandon-Hurst <brandon.hurst97@gmail.com>
1 parent 281b912 commit 8608024

3 files changed

Lines changed: 128 additions & 43 deletions

File tree

ports/analog/supervisor/internal_flash.c

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,25 +67,77 @@ static const flash_layout_t flash_layout[] = {
6767
};
6868
// must be able to hold a full page (for re-writing upon erase)
6969
static uint32_t page_buffer[FLASH_PAGE_SIZE / 4] = {0x0};
70+
71+
static void icc_flush(void) {
72+
// Flush all instruction cache
73+
// ME18 has bug where top-level sysctrl flush bit only works once.
74+
// Have to use low-level flush bits for each ICC instance.
75+
MXC_ICC_Flush(MXC_ICC0);
76+
}
77+
static void icc_enable(void) {
78+
MXC_ICC_Enable(MXC_ICC0);
79+
}
80+
static void icc_disable(void) {
81+
MXC_ICC_Disable(MXC_ICC0);
82+
}
83+
84+
static void flash_lock(void) {
85+
MXC_FLC0->ctrl |= MXC_S_FLC_REVA_CTRL_UNLOCK_LOCKED;
86+
MXC_FLC1->ctrl |= MXC_S_FLC_REVA_CTRL_UNLOCK_LOCKED;
87+
}
88+
7089
#elif defined(MAX32650)
7190
static const flash_layout_t flash_layout[] = {
7291
{ 0x10000000, FLASH_PAGE_SIZE, 192},
7392
};
7493
// must be able to hold a full page (for re-writing upon erase)
7594
static uint32_t page_buffer[FLASH_PAGE_SIZE / 4] = {0x0};
95+
96+
static void icc_flush(void) {
97+
// Flush all instruction cache
98+
MXC_ICC_Flush();
99+
}
100+
static void icc_enable(void) {
101+
MXC_ICC_Enable();
102+
}
103+
static void icc_disable(void) {
104+
MXC_ICC_Disable();
105+
}
106+
107+
static void flash_lock(void) {
108+
MXC_FLC->ctrl |= MXC_S_FLC_REVA_CTRL_UNLOCK_LOCKED;
109+
}
76110
#elif defined(MAX32665)
77-
// MAX32666 has two flash banks, but we do not actually need to
111+
// MAX32666 has two flash banks, but we do not actually need to
78112
// treat them separately
79113
static const flash_layout_t flash_layout[] = {
80114
{ 0x10000000, FLASH_PAGE_SIZE, 64},
81115
{ 0x10080000, FLASH_PAGE_SIZE, 64},
82116
};
83117
// must be able to hold a full page (for re-writing upon erase)
84118
static uint32_t page_buffer[FLASH_PAGE_SIZE / 4] = {0x0};
119+
120+
static void icc_flush(void) {
121+
// Flush all instruction cache
122+
MXC_ICC_Flush();
123+
}
124+
static void icc_enable(void) {
125+
MXC_ICC_Enable();
126+
}
127+
static void icc_disable(void) {
128+
MXC_ICC_Disable();
129+
}
130+
131+
static void flash_lock(void) {
132+
MXC_FLC0->cn |= MXC_S_FLC_REVA_CTRL_UNLOCK_LOCKED;
133+
MXC_FLC1->cn |= MXC_S_FLC_REVA_CTRL_UNLOCK_LOCKED;
134+
}
85135
#else
86136
#error "Invalid BOARD. Please set BOARD equal to any board under 'boards/'."
87137
#endif
88138

139+
140+
89141
static inline int32_t block2addr(uint32_t block) {
90142
if (block >= 0 && block < INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS) {
91143
return CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR + block * FILESYSTEM_BLOCK_SIZE;
@@ -110,9 +162,9 @@ int flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size) {
110162
flash_layout_t bank = flash_layout[i];
111163

112164
// Determine if the flash bank is a hit for this address
113-
if ((addr >= bank.base_addr) &&
165+
if ((addr >= bank.base_addr) &&
114166
(addr < bank.base_addr + bank.sector_size * bank.num_sectors)
115-
) {
167+
) {
116168
// Assign the sector index assuming uniform sector sizes
117169
sector_index = i * bank.num_sectors + ((addr - bank.base_addr) / bank.sector_size);
118170
*start_addr = flash_layout[0].base_addr + (sector_index * bank.sector_size);
@@ -137,12 +189,7 @@ uint32_t supervisor_flash_get_block_count(void) {
137189
}
138190

139191
void port_internal_flash_flush(void) {
140-
141-
// Flush all instruction cache
142-
// ME18 has bug where top-level sysctrl flush bit only works once.
143-
// Have to use low-level flush bits for each ICC instance.
144-
MXC_ICC_Flush(MXC_ICC0);
145-
MXC_ICC_Flush(MXC_ICC1);
192+
icc_flush();
146193

147194
// Clear the line fill buffer by reading 2 pages from flash
148195
volatile uint32_t *line_addr;
@@ -199,7 +246,7 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num,
199246
blocks_left = (page_size - (dest_addr - page_start)) / FILESYSTEM_BLOCK_SIZE;
200247
count = MIN(num_blocks, blocks_left);
201248

202-
MXC_ICC_Disable(MXC_ICC0);
249+
icc_disable();
203250

204251
// Buffer the page of flash to erase
205252
MXC_FLC_Read(page_start, page_buffer, page_size);
@@ -209,11 +256,7 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num,
209256
error = MXC_FLC_PageErase(dest_addr);
210257
);
211258
if (error != E_NO_ERROR) {
212-
// lock flash & reset
213-
MXC_FLC0->ctrl = (MXC_FLC0->ctrl & ~MXC_F_FLC_REVA_CTRL_UNLOCK) | MXC_S_FLC_REVA_CTRL_UNLOCK_LOCKED;
214-
#if defined(MAX32666)
215-
MXC_FLC1->ctrl = (MXC_FLC1->ctrl & ~MXC_F_FLC_REVA_CTRL_UNLOCK) | MXC_S_FLC_REVA_CTRL_UNLOCK_LOCKED;
216-
#endif
259+
flash_lock();
217260
reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL);
218261
}
219262

@@ -228,14 +271,11 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num,
228271
);
229272
if (error != E_NO_ERROR) {
230273
// lock flash & reset
231-
MXC_FLC0->ctrl = (MXC_FLC0->ctrl & ~MXC_F_FLC_REVA_CTRL_UNLOCK) | MXC_S_FLC_REVA_CTRL_UNLOCK_LOCKED;
232-
#if defined(MAX32666)
233-
MXC_FLC1->ctrl = (MXC_FLC1->ctrl & ~MXC_F_FLC_REVA_CTRL_UNLOCK) | MXC_S_FLC_REVA_CTRL_UNLOCK_LOCKED;
234-
#endif
274+
flash_lock();
235275
reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL);
236276
}
237277

238-
MXC_ICC_Enable(MXC_ICC0);
278+
icc_enable();
239279

240280
block_num += count;
241281
src += count * FILESYSTEM_BLOCK_SIZE;

ports/analog/supervisor/port.c

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,36 @@
4848
// true random number generator, TRNG
4949
#include "trng.h"
5050

51+
// Define macros for RTC flags for portability
52+
#if defined(MAX32690)
53+
#define TOD_FLAG MXC_F_RTC_CTRL_TOD_ALARM
54+
#define SSEC_FLAG MXC_F_RTC_CTRL_SSEC_ALARM
55+
#define RDY_FLAG MXC_F_RTC_CTRL_RDY
56+
57+
#define TOD_ENABLE MXC_F_RTC_CTRL_TOD_ALARM_IE
58+
#define SSEC_ENABLE MXC_F_RTC_CTRL_SSEC_ALARM_IE
59+
#define RDY_ENABLE MXC_F_RTC_CTRL_RDY_IE
60+
#define RTC_ENABLE MXC_F_RTC_CTRL_EN
61+
#elif defined(MAX32650)
62+
#define TOD_FLAG MXC_F_RTC_CTRL_TOD_ALARM_FL
63+
#define SSEC_FLAG MXC_F_RTC_CTRL_SSEC_ALARM_FL
64+
#define RDY_FLAG MXC_F_RTC_CTRL_READY
65+
66+
#define TOD_ENABLE MXC_F_RTC_CTRL_TOD_ALARM_EN
67+
#define SSEC_ENABLE MXC_F_RTC_CTRL_SSEC_ALARM_EN
68+
#define RDY_ENABLE MXC_F_RTC_CTRL_READY_INT_EN
69+
#define RTC_ENABLE MXC_F_RTC_CTRL_ENABLE
70+
#elif defined(MAX32665)
71+
#define TOD_FLAG MXC_F_RTC_CTRL_ALDF
72+
#define SSEC_FLAG MXC_F_RTC_CTRL_ALSF
73+
#define RDY_FLAG MXC_F_RTC_CTRL_RDY
74+
75+
#define TOD_ENABLE MXC_F_RTC_CTRL_ADE
76+
#define SSEC_ENABLE MXC_F_RTC_CTRL_ASE
77+
#define RDY_ENABLE MXC_F_RTC_CTRL_RDYE
78+
#define RTC_ENABLE MXC_F_RTC_CTRL_RTCE
79+
#endif
80+
5181
// msec to RTC subsec ticks (4 kHz)
5282
/* Converts a time in milleseconds to equivalent RSSA register value */
5383
#define MSEC_TO_SS_ALARM(x) (0 - ((x * 4096) / 1000))
@@ -100,12 +130,6 @@ safe_mode_t port_init(void) {
100130
}
101131
}
102132

103-
// Enable clock to RTC peripheral
104-
MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_ERTCO_EN;
105-
while (!(MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_ERTCO_RDY)) {
106-
;
107-
}
108-
109133
NVIC_EnableIRQ(RTC_IRQn);
110134
NVIC_EnableIRQ(USB_IRQn);
111135

@@ -116,9 +140,9 @@ safe_mode_t port_init(void) {
116140
;
117141

118142
// enable 1 sec RTC SSEC alarm
119-
MXC_RTC_DisableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE);
143+
MXC_RTC_DisableInt(SSEC_ENABLE);
120144
MXC_RTC_SetSubsecondAlarm(MSEC_TO_SS_ALARM(1000));
121-
MXC_RTC_EnableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE);
145+
MXC_RTC_EnableInt(SSEC_ENABLE);
122146

123147
// Enable RTC
124148
while (MXC_RTC_Start() != E_SUCCESS) {
@@ -142,14 +166,14 @@ void RTC_IRQHandler(void) {
142166
int flags = MXC_RTC_GetFlags();
143167

144168
switch (flags) {
145-
case MXC_F_RTC_CTRL_SSEC_ALARM:
146-
MXC_RTC_ClearFlags(MXC_F_RTC_CTRL_SSEC_ALARM);
169+
case SSEC_FLAG:
170+
MXC_RTC_ClearFlags(SSEC_FLAG);
147171
break;
148-
case MXC_F_RTC_CTRL_TOD_ALARM:
149-
MXC_RTC_ClearFlags(MXC_F_RTC_CTRL_TOD_ALARM);
172+
case TOD_FLAG:
173+
MXC_RTC_ClearFlags(TOD_FLAG);
150174
break;
151-
case MXC_F_RTC_CTRL_RDY:
152-
MXC_RTC_ClearFlags(MXC_F_RTC_CTRL_RDY);
175+
case RDY_FLAG:
176+
MXC_RTC_ClearFlags(RDY_FLAG);
153177
break;
154178
default:
155179
break;
@@ -217,7 +241,7 @@ uint32_t port_get_saved_word(void) {
217241
uint64_t port_get_raw_ticks(uint8_t *subticks) {
218242
// Ensure we can read from ssec register as soon as we can
219243
// MXC function does cross-tick / busy checking of RTC controller
220-
if (MXC_RTC->ctrl & MXC_F_RTC_CTRL_EN) {
244+
if (MXC_RTC->ctrl & RTC_ENABLE) {
221245
// NOTE: RTC_GetTime always returns BUSY if RTC is not running
222246
while ((MXC_RTC_GetTime(&sec, &subsec)) != E_NO_ERROR) {
223247
;
@@ -261,8 +285,7 @@ void port_interrupt_after_ticks(uint32_t ticks) {
261285
ticks_msec = (ticks / TICKS_PER_SEC) * 1000;
262286

263287
// Disable RTC interrupts
264-
MXC_RTC_DisableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE |
265-
MXC_F_RTC_CTRL_TOD_ALARM_IE | MXC_F_RTC_CTRL_RDY_IE);
288+
MXC_RTC_DisableInt(SSEC_ENABLE | TOD_ENABLE | RDY_ENABLE);
266289

267290
// Stop RTC & store current time & ticks
268291
port_get_raw_ticks(NULL);
@@ -275,14 +298,14 @@ void port_interrupt_after_ticks(uint32_t ticks) {
275298
while (MXC_RTC_SetSubsecondAlarm(MSEC_TO_SS_ALARM(ticks_msec)) != E_SUCCESS) {
276299
}
277300

278-
MXC_RTC_EnableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE);
301+
MXC_RTC_EnableInt(SSEC_ENABLE);
279302

280303
}
281304

282305
void port_idle_until_interrupt(void) {
283306
#if CIRCUITPY_RTC
284307
// Check if alarm triggers before we even got here
285-
if (MXC_RTC_GetFlags() == (MXC_F_RTC_CTRL_TOD_ALARM | MXC_F_RTC_CTRL_SSEC_ALARM)) {
308+
if (MXC_RTC_GetFlags() == (TOD_FLAG | SSEC_FLAG)) {
286309
return;
287310
}
288311
#endif

ports/analog/supervisor/usb.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,39 @@
1515
// max32 includes
1616
#include "max32_port.h"
1717

18+
#if defined(MAX32690)
19+
static void init_usb(void) {
20+
// Enable 120 MHz IPO, then 0.9V LDO supplying USB
21+
MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IPO);
22+
MXC_MCR->ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN;
23+
24+
MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB);
25+
MXC_SYS_Reset_Periph(MXC_SYS_RESET0_USB);
26+
}
27+
#elif defined(MAX32650)
28+
static void init_usb(void) {
29+
// Enable the 96MHz clock, then enable USB
30+
MXC_GCR->clk_ctrl |= MXC_F_GCR_CLK_CTRL_HIRC96_EN;
31+
MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB);
32+
MXC_SYS_Reset_Periph(MXC_SYS_RESET_USB);
33+
}
34+
#elif defined(MAX32665)
35+
static void init_usb(void) {
36+
// Enable the 96MHz clock, then enable USB
37+
MXC_GCR->clkcn |= MXC_F_GCR_CLKCN_HIRC96M_EN;
38+
MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB);
39+
MXC_SYS_Reset_Periph(MXC_SYS_RESET_USB);
40+
}
41+
#endif
42+
1843
void init_usb_hardware(void) {
1944
// USB GPIOs are non-configurable on MAX32 devices
2045
// No need to add them to the never_reset list for mcu/Pin API.
2146

2247
// 1 ms SysTick initialized in board.c
2348

2449
// Enable requisite clocks & power for USB
25-
MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IPO);
26-
MXC_MCR->ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN;
27-
MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB);
28-
MXC_SYS_Reset_Periph(MXC_SYS_RESET0_USB);
50+
init_usb();
2951

3052
// Supervisor calls TinyUSB's dcd_init,
3153
// which initializes the USB PHY.

0 commit comments

Comments
 (0)