sx127x_lora

A platform-agnostic driver for Semtech SX1276/77/78/79 based boards. It supports any device that implements the embedded-hal traits. Devices are connected over SPI and require an extra GPIO pin for RESET. This cate works with any Semtech based board including: * Modtronix inAir4, inAir9, and inAir9B * HopeRF RFM95W, RFM96W, and RFM98W

Examples

Raspberry Pi Basic Send

Utilizes a Raspberry Pi to send a message. The example utilizes the linux_embedded_hal crate. ```rust

![feature(externcrateitem_prelude)]

extern crate sx127xlora; extern crate linuxembedded_hal as hal;

use hal::spidev::{self, SpidevOptions}; use hal::{Pin, Spidev}; use hal::sysfs_gpio::Direction; use hal::Delay;

const LORACSPIN: u64 = 8; const LORARESETPIN: u64 = 21; const FREQUENCY: i64 = 915;

fn main(){

let mut spi = Spidev::open("/dev/spidev0.0").unwrap();
let options = SpidevOptions::new()
    .bits_per_word(8)
    .max_speed_hz(20_000)
    .mode(spidev::SPI_MODE_0)
    .build();
spi.configure(&options).unwrap();

let cs = Pin::new(LORA_CS_PIN);
cs.export().unwrap();
cs.set_direction(Direction::Out).unwrap();

let reset = Pin::new(LORA_RESET_PIN);
reset.export().unwrap();
reset.set_direction(Direction::Out).unwrap();

let mut lora = sx127x_lora::LoRa::new(
    spi, cs, reset,  FREQUENCY, Delay)
    .expect("Failed to communicate with radio module!");

lora.set_tx_power(17,1); //Using PA_BOOST. See your board for correct pin.

let message = "Hello, world!";
let mut buffer = [0;255];
for (i,c) in message.chars().enumerate() {
    buffer[i] = c as u8;
}

let transmit = lora.transmit_payload(buffer,message.len());
match transmit {
    Ok(packet_size) => println!("Sent packet with size: {}", packet_size),
    Err(()) => println!("Error"),
}

} ```

STM32F429 Blocking Receive

Utilizes a STM32F429 to receive data using the blocking poll_irq(timeout) function. It prints the received packet back out over semihosting. The example utilizes the stm32f429_hal, cortex_m, and panic_semihosting crates. ```rust

![no_std]

![no_main]

extern crate sx127xlora; extern crate stm32f429hal as hal; extern crate cortexm; extern crate panicsemihosting;

use sx127xlora::MODE; use cortexm_semihosting::*; use hal::gpio::GpioExt; use hal::flash::FlashExt; use hal::rcc::RccExt; use hal::time::MegaHertz; use hal::spi::Spi; use hal::delay::Delay;

const FREQUENCY: i64 = 915;

[entry]

fn main() -> !{ let cp = cortex_m::Peripherals::take().unwrap(); let p = hal::stm32f429::Peripherals::take().unwrap();

let mut rcc = p.RCC.constrain();
let mut flash = p.FLASH.constrain();
let clocks = rcc
    .cfgr
    .sysclk(MegaHertz(64))
    .pclk1(MegaHertz(32))
    .freeze(&mut flash.acr);

let mut gpioa = p.GPIOA.split(&mut rcc.ahb1);
let mut gpiod = p.GPIOD.split(&mut rcc.ahb1);
let mut gpiof = p.GPIOF.split(&mut rcc.ahb1);

let sck = gpioa.pa5.into_af5(&mut gpioa.moder, &mut gpioa.afrl);
let miso = gpioa.pa6.into_af5(&mut gpioa.moder, &mut gpioa.afrl);
let mosi = gpioa.pa7.into_af5(&mut gpioa.moder, &mut gpioa.afrl);
let reset = gpiof.pf13.into_push_pull_output(&mut gpiof.moder, &mut gpiof.otyper);
let cs = gpiod.pd14.into_push_pull_output(&mut gpiod.moder, &mut gpiod.otyper);

let spi = Spi::spi1(
    p.SPI1,
    (sck, miso, mosi),
    MODE,
    MegaHertz(8),
    clocks,
    &mut rcc.apb2,
);

let mut lora = sx127x_lora::LoRa::new(
    spi, cs, reset, FREQUENCY,
    Delay::new(cp.SYST, clocks)).unwrap();

loop {
    let poll = lora.poll_irq(Some(30)); //30 Second timeout
    match poll {
        Ok(size) =>{
           hprint!("with Payload: ");
           let buffer = lora.read_packet(); // Received buffer. NOTE: 255 bytes are always returned
           for i in 0..size{
               hprint!("{}",buffer[i] as char).unwrap();
           }
           hprintln!();
        },
        Err(()) => hprintln!("Timeout").unwrap(),
    }
}

} ```

Interrupts

The crate currently polls the IRQ register on the radio to determine if a new packet has arrived. This would be more efficient if instead an interrupt was connect the the module's DIO_0 pin. Once interrupt support is available in embedded-hal, then this will be added. It is possible to implement this function on a device-to-device basis by retrieving a packet with the read_packet() function.

Contributing

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.