[HAL] Add tones support for the RPi Pico (#1239)

* Add tones support for RPi Pico

* Add dependencies to CMakeLists

* Address review
This commit is contained in:
Ali Mosallaei 2024-09-27 14:26:13 -04:00 committed by GitHub
parent 42ae7c92ed
commit 83e05701fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 60 additions and 5 deletions

View file

@ -23,11 +23,11 @@ add_executable(${PROJECT_NAME}
)
# Pull in common dependencies
target_link_libraries(${PROJECT_NAME} pico_stdlib hardware_spi hardware_gpio hardware_timer RadioLib)
target_link_libraries(${PROJECT_NAME} pico_stdlib hardware_spi hardware_gpio hardware_timer pico_multicore hardware_pwm RadioLib)
pico_enable_stdio_usb(${PROJECT_NAME} 1)
pico_enable_stdio_uart(${PROJECT_NAME} 0)
# Create map/bin/hex file etc.
pico_add_extra_outputs(${PROJECT_NAME})
pico_add_extra_outputs(${PROJECT_NAME})

View file

@ -8,6 +8,45 @@
#include <pico/stdlib.h>
#include "hardware/spi.h"
#include "hardware/timer.h"
#include "hardware/pwm.h"
#include "hardware/clocks.h"
#include "pico/multicore.h"
uint32_t toneLoopPin;
unsigned int toneLoopFrequency;
unsigned long toneLoopDuration;
// pre-calculated pulse-widths for 1200 and 2200Hz
// we do this to save calculation time (see https://github.com/khoih-prog/RP2040_PWM/issues/6)
#define SLEEP_1200 416.666
#define SLEEP_2200 227.272
// === NOTE ===
// The tone(...) implementation uses the second core on the RPi Pico. This is to diminish as much
// jitter in the output tones as possible.
void toneLoop(){
gpio_set_dir(toneLoopPin, GPIO_OUT);
uint32_t sleep_dur;
if (toneLoopFrequency == 1200) {
sleep_dur = SLEEP_1200;
} else if (toneLoopFrequency == 2200) {
sleep_dur = SLEEP_2200;
} else {
sleep_dur = 500000 / toneLoopFrequency;
}
// tone bitbang
while(1){
gpio_put(toneLoopPin, 1);
sleep_us(sleep_dur);
gpio_put(toneLoopPin, 0);
sleep_us(sleep_dur);
tight_loop_contents();
}
}
// create a new Raspberry Pi Pico hardware abstraction
// layer using the Pico SDK
@ -21,8 +60,7 @@ public:
_spiSpeed(spiSpeed),
_misoPin(misoPin),
_mosiPin(mosiPin),
_sckPin(sckPin) {
}
_sckPin(sckPin){}
void init() override {
stdio_init_all();
@ -110,6 +148,19 @@ public:
return (this->micros() - start);
}
void tone(uint32_t pin, unsigned int frequency, unsigned long duration = 0) override {
// tones on the Pico are generated using bitbanging. This process is offloaded to the Pico's second core
multicore_reset_core1();
toneLoopPin = pin;
toneLoopFrequency = frequency;
toneLoopDuration = duration;
multicore_launch_core1(toneLoop);
}
void noTone(uint32_t pin) override {
multicore_reset_core1();
}
void spiBegin() {
spi_init(_spiChannel, _spiSpeed);
spi_set_format(_spiChannel, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
@ -125,6 +176,10 @@ public:
spi_write_read_blocking(_spiChannel, out, in, len);
}
void yield() override {
tight_loop_contents();
}
void spiEndTransaction() {}
void spiEnd() {
@ -140,4 +195,4 @@ private:
uint32_t _sckPin;
};
#endif
#endif