4#if defined(RADIOLIB_BUILD_RPI_PICO)
10#include <pico/stdlib.h>
11#include "hardware/spi.h"
12#include "hardware/timer.h"
13#include "hardware/pwm.h"
14#include "hardware/clocks.h"
15#include "hardware/gpio.h"
16#include "pico/multicore.h"
18#define PI_PICO_MAX_USER_GPIO (48)
24static irq_handler_t picoHalUserCallbacks[PI_PICO_MAX_USER_GPIO] = { 0 };
25static uint32_t picoHalIrqEventMasks[PI_PICO_MAX_USER_GPIO] = { 0 };
26static uint64_t picoHalIrqMask = 0;
28static void picoInterruptHandler(
void) {
29 for(
int gpio = 0; gpio < PI_PICO_MAX_USER_GPIO; gpio++) {
30 if(gpio_get_irq_event_mask(gpio) == picoHalIrqEventMasks[gpio]) {
31 gpio_acknowledge_irq(gpio, picoHalIrqEventMasks[gpio]);
32 if(picoHalUserCallbacks[gpio]) {
33 picoHalUserCallbacks[gpio]();
45 PicoHal(spi_inst_t *spiChannel, uint32_t misoPin, uint32_t mosiPin, uint32_t sckPin, uint32_t spiSpeed = 500 * 1000)
46 :
RadioLibHal(GPIO_IN, GPIO_OUT, 0, 1, GPIO_IRQ_EDGE_RISE, GPIO_IRQ_EDGE_FALL),
47 _spiChannel(spiChannel),
53 void init()
override {
58 void term()
override {
64 void pinMode(uint32_t pin, uint32_t mode)
override {
65 if (pin == RADIOLIB_NC) {
70 gpio_set_dir(pin, mode);
73 void digitalWrite(uint32_t pin, uint32_t value)
override {
74 if (pin == RADIOLIB_NC) {
78 gpio_put(pin, (
bool)value);
82 if (pin == RADIOLIB_NC) {
89 void attachInterrupt(uint32_t interruptNum,
void (*interruptCb)(
void), uint32_t mode)
override {
90 if (interruptNum == RADIOLIB_NC) {
95 picoHalUserCallbacks[interruptNum] = (irq_handler_t)interruptCb;
96 picoHalIrqEventMasks[interruptNum] = mode;
99 if (!(picoHalIrqMask & (1ULL << interruptNum))) {
103 if (picoHalIrqMask) {
104 irq_set_enabled(IO_IRQ_BANK0,
false);
105 gpio_remove_raw_irq_handler_masked64(picoHalIrqMask, picoInterruptHandler);
109 picoHalIrqMask |= (1ULL << interruptNum);
110 gpio_add_raw_irq_handler_masked64(picoHalIrqMask, picoInterruptHandler);
111 irq_set_enabled(IO_IRQ_BANK0,
true);
115 gpio_set_irq_enabled(interruptNum, mode,
true);
119 if (interruptNum == RADIOLIB_NC) {
124 gpio_set_irq_enabled(interruptNum, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL,
false);
127 picoHalUserCallbacks[interruptNum] = NULL;
128 picoHalIrqEventMasks[interruptNum] = 0;
131 void delay(
unsigned long ms)
override {
139 unsigned long millis()
override {
140 return to_ms_since_boot(get_absolute_time());
143 unsigned long micros()
override {
144 return to_us_since_boot(get_absolute_time());
147 long pulseIn(uint32_t pin, uint32_t state,
unsigned long timeout)
override {
148 if (pin == RADIOLIB_NC) {
153 uint32_t start = this->
micros();
154 uint32_t curtick = this->
micros();
157 if ((this->
micros() - curtick) > timeout) {
162 return (this->
micros() - start);
165 void tone(uint32_t pin,
unsigned int frequency,
unsigned long duration = 0)
override;
167 void noTone(uint32_t pin)
override {
168 multicore_reset_core1();
172 spi_init(_spiChannel, _spiSpeed);
173 spi_set_format(_spiChannel, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
175 gpio_set_function(_sckPin, GPIO_FUNC_SPI);
176 gpio_set_function(_mosiPin, GPIO_FUNC_SPI);
177 gpio_set_function(_misoPin, GPIO_FUNC_SPI);
182 void spiTransfer(uint8_t *out,
size_t len, uint8_t *in) {
183 spi_write_read_blocking(_spiChannel, out, in, len);
186 void yield()
override {
187 tight_loop_contents();
193 spi_deinit(_spiChannel);
198 spi_inst_t *_spiChannel;
Hardware abstraction library base interface.
Definition Hal.h:16
virtual uint32_t digitalRead(uint32_t pin)=0
Digital read method. Must be implemented by the platform-specific hardware abstraction!
virtual void yield()
Yield method, called from long loops in multi-threaded environment (to prevent blocking other threads...
Definition Hal.cpp:35
virtual void detachInterrupt(uint32_t interruptNum)=0
Method to detach function from an external interrupt. Must be implemented by the platform-specific ha...
virtual long pulseIn(uint32_t pin, uint32_t state, RadioLibTime_t timeout)=0
Measure the length of incoming digital pulse in microseconds. Must be implemented by the platform-spe...
virtual void spiEnd()=0
SPI termination method.
virtual void init()
Module initialization method. This will be called by all radio modules at the beginning of startup....
Definition Hal.cpp:17
virtual RadioLibTime_t millis()=0
Get number of milliseconds since start. Must be implemented by the platform-specific hardware abstrac...
virtual void digitalWrite(uint32_t pin, uint32_t value)=0
Digital write method. Must be implemented by the platform-specific hardware abstraction!
virtual void tone(uint32_t pin, unsigned int frequency, RadioLibTime_t duration=0)
Method to produce a square-wave with 50% duty cycle ("tone") of a given frequency at some pin.
Definition Hal.cpp:25
virtual RadioLibTime_t micros()=0
Get number of microseconds since start. Must be implemented by the platform-specific hardware abstrac...
virtual void spiEndTransaction()=0
Method to end SPI transaction.
virtual void noTone(uint32_t pin)
Method to stop producing a tone.
Definition Hal.cpp:31
virtual void spiBegin()=0
SPI initialization method.
virtual void delay(RadioLibTime_t ms)=0
Blocking wait function. Must be implemented by the platform-specific hardware abstraction!
virtual void term()
Module termination method. This will be called by all radio modules when the destructor is called....
Definition Hal.cpp:21
virtual void delayMicroseconds(RadioLibTime_t us)=0
Blocking microsecond wait function. Must be implemented by the platform-specific hardware abstraction...
virtual void spiBeginTransaction()=0
Method to start SPI transaction.
virtual void spiTransfer(uint8_t *out, size_t len, uint8_t *in)=0
Method to transfer buffer over SPI.
virtual void pinMode(uint32_t pin, uint32_t mode)=0
GPIO pin mode (input/output/...) configuration method. Must be implemented by the platform-specific h...
virtual void attachInterrupt(uint32_t interruptNum, void(*interruptCb)(void), uint32_t mode)=0
Method to attach function to an external interrupt. Must be implemented by the platform-specific hard...