diff --git a/src/energenie/build b/src/energenie/build deleted file mode 100755 index d8405e8..0000000 --- a/src/energenie/build +++ /dev/null @@ -1,41 +0,0 @@ -#! /bin/bash - - -# build gpio_test -gcc gpio_test.c gpio.c -mv a.out gpio_test -chmod u+x gpio_test - - -# build spis_test (soft SPI tester) -gcc spi_test.c spis.c gpio.c -mv a.out spis_test -chmod u+x spis_test - -# build spih_test (hard SPI tester) -gcc spi_test.c spih.c gpio.c -mv a.out spih_test -chmod u+x spish_test - - -# build hrf69_test -## gcc hrf69_test.c hrf69.c spis.c gpio.c -## mv a.out hrf69_test -## chmod u+x hrf69_test - - -# build radio_test -## gcc radio_test.c radio.c hrf69.c spis.c gpio.c -## mv a.out radio_test -## chmod u+x radio_test - - -# build spi .so library on Raspberry Pi -gcc -Wall -shared -o spi_rpi.so -fPIC spis.c gpio.c -# nm -D spi_rpi.so - -# radio spi .so library on Raspberry Pi -## gcc -Wall -shared -o radio_rpi.so -fPIC radio.c hrf69.c spis.c gpio.c -## nm -D spi_rpi.so - -# END diff --git a/src/energenie/drv/build b/src/energenie/drv/build new file mode 100755 index 0000000..5979933 --- /dev/null +++ b/src/energenie/drv/build @@ -0,0 +1,43 @@ +#! /bin/bash + + +# build gpio_test +gcc gpio_test.c gpio.c +mv a.out gpio_test +chmod u+x gpio_test + + +# build spis_test (soft SPI tester) +gcc spi_test.c spis.c gpio.c +mv a.out spis_test +chmod u+x spis_test + +# build spih_test (hard SPI tester) +gcc spi_test.c spih.c gpio.c +mv a.out spih_test +chmod u+x spish_test + + +# build hrf69_test +## gcc hrf69_test.c hrf69.c spis.c gpio.c +## mv a.out hrf69_test +## chmod u+x hrf69_test + + +# build radio_test +## gcc radio_test.c radio.c hrf69.c spis.c gpio.c +## mv a.out radio_test +## chmod u+x radio_test + + +# build spi .so library on Raspberry Pi +gcc -Wall -shared -o spi_rpi.so -fPIC spis.c gpio.c +# nm -D spi_rpi.so +cp spi_rpi.so .. + +# radio spi .so library on Raspberry Pi +## gcc -Wall -shared -o radio_rpi.so -fPIC radio.c hrf69.c spis.c gpio.c +## nm -D radio_rpi.so +## cp radio_rpi.so .. + +# END diff --git a/src/energenie/drv/gpio.c b/src/energenie/drv/gpio.c new file mode 100644 index 0000000..7d9a144 --- /dev/null +++ b/src/energenie/drv/gpio.c @@ -0,0 +1,182 @@ +/* gpio.c D.J.Whale 8/07/2014 + * + * A very simple interface to the GPIO port on the Raspberry Pi. + */ + +/***** INCLUDES *****/ + +#include +#include +#include +#include +#include +#include +#include + +#include "gpio.h" + + +/***** CONFIGURATION *****/ + +/* uncomment to make this a simulated driver */ +//#define GPIO_SIMULATED + + +/***** CONSTANTS *****/ + +#define BCM2708_PERI_BASE 0x20000000 +//#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ +#define GPIO_BASE_OFFSET 0x200000 + +#define PAGE_SIZE (4*1024) +#define BLOCK_SIZE (4*1024) + + +/***** VARIABLES *****/ + +static int mem_fd; +static void *gpio_map; + +static volatile unsigned *gpio; + + +/****** MACROS *****/ + +#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) +#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) +#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) + +#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0 +#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0 + +#define GPIO_READ(g) ((*(gpio+13)&(1< +#include + +#include "gpio.h" + +static void delay(struct timespec time) +{ + nanosleep(&time, NULL); +} + +static struct timespec delay_1sec = {1, 0}; + + +void main(void) +{ + int i; + + gpio_init(); + gpio_setout(2); + gpio_setout(3); + + for (i=0; i<10; i++) + { + puts("GPIO 2"); + gpio_write(2, 1); + delay(delay_1sec); + gpio_write(2, 0); + delay(delay_1sec); + + puts("GPIO 3"); + gpio_write(3, 1); + delay(delay_1sec); + gpio_write(3, 0); + delay(delay_1sec); + } +} diff --git a/src/energenie/drv/hrf69.c b/src/energenie/drv/hrf69.c new file mode 100644 index 0000000..652ff47 --- /dev/null +++ b/src/energenie/drv/hrf69.c @@ -0,0 +1,51 @@ +/* hrf69.c 03/04/2016 D.J.Whale + * + * Hope RF RFM69 radio controller code. + */ + +//import spi + +//def warning(msg): +// print("warning:" + str(msg)) + +//def trace(msg): +// print(str(msg)) + + +//def ashex(p): +// line = "" +// for b in p: +// line += str(hex(b)) + " " +// return line + + +//def HRF_writereg(addr, data): + +//def HRF_readreg(addr): + +//def HRF_writefifo_burst(buf): + +//def HRF_readfifo_burst(): + +//def HRF_checkreg(addr, mask, value): + +//def HRF_pollreg(addr, mask, value): + +//def HRF_wait_ready(): + +//def HRF_wait_txready(): + +//def HRF_change_mode(mode): + +//def HRF_clear_fifo(): + +//def HRF_check_payload(): + +//def HRF_receive_payload(): + +//def HRF_send_payload(payload): + +//def HRF_config(config): + + +//# END diff --git a/src/energenie/drv/hrf69.h b/src/energenie/drv/hrf69.h new file mode 100644 index 0000000..f17242a --- /dev/null +++ b/src/energenie/drv/hrf69.h @@ -0,0 +1,144 @@ +/* hrf69.h 03/04/2016 D.J.Whale + * + * Interface for HopeRF RFM69 radio + */ + +//# Precise register descriptions can be found in: +//# www.hoperf.com/upload/rf/RFM69W-V1.3.pdf +//# on page 63 - 74 + +#ifndef _HRF69_H +#define _HRF69_H + +typedef uint8_t HRF_RESULT; + +typedef struct +{ + uint8_t addr; + uint8_t value; +} HRF_CONFIG_REC; + + +// Register addresses +#define HRF_ADDR_FIFO = 0x00 +#define HRF_ADDR_OPMODE = 0x01 +#define HRF_ADDR_REGDATAMODUL = 0x02 +#define HRF_ADDR_BITRATEMSB = 0x03 +#define HRF_ADDR_BITRATELSB = 0x04 +#define HRF_ADDR_FDEVMSB = 0x05 +#define HRF_ADDR_FDEVLSB = 0x06 +#define HRF_ADDR_FRMSB = 0x07 +#define HRF_ADDR_FRMID = 0x08 +#define HRF_ADDR_FRLSB = 0x09 +#define HRF_ADDR_AFCCTRL = 0x0B +#define HRF_ADDR_LNA = 0x18 +#define HRF_ADDR_RXBW = 0x19 +#define HRF_ADDR_AFCFEI = 0x1E +#define HRF_ADDR_IRQFLAGS1 = 0x27 +#define HRF_ADDR_IRQFLAGS2 = 0x28 +#define HRF_ADDR_RSSITHRESH = 0x29 +#define HRF_ADDR_PREAMBLELSB = 0x2D +#define HRF_ADDR_SYNCCONFIG = 0x2E +#define HRF_ADDR_SYNCVALUE1 = 0x2F +#define HRF_ADDR_SYNCVALUE2 = 0x30 +#define HRF_ADDR_SYNCVALUE3 = 0x31 +#define HRF_ADDR_SYNCVALUE4 = 0x32 +#define HRF_ADDR_PACKETCONFIG1 = 0x37 +#define HRF_ADDR_PAYLOADLEN = 0x38 +#define HRF_ADDR_NODEADDRESS = 0x39 +#define HRF_ADDR_FIFOTHRESH = 0x3C + +// Masks to set and clear bits +#define HRF_MASK_REGDATAMODUL_OOK = 0x08 +#define HRF_MASK_REGDATAMODUL_FSK = 0x00 +#define HRF_MASK_WRITE_DATA = 0x80 +#define HRF_MASK_MODEREADY = 0x80 +#define HRF_MASK_FIFONOTEMPTY = 0x40 +#define HRF_MASK_FIFOLEVEL = 0x20 +#define HRF_MASK_FIFOOVERRUN = 0x10 +#define HRF_MASK_PACKETSENT = 0x08 +#define HRF_MASK_TXREADY = 0x20 +#define HRF_MASK_PACKETMODE = 0x60 +#define HRF_MASK_MODULATION = 0x18 +#define HRF_MASK_PAYLOADRDY = 0x04 + +// Radio modes +#define HRF_MODE_STANDBY = 0x04 // Standby +#define HRF_MODE_TRANSMITER = 0x0C // Transmiter +#define HRF_MODE_RECEIVER = 0x10 // Receiver + +// Values to store in registers +//TODO some of these are energenie radio config specific + +#define HRF_VAL_REGDATAMODUL_FSK = 0x00 // Modulation scheme FSK +#define HRF_VAL_REGDATAMODUL_OOK = 0x08 // Modulation scheme OOK +#define HRF_VAL_FDEVMSB30 = 0x01 // frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC +#define HRF_VAL_FDEVLSB30 = 0xEC // frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC +#define HRF_VAL_FRMSB434 = 0x6C // carrier freq -> 434.3MHz 0x6C9333 +#define HRF_VAL_FRMID434 = 0x93 // carrier freq -> 434.3MHz 0x6C9333 +#define HRF_VAL_FRLSB434 = 0x33 // carrier freq -> 434.3MHz 0x6C9333 +#define HRF_VAL_FRMSB433 = 0x6C // carrier freq -> 433.92MHz 0x6C7AE1 +#define HRF_VAL_FRMID433 = 0x7A // carrier freq -> 433.92MHz 0x6C7AE1 +#define HRF_VAL_FRLSB433 = 0xE1 // carrier freq -> 433.92MHz 0x6C7AE1 +#define HRF_VAL_AFCCTRLS = 0x00 // standard AFC routine +#define HRF_VAL_AFCCTRLI = 0x20 // improved AFC routine +#define HRF_VAL_LNA50 = 0x08 // LNA input impedance 50 ohms +#define HRF_VAL_LNA50G = 0x0E // LNA input impedance 50 ohms, LNA gain -> 48db +#define HRF_VAL_LNA200 = 0x88 // LNA input impedance 200 ohms +#define HRF_VAL_RXBW60 = 0x43 // channel filter bandwidth 10kHz -> 60kHz page:26 +#define HRF_VAL_RXBW120 = 0x41 // channel filter bandwidth 120kHz +#define HRF_VAL_AFCFEIRX = 0x04 // AFC is performed each time RX mode is entered + +//TODO: These might be energenie config specific +#define HRF_VAL_RSSITHRESH220 = 0xDC // RSSI threshold 0xE4 -> 0xDC (220) +#define HRF_VAL_PREAMBLELSB3 = 0x03 // preamble size LSB 3 +#define HRF_VAL_PREAMBLELSB5 = 0x05 // preamble size LSB 5 +#define HRF_VAL_SYNCCONFIG2 = 0x88 // Size of the Synch word = 2 (SyncSize + 1) +#define HRF_VAL_SYNCCONFIG4 = 0x98 // Size of the Synch word = 4 (SyncSize + 1) +#define HRF_VAL_SYNCVALUE1FSK = 0x2D // 1st byte of Sync word +#define HRF_VAL_SYNCVALUE2FSK = 0xD4 // 2nd byte of Sync word +#define HRF_VAL_SYNCVALUE1OOK = 0x80 // 1nd byte of Sync word +#define HRF_VAL_PACKETCONFIG1FSK = 0xA2 // Variable length, Manchester coding, Addr must match NodeAddress +#define HRF_VAL_PACKETCONFIG1FSKNO = 0xA0 // Variable length, Manchester coding +#define HRF_VAL_PACKETCONFIG1OOK = 0 // Fixed length, no Manchester coding +#define HRF_VAL_PAYLOADLEN255 = 0xFF // max Length in RX, not used in Tx +#define HRF_VAL_PAYLOADLEN66 = 66 // max Length in RX, not used in Tx +#define HRF_VAL_PAYLOADLEN_OOK = (13 + 8 * 17) // Payload Length +#define HRF_VAL_NODEADDRESS01 = 0x01 // Node address used in address filtering +#define HRF_VAL_NODEADDRESS04 = 0x04 // Node address used in address filtering +#define HRF_VAL_FIFOTHRESH1 = 0x81 // Condition to start packet transmission: at least one byte in FIFO +#define HRF_VAL_FIFOTHRESH30 = 0x1E // Condition to start packet transmission: wait for 30 bytes in FIFO + + +extern void HRF_writereg(uint8_t addr, uint8_t data); + +extern uint8_t HRF_readreg(uint8_t addr); + +extern void HRF_writefifo_burst(uint8_t* buf uint8_t len); + +extern uint8_t* HRF_readfifo_burst(void); + +extern HRF_RESULT HRF_checkreg(uint8_t addr, uint8_t mask, uint8_t value); + +extern void HRF_pollreg(uint8_t addr, uint8_t mask, uint8_t value); + +extern void HRF_wait_ready(void); + +extern void HRF_wait_txready(void); + +extern void HRF_change_mode(uint8_t mode); + +extern void HRF_clear_fifo(void); + +extern HRF_RESULT HRF_check_payload(void); + +extern uint8_t* HRF_receive_payload(void); + +extern void HRF_send_payload(uint8_t* payload, uint8_t len); + +extern void HRF_config(HRF_CONFIG_REC* config, uint8_t len); + +#endif + +/***** END OF FILE *****/ + diff --git a/src/energenie/drv/hrf69_test.c b/src/energenie/drv/hrf69_test.c new file mode 100644 index 0000000..2e62d03 --- /dev/null +++ b/src/energenie/drv/hrf69_test.c @@ -0,0 +1,24 @@ +/* hrf69_test.c D.J.Whale 03/04/2016 + * + * A simple exerciser for the HopeRF RFM69 radio + */ + + +/***** INCLUDES *****/ + +//#include +//#include +//#include "gpio.h" +//#include "spi.h" + + +/***** CONSTANTS *****/ + +int main(int argc, char **argv) +{ + //TODO + return 0; +} + + +/***** END OF FILE *****/ diff --git a/src/energenie/drv/radio.c b/src/energenie/drv/radio.c new file mode 100644 index 0000000..93310fe --- /dev/null +++ b/src/energenie/drv/radio.c @@ -0,0 +1,451 @@ +//TODO + +# test1.py 26/09/2015 D.J.Whale +# +# Simple low level test of the HopeRF interface +# Uses direct SPI commands to exercise the interface. +# +# Receives and dumps payload buffers. +# +# Eventually a lot of this will be pushed into a separate module, +# and then pushed back into C once it is proved working. + +import spi + +def warning(msg): + print("warning:" + str(msg)) + +def trace(msg): + print(str(msg)) + + +def ashex(p): + line = "" + for b in p: + line += str(hex(b)) + " " + return line + + +#----- HOPERF REGISTER INTERFACE ---------------------------------------------- +# Precise register descriptions can be found in: +# www.hoperf.com/upload/rf/RFM69W-V1.3.pdf +# on page 63 - 74 + +ADDR_FIFO = 0x00 +ADDR_OPMODE = 0x01 +ADDR_REGDATAMODUL = 0x02 +ADDR_BITRATEMSB = 0x03 +ADDR_BITRATELSB = 0x04 +ADDR_FDEVMSB = 0x05 +ADDR_FDEVLSB = 0x06 +ADDR_FRMSB = 0x07 +ADDR_FRMID = 0x08 +ADDR_FRLSB = 0x09 +ADDR_AFCCTRL = 0x0B +ADDR_LNA = 0x18 +ADDR_RXBW = 0x19 +ADDR_AFCFEI = 0x1E +ADDR_IRQFLAGS1 = 0x27 +ADDR_IRQFLAGS2 = 0x28 +ADDR_RSSITHRESH = 0x29 +ADDR_PREAMBLELSB = 0x2D +ADDR_SYNCCONFIG = 0x2E +ADDR_SYNCVALUE1 = 0x2F +ADDR_SYNCVALUE2 = 0x30 +ADDR_SYNCVALUE3 = 0x31 +ADDR_SYNCVALUE4 = 0x32 +ADDR_PACKETCONFIG1 = 0x37 +ADDR_PAYLOADLEN = 0x38 +ADDR_NODEADDRESS = 0x39 +ADDR_FIFOTHRESH = 0x3C + +# HopeRF masks to set and clear bits +MASK_REGDATAMODUL_OOK = 0x08 +MASK_REGDATAMODUL_FSK = 0x00 +MASK_WRITE_DATA = 0x80 +MASK_MODEREADY = 0x80 +MASK_FIFONOTEMPTY = 0x40 +MASK_FIFOLEVEL = 0x20 +MASK_FIFOOVERRUN = 0x10 +MASK_PACKETSENT = 0x08 +MASK_TXREADY = 0x20 +MASK_PACKETMODE = 0x60 +MASK_MODULATION = 0x18 +MASK_PAYLOADRDY = 0x04 + +MODE_STANDBY = 0x04 # Standby +MODE_TRANSMITER = 0x0C # Transmiter +MODE_RECEIVER = 0x10 # Receiver +VAL_REGDATAMODUL_FSK = 0x00 # Modulation scheme FSK +VAL_REGDATAMODUL_OOK = 0x08 # Modulation scheme OOK +VAL_FDEVMSB30 = 0x01 # frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC +VAL_FDEVLSB30 = 0xEC # frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC +VAL_FRMSB434 = 0x6C # carrier freq -> 434.3MHz 0x6C9333 +VAL_FRMID434 = 0x93 # carrier freq -> 434.3MHz 0x6C9333 +VAL_FRLSB434 = 0x33 # carrier freq -> 434.3MHz 0x6C9333 +VAL_FRMSB433 = 0x6C # carrier freq -> 433.92MHz 0x6C7AE1 +VAL_FRMID433 = 0x7A # carrier freq -> 433.92MHz 0x6C7AE1 +VAL_FRLSB433 = 0xE1 # carrier freq -> 433.92MHz 0x6C7AE1 +VAL_AFCCTRLS = 0x00 # standard AFC routine +VAL_AFCCTRLI = 0x20 # improved AFC routine +VAL_LNA50 = 0x08 # LNA input impedance 50 ohms +VAL_LNA50G = 0x0E # LNA input impedance 50 ohms, LNA gain -> 48db +VAL_LNA200 = 0x88 # LNA input impedance 200 ohms +VAL_RXBW60 = 0x43 # channel filter bandwidth 10kHz -> 60kHz page:26 +VAL_RXBW120 = 0x41 # channel filter bandwidth 120kHz +VAL_AFCFEIRX = 0x04 # AFC is performed each time RX mode is entered +VAL_RSSITHRESH220 = 0xDC # RSSI threshold 0xE4 -> 0xDC (220) +VAL_PREAMBLELSB3 = 0x03 # preamble size LSB 3 +VAL_PREAMBLELSB5 = 0x05 # preamble size LSB 5 +VAL_SYNCCONFIG2 = 0x88 # Size of the Synch word = 2 (SyncSize + 1) +VAL_SYNCCONFIG4 = 0x98 # Size of the Synch word = 4 (SyncSize + 1) +VAL_SYNCVALUE1FSK = 0x2D # 1st byte of Sync word +VAL_SYNCVALUE2FSK = 0xD4 # 2nd byte of Sync word +VAL_SYNCVALUE1OOK = 0x80 # 1nd byte of Sync word +VAL_PACKETCONFIG1FSK = 0xA2 # Variable length, Manchester coding, Addr must match NodeAddress +VAL_PACKETCONFIG1FSKNO = 0xA0 # Variable length, Manchester coding +VAL_PACKETCONFIG1OOK = 0 # Fixed length, no Manchester coding +VAL_PAYLOADLEN255 = 0xFF # max Length in RX, not used in Tx +VAL_PAYLOADLEN66 = 66 # max Length in RX, not used in Tx +VAL_PAYLOADLEN_OOK = (13 + 8 * 17) # Payload Length +VAL_NODEADDRESS01 = 0x01 # Node address used in address filtering +VAL_NODEADDRESS04 = 0x04 # Node address used in address filtering +VAL_FIFOTHRESH1 = 0x81 # Condition to start packet transmission: at least one byte in FIFO +VAL_FIFOTHRESH30 = 0x1E # Condition to start packet transmission: wait for 30 bytes in FIFO + + +#----- HOPERF RADIO INTERFACE ------------------------------------------------- + +def HRF_writereg(addr, data): + """Write an 8 bit value to a register""" + buf = [addr | MASK_WRITE_DATA, data] + spi.select() + spi.frame(buf) + spi.deselect() + + +def HRF_readreg(addr): + """Read an 8 bit value from a register""" + buf = [addr, 0x00] + spi.select() + res = spi.frame(buf) + spi.deselect() + #print(hex(res[1])) + return res[1] # all registers are 8 bit + + +def HRF_writefifo_burst(buf): + """Write all bytes in buf to the payload FIFO, in a single burst""" + # Don't modify buf, in case caller reuses it + txbuf = [ADDR_FIFO | MASK_WRITE_DATA] + for b in buf: + txbuf.append(b) + #print("write FIFO %s" % ashex(txbuf)) + + spi.select() + spi.frame(txbuf) + spi.deselect() + + +def HRF_readfifo_burst(): + """Read bytes from the payload FIFO using burst read""" + #first byte read is the length in remaining bytes + buf = [] + spi.select() + spi.frame([ADDR_FIFO]) + count = 1 # read at least the length byte + while count > 0: + rx = spi.frame([ADDR_FIFO]) + data = rx[0] + if len(buf) == 0: + count = data + else: + count -= 1 + buf.append(data) + spi.deselect() + trace("readfifo:" + str(ashex(buf))) + return buf + + +def HRF_checkreg(addr, mask, value): + """Check to see if a register matches a specific value or not""" + regval = HRF_readreg(addr) + #print("addr %d mask %d wanted %d actual %d" % (addr,mask,value,regval)) + return (regval & mask) == value + + +def HRF_pollreg(addr, mask, value): + """Poll a register until it meet some criteria""" + while not HRF_checkreg(addr, mask, value): + pass + + +def HRF_wait_ready(): + """Wait for HRF to be ready after last command""" + HRF_pollreg(ADDR_IRQFLAGS1, MASK_MODEREADY, MASK_MODEREADY) + + +def HRF_wait_txready(): + """Wait for HRF to be ready and ready for tx, after last command""" + trace("waiting for transmit ready...") + HRF_pollreg(ADDR_IRQFLAGS1, MASK_MODEREADY|MASK_TXREADY, MASK_MODEREADY|MASK_TXREADY) + trace("transmit ready") + + +def HRF_change_mode(mode): + HRF_writereg(ADDR_OPMODE, mode) + + +def HRF_clear_fifo(): + """Clear any data in the HRF payload FIFO by reading until empty""" + while (HRF_readreg(ADDR_IRQFLAGS2) & MASK_FIFONOTEMPTY) == MASK_FIFONOTEMPTY: + HRF_readreg(ADDR_FIFO) + + +def HRF_check_payload(): + """Check if there is a payload in the FIFO waiting to be processed""" + irqflags1 = HRF_readreg(ADDR_IRQFLAGS1) + irqflags2 = HRF_readreg(ADDR_IRQFLAGS2) + #trace("irq1 %s irq2 %s" % (hex(irqflags1), hex(irqflags2))) + + return (irqflags2 & MASK_PAYLOADRDY) == MASK_PAYLOADRDY + + +def HRF_receive_payload(): + """Receive the whole payload""" + return HRF_readfifo_burst() + + +def HRF_send_payload(payload): + trace("send_payload") + #trace("payload:%s" % ashex(payload)) + HRF_writefifo_burst(payload) + trace(" waiting for sent...") + HRF_pollreg(ADDR_IRQFLAGS2, MASK_PACKETSENT, MASK_PACKETSENT) + trace(" sent") + reg = HRF_readreg(ADDR_IRQFLAGS2) + trace(" irqflags2=%s" % hex(reg)) + if ((reg & MASK_FIFONOTEMPTY) != 0) or ((reg & MASK_FIFOOVERRUN) != 0): + warning("Failed to send payload to HRF") + + + +#----- ENERGENIE SPECIFIC CONFIGURATIONS -------------------------------------- + +config_FSK = [ + [ADDR_REGDATAMODUL, VAL_REGDATAMODUL_FSK], # modulation scheme FSK + [ADDR_FDEVMSB, VAL_FDEVMSB30], # frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC + [ADDR_FDEVLSB, VAL_FDEVLSB30], # frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC + [ADDR_FRMSB, VAL_FRMSB434], # carrier freq -> 434.3MHz 0x6C9333 + [ADDR_FRMID, VAL_FRMID434], # carrier freq -> 434.3MHz 0x6C9333 + [ADDR_FRLSB, VAL_FRLSB434], # carrier freq -> 434.3MHz 0x6C9333 + [ADDR_AFCCTRL, VAL_AFCCTRLS], # standard AFC routine + [ADDR_LNA, VAL_LNA50], # 200ohms, gain by AGC loop -> 50ohms + [ADDR_RXBW, VAL_RXBW60], # channel filter bandwidth 10kHz -> 60kHz page:26 + [ADDR_BITRATEMSB, 0x1A], # 4800b/s + [ADDR_BITRATELSB, 0x0B], # 4800b/s + #[ADDR_AFCFEI, VAL_AFCFEIRX], # AFC is performed each time rx mode is entered + #[ADDR_RSSITHRESH, VAL_RSSITHRESH220], # RSSI threshold 0xE4 -> 0xDC (220) + #[ADDR_PREAMBLELSB, VAL_PREAMBLELSB5], # preamble size LSB set to 5 + [ADDR_SYNCCONFIG, VAL_SYNCCONFIG2], # Size of the Synch word = 2 (SyncSize + 1) + [ADDR_SYNCVALUE1, VAL_SYNCVALUE1FSK], # 1st byte of Sync word + [ADDR_SYNCVALUE2, VAL_SYNCVALUE2FSK], # 2nd byte of Sync word + #[ADDR_PACKETCONFIG1, VAL_PACKETCONFIG1FSK], # Variable length, Manchester coding, Addr must match NodeAddress + [ADDR_PACKETCONFIG1, VAL_PACKETCONFIG1FSKNO], # Variable length, Manchester coding + [ADDR_PAYLOADLEN, VAL_PAYLOADLEN66], # max Length in RX, not used in Tx + #[ADDR_NODEADDRESS, VAL_NODEADDRESS01], # Node address used in address filtering + [ADDR_NODEADDRESS, 0x06], # Node address used in address filtering + [ADDR_FIFOTHRESH, VAL_FIFOTHRESH1], # Condition to start packet transmission: at least one byte in FIFO + [ADDR_OPMODE, MODE_RECEIVER] # Operating mode to Receiver +] + +config_OOK = [ + [ADDR_REGDATAMODUL, VAL_REGDATAMODUL_OOK], # modulation scheme OOK + [ADDR_FDEVMSB, 0], # frequency deviation -> 0kHz + [ADDR_FDEVLSB, 0], # frequency deviation -> 0kHz + [ADDR_FRMSB, VAL_FRMSB433], # carrier freq -> 433.92MHz 0x6C7AE1 + [ADDR_FRMID, VAL_FRMID433], # carrier freq -> 433.92MHz 0x6C7AE1 + [ADDR_FRLSB, VAL_FRLSB433], # carrier freq -> 433.92MHz 0x6C7AE1 + [ADDR_RXBW, VAL_RXBW120], # channel filter bandwidth 120kHz + [ADDR_BITRATEMSB, 0x40], # 1938b/s + [ADDR_BITRATELSB, 0x80], # 1938b/s + [ADDR_PREAMBLELSB, 0], # preamble size LSB 3 + [ADDR_SYNCCONFIG, VAL_SYNCCONFIG4], # Size of the Sync word = 4 (SyncSize + 1) + [ADDR_SYNCVALUE1, VAL_SYNCVALUE1OOK], # sync value 1 + [ADDR_SYNCVALUE2, 0], # sync value 2 + [ADDR_SYNCVALUE3, 0], # sync value 3 + [ADDR_SYNCVALUE4, 0], # sync value 4 + [ADDR_PACKETCONFIG1, VAL_PACKETCONFIG1OOK], # Fixed length, no Manchester coding, OOK + [ADDR_PAYLOADLEN, VAL_PAYLOADLEN_OOK], # Payload Length + [ADDR_FIFOTHRESH, VAL_FIFOTHRESH30], # Condition to start packet transmission: wait for 30 bytes in FIFO +] + + +def HRF_config(config): + """Load a table of configuration values into HRF registers""" + for cmd in config: + HRF_writereg(cmd[0], cmd[1]) + HRF_wait_ready() + + +#ORIGINAL C CODE +#void HRF_send_OOK_msg(uint8_t relayState) +#{ +# uint8_t buf[17]; +# uint8_t i; +# +# HRF_config_OOK(); +# +# buf[1] = 0x80; // Preambule 32b enclosed in sync words +# buf[2] = 0x00; +# buf[3] = 0x00; +# buf[4] = 0x00; +# +# for (i = 5; i <= 14; ++i){ +# buf[i] = 8 + (i&1) * 6 + 128 + (i&2) * 48; // address 20b * 4 = 10 Bytes +# } +# +# if (relayState == 1) +# { +# printf("relay ON\n\n"); +# buf[15] = 0xEE; // D0-high, D1-h // S1 on +# buf[16] = 0xEE; // D2-h, D3-h +# } +# else +# { +# printf("relay OFF\n\n"); +# buf[15] = 0xEE; // D0-high, D1-h // S1 off +# buf[16] = 0xE8; // D2-h, D3-l +# } +# +# HRF_wait_for (ADDR_IRQFLAGS1, MASK_MODEREADY | MASK_TXREADY, true); // wait for ModeReady + TX ready +# HRF_reg_Wn(buf + 4, 0, 12); // don't include sync word (4 bytes) into data buffer +# +# for (i = 0; i < 8; ++i) // Send the same message few more times +# { +# HRF_wait_for(ADDR_IRQFLAGS2, MASK_FIFOLEVEL, false); +# HRF_reg_Wn(buf, 0, 16); // with sync word +# } +# +# HRF_wait_for (ADDR_IRQFLAGS2, MASK_PACKETSENT, true); // wait for Packet sent +# HRF_assert_reg_val(ADDR_IRQFLAGS2, MASK_FIFONOTEMPTY | MASK_FIFOOVERRUN, false, "are all bytes sent?"); +# HRF_config_FSK(); +# HRF_wait_for (ADDR_IRQFLAGS1, MASK_MODEREADY, true); // wait for ModeReady +#} + + +def HRF_send_OOK_payload(payload): + """Send a payload multiple times""" + + p1 = [0x00] + payload + # This sync pattern does not match C code, but it works. + # The sync pattern from the C code does not work here + # Note that buf[0] in the C is undefined due to being uninitialised + #pn = [0x00,0x80,0x00,0x00,0x00] # from the C + # Currently there is no explanation for this. + pn = [0x80,0x80,0x80,0x80,0x80] + payload + + HRF_pollreg(ADDR_IRQFLAGS1, MASK_MODEREADY|MASK_TXREADY, MASK_MODEREADY|MASK_TXREADY) + HRF_writefifo_burst(p1) + + for i in range(8): + HRF_pollreg(ADDR_IRQFLAGS2, MASK_FIFOLEVEL, 0) + HRF_writefifo_burst(pn) + + HRF_pollreg(ADDR_IRQFLAGS2, MASK_PACKETSENT, MASK_PACKETSENT) # wait for Packet sent + + reg = HRF_readreg(ADDR_IRQFLAGS2) + #trace(" irqflags2=%s" % hex(reg)) + if (reg & (MASK_FIFONOTEMPTY) != 0) or ((reg & MASK_FIFOOVERRUN) != 0): + warning("Failed to send repeated payload to HRF") + + + +#----- RADIO API -------------------------------------------------------------- + +mode = None +modulation_fsk = None + +def init(): + """Initialise the module ready for use""" + spi.init_defaults() + trace("RESET") + + # Note that if another program left GPIO pins in a different state + # and did a dirty exit, the reset fails to work and the clear fifo hangs. + # Might have to make the spi.init() set everything to inputs first, + # then set to outputs, to make sure that the + # GPIO registers are in a deterministic start state. + spi.reset() # send a hardware reset to ensure radio in clean state + + HRF_clear_fifo() + + +def modulation(fsk=None, ook=None): + """Switch modulation, if needed""" + global modulation_fsk + + # Handle sensible module defaults for earlier versions of user code + if fsk == None and ook == None: + # Force FSK mode + fsk = True + + if fsk != None and fsk: + if modulation_fsk == None or modulation_fsk == False: + trace("switch to FSK") + HRF_config(config_FSK) + modulation_fsk = True + + elif ook != None and ook: + if modulation_fsk == None or modulation_fsk == True: + trace("switch to OOK") + HRF_config(config_OOK) + modulation_fsk = False + + +def transmitter(fsk=None, ook=None): + """Change into transmitter mode""" + global mode + + trace("transmitter mode") + modulation(fsk, ook) + HRF_change_mode(MODE_TRANSMITER) + mode = "TRANSMITTER" + HRF_wait_txready() + + +def transmit(payload): + """Transmit a single payload using the present modulation scheme""" + if not modulation_fsk: + HRF_send_OOK_payload(payload) + else: + HRF_send_payload(payload) + + +def receiver(fsk=None, ook=None): + """Change into receiver mode""" + global mode + + trace("receiver mode") + modulation(fsk, ook) + HRF_change_mode(MODE_RECEIVER) + HRF_wait_ready() + mode = "RECEIVER" + + +def isReceiveWaiting(): + """Check to see if a payload is waiting in the receive buffer""" + return HRF_check_payload() + + +def receive(): + """Receive a single payload from the buffer using the present modulation scheme""" + return HRF_receive_payload() + + +def finished(): + """Close the library down cleanly when finished""" + spi.finished() + + +# END diff --git a/src/energenie/drv/radio.h b/src/energenie/drv/radio.h new file mode 100644 index 0000000..5fd45b0 --- /dev/null +++ b/src/energenie/drv/radio.h @@ -0,0 +1,35 @@ +/* radio.h 03/04/2016 D.J.Whale + * + * Energenie radio interface + */ + +#ifndef _RADIO_H +#define _RADIO_H + +typedef uint8_t RADIO_RESULT; + +typedef uint8_t RADIO_MODULATION +#define RADIO_MODULATION_OOK 0 +#define RADIO_MODULATION_FSK 1 + +extern void radio_init(void); + +extern void radio_modulation(RADIO_MODULATION mod); + +extern void radio_transmitter(RADIO_MODULATION mod); + +extern void radio_transmit(uint8_t* payload, uint8_t len); + +extern void radio_send_OOK_payload(uint8_t* payload, uint8_t len); + +extern void radio_receiver(RADIO_MODULATION mod); + +extern RADIO_RESULT radio_isReceiveWaiting(void); + +extern uint8_t* radio_receive(uint8_t maxlen); + +extern void radio_finished(void); + +#endif + +/***** END OF FILE *****/ diff --git a/src/energenie/drv/radio_test.c b/src/energenie/drv/radio_test.c new file mode 100644 index 0000000..b4232fe --- /dev/null +++ b/src/energenie/drv/radio_test.c @@ -0,0 +1,25 @@ +/* radio_test.c D.J.Whale 03/04/2016 + * + * A simple Energenie radio exerciser + */ + + +/***** INCLUDES *****/ + +//#include +//#include +//#include "gpio.h" +//#include "spi.h" + + +/***** CONSTANTS *****/ + + +int main(int argc, char **argv) +{ + //TODO + return 0; +} + + +/***** END OF FILE *****/ diff --git a/src/energenie/drv/spi.h b/src/energenie/drv/spi.h new file mode 100644 index 0000000..7534264 --- /dev/null +++ b/src/energenie/drv/spi.h @@ -0,0 +1,64 @@ +/* spi.h D.J.Whale 19/07/2014 */ + + +#ifndef SPI_H +#define SPI_H + + +/***** INCLUDES *****/ + +//#include + + +/***** CONSTANTS *****/ + +#define SPI_CPOL0 0 +#define SPI_CPOL1 1 +#define SPI_SPOL0 0 +#define SPI_SPOL1 1 +#define SPI_CPHA0 0 +#define SPI_CPHA1 1 + + +/***** STRUCTURES *****/ + +typedef struct +{ + unsigned char cs; + unsigned char sclk; + unsigned char mosi; + unsigned char miso; + + unsigned char spol; + unsigned char cpol; + unsigned char cpha; + + //struct timespec tSettle; + //struct timespec tHold; + //struct timespec tFreq; + unsigned int tSettle; + unsigned int tHold; + unsigned int tFreq; +} SPI_CONFIG; + + + +/***** FUNCTION PROTOTYPES *****/ + +void spi_init_defaults(void); + +void spi_init(SPI_CONFIG* pConfig); + +void spi_select(void); + +void spi_deselect(void); + +int spi_byte(int txbyte); + +void spi_frame(unsigned char* pTx, unsigned char* pRx, unsigned char count); + +void spi_finished(void); + +#endif + +/***** END OF FILE *****/ diff --git a/src/energenie/drv/spi_test.c b/src/energenie/drv/spi_test.c new file mode 100644 index 0000000..4fe2332 --- /dev/null +++ b/src/energenie/drv/spi_test.c @@ -0,0 +1,83 @@ +/* spi_test.c D.J.Whale 18/07/2014 + * + * A simple SPI port exerciser. + * currently only uses the soft SPI (spis) + * TODO: Later will also support hard SPI (spih) + * but will have to sort out the pin configuration structure first for that to work. + */ + + +/***** INCLUDES *****/ + +#include +#include +#include "gpio.h" +#include "spi.h" + + +/***** CONSTANTS *****/ + +/* GPIO numbers on Raspberry Pi */ +#define CS 8 +#define SCLK 11 +#define MOSI 10 +#define MISO 9 + +/* ms */ +#define TSETTLE (1UL * 1000UL) /* us */ +#define THOLD (1UL * 1000UL) /* us */ +#define TFREQ (1UL * 1000UL) /* 1us = 1MHz */ + +int main(int argc, char **argv) +{ + unsigned char cmd_prog[4] = {0xAC, 0x53, 0x00, 0x00}; + unsigned char cmd_id0[4] = {0x30, 0x00, 0x00, 0x00}; + unsigned char cmd_id1[4] = {0x30, 0x00, 0x01, 0x00}; + unsigned char cmd_id2[4] = {0x30, 0x00, 0x02, 0x00}; + + unsigned char rx[4]; + SPI_CONFIG spiConfig = {CS, SCLK, MOSI, MISO, SPI_SPOL0, SPI_CPOL0, SPI_CPHA0, + {0,TSETTLE},{0,THOLD},{0,TFREQ}}; + int i; + unsigned char id[3]; + + + /* Init */ + + printf("init\n"); + //gpio_init(); + spi_init(&spiConfig); + + + /* Enter programming mode */ + + printf("select\n"); + spi_select(); + spi_frame(cmd_prog, NULL, 4); + + + /* Get ID bytes */ + + printf("read ID bytes\n"); + spi_frame(cmd_id0, rx, 4); + id[0] = rx[3]; + + spi_frame(cmd_id1, rx, 4); + id[1] = rx[3]; + + spi_frame(cmd_id2, rx, 4); + id[2] = rx[3]; + + spi_deselect(); + + + /* Show ID bytes */ + + printf("ID: %02X %02X %02X\n", id[0], id[1], id[2]); + + spi_finished(); + return 0; +} + + +/***** END OF FILE *****/ diff --git a/src/energenie/drv/spih.c b/src/energenie/drv/spih.c new file mode 100644 index 0000000..622afd5 --- /dev/null +++ b/src/energenie/drv/spih.c @@ -0,0 +1,65 @@ +/* spih.c (Hard SPI) D.J.Whale 19/07/2014 + */ + + +/***** INCLUDES *****/ + +//#include +//#include +//#include +//#include +//#include + +//#include "spi.h" +//#include "gpio.h" + + + +/***** VARIABLES *****/ + +static SPI_CONFIG config; + + +void spi_init_defaults(void) +{ + //TODO +} + + +void spi_init(SPI_CONFIG* pConfig) +{ + //TODO +} + + +void spi_finished(void) +{ + //TODO +} + + +void spi_select(void) +{ + //TODO +} + + +void spi_deselect(void) +{ + //TODO +} + + +int spi_byte(int txbyte) +{ + //TODO +} + + +void spi_frame(unsigned char* pTx, unsigned char* pRx, unsigned char count) +{ + //TODO +} + + +/***** END OF FILE *****/ diff --git a/src/energenie/drv/spis.c b/src/energenie/drv/spis.c new file mode 100644 index 0000000..f77b606 --- /dev/null +++ b/src/energenie/drv/spis.c @@ -0,0 +1,172 @@ +/* spis.c (soft SPI) D.J.Whale 19/07/2014 + */ + + +/***** INCLUDES *****/ + +#include +#include +//#include +#include +#include + +#include "spi.h" +#include "gpio.h" + + +/***** MACROS *****/ + +#define CLOCK_ACTIVE() gpio_write(config.sclk, config.cpol?0:1) +#define CLOCK_IDLE() gpio_write(config.sclk, config.cpol?1:0) + +#define SELECTED() gpio_write(config.cs, config.spol?1:0) +#define NOT_SELECTED() gpio_write(config.cs, config.spol?0:1) + + +/***** VARIABLES *****/ + +static SPI_CONFIG config; + + +/* Based on code suggested by Gordon Henderson: + * https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.c + * + * Note that his trick of using the hardware timer just didn't work, + * and this is the best of a bad bunch. nanosleep() delays at least + * 100uS in some cases. + */ + +static void delayus(unsigned int us) +{ + struct timeval tNow, tLong, tEnd; + + gettimeofday(&tNow, NULL); + tLong.tv_sec = us / 1000000; + tLong.tv_usec = us % 1000000; + timeradd(&tNow, &tLong, &tEnd); + + while (timercmp(&tNow, &tEnd, <)) + { + gettimeofday(&tNow, NULL); + } +} + + +void spi_init_defaults(void) +{ +#define CS 7 //CE1 +#define SCLK 11 +#define MOSI 10 +#define MISO 9 + +/* ms */ +#define TSETTLE (1) /* us settle */ +#define THOLD (1) /* us hold */ +#define TFREQ (1) /* us half clock */ + + SPI_CONFIG defaultConfig = {CS, SCLK, MOSI, MISO, SPI_SPOL0, SPI_CPOL0, SPI_CPHA0, + TSETTLE, THOLD, TFREQ}; + + spi_init(&defaultConfig); +} + + +void spi_init(SPI_CONFIG* pConfig) +{ + /* It's a standalone library, so init GPIO also */ + gpio_init(); + memcpy(&config, pConfig, sizeof(SPI_CONFIG)); + + //TODO: Implement CPHA1 + if (config.cpha != 0) + { + fprintf(stderr, "error: CPHA 1 not yet supported"); + exit(-1); + } + + gpio_setout(config.sclk); + CLOCK_IDLE(); + + gpio_setout(config.mosi); + gpio_low(config.mosi); + gpio_setin(config.miso); + + gpio_setout(config.cs); + NOT_SELECTED(); +} + + +void spi_finished(void) +{ + gpio_setin(config.mosi); + gpio_setin(config.sclk); + gpio_setin(config.cs); +} + + +void spi_select(void) +{ + SELECTED(); + delayus(config.tSettle); +} + + +void spi_deselect(void) +{ + NOT_SELECTED(); + delayus(config.tSettle); +} + + +int spi_byte(int txbyte) +{ + int rxbyte = 0; + int bitno; + int bit ; + + //TODO: Implement CPHA1 + + for (bitno=0; bitno<8; bitno++) + { + /* Transmit MSB first */ + bit = ((txbyte & 0x80) != 0x00); + txbyte <<= 1; + gpio_write(config.mosi, bit); + delayus(config.tSettle); + CLOCK_ACTIVE(); + delayus(config.tHold); + delayus(config.tFreq); + + /* Read MSB first */ + bit = gpio_read(config.miso); + rxbyte = (rxbyte<<1) | bit; + + CLOCK_IDLE(); + delayus(config.tFreq); + } + return rxbyte; +} + + +void spi_frame(unsigned char* pTx, unsigned char* pRx, unsigned char count) +{ + unsigned char tx = 0; + unsigned char rx; + + while (count > 0) + { + if (pTx != NULL) + { + tx = *(pTx++); + } + rx = spi_byte(tx); + if (pRx != NULL) + { + *(pRx++) = rx; + } + count--; + } +} + + +/***** END OF FILE *****/ diff --git a/src/energenie/gpio.c b/src/energenie/gpio.c deleted file mode 100644 index 7d9a144..0000000 --- a/src/energenie/gpio.c +++ /dev/null @@ -1,182 +0,0 @@ -/* gpio.c D.J.Whale 8/07/2014 - * - * A very simple interface to the GPIO port on the Raspberry Pi. - */ - -/***** INCLUDES *****/ - -#include -#include -#include -#include -#include -#include -#include - -#include "gpio.h" - - -/***** CONFIGURATION *****/ - -/* uncomment to make this a simulated driver */ -//#define GPIO_SIMULATED - - -/***** CONSTANTS *****/ - -#define BCM2708_PERI_BASE 0x20000000 -//#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ -#define GPIO_BASE_OFFSET 0x200000 - -#define PAGE_SIZE (4*1024) -#define BLOCK_SIZE (4*1024) - - -/***** VARIABLES *****/ - -static int mem_fd; -static void *gpio_map; - -static volatile unsigned *gpio; - - -/****** MACROS *****/ - -#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) -#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) -#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) - -#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0 -#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0 - -#define GPIO_READ(g) ((*(gpio+13)&(1< -#include - -#include "gpio.h" - -static void delay(struct timespec time) -{ - nanosleep(&time, NULL); -} - -static struct timespec delay_1sec = {1, 0}; - - -void main(void) -{ - int i; - - gpio_init(); - gpio_setout(2); - gpio_setout(3); - - for (i=0; i<10; i++) - { - puts("GPIO 2"); - gpio_write(2, 1); - delay(delay_1sec); - gpio_write(2, 0); - delay(delay_1sec); - - puts("GPIO 3"); - gpio_write(3, 1); - delay(delay_1sec); - gpio_write(3, 0); - delay(delay_1sec); - } -} diff --git a/src/energenie/hrf69.c b/src/energenie/hrf69.c deleted file mode 100644 index 652ff47..0000000 --- a/src/energenie/hrf69.c +++ /dev/null @@ -1,51 +0,0 @@ -/* hrf69.c 03/04/2016 D.J.Whale - * - * Hope RF RFM69 radio controller code. - */ - -//import spi - -//def warning(msg): -// print("warning:" + str(msg)) - -//def trace(msg): -// print(str(msg)) - - -//def ashex(p): -// line = "" -// for b in p: -// line += str(hex(b)) + " " -// return line - - -//def HRF_writereg(addr, data): - -//def HRF_readreg(addr): - -//def HRF_writefifo_burst(buf): - -//def HRF_readfifo_burst(): - -//def HRF_checkreg(addr, mask, value): - -//def HRF_pollreg(addr, mask, value): - -//def HRF_wait_ready(): - -//def HRF_wait_txready(): - -//def HRF_change_mode(mode): - -//def HRF_clear_fifo(): - -//def HRF_check_payload(): - -//def HRF_receive_payload(): - -//def HRF_send_payload(payload): - -//def HRF_config(config): - - -//# END diff --git a/src/energenie/hrf69.h b/src/energenie/hrf69.h deleted file mode 100644 index f17242a..0000000 --- a/src/energenie/hrf69.h +++ /dev/null @@ -1,144 +0,0 @@ -/* hrf69.h 03/04/2016 D.J.Whale - * - * Interface for HopeRF RFM69 radio - */ - -//# Precise register descriptions can be found in: -//# www.hoperf.com/upload/rf/RFM69W-V1.3.pdf -//# on page 63 - 74 - -#ifndef _HRF69_H -#define _HRF69_H - -typedef uint8_t HRF_RESULT; - -typedef struct -{ - uint8_t addr; - uint8_t value; -} HRF_CONFIG_REC; - - -// Register addresses -#define HRF_ADDR_FIFO = 0x00 -#define HRF_ADDR_OPMODE = 0x01 -#define HRF_ADDR_REGDATAMODUL = 0x02 -#define HRF_ADDR_BITRATEMSB = 0x03 -#define HRF_ADDR_BITRATELSB = 0x04 -#define HRF_ADDR_FDEVMSB = 0x05 -#define HRF_ADDR_FDEVLSB = 0x06 -#define HRF_ADDR_FRMSB = 0x07 -#define HRF_ADDR_FRMID = 0x08 -#define HRF_ADDR_FRLSB = 0x09 -#define HRF_ADDR_AFCCTRL = 0x0B -#define HRF_ADDR_LNA = 0x18 -#define HRF_ADDR_RXBW = 0x19 -#define HRF_ADDR_AFCFEI = 0x1E -#define HRF_ADDR_IRQFLAGS1 = 0x27 -#define HRF_ADDR_IRQFLAGS2 = 0x28 -#define HRF_ADDR_RSSITHRESH = 0x29 -#define HRF_ADDR_PREAMBLELSB = 0x2D -#define HRF_ADDR_SYNCCONFIG = 0x2E -#define HRF_ADDR_SYNCVALUE1 = 0x2F -#define HRF_ADDR_SYNCVALUE2 = 0x30 -#define HRF_ADDR_SYNCVALUE3 = 0x31 -#define HRF_ADDR_SYNCVALUE4 = 0x32 -#define HRF_ADDR_PACKETCONFIG1 = 0x37 -#define HRF_ADDR_PAYLOADLEN = 0x38 -#define HRF_ADDR_NODEADDRESS = 0x39 -#define HRF_ADDR_FIFOTHRESH = 0x3C - -// Masks to set and clear bits -#define HRF_MASK_REGDATAMODUL_OOK = 0x08 -#define HRF_MASK_REGDATAMODUL_FSK = 0x00 -#define HRF_MASK_WRITE_DATA = 0x80 -#define HRF_MASK_MODEREADY = 0x80 -#define HRF_MASK_FIFONOTEMPTY = 0x40 -#define HRF_MASK_FIFOLEVEL = 0x20 -#define HRF_MASK_FIFOOVERRUN = 0x10 -#define HRF_MASK_PACKETSENT = 0x08 -#define HRF_MASK_TXREADY = 0x20 -#define HRF_MASK_PACKETMODE = 0x60 -#define HRF_MASK_MODULATION = 0x18 -#define HRF_MASK_PAYLOADRDY = 0x04 - -// Radio modes -#define HRF_MODE_STANDBY = 0x04 // Standby -#define HRF_MODE_TRANSMITER = 0x0C // Transmiter -#define HRF_MODE_RECEIVER = 0x10 // Receiver - -// Values to store in registers -//TODO some of these are energenie radio config specific - -#define HRF_VAL_REGDATAMODUL_FSK = 0x00 // Modulation scheme FSK -#define HRF_VAL_REGDATAMODUL_OOK = 0x08 // Modulation scheme OOK -#define HRF_VAL_FDEVMSB30 = 0x01 // frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC -#define HRF_VAL_FDEVLSB30 = 0xEC // frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC -#define HRF_VAL_FRMSB434 = 0x6C // carrier freq -> 434.3MHz 0x6C9333 -#define HRF_VAL_FRMID434 = 0x93 // carrier freq -> 434.3MHz 0x6C9333 -#define HRF_VAL_FRLSB434 = 0x33 // carrier freq -> 434.3MHz 0x6C9333 -#define HRF_VAL_FRMSB433 = 0x6C // carrier freq -> 433.92MHz 0x6C7AE1 -#define HRF_VAL_FRMID433 = 0x7A // carrier freq -> 433.92MHz 0x6C7AE1 -#define HRF_VAL_FRLSB433 = 0xE1 // carrier freq -> 433.92MHz 0x6C7AE1 -#define HRF_VAL_AFCCTRLS = 0x00 // standard AFC routine -#define HRF_VAL_AFCCTRLI = 0x20 // improved AFC routine -#define HRF_VAL_LNA50 = 0x08 // LNA input impedance 50 ohms -#define HRF_VAL_LNA50G = 0x0E // LNA input impedance 50 ohms, LNA gain -> 48db -#define HRF_VAL_LNA200 = 0x88 // LNA input impedance 200 ohms -#define HRF_VAL_RXBW60 = 0x43 // channel filter bandwidth 10kHz -> 60kHz page:26 -#define HRF_VAL_RXBW120 = 0x41 // channel filter bandwidth 120kHz -#define HRF_VAL_AFCFEIRX = 0x04 // AFC is performed each time RX mode is entered - -//TODO: These might be energenie config specific -#define HRF_VAL_RSSITHRESH220 = 0xDC // RSSI threshold 0xE4 -> 0xDC (220) -#define HRF_VAL_PREAMBLELSB3 = 0x03 // preamble size LSB 3 -#define HRF_VAL_PREAMBLELSB5 = 0x05 // preamble size LSB 5 -#define HRF_VAL_SYNCCONFIG2 = 0x88 // Size of the Synch word = 2 (SyncSize + 1) -#define HRF_VAL_SYNCCONFIG4 = 0x98 // Size of the Synch word = 4 (SyncSize + 1) -#define HRF_VAL_SYNCVALUE1FSK = 0x2D // 1st byte of Sync word -#define HRF_VAL_SYNCVALUE2FSK = 0xD4 // 2nd byte of Sync word -#define HRF_VAL_SYNCVALUE1OOK = 0x80 // 1nd byte of Sync word -#define HRF_VAL_PACKETCONFIG1FSK = 0xA2 // Variable length, Manchester coding, Addr must match NodeAddress -#define HRF_VAL_PACKETCONFIG1FSKNO = 0xA0 // Variable length, Manchester coding -#define HRF_VAL_PACKETCONFIG1OOK = 0 // Fixed length, no Manchester coding -#define HRF_VAL_PAYLOADLEN255 = 0xFF // max Length in RX, not used in Tx -#define HRF_VAL_PAYLOADLEN66 = 66 // max Length in RX, not used in Tx -#define HRF_VAL_PAYLOADLEN_OOK = (13 + 8 * 17) // Payload Length -#define HRF_VAL_NODEADDRESS01 = 0x01 // Node address used in address filtering -#define HRF_VAL_NODEADDRESS04 = 0x04 // Node address used in address filtering -#define HRF_VAL_FIFOTHRESH1 = 0x81 // Condition to start packet transmission: at least one byte in FIFO -#define HRF_VAL_FIFOTHRESH30 = 0x1E // Condition to start packet transmission: wait for 30 bytes in FIFO - - -extern void HRF_writereg(uint8_t addr, uint8_t data); - -extern uint8_t HRF_readreg(uint8_t addr); - -extern void HRF_writefifo_burst(uint8_t* buf uint8_t len); - -extern uint8_t* HRF_readfifo_burst(void); - -extern HRF_RESULT HRF_checkreg(uint8_t addr, uint8_t mask, uint8_t value); - -extern void HRF_pollreg(uint8_t addr, uint8_t mask, uint8_t value); - -extern void HRF_wait_ready(void); - -extern void HRF_wait_txready(void); - -extern void HRF_change_mode(uint8_t mode); - -extern void HRF_clear_fifo(void); - -extern HRF_RESULT HRF_check_payload(void); - -extern uint8_t* HRF_receive_payload(void); - -extern void HRF_send_payload(uint8_t* payload, uint8_t len); - -extern void HRF_config(HRF_CONFIG_REC* config, uint8_t len); - -#endif - -/***** END OF FILE *****/ - diff --git a/src/energenie/hrf69_test.c b/src/energenie/hrf69_test.c deleted file mode 100644 index 2e62d03..0000000 --- a/src/energenie/hrf69_test.c +++ /dev/null @@ -1,24 +0,0 @@ -/* hrf69_test.c D.J.Whale 03/04/2016 - * - * A simple exerciser for the HopeRF RFM69 radio - */ - - -/***** INCLUDES *****/ - -//#include -//#include -//#include "gpio.h" -//#include "spi.h" - - -/***** CONSTANTS *****/ - -int main(int argc, char **argv) -{ - //TODO - return 0; -} - - -/***** END OF FILE *****/ diff --git a/src/energenie/radio.c b/src/energenie/radio.c deleted file mode 100644 index 93310fe..0000000 --- a/src/energenie/radio.c +++ /dev/null @@ -1,451 +0,0 @@ -//TODO - -# test1.py 26/09/2015 D.J.Whale -# -# Simple low level test of the HopeRF interface -# Uses direct SPI commands to exercise the interface. -# -# Receives and dumps payload buffers. -# -# Eventually a lot of this will be pushed into a separate module, -# and then pushed back into C once it is proved working. - -import spi - -def warning(msg): - print("warning:" + str(msg)) - -def trace(msg): - print(str(msg)) - - -def ashex(p): - line = "" - for b in p: - line += str(hex(b)) + " " - return line - - -#----- HOPERF REGISTER INTERFACE ---------------------------------------------- -# Precise register descriptions can be found in: -# www.hoperf.com/upload/rf/RFM69W-V1.3.pdf -# on page 63 - 74 - -ADDR_FIFO = 0x00 -ADDR_OPMODE = 0x01 -ADDR_REGDATAMODUL = 0x02 -ADDR_BITRATEMSB = 0x03 -ADDR_BITRATELSB = 0x04 -ADDR_FDEVMSB = 0x05 -ADDR_FDEVLSB = 0x06 -ADDR_FRMSB = 0x07 -ADDR_FRMID = 0x08 -ADDR_FRLSB = 0x09 -ADDR_AFCCTRL = 0x0B -ADDR_LNA = 0x18 -ADDR_RXBW = 0x19 -ADDR_AFCFEI = 0x1E -ADDR_IRQFLAGS1 = 0x27 -ADDR_IRQFLAGS2 = 0x28 -ADDR_RSSITHRESH = 0x29 -ADDR_PREAMBLELSB = 0x2D -ADDR_SYNCCONFIG = 0x2E -ADDR_SYNCVALUE1 = 0x2F -ADDR_SYNCVALUE2 = 0x30 -ADDR_SYNCVALUE3 = 0x31 -ADDR_SYNCVALUE4 = 0x32 -ADDR_PACKETCONFIG1 = 0x37 -ADDR_PAYLOADLEN = 0x38 -ADDR_NODEADDRESS = 0x39 -ADDR_FIFOTHRESH = 0x3C - -# HopeRF masks to set and clear bits -MASK_REGDATAMODUL_OOK = 0x08 -MASK_REGDATAMODUL_FSK = 0x00 -MASK_WRITE_DATA = 0x80 -MASK_MODEREADY = 0x80 -MASK_FIFONOTEMPTY = 0x40 -MASK_FIFOLEVEL = 0x20 -MASK_FIFOOVERRUN = 0x10 -MASK_PACKETSENT = 0x08 -MASK_TXREADY = 0x20 -MASK_PACKETMODE = 0x60 -MASK_MODULATION = 0x18 -MASK_PAYLOADRDY = 0x04 - -MODE_STANDBY = 0x04 # Standby -MODE_TRANSMITER = 0x0C # Transmiter -MODE_RECEIVER = 0x10 # Receiver -VAL_REGDATAMODUL_FSK = 0x00 # Modulation scheme FSK -VAL_REGDATAMODUL_OOK = 0x08 # Modulation scheme OOK -VAL_FDEVMSB30 = 0x01 # frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC -VAL_FDEVLSB30 = 0xEC # frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC -VAL_FRMSB434 = 0x6C # carrier freq -> 434.3MHz 0x6C9333 -VAL_FRMID434 = 0x93 # carrier freq -> 434.3MHz 0x6C9333 -VAL_FRLSB434 = 0x33 # carrier freq -> 434.3MHz 0x6C9333 -VAL_FRMSB433 = 0x6C # carrier freq -> 433.92MHz 0x6C7AE1 -VAL_FRMID433 = 0x7A # carrier freq -> 433.92MHz 0x6C7AE1 -VAL_FRLSB433 = 0xE1 # carrier freq -> 433.92MHz 0x6C7AE1 -VAL_AFCCTRLS = 0x00 # standard AFC routine -VAL_AFCCTRLI = 0x20 # improved AFC routine -VAL_LNA50 = 0x08 # LNA input impedance 50 ohms -VAL_LNA50G = 0x0E # LNA input impedance 50 ohms, LNA gain -> 48db -VAL_LNA200 = 0x88 # LNA input impedance 200 ohms -VAL_RXBW60 = 0x43 # channel filter bandwidth 10kHz -> 60kHz page:26 -VAL_RXBW120 = 0x41 # channel filter bandwidth 120kHz -VAL_AFCFEIRX = 0x04 # AFC is performed each time RX mode is entered -VAL_RSSITHRESH220 = 0xDC # RSSI threshold 0xE4 -> 0xDC (220) -VAL_PREAMBLELSB3 = 0x03 # preamble size LSB 3 -VAL_PREAMBLELSB5 = 0x05 # preamble size LSB 5 -VAL_SYNCCONFIG2 = 0x88 # Size of the Synch word = 2 (SyncSize + 1) -VAL_SYNCCONFIG4 = 0x98 # Size of the Synch word = 4 (SyncSize + 1) -VAL_SYNCVALUE1FSK = 0x2D # 1st byte of Sync word -VAL_SYNCVALUE2FSK = 0xD4 # 2nd byte of Sync word -VAL_SYNCVALUE1OOK = 0x80 # 1nd byte of Sync word -VAL_PACKETCONFIG1FSK = 0xA2 # Variable length, Manchester coding, Addr must match NodeAddress -VAL_PACKETCONFIG1FSKNO = 0xA0 # Variable length, Manchester coding -VAL_PACKETCONFIG1OOK = 0 # Fixed length, no Manchester coding -VAL_PAYLOADLEN255 = 0xFF # max Length in RX, not used in Tx -VAL_PAYLOADLEN66 = 66 # max Length in RX, not used in Tx -VAL_PAYLOADLEN_OOK = (13 + 8 * 17) # Payload Length -VAL_NODEADDRESS01 = 0x01 # Node address used in address filtering -VAL_NODEADDRESS04 = 0x04 # Node address used in address filtering -VAL_FIFOTHRESH1 = 0x81 # Condition to start packet transmission: at least one byte in FIFO -VAL_FIFOTHRESH30 = 0x1E # Condition to start packet transmission: wait for 30 bytes in FIFO - - -#----- HOPERF RADIO INTERFACE ------------------------------------------------- - -def HRF_writereg(addr, data): - """Write an 8 bit value to a register""" - buf = [addr | MASK_WRITE_DATA, data] - spi.select() - spi.frame(buf) - spi.deselect() - - -def HRF_readreg(addr): - """Read an 8 bit value from a register""" - buf = [addr, 0x00] - spi.select() - res = spi.frame(buf) - spi.deselect() - #print(hex(res[1])) - return res[1] # all registers are 8 bit - - -def HRF_writefifo_burst(buf): - """Write all bytes in buf to the payload FIFO, in a single burst""" - # Don't modify buf, in case caller reuses it - txbuf = [ADDR_FIFO | MASK_WRITE_DATA] - for b in buf: - txbuf.append(b) - #print("write FIFO %s" % ashex(txbuf)) - - spi.select() - spi.frame(txbuf) - spi.deselect() - - -def HRF_readfifo_burst(): - """Read bytes from the payload FIFO using burst read""" - #first byte read is the length in remaining bytes - buf = [] - spi.select() - spi.frame([ADDR_FIFO]) - count = 1 # read at least the length byte - while count > 0: - rx = spi.frame([ADDR_FIFO]) - data = rx[0] - if len(buf) == 0: - count = data - else: - count -= 1 - buf.append(data) - spi.deselect() - trace("readfifo:" + str(ashex(buf))) - return buf - - -def HRF_checkreg(addr, mask, value): - """Check to see if a register matches a specific value or not""" - regval = HRF_readreg(addr) - #print("addr %d mask %d wanted %d actual %d" % (addr,mask,value,regval)) - return (regval & mask) == value - - -def HRF_pollreg(addr, mask, value): - """Poll a register until it meet some criteria""" - while not HRF_checkreg(addr, mask, value): - pass - - -def HRF_wait_ready(): - """Wait for HRF to be ready after last command""" - HRF_pollreg(ADDR_IRQFLAGS1, MASK_MODEREADY, MASK_MODEREADY) - - -def HRF_wait_txready(): - """Wait for HRF to be ready and ready for tx, after last command""" - trace("waiting for transmit ready...") - HRF_pollreg(ADDR_IRQFLAGS1, MASK_MODEREADY|MASK_TXREADY, MASK_MODEREADY|MASK_TXREADY) - trace("transmit ready") - - -def HRF_change_mode(mode): - HRF_writereg(ADDR_OPMODE, mode) - - -def HRF_clear_fifo(): - """Clear any data in the HRF payload FIFO by reading until empty""" - while (HRF_readreg(ADDR_IRQFLAGS2) & MASK_FIFONOTEMPTY) == MASK_FIFONOTEMPTY: - HRF_readreg(ADDR_FIFO) - - -def HRF_check_payload(): - """Check if there is a payload in the FIFO waiting to be processed""" - irqflags1 = HRF_readreg(ADDR_IRQFLAGS1) - irqflags2 = HRF_readreg(ADDR_IRQFLAGS2) - #trace("irq1 %s irq2 %s" % (hex(irqflags1), hex(irqflags2))) - - return (irqflags2 & MASK_PAYLOADRDY) == MASK_PAYLOADRDY - - -def HRF_receive_payload(): - """Receive the whole payload""" - return HRF_readfifo_burst() - - -def HRF_send_payload(payload): - trace("send_payload") - #trace("payload:%s" % ashex(payload)) - HRF_writefifo_burst(payload) - trace(" waiting for sent...") - HRF_pollreg(ADDR_IRQFLAGS2, MASK_PACKETSENT, MASK_PACKETSENT) - trace(" sent") - reg = HRF_readreg(ADDR_IRQFLAGS2) - trace(" irqflags2=%s" % hex(reg)) - if ((reg & MASK_FIFONOTEMPTY) != 0) or ((reg & MASK_FIFOOVERRUN) != 0): - warning("Failed to send payload to HRF") - - - -#----- ENERGENIE SPECIFIC CONFIGURATIONS -------------------------------------- - -config_FSK = [ - [ADDR_REGDATAMODUL, VAL_REGDATAMODUL_FSK], # modulation scheme FSK - [ADDR_FDEVMSB, VAL_FDEVMSB30], # frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC - [ADDR_FDEVLSB, VAL_FDEVLSB30], # frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC - [ADDR_FRMSB, VAL_FRMSB434], # carrier freq -> 434.3MHz 0x6C9333 - [ADDR_FRMID, VAL_FRMID434], # carrier freq -> 434.3MHz 0x6C9333 - [ADDR_FRLSB, VAL_FRLSB434], # carrier freq -> 434.3MHz 0x6C9333 - [ADDR_AFCCTRL, VAL_AFCCTRLS], # standard AFC routine - [ADDR_LNA, VAL_LNA50], # 200ohms, gain by AGC loop -> 50ohms - [ADDR_RXBW, VAL_RXBW60], # channel filter bandwidth 10kHz -> 60kHz page:26 - [ADDR_BITRATEMSB, 0x1A], # 4800b/s - [ADDR_BITRATELSB, 0x0B], # 4800b/s - #[ADDR_AFCFEI, VAL_AFCFEIRX], # AFC is performed each time rx mode is entered - #[ADDR_RSSITHRESH, VAL_RSSITHRESH220], # RSSI threshold 0xE4 -> 0xDC (220) - #[ADDR_PREAMBLELSB, VAL_PREAMBLELSB5], # preamble size LSB set to 5 - [ADDR_SYNCCONFIG, VAL_SYNCCONFIG2], # Size of the Synch word = 2 (SyncSize + 1) - [ADDR_SYNCVALUE1, VAL_SYNCVALUE1FSK], # 1st byte of Sync word - [ADDR_SYNCVALUE2, VAL_SYNCVALUE2FSK], # 2nd byte of Sync word - #[ADDR_PACKETCONFIG1, VAL_PACKETCONFIG1FSK], # Variable length, Manchester coding, Addr must match NodeAddress - [ADDR_PACKETCONFIG1, VAL_PACKETCONFIG1FSKNO], # Variable length, Manchester coding - [ADDR_PAYLOADLEN, VAL_PAYLOADLEN66], # max Length in RX, not used in Tx - #[ADDR_NODEADDRESS, VAL_NODEADDRESS01], # Node address used in address filtering - [ADDR_NODEADDRESS, 0x06], # Node address used in address filtering - [ADDR_FIFOTHRESH, VAL_FIFOTHRESH1], # Condition to start packet transmission: at least one byte in FIFO - [ADDR_OPMODE, MODE_RECEIVER] # Operating mode to Receiver -] - -config_OOK = [ - [ADDR_REGDATAMODUL, VAL_REGDATAMODUL_OOK], # modulation scheme OOK - [ADDR_FDEVMSB, 0], # frequency deviation -> 0kHz - [ADDR_FDEVLSB, 0], # frequency deviation -> 0kHz - [ADDR_FRMSB, VAL_FRMSB433], # carrier freq -> 433.92MHz 0x6C7AE1 - [ADDR_FRMID, VAL_FRMID433], # carrier freq -> 433.92MHz 0x6C7AE1 - [ADDR_FRLSB, VAL_FRLSB433], # carrier freq -> 433.92MHz 0x6C7AE1 - [ADDR_RXBW, VAL_RXBW120], # channel filter bandwidth 120kHz - [ADDR_BITRATEMSB, 0x40], # 1938b/s - [ADDR_BITRATELSB, 0x80], # 1938b/s - [ADDR_PREAMBLELSB, 0], # preamble size LSB 3 - [ADDR_SYNCCONFIG, VAL_SYNCCONFIG4], # Size of the Sync word = 4 (SyncSize + 1) - [ADDR_SYNCVALUE1, VAL_SYNCVALUE1OOK], # sync value 1 - [ADDR_SYNCVALUE2, 0], # sync value 2 - [ADDR_SYNCVALUE3, 0], # sync value 3 - [ADDR_SYNCVALUE4, 0], # sync value 4 - [ADDR_PACKETCONFIG1, VAL_PACKETCONFIG1OOK], # Fixed length, no Manchester coding, OOK - [ADDR_PAYLOADLEN, VAL_PAYLOADLEN_OOK], # Payload Length - [ADDR_FIFOTHRESH, VAL_FIFOTHRESH30], # Condition to start packet transmission: wait for 30 bytes in FIFO -] - - -def HRF_config(config): - """Load a table of configuration values into HRF registers""" - for cmd in config: - HRF_writereg(cmd[0], cmd[1]) - HRF_wait_ready() - - -#ORIGINAL C CODE -#void HRF_send_OOK_msg(uint8_t relayState) -#{ -# uint8_t buf[17]; -# uint8_t i; -# -# HRF_config_OOK(); -# -# buf[1] = 0x80; // Preambule 32b enclosed in sync words -# buf[2] = 0x00; -# buf[3] = 0x00; -# buf[4] = 0x00; -# -# for (i = 5; i <= 14; ++i){ -# buf[i] = 8 + (i&1) * 6 + 128 + (i&2) * 48; // address 20b * 4 = 10 Bytes -# } -# -# if (relayState == 1) -# { -# printf("relay ON\n\n"); -# buf[15] = 0xEE; // D0-high, D1-h // S1 on -# buf[16] = 0xEE; // D2-h, D3-h -# } -# else -# { -# printf("relay OFF\n\n"); -# buf[15] = 0xEE; // D0-high, D1-h // S1 off -# buf[16] = 0xE8; // D2-h, D3-l -# } -# -# HRF_wait_for (ADDR_IRQFLAGS1, MASK_MODEREADY | MASK_TXREADY, true); // wait for ModeReady + TX ready -# HRF_reg_Wn(buf + 4, 0, 12); // don't include sync word (4 bytes) into data buffer -# -# for (i = 0; i < 8; ++i) // Send the same message few more times -# { -# HRF_wait_for(ADDR_IRQFLAGS2, MASK_FIFOLEVEL, false); -# HRF_reg_Wn(buf, 0, 16); // with sync word -# } -# -# HRF_wait_for (ADDR_IRQFLAGS2, MASK_PACKETSENT, true); // wait for Packet sent -# HRF_assert_reg_val(ADDR_IRQFLAGS2, MASK_FIFONOTEMPTY | MASK_FIFOOVERRUN, false, "are all bytes sent?"); -# HRF_config_FSK(); -# HRF_wait_for (ADDR_IRQFLAGS1, MASK_MODEREADY, true); // wait for ModeReady -#} - - -def HRF_send_OOK_payload(payload): - """Send a payload multiple times""" - - p1 = [0x00] + payload - # This sync pattern does not match C code, but it works. - # The sync pattern from the C code does not work here - # Note that buf[0] in the C is undefined due to being uninitialised - #pn = [0x00,0x80,0x00,0x00,0x00] # from the C - # Currently there is no explanation for this. - pn = [0x80,0x80,0x80,0x80,0x80] + payload - - HRF_pollreg(ADDR_IRQFLAGS1, MASK_MODEREADY|MASK_TXREADY, MASK_MODEREADY|MASK_TXREADY) - HRF_writefifo_burst(p1) - - for i in range(8): - HRF_pollreg(ADDR_IRQFLAGS2, MASK_FIFOLEVEL, 0) - HRF_writefifo_burst(pn) - - HRF_pollreg(ADDR_IRQFLAGS2, MASK_PACKETSENT, MASK_PACKETSENT) # wait for Packet sent - - reg = HRF_readreg(ADDR_IRQFLAGS2) - #trace(" irqflags2=%s" % hex(reg)) - if (reg & (MASK_FIFONOTEMPTY) != 0) or ((reg & MASK_FIFOOVERRUN) != 0): - warning("Failed to send repeated payload to HRF") - - - -#----- RADIO API -------------------------------------------------------------- - -mode = None -modulation_fsk = None - -def init(): - """Initialise the module ready for use""" - spi.init_defaults() - trace("RESET") - - # Note that if another program left GPIO pins in a different state - # and did a dirty exit, the reset fails to work and the clear fifo hangs. - # Might have to make the spi.init() set everything to inputs first, - # then set to outputs, to make sure that the - # GPIO registers are in a deterministic start state. - spi.reset() # send a hardware reset to ensure radio in clean state - - HRF_clear_fifo() - - -def modulation(fsk=None, ook=None): - """Switch modulation, if needed""" - global modulation_fsk - - # Handle sensible module defaults for earlier versions of user code - if fsk == None and ook == None: - # Force FSK mode - fsk = True - - if fsk != None and fsk: - if modulation_fsk == None or modulation_fsk == False: - trace("switch to FSK") - HRF_config(config_FSK) - modulation_fsk = True - - elif ook != None and ook: - if modulation_fsk == None or modulation_fsk == True: - trace("switch to OOK") - HRF_config(config_OOK) - modulation_fsk = False - - -def transmitter(fsk=None, ook=None): - """Change into transmitter mode""" - global mode - - trace("transmitter mode") - modulation(fsk, ook) - HRF_change_mode(MODE_TRANSMITER) - mode = "TRANSMITTER" - HRF_wait_txready() - - -def transmit(payload): - """Transmit a single payload using the present modulation scheme""" - if not modulation_fsk: - HRF_send_OOK_payload(payload) - else: - HRF_send_payload(payload) - - -def receiver(fsk=None, ook=None): - """Change into receiver mode""" - global mode - - trace("receiver mode") - modulation(fsk, ook) - HRF_change_mode(MODE_RECEIVER) - HRF_wait_ready() - mode = "RECEIVER" - - -def isReceiveWaiting(): - """Check to see if a payload is waiting in the receive buffer""" - return HRF_check_payload() - - -def receive(): - """Receive a single payload from the buffer using the present modulation scheme""" - return HRF_receive_payload() - - -def finished(): - """Close the library down cleanly when finished""" - spi.finished() - - -# END diff --git a/src/energenie/radio.h b/src/energenie/radio.h deleted file mode 100644 index 5fd45b0..0000000 --- a/src/energenie/radio.h +++ /dev/null @@ -1,35 +0,0 @@ -/* radio.h 03/04/2016 D.J.Whale - * - * Energenie radio interface - */ - -#ifndef _RADIO_H -#define _RADIO_H - -typedef uint8_t RADIO_RESULT; - -typedef uint8_t RADIO_MODULATION -#define RADIO_MODULATION_OOK 0 -#define RADIO_MODULATION_FSK 1 - -extern void radio_init(void); - -extern void radio_modulation(RADIO_MODULATION mod); - -extern void radio_transmitter(RADIO_MODULATION mod); - -extern void radio_transmit(uint8_t* payload, uint8_t len); - -extern void radio_send_OOK_payload(uint8_t* payload, uint8_t len); - -extern void radio_receiver(RADIO_MODULATION mod); - -extern RADIO_RESULT radio_isReceiveWaiting(void); - -extern uint8_t* radio_receive(uint8_t maxlen); - -extern void radio_finished(void); - -#endif - -/***** END OF FILE *****/ diff --git a/src/energenie/radio_test.c b/src/energenie/radio_test.c deleted file mode 100644 index b4232fe..0000000 --- a/src/energenie/radio_test.c +++ /dev/null @@ -1,25 +0,0 @@ -/* radio_test.c D.J.Whale 03/04/2016 - * - * A simple Energenie radio exerciser - */ - - -/***** INCLUDES *****/ - -//#include -//#include -//#include "gpio.h" -//#include "spi.h" - - -/***** CONSTANTS *****/ - - -int main(int argc, char **argv) -{ - //TODO - return 0; -} - - -/***** END OF FILE *****/ diff --git a/src/energenie/spi.h b/src/energenie/spi.h deleted file mode 100644 index 7534264..0000000 --- a/src/energenie/spi.h +++ /dev/null @@ -1,64 +0,0 @@ -/* spi.h D.J.Whale 19/07/2014 */ - - -#ifndef SPI_H -#define SPI_H - - -/***** INCLUDES *****/ - -//#include - - -/***** CONSTANTS *****/ - -#define SPI_CPOL0 0 -#define SPI_CPOL1 1 -#define SPI_SPOL0 0 -#define SPI_SPOL1 1 -#define SPI_CPHA0 0 -#define SPI_CPHA1 1 - - -/***** STRUCTURES *****/ - -typedef struct -{ - unsigned char cs; - unsigned char sclk; - unsigned char mosi; - unsigned char miso; - - unsigned char spol; - unsigned char cpol; - unsigned char cpha; - - //struct timespec tSettle; - //struct timespec tHold; - //struct timespec tFreq; - unsigned int tSettle; - unsigned int tHold; - unsigned int tFreq; -} SPI_CONFIG; - - - -/***** FUNCTION PROTOTYPES *****/ - -void spi_init_defaults(void); - -void spi_init(SPI_CONFIG* pConfig); - -void spi_select(void); - -void spi_deselect(void); - -int spi_byte(int txbyte); - -void spi_frame(unsigned char* pTx, unsigned char* pRx, unsigned char count); - -void spi_finished(void); - -#endif - -/***** END OF FILE *****/ diff --git a/src/energenie/spi_test.c b/src/energenie/spi_test.c deleted file mode 100644 index 4fe2332..0000000 --- a/src/energenie/spi_test.c +++ /dev/null @@ -1,83 +0,0 @@ -/* spi_test.c D.J.Whale 18/07/2014 - * - * A simple SPI port exerciser. - * currently only uses the soft SPI (spis) - * TODO: Later will also support hard SPI (spih) - * but will have to sort out the pin configuration structure first for that to work. - */ - - -/***** INCLUDES *****/ - -#include -#include -#include "gpio.h" -#include "spi.h" - - -/***** CONSTANTS *****/ - -/* GPIO numbers on Raspberry Pi */ -#define CS 8 -#define SCLK 11 -#define MOSI 10 -#define MISO 9 - -/* ms */ -#define TSETTLE (1UL * 1000UL) /* us */ -#define THOLD (1UL * 1000UL) /* us */ -#define TFREQ (1UL * 1000UL) /* 1us = 1MHz */ - -int main(int argc, char **argv) -{ - unsigned char cmd_prog[4] = {0xAC, 0x53, 0x00, 0x00}; - unsigned char cmd_id0[4] = {0x30, 0x00, 0x00, 0x00}; - unsigned char cmd_id1[4] = {0x30, 0x00, 0x01, 0x00}; - unsigned char cmd_id2[4] = {0x30, 0x00, 0x02, 0x00}; - - unsigned char rx[4]; - SPI_CONFIG spiConfig = {CS, SCLK, MOSI, MISO, SPI_SPOL0, SPI_CPOL0, SPI_CPHA0, - {0,TSETTLE},{0,THOLD},{0,TFREQ}}; - int i; - unsigned char id[3]; - - - /* Init */ - - printf("init\n"); - //gpio_init(); - spi_init(&spiConfig); - - - /* Enter programming mode */ - - printf("select\n"); - spi_select(); - spi_frame(cmd_prog, NULL, 4); - - - /* Get ID bytes */ - - printf("read ID bytes\n"); - spi_frame(cmd_id0, rx, 4); - id[0] = rx[3]; - - spi_frame(cmd_id1, rx, 4); - id[1] = rx[3]; - - spi_frame(cmd_id2, rx, 4); - id[2] = rx[3]; - - spi_deselect(); - - - /* Show ID bytes */ - - printf("ID: %02X %02X %02X\n", id[0], id[1], id[2]); - - spi_finished(); - return 0; -} - - -/***** END OF FILE *****/ diff --git a/src/energenie/spih.c b/src/energenie/spih.c deleted file mode 100644 index 622afd5..0000000 --- a/src/energenie/spih.c +++ /dev/null @@ -1,65 +0,0 @@ -/* spih.c (Hard SPI) D.J.Whale 19/07/2014 - */ - - -/***** INCLUDES *****/ - -//#include -//#include -//#include -//#include -//#include - -//#include "spi.h" -//#include "gpio.h" - - - -/***** VARIABLES *****/ - -static SPI_CONFIG config; - - -void spi_init_defaults(void) -{ - //TODO -} - - -void spi_init(SPI_CONFIG* pConfig) -{ - //TODO -} - - -void spi_finished(void) -{ - //TODO -} - - -void spi_select(void) -{ - //TODO -} - - -void spi_deselect(void) -{ - //TODO -} - - -int spi_byte(int txbyte) -{ - //TODO -} - - -void spi_frame(unsigned char* pTx, unsigned char* pRx, unsigned char count) -{ - //TODO -} - - -/***** END OF FILE *****/ diff --git a/src/energenie/spis.c b/src/energenie/spis.c deleted file mode 100644 index f77b606..0000000 --- a/src/energenie/spis.c +++ /dev/null @@ -1,172 +0,0 @@ -/* spis.c (soft SPI) D.J.Whale 19/07/2014 - */ - - -/***** INCLUDES *****/ - -#include -#include -//#include -#include -#include - -#include "spi.h" -#include "gpio.h" - - -/***** MACROS *****/ - -#define CLOCK_ACTIVE() gpio_write(config.sclk, config.cpol?0:1) -#define CLOCK_IDLE() gpio_write(config.sclk, config.cpol?1:0) - -#define SELECTED() gpio_write(config.cs, config.spol?1:0) -#define NOT_SELECTED() gpio_write(config.cs, config.spol?0:1) - - -/***** VARIABLES *****/ - -static SPI_CONFIG config; - - -/* Based on code suggested by Gordon Henderson: - * https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.c - * - * Note that his trick of using the hardware timer just didn't work, - * and this is the best of a bad bunch. nanosleep() delays at least - * 100uS in some cases. - */ - -static void delayus(unsigned int us) -{ - struct timeval tNow, tLong, tEnd; - - gettimeofday(&tNow, NULL); - tLong.tv_sec = us / 1000000; - tLong.tv_usec = us % 1000000; - timeradd(&tNow, &tLong, &tEnd); - - while (timercmp(&tNow, &tEnd, <)) - { - gettimeofday(&tNow, NULL); - } -} - - -void spi_init_defaults(void) -{ -#define CS 7 //CE1 -#define SCLK 11 -#define MOSI 10 -#define MISO 9 - -/* ms */ -#define TSETTLE (1) /* us settle */ -#define THOLD (1) /* us hold */ -#define TFREQ (1) /* us half clock */ - - SPI_CONFIG defaultConfig = {CS, SCLK, MOSI, MISO, SPI_SPOL0, SPI_CPOL0, SPI_CPHA0, - TSETTLE, THOLD, TFREQ}; - - spi_init(&defaultConfig); -} - - -void spi_init(SPI_CONFIG* pConfig) -{ - /* It's a standalone library, so init GPIO also */ - gpio_init(); - memcpy(&config, pConfig, sizeof(SPI_CONFIG)); - - //TODO: Implement CPHA1 - if (config.cpha != 0) - { - fprintf(stderr, "error: CPHA 1 not yet supported"); - exit(-1); - } - - gpio_setout(config.sclk); - CLOCK_IDLE(); - - gpio_setout(config.mosi); - gpio_low(config.mosi); - gpio_setin(config.miso); - - gpio_setout(config.cs); - NOT_SELECTED(); -} - - -void spi_finished(void) -{ - gpio_setin(config.mosi); - gpio_setin(config.sclk); - gpio_setin(config.cs); -} - - -void spi_select(void) -{ - SELECTED(); - delayus(config.tSettle); -} - - -void spi_deselect(void) -{ - NOT_SELECTED(); - delayus(config.tSettle); -} - - -int spi_byte(int txbyte) -{ - int rxbyte = 0; - int bitno; - int bit ; - - //TODO: Implement CPHA1 - - for (bitno=0; bitno<8; bitno++) - { - /* Transmit MSB first */ - bit = ((txbyte & 0x80) != 0x00); - txbyte <<= 1; - gpio_write(config.mosi, bit); - delayus(config.tSettle); - CLOCK_ACTIVE(); - delayus(config.tHold); - delayus(config.tFreq); - - /* Read MSB first */ - bit = gpio_read(config.miso); - rxbyte = (rxbyte<<1) | bit; - - CLOCK_IDLE(); - delayus(config.tFreq); - } - return rxbyte; -} - - -void spi_frame(unsigned char* pTx, unsigned char* pRx, unsigned char count) -{ - unsigned char tx = 0; - unsigned char rx; - - while (count > 0) - { - if (pTx != NULL) - { - tx = *(pTx++); - } - rx = spi_byte(tx); - if (pRx != NULL) - { - *(pRx++) = rx; - } - count--; - } -} - - -/***** END OF FILE *****/