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 (NUM_BANK0_GPIOS)
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(
unsigned int gpio = 0; gpio < PI_PICO_MAX_USER_GPIO; gpio++) {
31 if(picoHalIrqEventMasks[gpio] == 0) {
34 uint32_t activeEvents = gpio_get_irq_event_mask(gpio);
36 gpio_acknowledge_irq(gpio, activeEvents);
37 if((activeEvents & picoHalIrqEventMasks[gpio]) && picoHalUserCallbacks[gpio]) {
38 picoHalUserCallbacks[gpio]();
50 PicoHal(spi_inst_t *spiChannel, uint32_t misoPin, uint32_t mosiPin, uint32_t sckPin, uint32_t spiSpeed = 500 * 1000)
51 :
RadioLibHal(GPIO_IN, GPIO_OUT, 0, 1, GPIO_IRQ_EDGE_RISE, GPIO_IRQ_EDGE_FALL),
52 _spiChannel(spiChannel),
58 void init()
override {
63 void term()
override {
69 void pinMode(uint32_t pin, uint32_t mode)
override {
70 if (pin == RADIOLIB_NC) {
75 gpio_set_dir(pin, mode);
78 void digitalWrite(uint32_t pin, uint32_t value)
override {
79 if (pin == RADIOLIB_NC) {
83 gpio_put(pin, (
bool)value);
87 if (pin == RADIOLIB_NC) {
94 void attachInterrupt(uint32_t interruptNum,
void (*interruptCb)(
void), uint32_t mode)
override {
95 if (interruptNum == RADIOLIB_NC) {
100 picoHalUserCallbacks[interruptNum] = (irq_handler_t)interruptCb;
101 picoHalIrqEventMasks[interruptNum] = mode;
104 if (!(picoHalIrqMask & (1ULL << interruptNum))) {
108 if (picoHalIrqMask) {
109 irq_set_enabled(IO_IRQ_BANK0,
false);
110 gpio_remove_raw_irq_handler_masked64(picoHalIrqMask, picoInterruptHandler);
114 picoHalIrqMask |= (1ULL << interruptNum);
115 gpio_add_raw_irq_handler_masked64(picoHalIrqMask, picoInterruptHandler);
116 irq_set_enabled(IO_IRQ_BANK0,
true);
120 gpio_set_irq_enabled(interruptNum, mode,
true);
124 if (interruptNum == RADIOLIB_NC) {
129 gpio_set_irq_enabled(interruptNum, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL,
false);
132 picoHalUserCallbacks[interruptNum] = NULL;
133 picoHalIrqEventMasks[interruptNum] = 0;
136 void delay(
unsigned long ms)
override {
144 unsigned long millis()
override {
145 return to_ms_since_boot(get_absolute_time());
148 unsigned long micros()
override {
149 return to_us_since_boot(get_absolute_time());
152 long pulseIn(uint32_t pin, uint32_t state,
unsigned long timeout)
override {
153 if (pin == RADIOLIB_NC) {
158 uint32_t start = this->
micros();
159 uint32_t curtick = this->
micros();
162 if ((this->
micros() - curtick) > timeout) {
167 return (this->
micros() - start);
170 void tone(uint32_t pin,
unsigned int frequency,
unsigned long duration = 0)
override;
172 void noTone(uint32_t pin)
override {
174 multicore_reset_core1();
178 spi_init(_spiChannel, _spiSpeed);
179 spi_set_format(_spiChannel, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
181 gpio_set_function(_sckPin, GPIO_FUNC_SPI);
182 gpio_set_function(_mosiPin, GPIO_FUNC_SPI);
183 gpio_set_function(_misoPin, GPIO_FUNC_SPI);
188 void spiTransfer(uint8_t *out,
size_t len, uint8_t *in) {
189 spi_write_read_blocking(_spiChannel, out, in, len);
192 void yield()
override {
193 tight_loop_contents();
199 spi_deinit(_spiChannel);
204 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...