mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-13 03:20:00 +03:00
PICO: system.c use DWT_CYCCNT, same as for STM32.
This commit is contained in:
parent
6d9b333498
commit
e19ddaba04
1 changed files with 55 additions and 82 deletions
|
@ -34,16 +34,11 @@
|
||||||
#include "hardware/clocks.h"
|
#include "hardware/clocks.h"
|
||||||
#include "pico/unique_id.h"
|
#include "pico/unique_id.h"
|
||||||
|
|
||||||
int main(int argc, char * argv[]);
|
///////////////////////////////////////////////////
|
||||||
|
|
||||||
void Reset_Handler(void);
|
|
||||||
void Default_Handler(void);
|
|
||||||
|
|
||||||
// cycles per microsecond
|
|
||||||
static uint32_t usTicks = 0;
|
|
||||||
|
|
||||||
// SystemInit and SystemCoreClock variables/functions,
|
// SystemInit and SystemCoreClock variables/functions,
|
||||||
// as per pico-sdk rp2_common/cmsis/stub/CMSIS/Device/RP2350/Source/system_RP2350.c
|
// as per pico-sdk rp2_common/cmsis/stub/CMSIS/Device/RP2350/Source/system_RP2350.c
|
||||||
|
|
||||||
uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock)*/
|
uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock)*/
|
||||||
|
|
||||||
void SystemCoreClockUpdate (void)
|
void SystemCoreClockUpdate (void)
|
||||||
|
@ -56,61 +51,7 @@ void __attribute__((constructor)) SystemInit (void)
|
||||||
SystemCoreClockUpdate();
|
SystemCoreClockUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// TODO: check: don't define functions here provided by pico-sdk crt0
|
|
||||||
// crt0.S defines the vector table in the .vectors section, with
|
|
||||||
// initial stack pointer at __StackTop (defined in linker script),
|
|
||||||
// and with reset handler pointing to code inside crt0.S
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
void (* const vector_table[])() __attribute__((section(".vectors"))) = {
|
|
||||||
(void (*)())0x20000000, // Initial Stack Pointer
|
|
||||||
Reset_Handler, // Interrupt Handler for reset
|
|
||||||
Default_Handler, // Default handler for other interrupts
|
|
||||||
};
|
|
||||||
|
|
||||||
void Default_Handler(void)
|
|
||||||
{
|
|
||||||
while (1); // Infinite loop on default handler
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset_Handler(void)
|
|
||||||
{
|
|
||||||
// Initialize data segments
|
|
||||||
extern uint32_t _sdata, _edata, _sidata;
|
|
||||||
uint32_t *src = &_sidata;
|
|
||||||
uint32_t *dst = &_sdata;
|
|
||||||
|
|
||||||
while (dst < &_edata) {
|
|
||||||
*dst++ = *src++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear bss segment
|
|
||||||
extern uint32_t _sbss, _ebss;
|
|
||||||
dst = &_sbss;
|
|
||||||
|
|
||||||
while (dst < &_ebss) {
|
|
||||||
*dst++ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
usTicks = clock_get_hz(clk_sys) / 1000000;
|
|
||||||
|
|
||||||
// Call main function
|
|
||||||
main(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void __unhandled_user_irq(void)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
void systemReset(void)
|
void systemReset(void)
|
||||||
{
|
{
|
||||||
|
@ -119,10 +60,36 @@ void systemReset(void)
|
||||||
|
|
||||||
uint32_t systemUniqueId[3] = { 0 };
|
uint32_t systemUniqueId[3] = { 0 };
|
||||||
|
|
||||||
|
// cycles per microsecond
|
||||||
|
static uint32_t usTicks = 0;
|
||||||
|
static float usTicksInv = 0.0f;
|
||||||
|
|
||||||
|
#define PICO_DWT_CTRL ((uint32_t *)(PPB_BASE + M33_DWT_CTRL_OFFSET))
|
||||||
|
#define PICO_DWT_CYCCNT ((uint32_t *)(PPB_BASE + M33_DWT_CYCCNT_OFFSET))
|
||||||
|
#define PICO_DEMCR ((uint32_t *)(PPB_BASE + M33_DEMCR_OFFSET))
|
||||||
|
|
||||||
|
void cycleCounterInit(void)
|
||||||
|
{
|
||||||
|
// TODO check clock_get_hz(clk_sys) is the clock for CPU cycles
|
||||||
|
usTicks = SystemCoreClock / 1000000;
|
||||||
|
usTicksInv = 1e6f / SystemCoreClock;
|
||||||
|
|
||||||
|
// Global DWT enable
|
||||||
|
*PICO_DEMCR |= M33_DEMCR_TRCENA_BITS;
|
||||||
|
|
||||||
|
// Reset and enable cycle counter
|
||||||
|
*PICO_DWT_CYCCNT = 0;
|
||||||
|
*PICO_DWT_CTRL |= M33_DWT_CTRL_CYCCNTENA_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
void systemInit(void)
|
void systemInit(void)
|
||||||
{
|
{
|
||||||
//TODO: implement
|
//TODO: implement
|
||||||
|
|
||||||
|
SystemInit();
|
||||||
|
|
||||||
|
cycleCounterInit();
|
||||||
|
|
||||||
// load the unique id into a local array
|
// load the unique id into a local array
|
||||||
pico_unique_board_id_t id;
|
pico_unique_board_id_t id;
|
||||||
pico_get_unique_board_id(&id);
|
pico_get_unique_board_id(&id);
|
||||||
|
@ -138,11 +105,10 @@ void systemResetToBootloader(bootloaderRequestType_e requestType)
|
||||||
// Return system uptime in milliseconds (rollover in 49 days)
|
// Return system uptime in milliseconds (rollover in 49 days)
|
||||||
uint32_t millis(void)
|
uint32_t millis(void)
|
||||||
{
|
{
|
||||||
//TODO: correction required?
|
return (uint32_t)(time_us_64() / 1000);
|
||||||
return time_us_32() / 1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return system uptime in micros
|
// Return system uptime in micros (rollover in 71 mins)
|
||||||
uint32_t micros(void)
|
uint32_t micros(void)
|
||||||
{
|
{
|
||||||
return time_us_32();
|
return time_us_32();
|
||||||
|
@ -153,38 +119,46 @@ uint32_t microsISR(void)
|
||||||
return micros();
|
return micros();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PICO_NON_BUSY_SLEEP
|
|
||||||
void delayMicroseconds(uint32_t us)
|
void delayMicroseconds(uint32_t us)
|
||||||
{
|
{
|
||||||
#ifdef PICO_NON_BUSY_SLEEP
|
|
||||||
sleep_us(us);
|
sleep_us(us);
|
||||||
#else
|
|
||||||
uint32_t now = micros();
|
|
||||||
while (micros() - now < us);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void delay(uint32_t ms)
|
void delay(uint32_t ms)
|
||||||
{
|
{
|
||||||
#ifdef PICO_NON_BUSY_SLEEP
|
|
||||||
sleep_ms(ms);
|
sleep_ms(ms);
|
||||||
#else
|
|
||||||
while (ms--) {
|
|
||||||
delayMicroseconds(1000);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getCycleCounter(void)
|
uint32_t getCycleCounter(void)
|
||||||
{
|
{
|
||||||
return time_us_32();
|
return *PICO_DWT_CYCCNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conversion routines copied from platform/common/stm32/system.c
|
||||||
|
int32_t clockCyclesToMicros(int32_t clockCycles)
|
||||||
|
{
|
||||||
|
return clockCycles / usTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
float clockCyclesToMicrosf(int32_t clockCycles)
|
||||||
|
{
|
||||||
|
return clockCycles * usTicksInv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that this conversion is signed as this is used for periods rather than absolute timestamps
|
||||||
|
int32_t clockCyclesTo10thMicros(int32_t clockCycles)
|
||||||
|
{
|
||||||
|
return 10 * clockCycles / (int32_t)usTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that this conversion is signed as this is used for periods rather than absolute timestamps
|
||||||
|
int32_t clockCyclesTo100thMicros(int32_t clockCycles)
|
||||||
|
{
|
||||||
|
return 100 * clockCycles / (int32_t)usTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t clockMicrosToCycles(uint32_t micros)
|
uint32_t clockMicrosToCycles(uint32_t micros)
|
||||||
{
|
{
|
||||||
if (!usTicks) {
|
|
||||||
usTicks = clock_get_hz(clk_sys) / 1000000;
|
|
||||||
}
|
|
||||||
return micros * usTicks;
|
return micros * usTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +206,6 @@ void failureMode(failureMode_e mode)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void unusedPinInit(IO_t io)
|
static void unusedPinInit(IO_t io)
|
||||||
{
|
{
|
||||||
if (IOGetOwner(io) == OWNER_FREE) {
|
if (IOGetOwner(io) == OWNER_FREE) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue