diff --git a/src/energenie/drv/build_mac b/src/energenie/drv/build_mac index 8e7a16e..1ac5cf6 100755 --- a/src/energenie/drv/build_mac +++ b/src/energenie/drv/build_mac @@ -3,20 +3,21 @@ # build file for Mac use # build gpio_test -gcc gpio_test.c gpio_sim.c delay_posix.c -mv a.out gpio_test -chmod u+x gpio_test +##gcc gpio_test.c gpio_sim.c delay_posix.c +##mv a.out gpio_test +##chmod u+x gpio_test # build spis_test (soft SPI tester) -gcc spi_test.c spis.c gpio_sim.c delay_posix.c -mv a.out spis_test -chmod u+x spis_test +##gcc spi_test.c spis.c gpio_sim.c delay_posix.c +##mv a.out spis_test +##chmod u+x spis_test + # build hrf69_test -gcc hrf69_test.c hrf69.c spis.c gpio_sim.c delay_posix.c -mv a.out hrf69_test -chmod u+x hrf69_test +gcc hrfm69_test.c hrfm69.c spis.c gpio_sim.c delay_posix.c +mv a.out hrfm69_test +chmod u+x hrfm69_test diff --git a/src/energenie/drv/hrf69.c b/src/energenie/drv/hrf69.c deleted file mode 100644 index 71a49b4..0000000 --- a/src/energenie/drv/hrf69.c +++ /dev/null @@ -1,166 +0,0 @@ -/* hrf69.c 03/04/2016 D.J.Whale - * - * Hope RF RFM69 radio controller code. - */ -#include -#include "system.h" -#include "hrf69.h" -#include "spi.h" - - -// Write an 8 bit value to a register -void HRF_writereg(uint8_t addr, uint8_t data) -{ - spi_select(); - spi_byte(addr | HRF_MASK_WRITE_DATA); - spi_byte(data); - spi_deselect(); -} - - -// Read an 8 bit value from a register -uint8_t HRF_readreg(uint8_t addr) -{ - uint8_t result; - - spi_select(); - spi_byte(addr); - result = spi_byte(0x00); - spi_deselect(); - return result; -} - - -// Write all bytes in buf to the payload FIFO, in a single burst -void HRF_writefifo_burst(uint8_t* buf, uint8_t len) -{ - spi_select(); - spi_byte(HRF_ADDR_FIFO | HRF_MASK_WRITE_DATA); - spi_frame(buf, NULL, len); - spi_deselect(); -} - - -//TODO: where is the buffer memory defined? -//perhaps pass in buffer memory and maxlen -//how do we know the actual length of buffer written to? -//pass in ptr to len variable -uint8_t* HRF_readfifo_burst(void) -{ -//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() -// return buf - return (void*)0; // TODO -} - - -// Check to see if a register matches a specific value or not -HRF_RESULT HRF_checkreg(uint8_t addr, uint8_t mask, uint8_t value) -{ - uint8_t regval = HRF_readreg(addr); - return (regval & mask) == value; -} - - -// Poll a register until it meets some criteria -void HRF_pollreg(uint8_t addr, uint8_t mask, uint8_t value) -{ - while (! HRF_checkreg(addr, mask, value)) - { - // busy wait - } -} - - -// Wait for HRF to be ready after last command -void HRF_wait_ready(void) -{ - HRF_pollreg(HRF_ADDR_IRQFLAGS1, HRF_MASK_MODEREADY, HRF_MASK_MODEREADY); -} - - -// Wait for the HRF to be ready, and ready for tx, after last command -void HRF_wait_txready(void) -{ - HRF_pollreg(HRF_ADDR_IRQFLAGS1, HRF_MASK_MODEREADY|HRF_MASK_TXREADY, HRF_MASK_MODEREADY|HRF_MASK_TXREADY); -} - - -// Change the operating mode of the HRF radi -void HRF_change_mode(uint8_t mode) -{ - HRF_writereg(HRF_ADDR_OPMODE, mode); -} - - -// Clear any data in the HRF payload FIFO, by reading until empty -void HRF_clear_fifo(void) -{ - while ((HRF_readreg(HRF_ADDR_IRQFLAGS2) & HRF_MASK_FIFONOTEMPTY) == HRF_MASK_FIFONOTEMPTY) - { - HRF_readreg(HRF_ADDR_FIFO); - } -} - - -// Check if there is a payload in the FIFO waiting to be processed -HRF_RESULT HRF_check_payload(void) -{ - //TODO: First read might be superflous, but left in just in case - uint8_t irqflags1 = HRF_readreg(HRF_ADDR_IRQFLAGS1); - - uint8_t irqflags2 = HRF_readreg(HRF_ADDR_IRQFLAGS2); - return (irqflags2 & HRF_MASK_PAYLOADRDY) == HRF_MASK_PAYLOADRDY; -} - - -//TODO: unnecessary level of runtime indirection? -//TODO: where is the buffer memory defined? -//perhaps pass in buffer memory and maxlen -//how do we know the actual length of buffer written to? -//pass in ptr to len variable -uint8_t* HRF_receive_payload(void) -{ - return HRF_readfifo_burst(); -} - - -// Send a preformatted payload of data -void HRF_send_payload(uint8_t* payload, uint8_t len) -{ - uint8_t reg; - - HRF_writefifo_burst(payload, len); - HRF_pollreg(HRF_ADDR_IRQFLAGS2, HRF_MASK_PACKETSENT, HRF_MASK_PACKETSENT); - reg = HRF_readreg(HRF_ADDR_IRQFLAGS2); - //if ((reg & HRF_MASK_FIFONOTEMPTY) != 0) or ((reg & HRF_MASK_FIFOOVERRUN) != 0): - // warning("Failed to send payload to HRF") -} - - -// Load a table of configuration values into HRF registers -void HRF_config(HRF_CONFIG_REC* config, uint8_t len) -{ - while (len-- != 0) - { - HRF_writereg(config->addr, config->value); - config++; - } -} - - -//# END diff --git a/src/energenie/drv/hrf69.h b/src/energenie/drv/hrf69.h deleted file mode 100644 index 6402116..0000000 --- a/src/energenie/drv/hrf69.h +++ /dev/null @@ -1,157 +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 - -#include "system.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_TRANSMITTER 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); - -//TODO unnecessary level of runtime indirection? -//TODO where is the buffer memory defined? -//perhaps pass in buffer memory and maxlen -//how do we know the actual length of buffer written to? -//pass in ptr to len variable -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); - - -//TODO unnecessary level of runtime indirection? -//TODO where is the buffer memory defined? -//perhaps pass in buffer memory and maxlen -//how do we know the actual length of buffer written to? -//pass in ptr to len variable -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 deleted file mode 100644 index a0d3b39..0000000 --- a/src/energenie/drv/hrf69_test.c +++ /dev/null @@ -1,189 +0,0 @@ -/* hrf69_test.c D.J.Whale 03/04/2016 - * - * A simple exerciser for the HopeRF RFM69 radio - */ - - -/***** INCLUDES *****/ - -#include -//#include -#include "system.h" -#include "delay.h" -#include "gpio.h" -#include "spi.h" -#include "hrf69.h" -#include "trace.h" - - -/***** CONFIGURATION *****/ - -/* Only define this if you are running mac/pc/pi, - * arduino will have a different console wrapper to drive tests, probably - */ - -#define HRF69_TEST - -/* GPIO assignments for Arduino Pro Micro */ - -#define RESET 2 -#define CS 3 -#define MOSI 4 -#define MISO 5 -#define SCLK 6 - - -/***** FUNCTION PROTOTYPES *****/ - -static void reset(void); -void hrf_test_rw(void); -void hrf_test_send_ook(void); - - -#if defined(HRF69_TEST) -int main(int argc, char **argv) -{ - hrf_test_rw(); - - //TODO: Can't test this until real radio added, - // polling means flags will never clear - //hrf_test_send_ook(); - - return 0; -} -#endif - -// Reset is really a function of how the Energenie radio is wired up to the Pi or -// Arduino, so it will appear in the 'radio' module. It is here for testing convenience. - - -static void reset(void) -{ - SPI_CONFIG radioConfig = {CS, SCLK, MOSI, MISO, SPI_SPOL0, SPI_CPOL0, SPI_CPHA0}; - //TSETTLE, THOLD, TFREQ}; - spi_init(&radioConfig); - - gpio_setout(RESET); - gpio_low(RESET); - delayus(100); - - gpio_high(RESET); - delayms(150); - - gpio_low(RESET); - delayus(100); -} - - -extern void gpio_mock_set_in(uint8_t g, uint8_t v); - - -// write a register and read it back - -#define TX 0x04 -#define RX 0x0C - -void hrf_test_rw(void) -{ - uint8_t result; - - reset(); - gpio_mock_set_in(MISO, 1); // force return bus high to test - - //printf("** write:%02X\n", (unsigned int) HRF_MODE_TRANSMITER); - TRACE_OUTS("** write:"); - TRACE_OUTN(TX); - TRACE_NL(); - - HRF_writereg(HRF_ADDR_OPMODE, TX); - result = HRF_readreg(0x00); - - //printf("** read:%02X\n", (unsigned int) result); - TRACE_OUTS("** read:"); - TRACE_OUTN(result); - TRACE_NL(); - - //printf("** write:%02X\n", (unsigned int) HRF_MODE_RECEIVER); - TRACE_OUTS("** write:"); - TRACE_OUTN(RX); - TRACE_NL(); - - HRF_writereg(HRF_ADDR_OPMODE, RX); - result = HRF_readreg(0x00); - - //printf("** read:%02X\n", (unsigned int) result); - TRACE_OUTS("** read:"); - TRACE_OUTN(result); - TRACE_NL(); - - spi_finished(); -} - - -HRF_CONFIG_REC config_OOK[] = { - {HRF_ADDR_REGDATAMODUL, HRF_VAL_REGDATAMODUL_OOK}, // modulation scheme OOK - {HRF_ADDR_FDEVMSB, 0}, // frequency deviation -> 0kHz - {HRF_ADDR_FDEVLSB, 0}, // frequency deviation -> 0kHz - {HRF_ADDR_FRMSB, HRF_VAL_FRMSB433}, // carrier freq -> 433.92MHz 0x6C7AE1 - {HRF_ADDR_FRMID, HRF_VAL_FRMID433}, // carrier freq -> 433.92MHz 0x6C7AE1 - {HRF_ADDR_FRLSB, HRF_VAL_FRLSB433}, // carrier freq -> 433.92MHz 0x6C7AE1 - {HRF_ADDR_RXBW, HRF_VAL_RXBW120}, // channel filter bandwidth 120kHz - {HRF_ADDR_BITRATEMSB, 0x40}, // 1938b/s - {HRF_ADDR_BITRATELSB, 0x80}, // 1938b/s - {HRF_ADDR_PREAMBLELSB, 0}, // preamble size LSB 3 - {HRF_ADDR_SYNCCONFIG, HRF_VAL_SYNCCONFIG4}, // Size of the Sync word = 4 (SyncSize + 1) - {HRF_ADDR_SYNCVALUE1, HRF_VAL_SYNCVALUE1OOK}, // sync value 1 - {HRF_ADDR_SYNCVALUE2, 0}, // sync value 2 - {HRF_ADDR_SYNCVALUE3, 0}, // sync value 3 - {HRF_ADDR_SYNCVALUE4, 0}, // sync value 4 - {HRF_ADDR_PACKETCONFIG1, HRF_VAL_PACKETCONFIG1OOK}, // Fixed length, no Manchester coding, OOK - {HRF_ADDR_PAYLOADLEN, HRF_VAL_PAYLOADLEN_OOK}, // Payload Length - {HRF_ADDR_FIFOTHRESH, HRF_VAL_FIFOTHRESH30} // Condition to start packet transmission: wait for 30 bytes in FIFO -}; - -// A 'go for broke' OOK payload sender -void hrf_test_send_ook(void) -{ - - reset(); - gpio_mock_set_in(MISO, 1); // force return bus high to test - - HRF_config(config_OOK, sizeof(config_OOK)); - HRF_change_mode(HRF_MODE_TRANSMITTER); - - static uint8_t payload[] = { - // Preamble - 0x00, 0x80, 0x00, 0x00, 0x00, - // Encoded 20 bit address - 0x8E, 0xE8, 0xEE, 0x88, 0x8E, 0xE8, 0xEE, 0x88, 0x8E, 0xE8, - // Command bits - 0xEE, 0xE8 // 1110 = E = switch 1 off - //0xEE, 0xEE // 1111 = F = switch 1 on - }; - - HRF_pollreg(HRF_ADDR_IRQFLAGS1, HRF_MASK_MODEREADY|HRF_MASK_TXREADY, HRF_MASK_MODEREADY|HRF_MASK_TXREADY); - HRF_writefifo_burst(payload, sizeof(payload)); - - for (int i=0; i<8; i++) - { - HRF_pollreg(HRF_ADDR_IRQFLAGS2, HRF_MASK_FIFOLEVEL, 0); - HRF_writefifo_burst(payload, sizeof(payload)); - } - - HRF_pollreg(HRF_ADDR_IRQFLAGS2, HRF_MASK_PACKETSENT, HRF_MASK_PACKETSENT); // wait for Packet sent - - uint8_t irqflags2 = HRF_readreg(HRF_ADDR_IRQFLAGS2); - - TRACE_OUTS("irqflags2:"); - TRACE_OUTN(irqflags2); - TRACE_NL(); - if (((irqflags2 & HRF_MASK_FIFONOTEMPTY) != 0) || ((irqflags2 & HRF_MASK_FIFOOVERRUN) != 0)) - { - TRACE_FAIL("Failed to send repeated payload"); - } - - spi_finished(); -} - - -/***** END OF FILE *****/ diff --git a/src/energenie/drv/hrfm69.c b/src/energenie/drv/hrfm69.c new file mode 100644 index 0000000..3a24f4c --- /dev/null +++ b/src/energenie/drv/hrfm69.c @@ -0,0 +1,167 @@ +/* hrf69.c 03/04/2016 D.J.Whale + * + * Hope RF RFM69 radio controller code. + */ + +#include +#include "system.h" +#include "hrfm69.h" +#include "spi.h" + + +// Write an 8 bit value to a register +void HRF_writereg(uint8_t addr, uint8_t data) +{ + spi_select(); + spi_byte(addr | HRF_MASK_WRITE_DATA); + spi_byte(data); + spi_deselect(); +} + + +// Read an 8 bit value from a register +uint8_t HRF_readreg(uint8_t addr) +{ + uint8_t result; + + spi_select(); + spi_byte(addr); + result = spi_byte(0x00); + spi_deselect(); + return result; +} + + +// Write all bytes in buf to the payload FIFO, in a single burst +void HRF_writefifo_burst(uint8_t* buf, uint8_t len) +{ + spi_select(); + spi_byte(HRF_ADDR_FIFO | HRF_MASK_WRITE_DATA); + spi_frame(buf, NULL, len); + spi_deselect(); +} + + +//TODO: where is the buffer memory defined? +//perhaps pass in buffer memory and maxlen +//how do we know the actual length of buffer written to? +//pass in ptr to len variable +uint8_t* HRF_readfifo_burst(void) +{ +//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() +// return buf + return (void*)0; // TODO +} + + +// Check to see if a register matches a specific value or not +HRF_RESULT HRF_checkreg(uint8_t addr, uint8_t mask, uint8_t value) +{ + uint8_t regval = HRF_readreg(addr); + return (regval & mask) == value; +} + + +// Poll a register until it meets some criteria +void HRF_pollreg(uint8_t addr, uint8_t mask, uint8_t value) +{ + while (! HRF_checkreg(addr, mask, value)) + { + // busy wait + } +} + + +// Wait for HRF to be ready after last command +void HRF_wait_ready(void) +{ + HRF_pollreg(HRF_ADDR_IRQFLAGS1, HRF_MASK_MODEREADY, HRF_MASK_MODEREADY); +} + + +// Wait for the HRF to be ready, and ready for tx, after last command +void HRF_wait_txready(void) +{ + HRF_pollreg(HRF_ADDR_IRQFLAGS1, HRF_MASK_MODEREADY|HRF_MASK_TXREADY, HRF_MASK_MODEREADY|HRF_MASK_TXREADY); +} + + +// Change the operating mode of the HRF radi +void HRF_change_mode(uint8_t mode) +{ + HRF_writereg(HRF_ADDR_OPMODE, mode); +} + + +// Clear any data in the HRF payload FIFO, by reading until empty +void HRF_clear_fifo(void) +{ + while ((HRF_readreg(HRF_ADDR_IRQFLAGS2) & HRF_MASK_FIFONOTEMPTY) == HRF_MASK_FIFONOTEMPTY) + { + HRF_readreg(HRF_ADDR_FIFO); + } +} + + +// Check if there is a payload in the FIFO waiting to be processed +HRF_RESULT HRF_check_payload(void) +{ + //TODO: First read might be superflous, but left in just in case + uint8_t irqflags1 = HRF_readreg(HRF_ADDR_IRQFLAGS1); + + uint8_t irqflags2 = HRF_readreg(HRF_ADDR_IRQFLAGS2); + return (irqflags2 & HRF_MASK_PAYLOADRDY) == HRF_MASK_PAYLOADRDY; +} + + +//TODO: unnecessary level of runtime indirection? +//TODO: where is the buffer memory defined? +//perhaps pass in buffer memory and maxlen +//how do we know the actual length of buffer written to? +//pass in ptr to len variable +uint8_t* HRF_receive_payload(void) +{ + return HRF_readfifo_burst(); +} + + +// Send a preformatted payload of data +void HRF_send_payload(uint8_t* payload, uint8_t len) +{ + uint8_t reg; + + HRF_writefifo_burst(payload, len); + HRF_pollreg(HRF_ADDR_IRQFLAGS2, HRF_MASK_PACKETSENT, HRF_MASK_PACKETSENT); + reg = HRF_readreg(HRF_ADDR_IRQFLAGS2); + //if ((reg & HRF_MASK_FIFONOTEMPTY) != 0) or ((reg & HRF_MASK_FIFOOVERRUN) != 0): + // warning("Failed to send payload to HRF") +} + + +// Load a table of configuration values into HRF registers +void HRF_config(HRF_CONFIG_REC* config, uint8_t len) +{ + while (len-- != 0) + { + HRF_writereg(config->addr, config->value); + config++; + } +} + + +//# END diff --git a/src/energenie/drv/hrfm69.h b/src/energenie/drv/hrfm69.h new file mode 100644 index 0000000..c40b04e --- /dev/null +++ b/src/energenie/drv/hrfm69.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 + +#include "system.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_TRANSMITTER 0x0C // Transmiter +#define HRF_MODE_RECEIVER 0x10 // Receiver + +// Values to store in registers +#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 +#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_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_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); + +//TODO unnecessary level of runtime indirection? +//TODO where is the buffer memory defined? +//perhaps pass in buffer memory and maxlen +//how do we know the actual length of buffer written to? +//pass in ptr to len variable +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); + + +//TODO unnecessary level of runtime indirection? +//TODO where is the buffer memory defined? +//perhaps pass in buffer memory and maxlen +//how do we know the actual length of buffer written to? +//pass in ptr to len variable +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/hrfm69_test.c b/src/energenie/drv/hrfm69_test.c new file mode 100644 index 0000000..d14d47b --- /dev/null +++ b/src/energenie/drv/hrfm69_test.c @@ -0,0 +1,209 @@ +/* hrf69_test.c D.J.Whale 03/04/2016 + * + * A simple exerciser for the HopeRF RFM69 radio + * Configures for OOK, and uses a bitpattern than generates + * a fixed tone, that can be measured at the receiving end. + */ + + +/***** INCLUDES *****/ + +//#include +//#include +#include "system.h" +#include "delay.h" +#include "gpio.h" +#include "spi.h" +#include "hrfm69.h" +#include "trace.h" + + +/***** CONFIGURATION *****/ + +/* Only define this if you are running mac/pc/pi, + * arduino will have a different console wrapper to drive tests, probably + */ + +#define HRFM69_TEST +extern void gpio_mock_set_in(uint8_t g, uint8_t v); + + +/* GPIO assignments for Arduino Pro Micro */ + +//#define RESET 2 +//#define CS 3 +//#define MOSI 4 +//#define MISO 5 +//#define SCLK 6 + +/* GPIO assignments for Raspberry Pi using BCM numbering */ +#define RESET 25 +#define LED_GREEN 27 // (not B rev1) +#define LED_RED 22 + +#define CS 7 // CE1 +#define SCLK 11 +#define MOSI 10 +#define MISO 9 + +SPI_CONFIG radioConfig = {CS, SCLK, MOSI, MISO, SPI_SPOL0, SPI_CPOL0, SPI_CPHA0}; + //TSETTLE, THOLD, TFREQ}; + + +/***** FUNCTION PROTOTYPES *****/ + +static void reset(void); +//void hrf_test_rw(void); +//void hrf_test_send_ook_tone(void); + + +#if defined(HRFM69_TEST) +int main(int argc, char **argv) +{ + gpio_init(); + + gpio_setout(RESET); + gpio_low(RESET); + + gpio_setout(LED_RED); + gpio_low(LED_RED); + gpio_setout(LED_GREEN); + gpio_low(LED_GREEN); + + // spi_init does gpio_init (might not be correct in the longer term for shared GPIO) + //spi_init(&radioConfig); + + gpio_high(LED_RED); + gpio_high(LED_GREEN); + + + delaysec(2); + + gpio_low(LED_RED); + gpio_low(LED_GREEN); + + //hrf_test_send_ook(); + //spi_finished(); + + gpio_finished(); + + return 0; +} +#endif + + +// Reset is really a function of how the Energenie radio is wired up to the Pi or +// Arduino, so it will appear in the 'radio' module. It is here for testing convenience. + +static void reset(void) +{ + gpio_high(RESET); + delayms(150); + + gpio_low(RESET); + delayus(100); +} + + +// write a register and read it back +// TODO readback should read the version register +// write should write a register that is not likely to mess with too much configuration + +//#define TX 0x04 +//#define RX 0x0C + +//void hrf_test_rw(void) +//{ +// uint8_t result; +// +// reset(); +// gpio_mock_set_in(MISO, 1); // force return bus high to test +// +// //printf("** write:%02X\n", (unsigned int) HRF_MODE_TRANSMITER); +// TRACE_OUTS("** write:"); +// TRACE_OUTN(TX); +// TRACE_NL(); +// +// HRF_writereg(HRF_ADDR_OPMODE, TX); +// result = HRF_readreg(0x00); +// +// //printf("** read:%02X\n", (unsigned int) result); +// TRACE_OUTS("** read:"); +// TRACE_OUTN(result); +// TRACE_NL(); +// +// //printf("** write:%02X\n", (unsigned int) HRF_MODE_RECEIVER); +// TRACE_OUTS("** write:"); +// TRACE_OUTN(RX); +// TRACE_NL(); +// +// HRF_writereg(HRF_ADDR_OPMODE, RX); +// result = HRF_readreg(0x00); +// +// //printf("** read:%02X\n", (unsigned int) result); +// TRACE_OUTS("** read:"); +// TRACE_OUTN(result); +// TRACE_NL(); +// +// spi_finished(); +//} + + +#if 0 +HRF_CONFIG_REC config_OOK[] = { + {HRF_ADDR_REGDATAMODUL, HRF_VAL_REGDATAMODUL_OOK}, // modulation scheme OOK + {HRF_ADDR_FDEVMSB, 0}, // frequency deviation -> 0kHz + {HRF_ADDR_FDEVLSB, 0}, // frequency deviation -> 0kHz + {HRF_ADDR_FRMSB, HRF_VAL_FRMSB433}, // carrier freq -> 433.92MHz 0x6C7AE1 + {HRF_ADDR_FRMID, HRF_VAL_FRMID433}, // carrier freq -> 433.92MHz 0x6C7AE1 + {HRF_ADDR_FRLSB, HRF_VAL_FRLSB433}, // carrier freq -> 433.92MHz 0x6C7AE1 + {HRF_ADDR_RXBW, HRF_VAL_RXBW120}, // channel filter bandwidth 120kHz + {HRF_ADDR_BITRATEMSB, 0x1A}, // 4800b/s + {HRF_ADDR_BITRATELSB, 0x0B}, // 4800b/s + {HRF_ADDR_PREAMBLELSB, 0}, // preamble size LSB 3 + {HRF_ADDR_SYNCCONFIG, HRF_VAL_SYNCCONFIG0}, // Size of the Sync word = 4 (SyncSize + 1) + {HRF_ADDR_PACKETCONFIG1, HRF_VAL_PACKETCONFIG1OOK}, // Fixed length, no Manchester coding, OOK + {HRF_ADDR_PAYLOADLEN, 8}, // Payload Length + {HRF_ADDR_FIFOTHRESH, 8} // Condition to start packet transmission: wait for 30 bytes in FIFO +}; +#endif + + +#if 0 +// Send a test tone using OOK modulation +void hrf_test_send_ook_tone(void) +{ + reset(); + + HRF_config(config_OOK, sizeof(config_OOK)); + HRF_change_mode(HRF_MODE_TRANSMITTER); + + /* Wait for transmitter to be ready */ + HRF_pollreg(HRF_ADDR_IRQFLAGS1, HRF_MASK_MODEREADY|HRF_MASK_TXREADY, HRF_MASK_MODEREADY|HRF_MASK_TXREADY); + + /* A regular tone */ + static uint8_t payload[] = { + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA + }; + + while (1) /* Forever */ + { + HRF_writefifo_burst(payload, sizeof(payload)); + HRF_pollreg(HRF_ADDR_IRQFLAGS2, HRF_MASK_PACKETSENT, HRF_MASK_PACKETSENT); // wait for Packet sent + } + + + //uint8_t irqflags2 = HRF_readreg(HRF_ADDR_IRQFLAGS2); + + //TRACE_OUTS("irqflags2:"); + //TRACE_OUTN(irqflags2); + //TRACE_NL(); + //if (((irqflags2 & HRF_MASK_FIFONOTEMPTY) != 0) || ((irqflags2 & HRF_MASK_FIFOOVERRUN) != 0)) + //{ + // TRACE_FAIL("Failed to send repeated payload"); + //} +} +#endif + + +/***** END OF FILE *****/ diff --git a/src/energenie/drv/radio.c b/src/energenie/drv/radio.c index a41c0bb..029959a 100644 --- a/src/energenie/drv/radio.c +++ b/src/energenie/drv/radio.c @@ -1,15 +1,17 @@ -/* radio.c D.J.Whale */ +/* radio.c 12/04/2016 D.J.Whale + * + * An interface to the Energenie radio. + */ -// # 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. -// // + +/***** CONFIGURATION TABLES *****/ + + + + + + +// // // import spi // // // def warning(msg): diff --git a/src/energenie/drv/radio.h b/src/energenie/drv/radio.h index 5fd45b0..37719c7 100644 --- a/src/energenie/drv/radio.h +++ b/src/energenie/drv/radio.h @@ -12,6 +12,19 @@ #define RADIO_MODULATION_OOK 0 #define RADIO_MODULATION_FSK 1 + +// Energenie specific Values +#define RADIO_VAL_SYNCVALUE1FSK 0x2D // 1st byte of Sync word +#define RADIO_VAL_SYNCVALUE2FSK 0xD4 // 2nd byte of Sync word +#define RADIO_VAL_SYNCVALUE1OOK 0x80 // 1nd byte of Sync word +#define RADIO_VAL_PACKETCONFIG1FSK 0xA2 // Variable length, Manchester coding, Addr must match NodeAddress +#define RADIO_VAL_PACKETCONFIG1FSKNO 0xA0 // Variable length, Manchester coding +#define RADIO_VAL_PACKETCONFIG1OOK 0 // Fixed length, no Manchester coding +#define RADIO_VAL_PAYLOADLEN_OOK (13 + 8 * 17) // Payload Length +//#define RADIO_VAL_NODEADDRESS01 0x01 // Node address used in address filtering +//#define RADIO_VAL_NODEADDRESS04 0x04 // Node address used in address filtering + + extern void radio_init(void); extern void radio_modulation(RADIO_MODULATION mod); diff --git a/src/energenie/drv/radio_test.c b/src/energenie/drv/radio_test.c index b4232fe..9dc8084 100644 --- a/src/energenie/drv/radio_test.c +++ b/src/energenie/drv/radio_test.c @@ -1,15 +1,18 @@ /* radio_test.c D.J.Whale 03/04/2016 * * A simple Energenie radio exerciser + * + * Repeatedly transmits OOK packets to turn switch 1 on and off. */ /***** INCLUDES *****/ -//#include -//#include -//#include "gpio.h" -//#include "spi.h" +#include "system.h" +#include "radio.h" +#include "gpio.h" +#include "spi.h" +#include "hrf69.h" /***** CONSTANTS *****/ @@ -17,6 +20,9 @@ int main(int argc, char **argv) { + gpio_init(); + spi_init_defaults(); + //TODO return 0; } diff --git a/src/energenie/drv/spis.c b/src/energenie/drv/spis.c index 5e1bd40..75b5290 100644 --- a/src/energenie/drv/spis.c +++ b/src/energenie/drv/spis.c @@ -7,8 +7,8 @@ /***** INCLUDES *****/ //#include -//#include -//#include +//#include // memcpy +#include // memcpy (not on Arduino?) #include "system.h" #include "spi.h"