Skip to content

Commit

Permalink
Example of emulation of Nordic NRF905 silicon by Semtech SX1276. Nord…
Browse files Browse the repository at this point in the history
…ic radio settings does match typical FLARM session
  • Loading branch information
lyusupov committed Apr 25, 2017
1 parent 383657e commit f327d09
Show file tree
Hide file tree
Showing 8 changed files with 769 additions and 57 deletions.
7 changes: 5 additions & 2 deletions examples/raspi/raw/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# http://www.airspayce.com/mikem/bcm2835/

CC = g++
CFLAGS = -std=c++11 -DRASPBERRY_PI -DBCM2835_NO_DELAY_COMPATIBILITY -D__BASEFILE__=\"$*\"
CFLAGS = -g -std=c++11 -DRASPBERRY_PI -DBCM2835_NO_DELAY_COMPATIBILITY -D__BASEFILE__=\"$*\"
LIBS = -lbcm2835
LMICBASE = ../../../src
INCLUDE = -I$(LMICBASE)
Expand All @@ -17,6 +17,9 @@ raspi.o: $(LMICBASE)/raspi/raspi.cpp
radio.o: $(LMICBASE)/lmic/radio.c
$(CC) $(CFLAGS) -c $(LMICBASE)/lmic/radio.c $(INCLUDE)

lib_crc.o: lib_crc.c
$(CC) $(CFLAGS) -c $(INCLUDE) $<

oslmic.o: $(LMICBASE)/lmic/oslmic.c
$(CC) $(CFLAGS) -c $(LMICBASE)/lmic/oslmic.c $(INCLUDE)

Expand All @@ -32,7 +35,7 @@ aes.o: $(LMICBASE)/aes/lmic.c
raw.o: raw.cpp
$(CC) $(CFLAGS) -c $(INCLUDE) $<

raw: raw.o raspi.o radio.o oslmic.o lmic.o hal.o aes.o
raw: raw.o raspi.o radio.o lib_crc.o oslmic.o lmic.o hal.o aes.o
$(CC) $^ $(LIBS) -o raw

clean:
Expand Down
459 changes: 459 additions & 0 deletions examples/raspi/raw/lib_crc.c

Large diffs are not rendered by default.

66 changes: 66 additions & 0 deletions examples/raspi/raw/lib_crc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*******************************************************************\
* *
* Library : lib_crc *
* File : lib_crc.h *
* Author : Lammert Bies 1999-2008 *
* E-mail : info@lammertbies.nl *
* Language : ANSI C *
* *
* *
* Description *
* =========== *
* *
* The file lib_crc.h contains public definitions and proto- *
* types for the CRC functions present in lib_crc.c. *
* *
* *
* Dependencies *
* ============ *
* *
* none *
* *
* *
* Modification history *
* ==================== *
* *
* Date Version Comment *
* *
* 2008-04-20 1.16 Added CRC-CCITT routine for Kermit *
* *
* 2007-04-01 1.15 Added CRC16 calculation for Modbus *
* *
* 2007-03-28 1.14 Added CRC16 routine for Sick devices *
* *
* 2005-12-17 1.13 Added CRC-CCITT with initial 0x1D0F *
* *
* 2005-02-14 1.12 Added CRC-CCITT with initial 0x0000 *
* *
* 2005-02-05 1.11 Fixed bug in CRC-DNP routine *
* *
* 2005-02-04 1.10 Added CRC-DNP routines *
* *
* 2005-01-07 1.02 Changes in tst_crc.c *
* *
* 1999-02-21 1.01 Added FALSE and TRUE mnemonics *
* *
* 1999-01-22 1.00 Initial source *
* *
\*******************************************************************/



#define CRC_VERSION "1.16"



#define FALSE 0
#define TRUE 1



unsigned short update_crc_16( unsigned short crc, char c );
unsigned long update_crc_32( unsigned long crc, char c );
unsigned short update_crc_ccitt( unsigned short crc, char c );
unsigned short update_crc_dnp( unsigned short crc, char c );
unsigned short update_crc_kermit( unsigned short crc, char c );
unsigned short update_crc_sick( unsigned short crc, char c, char prev_byte );
105 changes: 87 additions & 18 deletions examples/raspi/raw/raw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <lmic.h>
#include <hal/hal.h>
#include "lib_crc.h"

#if !defined(DISABLE_INVERT_IQ_ON_RX)
#error This example requires DISABLE_INVERT_IQ_ON_RX to be set. Update \
Expand All @@ -26,16 +27,26 @@
// this interval should not also be increased.
// See this spreadsheet for an easy airtime and duty cycle calculator:
// https://docs.google.com/spreadsheets/d/1voGAtQAjC1qBmaVuP1ApNKs1ekgUjavHuVQIXyYSvNc
#define TX_INTERVAL 2000
#define TX_INTERVAL 1000 /* 2000 */

// Dragino Raspberry PI hat (no onboard led)
// see https://github.com/dragino/Lora
#define RF_CS_PIN RPI_V2_GPIO_P1_22 // Slave Select on GPIO25 so P1 connector pin #22
#define RF_IRQ_PIN RPI_V2_GPIO_P1_07 // IRQ on GPIO4 so P1 connector pin #7
#define RF_RST_PIN RPI_V2_GPIO_P1_11 // Reset on GPIO17 so P1 connector pin #11

// Pin mapping
const lmic_pinmap lmic_pins = {
.nss = 6,
const lmic_pinmap lmic_pins = {
.nss = RF_CS_PIN,
.rxtx = LMIC_UNUSED_PIN,
.rst = 5,
.dio = {2, 3, 4},
.rst = RF_RST_PIN,
.dio = {RF_IRQ_PIN, LMIC_UNUSED_PIN, LMIC_UNUSED_PIN},
};

#ifndef RF_LED_PIN
#define RF_LED_PIN NOT_A_PIN
#endif


// These callbacks are only used in over-the-air activation, so they are
// left empty here (we cannot leave them out completely unless
Expand All @@ -53,11 +64,32 @@ static void tx_func (osjob_t* job);

// Transmit the given string and call the given function afterwards
void tx(const char *str, osjobcb_t func) {
u2_t crc16 = 0xffff; /* seed value */

os_radio(RADIO_RST); // Stop RX first
delay(1); // Wait a bit, without this os_radio below asserts, apparently because the state hasn't changed yet

LMIC.dataLen = 0;
while (*str)
LMIC.frame[LMIC.dataLen++] = *str++;

LMIC.frame[LMIC.dataLen] = 0x31;
crc16 = update_crc_ccitt(crc16, LMIC.frame[LMIC.dataLen++]);
LMIC.frame[LMIC.dataLen] = 0xFA;
crc16 = update_crc_ccitt(crc16, LMIC.frame[LMIC.dataLen++]);
LMIC.frame[LMIC.dataLen] = 0xB6;
crc16 = update_crc_ccitt(crc16, LMIC.frame[LMIC.dataLen++]);

// printf("crc16: ");
while (*str) {
LMIC.frame[LMIC.dataLen] = *str++;
// printf("%02x", (u1_t)(LMIC.frame[LMIC.dataLen]));
crc16 = update_crc_ccitt(crc16, (u1_t)(LMIC.frame[LMIC.dataLen]));
LMIC.dataLen++;
}
// printf(" : %x\n", crc16);

LMIC.frame[LMIC.dataLen++] = (crc16 >> 8) & 0xFF;
LMIC.frame[LMIC.dataLen++] = (crc16 ) & 0xFF;

LMIC.osjob.func = func;
os_radio(RADIO_TX);
Serial.println("TX");
Expand All @@ -69,7 +101,7 @@ void rx(osjobcb_t func) {
LMIC.rxtime = os_getTime(); // RX _now_
// Enable "continuous" RX (e.g. without a timeout, still stops after
// receiving a packet)
os_radio(RADIO_RXON);
os_radio(RADIO_RX /* RADIO_RXON */);
Serial.println("RX");
}

Expand All @@ -78,6 +110,10 @@ static void rxtimeout_func(osjob_t *job) {
}

static void rx_func (osjob_t* job) {

u2_t crc16 = 0xffff; /* seed value */
u1_t i;

// Blink once to confirm reception and then keep the led on
digitalWrite(LED_BUILTIN, LOW); // off
delay(10);
Expand All @@ -93,64 +129,97 @@ static void rx_func (osjob_t* job) {
Serial.print("Got ");
Serial.print(LMIC.dataLen);
Serial.println(" bytes");
Serial.write(LMIC.frame, LMIC.dataLen);
Serial.println();

u4_t address = (LMIC.frame[0] << 16) | (LMIC.frame[1] << 8) | LMIC.frame[2] ;
if (address == 0x31FAB6)
{

for (i=0; i<(LMIC.dataLen-2); i++)
{
printf("%02x", (u1_t)(LMIC.frame[i]));
crc16 = update_crc_ccitt(crc16, (u1_t)(LMIC.frame[i]));
}
u2_t pkt_crc = (LMIC.frame[i] << 8 | LMIC.frame[i+1]);
if (crc16 == pkt_crc ) {
printf(" %04x is valid crc", pkt_crc);
} else {
printf(" %04x is wrong crc", pkt_crc);
}

} else {
printf(" %06x is wrong address", address);
}
Serial.println();

// Restart RX
rx(rx_func);
}

static void txdone_func (osjob_t* job) {
// printf("txdone_func\n");
rx(rx_func);
}

// log text to USART and toggle LED
static void tx_func (osjob_t* job) {
// say hello
tx("Hello, world!", txdone_func);
//tx("Hello, world!", txdone_func);
tx("\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001", txdone_func);
// reschedule job every TX_INTERVAL (plus a bit of random to prevent
// systematic collisions), unless packets are received, then rx_func
// will reschedule at half this time.
os_setTimedCallback(job, os_getTime() + ms2osticks(TX_INTERVAL + random(500)), tx_func);
}

// application entry point
void setup() {
int setup() {
printf("Starting\n");

// Init GPIO bcm
if (!bcm2835_init()) {
fprintf( stderr, "bcm2835_init() Failed\n\n" );
return 1;
}
// printf("Starting 1\n");
pinMode(LED_BUILTIN, OUTPUT);

// initialize runtime env
os_init();

// printf("Starting 2\n");
// Set up these settings once, and use them for both TX and RX

#if defined(CFG_eu868)
// Use a frequency in the g3 which allows 10% duty cycling.
LMIC.freq = 869525000;
LMIC.freq = 868400000;
#elif defined(CFG_us915)
LMIC.freq = 902300000;
#endif

// Maximum TX power
LMIC.txpow = 27;
LMIC.txpow = 5;
// Use a medium spread factor. This can be increased up to SF12 for
// better range, but then the interval should be (significantly)
// lowered to comply with duty cycle limits as well.
LMIC.datarate = DR_SF9;
LMIC.datarate = DR_FSK /* DR_SF9 */ ;
//LMIC.datarate = DR_SF9 ;
// This sets CR 4/5, BW125 (except for DR_SF7B, which uses BW250)
LMIC.rps = updr2rps(LMIC.datarate);

printf("Started\n");

// setup initial job
os_setCallback(&txjob, tx_func);

return 0;
}

int main(void) {

setup();

if (setup())
return 1;

printf("Loop\n");

while(1) {
// execute scheduled jobs and events
os_runloop_once();
Expand Down
2 changes: 1 addition & 1 deletion examples/raspi/spi_scan/spi_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ int main(int argc, char **argv)
} else {
// List of all CS line where module can be connected
// GPIO6, GPIO8/CE0, GPIO7/CE1, GPIO26
uint8_t CS_pins[] = {6, 7, 8, 26};
uint8_t CS_pins[] = {6, 7, 8, 25};
uint8_t i;

// Init SPI
Expand Down
2 changes: 1 addition & 1 deletion src/lmic/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
// hear gateways). This should probably only be used when debugging
// and/or when talking to the radio directly (e.g. like in the "raw"
// example).
//#define DISABLE_INVERT_IQ_ON_RX
#define DISABLE_INVERT_IQ_ON_RX

// This allows choosing between multiple included AES implementations.
// Make sure exactly one of these is uncommented.
Expand Down
7 changes: 5 additions & 2 deletions src/lmic/oslmic.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ static struct {
void os_init () {
memset(&OS, 0x00, sizeof(OS));
hal_init();
//printf("1 ***\n");
radio_init();
//printf("2 ***\n");
LMIC_init();
//printf("3 ***\n");
}

ostime_t os_getTime () {
Expand Down Expand Up @@ -103,7 +106,7 @@ void os_runloop_once() {
hal_sleep(); // wake by irq (timer already restarted)
}
hal_enableIRQs();
if(j) { // run job callback
j->func(j);
if(j && j->func) { // run job callback
j->func(j);
}
}
Loading

0 comments on commit f327d09

Please sign in to comment.