mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-23 16:25:31 +03:00
Adding RP2350 SDK and target framework (#13988)
* Adding RP2350 SDK and target framework * Spacing * Removing board definitions
This commit is contained in:
parent
462cb05930
commit
2dd6f95aad
576 changed files with 435012 additions and 0 deletions
167
lib/main/pico-sdk/rp2_common/pico_aon_timer/aon_timer.c
Normal file
167
lib/main/pico-sdk/rp2_common/pico_aon_timer/aon_timer.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "pico/aon_timer.h"
|
||||
#include "hardware/irq.h"
|
||||
#include "hardware/sync.h"
|
||||
|
||||
static aon_timer_alarm_handler_t aon_timer_alarm_handler;
|
||||
|
||||
#if HAS_RP2040_RTC
|
||||
#include "hardware/rtc.h"
|
||||
#include "pico/util/datetime.h"
|
||||
#elif HAS_POWMAN_TIMER
|
||||
#include "hardware/powman.h"
|
||||
|
||||
static void powman_timer_irq_handler(void) {
|
||||
uint irq_num = aon_timer_get_irq_num();
|
||||
// we are one-shot, so remove ourselves
|
||||
irq_set_enabled(irq_num, false);
|
||||
irq_remove_handler(irq_num, powman_timer_irq_handler);
|
||||
if (aon_timer_alarm_handler) aon_timer_alarm_handler();
|
||||
}
|
||||
#endif
|
||||
|
||||
void aon_timer_set_time(const struct timespec *ts) {
|
||||
#if HAS_RP2040_RTC
|
||||
datetime_t dt;
|
||||
bool ok = time_to_datetime(ts->tv_sec, &dt);
|
||||
assert(ok);
|
||||
if (ok) rtc_set_datetime(&dt);
|
||||
#elif HAS_POWMAN_TIMER
|
||||
powman_timer_set_ms(timespec_to_ms(ts));
|
||||
#else
|
||||
panic_unsupported();
|
||||
#endif
|
||||
}
|
||||
|
||||
void aon_timer_get_time(struct timespec *ts) {
|
||||
#if HAS_RP2040_RTC
|
||||
datetime_t dt;
|
||||
rtc_get_datetime(&dt);
|
||||
time_t t;
|
||||
bool ok = datetime_to_time(&dt, &t);
|
||||
assert(ok);
|
||||
ts->tv_nsec = 0;
|
||||
if (ok) {
|
||||
ts->tv_sec = t;
|
||||
} else {
|
||||
ts->tv_sec = -1;
|
||||
}
|
||||
#elif HAS_POWMAN_TIMER
|
||||
ms_to_timespec(powman_timer_get_ms(), ts);
|
||||
#else
|
||||
panic_unsupported();
|
||||
#endif
|
||||
}
|
||||
|
||||
aon_timer_alarm_handler_t aon_timer_enable_alarm(const struct timespec *ts, aon_timer_alarm_handler_t handler, bool wakeup_from_low_power) {
|
||||
uint32_t save = save_and_disable_interrupts();
|
||||
aon_timer_alarm_handler_t old_handler = aon_timer_alarm_handler;
|
||||
struct timespec ts_adjusted = *ts;
|
||||
#if HAS_RP2040_RTC
|
||||
((void)wakeup_from_low_power); // don't have a choice
|
||||
datetime_t dt;
|
||||
// adjust to after the target time
|
||||
if (ts_adjusted.tv_nsec) ts_adjusted.tv_sec++;
|
||||
bool ok = time_to_datetime(ts_adjusted.tv_sec, &dt);
|
||||
assert(ok);
|
||||
if (ok) {
|
||||
rtc_set_alarm(&dt, handler);
|
||||
}
|
||||
#elif HAS_POWMAN_TIMER
|
||||
uint irq_num = aon_timer_get_irq_num();
|
||||
powman_timer_disable_alarm();
|
||||
// adjust to after the target time
|
||||
ts_adjusted.tv_nsec += 999999;
|
||||
if (ts_adjusted.tv_nsec > 1000000000) {
|
||||
ts_adjusted.tv_nsec -= 1000000000;
|
||||
ts_adjusted.tv_sec++;
|
||||
}
|
||||
if (ts_adjusted.tv_nsec) ts_adjusted.tv_sec++;
|
||||
if (wakeup_from_low_power) {
|
||||
powman_enable_alarm_wakeup_at_ms(timespec_to_ms(ts));
|
||||
} else {
|
||||
powman_disable_alarm_wakeup();
|
||||
powman_timer_enable_alarm_at_ms(timespec_to_ms(ts));
|
||||
}
|
||||
if (handler) {
|
||||
irq_set_exclusive_handler(irq_num, powman_timer_irq_handler);
|
||||
irq_set_enabled(irq_num, true);
|
||||
}
|
||||
#else
|
||||
panic_unsupported();
|
||||
#endif
|
||||
aon_timer_alarm_handler = handler;
|
||||
restore_interrupts_from_disabled(save);
|
||||
return old_handler;
|
||||
}
|
||||
|
||||
void aon_timer_disable_alarm(void) {
|
||||
irq_set_enabled(aon_timer_get_irq_num(), false);
|
||||
#if HAS_RP2040_RTC
|
||||
rtc_disable_alarm();
|
||||
#elif HAS_POWMAN_TIMER
|
||||
powman_timer_disable_alarm();
|
||||
#else
|
||||
panic_unsupported();
|
||||
#endif
|
||||
}
|
||||
|
||||
void aon_timer_start_with_timeofday(void) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
struct timespec ts;
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
ts.tv_nsec = tv.tv_usec * 1000;
|
||||
aon_timer_start(&ts);
|
||||
}
|
||||
|
||||
void aon_timer_start(const struct timespec *ts) {
|
||||
#if HAS_RP2040_RTC
|
||||
rtc_init();
|
||||
aon_timer_set_time(ts);
|
||||
#elif HAS_POWMAN_TIMER
|
||||
// todo how best to allow different configurations; this should just be the default
|
||||
powman_timer_set_1khz_tick_source_xosc();
|
||||
powman_timer_set_ms(timespec_to_ms(ts));
|
||||
powman_timer_start();
|
||||
#else
|
||||
panic_unsupported();
|
||||
#endif
|
||||
}
|
||||
|
||||
void aon_timer_stop(void) {
|
||||
#if HAS_RP2040_RTC
|
||||
hw_clear_bits(&rtc_hw->ctrl, RTC_CTRL_RTC_ENABLE_BITS);
|
||||
#elif HAS_POWMAN_TIMER
|
||||
powman_timer_stop();
|
||||
#else
|
||||
panic_unsupported();
|
||||
#endif
|
||||
}
|
||||
|
||||
void aon_timer_get_resolution(struct timespec *ts) {
|
||||
#if HAS_RP2040_RTC
|
||||
ts->tv_sec = 1;
|
||||
ts->tv_nsec = 0;
|
||||
#elif HAS_POWMAN_TIMER
|
||||
ts->tv_sec = 0;
|
||||
ts->tv_nsec = 1000000000 / 1000;
|
||||
#else
|
||||
panic_unsupported();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool aon_timer_is_running(void) {
|
||||
#if HAS_RP2040_RTC
|
||||
return rtc_running();
|
||||
#elif HAS_POWMAN_TIMER
|
||||
return powman_timer_is_running();
|
||||
#else
|
||||
panic_unsupported();
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _PICO_AON_TIMER_H
|
||||
#define _PICO_AON_TIMER_H
|
||||
|
||||
#include "pico.h"
|
||||
#include <time.h>
|
||||
#include "pico/util/datetime.h"
|
||||
#include "hardware/regs/intctrl.h"
|
||||
|
||||
/** \file pico/aon_timer.h
|
||||
* \defgroup pico_aon_timer pico_aon_timer
|
||||
*
|
||||
* \brief High Level "Always on Timer" Abstraction
|
||||
*
|
||||
* \if rp2040_specific
|
||||
* This library uses the RTC on RP2040.
|
||||
* \endif
|
||||
* \if rp2350_specific
|
||||
* This library uses the Powman Timer on RP2350.
|
||||
* \endif
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def AON_TIMER_IRQ_NUM()
|
||||
* \ingroup pico_aon_timer
|
||||
* \hideinitializer
|
||||
* \brief Returns the \ref irq_num_t for interrupts for the actual hardware backing the AON timer abstraction
|
||||
*
|
||||
* Note this macro is intended to resolve at compile time, and does no parameter checking
|
||||
*/
|
||||
#ifndef AON_TIMER_IRQ_NUM
|
||||
#if HAS_RP2040_RTC
|
||||
#define AON_TIMER_IRQ_NUM() RTC_IRQ
|
||||
#elif HAS_POWMAN_TIMER
|
||||
#define AON_TIMER_IRQ_NUM() POWMAN_IRQ_TIMER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef void (*aon_timer_alarm_handler_t)(void);
|
||||
|
||||
/**
|
||||
* \brief Start the AON timer running using the result from the gettimeofday() function as the current time
|
||||
* \ingroup pico_aon_timer
|
||||
*/
|
||||
void aon_timer_start_with_timeofday(void);
|
||||
|
||||
/**
|
||||
* \brief Start the AON timer running using the specified timespec as the current time
|
||||
* \ingroup pico_aon_timer
|
||||
* \param ts the current time
|
||||
*/
|
||||
void aon_timer_start(const struct timespec *ts);
|
||||
|
||||
/**
|
||||
* \brief Stop the AON timer
|
||||
* \ingroup pico_aon_timer
|
||||
*/
|
||||
void aon_timer_stop(void);
|
||||
|
||||
/**
|
||||
* \brief Update the current time of the AON timer
|
||||
* \ingroup pico_aon_timer
|
||||
* \param ts the new current time
|
||||
*/
|
||||
void aon_timer_set_time(const struct timespec *ts);
|
||||
|
||||
/**
|
||||
* \brief Get the current time of the AON timer
|
||||
* \ingroup pico_aon_timer
|
||||
* \param ts out value for the current time
|
||||
*/
|
||||
void aon_timer_get_time(struct timespec *ts);
|
||||
|
||||
/**
|
||||
* \brief Get the resolution of the AON timer
|
||||
* \ingroup pico_aon_timer
|
||||
* \param ts out value for the resolution of the AON timer
|
||||
*/
|
||||
void aon_timer_get_resolution(struct timespec *ts);
|
||||
|
||||
/**
|
||||
* \brief Enable an AON timer alarm for a specified time
|
||||
* \ingroup pico_aon_timer
|
||||
*
|
||||
* \if rp2040_specific
|
||||
* On RP2040 the alarm will not fire if it is in the past
|
||||
* \endif
|
||||
* \if rp2350_specific
|
||||
* On RP2350 the alarm will fire if it is in the past
|
||||
* \endif
|
||||
*
|
||||
* \param ts the alarm time
|
||||
* \param handler a callback to call when the timer fires (may be NULL for wakeup_from_low_power = true)
|
||||
* \param wakeup_from_low_power true if the AON timer is to be used to wake up from a DORMANT state
|
||||
*/
|
||||
aon_timer_alarm_handler_t aon_timer_enable_alarm(const struct timespec *ts, aon_timer_alarm_handler_t handler, bool wakeup_from_low_power);
|
||||
|
||||
/**
|
||||
* \brief Disable the currently enabled AON timer alarm if any
|
||||
* \ingroup pico_aon_timer
|
||||
*/
|
||||
void aon_timer_disable_alarm(void);
|
||||
|
||||
/**
|
||||
* \brief Disable the currently enabled AON timer alarm if any
|
||||
* \ingroup pico_aon_timer
|
||||
* \return true if the AON timer is running
|
||||
*/
|
||||
bool aon_timer_is_running(void);
|
||||
|
||||
static inline uint aon_timer_get_irq_num(void) {
|
||||
return AON_TIMER_IRQ_NUM();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue