Skip to content

Commit aabbba6

Browse files
Add some Doxygen documentation to core and libraries (earlephilhower#2780)
1 parent 50b9ea9 commit aabbba6

File tree

6 files changed

+525
-31
lines changed

6 files changed

+525
-31
lines changed

cores/rp2040/Bootsel.h

+11
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,21 @@
2020

2121
#pragma once
2222

23+
/**
24+
@brief Wrapper class for polling the BOOTSEL button
25+
*/
2326
class __Bootsel {
2427
public:
2528
__Bootsel() { }
29+
/**
30+
@brief Get state of the BOOTSEL pin
31+
32+
@returns True if BOOTSEL pushed
33+
*/
2634
operator bool();
2735
};
2836

37+
/**
38+
@brief BOOTSEL accessor instance
39+
*/
2940
extern __Bootsel BOOTSEL;

cores/rp2040/RP2040Support.h

+172-5
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ extern "C" void loop1() __attribute__((weak));
182182
extern "C" bool core1_separate_stack;
183183
extern "C" uint32_t* core1_separate_stack_address;
184184

185+
/**
186+
@brief RP2040/RP2350 helper function for HW-specific features
187+
*/
185188
class RP2040 {
186189
public:
187190
RP2040() { /* noop */ }
@@ -207,26 +210,50 @@ class RP2040 {
207210
#endif
208211
}
209212

210-
// Convert from microseconds to PIO clock cycles
213+
/**
214+
@brief Convert from microseconds to PIO clock cycles
215+
216+
@returns the PIO cycles for a given microsecond delay
217+
*/
211218
static int usToPIOCycles(int us) {
212219
// Parenthesis needed to guarantee order of operations to avoid 32bit overflow
213220
return (us * (clock_get_hz(clk_sys) / 1'000'000));
214221
}
215222

216-
// Get current clock frequency
223+
/**
224+
@brief Gets the active CPU speed (may differ from F_CPU
225+
226+
@returns CPU frequency in Hz
227+
*/
217228
static int f_cpu() {
218229
return clock_get_hz(clk_sys);
219230
}
220231

221-
// Get current CPU core number
232+
/**
233+
@brief Get the core ID that is currently executing this code
234+
235+
@returns 0 for Core 0, 1 for Core 1
236+
*/
222237
static int cpuid() {
223238
return sio_hw->cpuid;
224239
}
225240

226-
// Get CPU cycle count. Needs to do magic to extens 24b HW to something longer
241+
/**
242+
@brief CPU cycle counter epoch (24-bit cycle). For internal use
243+
*/
227244
volatile uint64_t _epoch = 0;
245+
/**
246+
@brief Get the count of CPU clock cycles since power on.
247+
248+
@details
249+
The 32-bit count will overflow every 4 billion cycles, so consider using ``getCycleCount64`` for
250+
longer measurements
251+
252+
@returns CPU clock cycles since power up
253+
*/
228254
inline uint32_t getCycleCount() {
229255
#if !defined(__riscv) && !defined(__PROFILE)
256+
// Get CPU cycle count. Needs to do magic to extend 24b HW to something longer
230257
if (!__isFreeRTOS) {
231258
uint32_t epoch;
232259
uint32_t ctr;
@@ -242,7 +269,11 @@ class RP2040 {
242269
}
243270
#endif
244271
}
272+
/**
273+
@brief Get the count of CPU clock cycles since power on as a 64-bit quantrity
245274
275+
@returns CPU clock cycles since power up
276+
*/
246277
inline uint64_t getCycleCount64() {
247278
#if !defined(__riscv) && !defined(__PROFILE)
248279
if (!__isFreeRTOS) {
@@ -261,23 +292,53 @@ class RP2040 {
261292
#endif
262293
}
263294

295+
/**
296+
@brief Gets total unused heap (dynamic memory)
297+
298+
@details
299+
Note that the allocations of the size of the total free heap may fail due to fragmentation.
300+
For example, ``getFreeHeap`` can report 100KB available, but an allocation of 90KB may fail
301+
because there may not be a contiguous 90KB space available
302+
303+
@returns Free heap in bytes
304+
*/
264305
inline int getFreeHeap() {
265306
return getTotalHeap() - getUsedHeap();
266307
}
267308

309+
/**
310+
@brief Gets total used heap (dynamic memory)
311+
312+
@returns Used heap in bytes
313+
*/
268314
inline int getUsedHeap() {
269315
struct mallinfo m = mallinfo();
270316
return m.uordblks;
271317
}
272318

319+
/**
320+
@brief Gets total heap (dynamic memory) compiled into the program
321+
322+
@returns Total heap size in bytes
323+
*/
273324
inline int getTotalHeap() {
274325
return &__StackLimit - &__bss_end__;
275326
}
276327

328+
/**
329+
@brief On the RP2350, returns the amount of heap (dynamic memory) available in PSRAM
330+
331+
@returns Total free heap in PSRAM, or 0 if no PSRAM present
332+
*/
277333
inline int getFreePSRAMHeap() {
278334
return getTotalPSRAMHeap() - getUsedPSRAMHeap();
279335
}
280336

337+
/**
338+
@brief On the RP2350, returns the total amount of PSRAM heap (dynamic memory) used
339+
340+
@returns Bytes used in PSRAM, or 0 if no PSRAM present
341+
*/
281342
inline int getUsedPSRAMHeap() {
282343
#if defined(RP2350_PSRAM_CS)
283344
extern size_t __psram_total_used();
@@ -287,6 +348,11 @@ class RP2040 {
287348
#endif
288349
}
289350

351+
/**
352+
@brief On the RP2350, gets total heap (dynamic memory) compiled into the program
353+
354+
@returns Total PSRAM heap size in bytes, or 0 if no PSRAM present
355+
*/
290356
inline int getTotalPSRAMHeap() {
291357
#if defined(RP2350_PSRAM_CS)
292358
extern size_t __psram_total_space();
@@ -296,6 +362,11 @@ class RP2040 {
296362
#endif
297363
}
298364

365+
/**
366+
@brief Gets the current stack pointer in a ARM/RISC-V safe manner
367+
368+
@returns Current SP
369+
*/
299370
inline uint32_t getStackPointer() {
300371
uint32_t *sp;
301372
#if defined(__riscv)
@@ -306,6 +377,14 @@ class RP2040 {
306377
return (uint32_t)sp;
307378
}
308379

380+
/**
381+
@brief Calculates approximately how much stack space is still available for the running core. Handles multiprocessing and separate stacks.
382+
383+
@details
384+
Not valid in FreeRTOS. Use the FreeRTOS internal functions to access this information.
385+
386+
@returns Approximation of the amount of stack available for use on the specific core
387+
*/
309388
inline int getFreeStack() {
310389
const unsigned int sp = getStackPointer();
311390
uint32_t ref = 0x20040000;
@@ -319,6 +398,11 @@ class RP2040 {
319398
return sp - ref;
320399
}
321400

401+
/**
402+
@brief On the RP2350, gets the size of attached PSRAM
403+
404+
@returns PSRAM size in bytes, or 0 if no PSRAM present
405+
*/
322406
inline size_t getPSRAMSize() {
323407
#if defined(RP2350_PSRAM_CS)
324408
extern size_t __psram_size;
@@ -328,31 +412,65 @@ class RP2040 {
328412
#endif
329413
}
330414

415+
/**
416+
@brief Freezes the other core in a flash-write-safe state. Not generally needed by applications
417+
418+
@details
419+
When the external flash chip is erasing or writing, the Pico cannot fetch instructions from it.
420+
In this case both the core doing the writing and the other core (if active) need to run from a
421+
routine that's contained in RAM. This call forces the other core into a tight, RAM-based loop
422+
safe for this operation. When flash erase/write is completed, ``resumeOtherCore`` to return
423+
it to operation.
424+
425+
Be sure to disable any interrupts or task switches before calling to avoid deadlocks.
426+
427+
If the second core is not started, this is a no-op.
428+
*/
331429
void idleOtherCore() {
332430
fifo.idleOtherCore();
333431
}
334432

433+
/**
434+
@brief Resumes normal operation of the other core
435+
*/
335436
void resumeOtherCore() {
336437
fifo.resumeOtherCore();
337438
}
338439

440+
/**
441+
@brief Hard resets the 2nd core (CORE1).
442+
443+
@details
444+
Because core1 will restart with the heap and global variables not in the same state as
445+
power-on, this call may not work as desired and a full CPU reset may be necessary in
446+
certain cases.
447+
*/
339448
void restartCore1() {
340449
multicore_reset_core1();
341450
fifo.clear();
342451
multicore_launch_core1(main1);
343452
}
344453

454+
/**
455+
@brief Warm-reboots the chip in normal mode
456+
*/
345457
void reboot() {
346458
watchdog_reboot(0, 0, 10);
347459
while (1) {
348460
continue;
349461
}
350462
}
351463

464+
/**
465+
@brief Warm-reboots the chip in normal mode
466+
*/
352467
inline void restart() {
353468
reboot();
354469
}
355470

471+
/**
472+
@brief Warm-reboots the chip into the USB bootloader mode
473+
*/
356474
inline void rebootToBootloader() {
357475
reset_usb_boot(0, 0);
358476
while (1) {
@@ -364,16 +482,32 @@ class RP2040 {
364482
static void enableDoubleResetBootloader();
365483
#endif
366484

485+
/**
486+
@brief Starts the hardware watchdog timer. The CPU will reset if the watchdog is not fed every delay_ms
487+
488+
@param [in] delay_ms Milliseconds without a wdt_reset before rebooting
489+
*/
367490
void wdt_begin(uint32_t delay_ms) {
368491
watchdog_enable(delay_ms, 1);
369492
}
370493

494+
/**
495+
@brief Feeds the watchdog timer, resetting it for another delay_ms countdown
496+
*/
371497
void wdt_reset() {
372498
watchdog_update();
373499
}
374500

501+
/**
502+
@brief Best-effort reasons for chip reset
503+
*/
375504
enum resetReason_t {UNKNOWN_RESET, PWRON_RESET, RUN_PIN_RESET, SOFT_RESET, WDT_RESET, DEBUG_RESET, GLITCH_RESET, BROWNOUT_RESET};
376505

506+
/**
507+
@brief Attempts to determine the reason for the last chip reset. May not always be able to determine accurately
508+
509+
@returns Reason for reset
510+
*/
377511
resetReason_t getResetReason(void) {
378512
io_rw_32 *WD_reason_reg = (io_rw_32 *)(WATCHDOG_BASE + WATCHDOG_REASON_OFFSET);
379513

@@ -427,6 +561,10 @@ class RP2040 {
427561
return UNKNOWN_RESET;
428562
}
429563

564+
/**
565+
@brief Get unique ID string for the running board
566+
@returns String with the unique board ID as determined by the SDK
567+
*/
430568
const char *getChipID() {
431569
static char id[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1] = { 0 };
432570
if (!id[0]) {
@@ -437,6 +575,17 @@ class RP2040 {
437575

438576
#pragma GCC push_options
439577
#pragma GCC optimize ("Os")
578+
/**
579+
@brief Perform a memcpy using a DMA engine for speed
580+
581+
@details
582+
Uses the DMA to copy to and from RAM. Only works on 4-byte aligned, 4-byte multiple length
583+
sources and destination (i.e. word-aligned, word-length). Falls back to normal memcpy otherwise.
584+
585+
@param [out] dest Memcpy destination, 4-byte aligned
586+
@param [in] src Memcpy source, 4-byte aligned
587+
@param [in] n Count in bytes to transfer (should be a multiple of 4 bytes)
588+
*/
440589
void *memcpyDMA(void *dest, const void *src, size_t n) {
441590
// Allocate a DMA channel on 1st call, reuse it every call after
442591
if (memcpyDMAChannel < 1) {
@@ -465,14 +614,32 @@ class RP2040 {
465614
}
466615
#pragma GCC pop_options
467616

468-
// Multicore comms FIFO
617+
/**
618+
@brief Multicore communications FIFO
619+
*/
469620
_MFIFO fifo;
470621

471622

623+
/**
624+
@brief Return a 32-bit from the hardware random number generator
625+
626+
@returns Random value using appropriate hardware (RP2350 has true RNG, RP2040 has a less true RNG method)
627+
*/
472628
uint32_t hwrand32() {
473629
return get_rand_32();
474630
}
475631

632+
/**
633+
@brief Determines if code is running on a Pico or a PicoW
634+
635+
@details
636+
Code compiled for the RP2040 PicoW can run on the RP2040 Pico. This call lets an application
637+
identify if the current device is really a Pico or PicoW and handle appropriately. For
638+
the RP2350, this runtime detection is not available and the call returns whether it was
639+
compiled for the CYW43 WiFi driver
640+
641+
@returns True if running on a PicoW board with CYW43 WiFi chip.
642+
*/
476643
bool isPicoW() {
477644
#if !defined(PICO_CYW43_SUPPORTED)
478645
return false;

0 commit comments

Comments
 (0)