-
Notifications
You must be signed in to change notification settings - Fork 409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
examples: NonArduino: Raspberry Pi Pico #941
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
cmake_minimum_required(VERSION 3.18) | ||
|
||
# Pull in SDK (must be before project) | ||
include(pico_sdk_import.cmake) | ||
|
||
project(pico-sx1276 C CXX ASM) | ||
set(CMAKE_C_STANDARD 11) | ||
set(CMAKE_CXX_STANDARD 17) | ||
|
||
# Initialize the SDK | ||
pico_sdk_init() | ||
|
||
add_compile_options( | ||
-Wall | ||
-Wno-format | ||
-Wno-unused-function | ||
) | ||
|
||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib") | ||
|
||
add_executable(${PROJECT_NAME} | ||
main.cpp | ||
) | ||
|
||
# Pull in common dependencies | ||
target_link_libraries(${PROJECT_NAME} pico_stdlib hardware_spi hardware_gpio hardware_timer 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}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
#ifndef PICO_HAL_H | ||
#define PICO_HAL_H | ||
|
||
// include RadioLib | ||
#include <RadioLib.h> | ||
|
||
// include the necessary Pico libraries | ||
#include <pico/stdlib.h> | ||
#include "hardware/spi.h" | ||
#include "hardware/timer.h" | ||
|
||
// create a new Raspberry Pi Pico hardware abstraction | ||
// layer using the Pico SDK | ||
// the HAL must inherit from the base RadioLibHal class | ||
// and implement all of its virtual methods | ||
class PicoHal : public RadioLibHal { | ||
public: | ||
PicoHal(spi_inst_t *spiChannel, uint32_t misoPin, uint32_t mosiPin, uint32_t sckPin, uint32_t spiSpeed = 500 * 1000) | ||
: RadioLibHal(GPIO_IN, GPIO_OUT, 0, 1, GPIO_IRQ_EDGE_RISE, GPIO_IRQ_EDGE_FALL), | ||
_spiChannel(spiChannel), | ||
_spiSpeed(spiSpeed), | ||
_misoPin(misoPin), | ||
_mosiPin(mosiPin), | ||
_sckPin(sckPin) { | ||
} | ||
|
||
void init() override { | ||
stdio_init_all(); | ||
spiBegin(); | ||
} | ||
|
||
void term() override { | ||
spiEnd(); | ||
} | ||
|
||
// GPIO-related methods (pinMode, digitalWrite etc.) should check | ||
// RADIOLIB_NC as an alias for non-connected pins | ||
void pinMode(uint32_t pin, uint32_t mode) override { | ||
if (pin == RADIOLIB_NC) { | ||
return; | ||
} | ||
|
||
gpio_set_dir(pin, mode); | ||
} | ||
|
||
void digitalWrite(uint32_t pin, uint32_t value) override { | ||
if (pin == RADIOLIB_NC) { | ||
return; | ||
} | ||
|
||
gpio_put(pin, (bool)value); | ||
} | ||
|
||
uint32_t digitalRead(uint32_t pin) override { | ||
if (pin == RADIOLIB_NC) { | ||
return 0; | ||
} | ||
|
||
return gpio_get(pin); | ||
} | ||
|
||
void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override { | ||
if (interruptNum == RADIOLIB_NC) { | ||
return; | ||
} | ||
|
||
gpio_set_irq_enabled_with_callback(interruptNum, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, (gpio_irq_callback_t)interruptCb); | ||
} | ||
|
||
void detachInterrupt(uint32_t interruptNum) override { | ||
if (interruptNum == RADIOLIB_NC) { | ||
return; | ||
} | ||
|
||
gpio_set_irq_enabled_with_callback(interruptNum, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, false, NULL); | ||
} | ||
|
||
void delay(unsigned long ms) override { | ||
sleep_ms(ms); | ||
} | ||
|
||
void delayMicroseconds(unsigned long us) override { | ||
sleep_us(us); | ||
} | ||
|
||
unsigned long millis() override { | ||
return to_ms_since_boot(get_absolute_time()); | ||
} | ||
|
||
unsigned long micros() override { | ||
return to_us_since_boot(get_absolute_time()); | ||
} | ||
|
||
long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override { | ||
if (pin == RADIOLIB_NC) { | ||
return 0; | ||
} | ||
|
||
this->pinMode(pin, GPIO_IN); | ||
uint32_t start = this->micros(); | ||
uint32_t curtick = this->micros(); | ||
|
||
while (this->digitalRead(pin) == state) { | ||
if ((this->micros() - curtick) > timeout) { | ||
return 0; | ||
} | ||
} | ||
|
||
return (this->micros() - start); | ||
} | ||
|
||
void spiBegin() { | ||
spi_init(_spiChannel, _spiSpeed); | ||
spi_set_format(_spiChannel, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST); | ||
|
||
gpio_set_function(_sckPin, GPIO_FUNC_SPI); | ||
gpio_set_function(_mosiPin, GPIO_FUNC_SPI); | ||
gpio_set_function(_misoPin, GPIO_FUNC_SPI); | ||
} | ||
|
||
void spiBeginTransaction() {} | ||
|
||
void spiTransfer(uint8_t *out, size_t len, uint8_t *in) { | ||
spi_write_read_blocking(_spiChannel, out, in, len); | ||
} | ||
|
||
void spiEndTransaction() {} | ||
|
||
void spiEnd() { | ||
spi_deinit(_spiChannel); | ||
} | ||
|
||
private: | ||
// the HAL can contain any additional private members | ||
spi_inst_t *_spiChannel; | ||
uint32_t _spiSpeed; | ||
uint32_t _misoPin; | ||
uint32_t _mosiPin; | ||
uint32_t _sckPin; | ||
}; | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
RadioLib Non-Arduino Raspberry Pi Pico library example | ||
|
||
Licensed under the MIT License | ||
|
||
Copyright (c) 2024 Cameron Goddard | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
*/ | ||
|
||
// define pins to be used | ||
#define SPI_PORT spi0 | ||
#define SPI_MISO 4 | ||
#define SPI_MOSI 3 | ||
#define SPI_SCK 2 | ||
|
||
#define RFM_NSS 26 | ||
#define RFM_RST 22 | ||
#define RFM_DIO0 14 | ||
#define RFM_DIO1 15 | ||
|
||
#include <pico/stdlib.h> | ||
|
||
// include the library | ||
#include <RadioLib.h> | ||
|
||
// include the hardware abstraction layer | ||
#include "PicoHal.h" | ||
|
||
// create a new instance of the HAL class | ||
PicoHal* hal = new PicoHal(SPI_PORT, SPI_MISO, SPI_MOSI, SPI_SCK); | ||
|
||
// now we can create the radio module | ||
// NSS pin: 26 | ||
// DIO0 pin: 14 | ||
// RESET pin: 22 | ||
// DIO1 pin: 15 | ||
SX1276 radio = new Module(hal, RFM_NSS, RFM_DIO0, RFM_RST, RFM_DIO1); | ||
|
||
|
||
int main() { | ||
stdio_init_all(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's probably not needed to call this here, as |
||
|
||
gpio_init(RFM_NSS); | ||
gpio_init(RFM_RST); | ||
|
||
gpio_set_dir(RFM_NSS, GPIO_OUT); | ||
gpio_set_dir(RFM_RST, GPIO_OUT); | ||
Comment on lines
+60
to
+64
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pin direction configuration is handled by the library. However, if it requires a call to |
||
|
||
// reset the RF module | ||
|
||
sleep_ms(10); | ||
gpio_put(RFM_RST, 0); | ||
sleep_ms(10); | ||
gpio_put(RFM_RST, 1); | ||
Comment on lines
+66
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, this is not needed, the module will be reset during Just trying to remove the redundant portions of code ;) |
||
|
||
// initialize just like with Arduino | ||
printf("[SX1276] Initializing ... "); | ||
int state = radio.begin(); | ||
if (state != RADIOLIB_ERR_NONE) { | ||
printf("failed, code %d\n", state); | ||
return(1); | ||
} | ||
printf("success!\n"); | ||
|
||
// loop forever | ||
for(;;) { | ||
// send a packet | ||
printf("[SX1276] Transmitting packet ... "); | ||
state = radio.transmit("Hello World!"); | ||
if(state == RADIOLIB_ERR_NONE) { | ||
// the packet was successfully transmitted | ||
printf("success!\n"); | ||
|
||
// wait for a second before transmitting again | ||
hal->delay(1000); | ||
|
||
} else { | ||
printf("failed, code %d\n", state); | ||
|
||
} | ||
|
||
} | ||
|
||
return(0); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake | ||
|
||
# This can be dropped into an external project to help locate this SDK | ||
# It should be include()ed prior to project() | ||
|
||
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) | ||
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) | ||
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") | ||
endif () | ||
|
||
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) | ||
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) | ||
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") | ||
endif () | ||
|
||
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) | ||
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) | ||
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") | ||
endif () | ||
|
||
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") | ||
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") | ||
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") | ||
|
||
if (NOT PICO_SDK_PATH) | ||
if (PICO_SDK_FETCH_FROM_GIT) | ||
include(FetchContent) | ||
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) | ||
if (PICO_SDK_FETCH_FROM_GIT_PATH) | ||
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") | ||
endif () | ||
# GIT_SUBMODULES_RECURSE was added in 3.17 | ||
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") | ||
FetchContent_Declare( | ||
pico_sdk | ||
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk | ||
GIT_TAG master | ||
GIT_SUBMODULES_RECURSE FALSE | ||
) | ||
else () | ||
FetchContent_Declare( | ||
pico_sdk | ||
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk | ||
GIT_TAG master | ||
) | ||
endif () | ||
|
||
if (NOT pico_sdk) | ||
message("Downloading Raspberry Pi Pico SDK") | ||
FetchContent_Populate(pico_sdk) | ||
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) | ||
endif () | ||
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) | ||
else () | ||
message(FATAL_ERROR | ||
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." | ||
) | ||
endif () | ||
endif () | ||
|
||
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") | ||
if (NOT EXISTS ${PICO_SDK_PATH}) | ||
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") | ||
endif () | ||
|
||
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) | ||
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) | ||
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") | ||
endif () | ||
|
||
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) | ||
|
||
include(${PICO_SDK_INIT_CMAKE_FILE}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default SPI speed is quite low (500 kHz vs 2 MHz in Arduino). Is there a specific reason for that? Asking because of #938.