diff --git a/src/energenie/drv/build_mac b/src/energenie/drv/build_mac index 1ac5cf6..ba60d4a 100755 --- a/src/energenie/drv/build_mac +++ b/src/energenie/drv/build_mac @@ -1,5 +1,6 @@ #! /bin/bash +echo '********************************************************************************' # build file for Mac use # build gpio_test @@ -34,9 +35,9 @@ # build radio_test -## gcc radio_test.c radio.c hrf69.c spis_rpi.c gpio_rpi.c -## mv a.out radio_test -## chmod u+x radio_test +gcc radio_test.c radio.c hrfm69.c spis.c gpio_rpi.c delay_posix.c +mv a.out radio_test +chmod u+x radio_test # build spi .so library on Raspberry Pi diff --git a/src/energenie/drv/hrfm69_test.c b/src/energenie/drv/hrfm69_test.c index fdb304b..eaa69b4 100644 --- a/src/energenie/drv/hrfm69_test.c +++ b/src/energenie/drv/hrfm69_test.c @@ -8,8 +8,6 @@ /***** INCLUDES *****/ -//#include -//#include #include "system.h" #include "delay.h" #include "gpio.h" diff --git a/src/energenie/drv/radio.c b/src/energenie/drv/radio.c index 029959a..68e21e1 100644 --- a/src/energenie/drv/radio.c +++ b/src/energenie/drv/radio.c @@ -1,239 +1,50 @@ /* radio.c 12/04/2016 D.J.Whale * - * An interface to the Energenie radio. + * An interface to the Energenie Raspberry Pi Radio. */ -/***** CONFIGURATION TABLES *****/ +/***** INCLUDES *****/ + +#include "system.h" +#include "radio.h" +#include "delay.h" +#include "gpio.h" +#include "spi.h" +#include "hrfm69.h" +#include "trace.h" +/***** CONFIGURATION *****/ + +// Energenie specific radio config 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 (WRONG!) + +//TODO: Not sure, might pass this in? What about on Arduino? +//What about if we have multiple chip selects on same SPI? +//What about if we have multiple spi's on different pins? + +/* 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}; - - -// // -// 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 -------------------------------------- -// // +//----- ENERGENIE SPECIFIC CONFIGURATIONS -------------------------------------- // config_FSK = [ // [ADDR_REGDATAMODUL, VAL_REGDATAMODUL_FSK], # modulation scheme FSK // [ADDR_FDEVMSB, VAL_FDEVMSB30], # frequency deviation 5kHz 0x0052 -> 30kHz 0x01EC @@ -246,208 +57,387 @@ // [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_NODEADDRESS, 0x06], # Node address used in address filtering TODO??? // [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 -------------------------------------------------------------- -// // + + +static 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}, // bitrate:4800b/s + {HRF_ADDR_BITRATELSB, 0x0B}, // bitrate:4800b/s + {HRF_ADDR_PREAMBLELSB, 0}, // preamble size LSB + {HRF_ADDR_SYNCCONFIG, HRF_VAL_SYNCCONFIG0}, // Size of sync word (disabled) + {HRF_ADDR_PACKETCONFIG1, 0x00}, // Fixed length, no Manchester coding +}; +#define CONFIG_OOK_COUNT (sizeof(config_OOK)/sizeof(HRF_CONFIG_REC)) + + +/***** MODULE STATE *****/ + // mode = None // modulation_fsk = None -// // + + +/***** LOCAL FUNCTION PROTOTYPES *****/ + +static uint8_t read_ver(void); +static void reset(void); + + +/*---------------------------------------------------------------------------*/ + +static void reset(void) +{ + gpio_high(RESET); + delayms(150); + + gpio_low(RESET); + delayus(100); +} + + +/*---------------------------------------------------------------------------*/ + +static uint8_t read_ver(void) +{ + return HRF_readreg(HRF_ADDR_VERSION); +} + + +/*---------------------------------------------------------------------------*/ + +void radio_init(void) +{ +#if 0 + + TRACE_OUTS("start\n"); + + //gpio_init(); done by spi_init at moment + spi_init(&radioConfig); + + gpio_setout(RESET); + gpio_low(RESET); + gpio_setout(LED_RED); + gpio_low(LED_RED); + gpio_setout(LED_GREEN); + gpio_low(LED_GREEN); + + TRACE_OUTS("reset...\n"); + reset(); + + TRACE_OUTS("reading radiover...\n"); + uint8_t rv = read_ver(); + TRACE_OUTN(rv); + TRACE_NL(); + if (rv != 36) + { + TRACE_FAIL("unexpected radio ver, not 36(dec)\n"); + } + + TRACE_OUTS("standby mode\n"); + HRF_change_mode(HRF_MODE_STANDBY); + HRF_pollreg(HRF_ADDR_IRQFLAGS1, HRF_MASK_MODEREADY, HRF_MASK_MODEREADY); + + + TRACE_OUTS("testing...\n"); + //hrf_test_send_ook_tick(); + hrf_test_send_energenie_ook_switch(); + + //spi_finished(); + gpio_finished(); + + return 0; +#endif +// // // 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() -// // -// +// +// HRF_clear_fifo() // not needed? +} + + +/*---------------------------------------------------------------------------*/ + +void radio_modulation(RADIO_MODULATION mod) +{ // 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 -// // -// +} + + +/*---------------------------------------------------------------------------*/ + +void radio_transmitter(RADIO_MODULATION mod) +{ // 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() -// // -// +} + + +/*---------------------------------------------------------------------------*/ + +void radio_transmit(uint8_t* payload, uint8_t len, uint8_t repeats) +{ +// NOTE: repeats parameter, needs to configure HRF payload sender to repeat +// packet that number of times. +// NOTE: Payload should already be bit encoded and preambled by time it gets here + // def transmit(payload): // """Transmit a single payload using the present modulation scheme""" // if not modulation_fsk: -// HRF_send_OOK_payload(payload) +// HRF_send_OOK_payload(payload, repeats) // might not actually be different // else: -// HRF_send_payload(payload) -// // -// +// HRF_send_payload(payload, repeats) +} + + +/*---------------------------------------------------------------------------*/ + +void radio_receiver(RADIO_MODULATION mod) +{ // 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" -// // -// +} + + +/*---------------------------------------------------------------------------*/ + +RADIO_RESULT radio_isReceiveWaiting(void) +{ // def isReceiveWaiting(): // """Check to see if a payload is waiting in the receive buffer""" // return HRF_check_payload() -// // -// + return RADIO_RESULT_ERR_UNIMPLEMENTED; +} + + +/*---------------------------------------------------------------------------*/ + +RADIO_RESULT radio_receive(uint8_t* buf, uint8_t len) +{ // def receive(): // """Receive a single payload from the buffer using the present modulation scheme""" // return HRF_receive_payload() -// // -// + return RADIO_RESULT_ERR_UNIMPLEMENTED; +} + + +/*---------------------------------------------------------------------------*/ + +void radio_standby(void) +{ + //TODO: change radio mode to STANDBY to turn PA off and preserve power. +} + + +/*---------------------------------------------------------------------------*/ + +void radio_finished(void) +{ // def finished(): // """Close the library down cleanly when finished""" -// spi.finished() -// // -// -// # END +// radio.standby() ?? +// spi.finished() ?? +// gpio.finished() ?? +} + + +/*---------------------------------------------------------------------------*/ + +// A hard coded test of switching an Energenie switch on and off +//TODO this is for testing only, will be simplified and moved into radio_transmit. +// +//TODO note that we want to change this to use FIFO level rather than PACKETSENT +//so that we can send arbitrary length packets with arbitrary number of repeats +//(i.e. not limited by the U8 size of the payloadlen register in HRF) + +static void hrf_test_send_energenie_ook_switch(void) +{ +#if 0 + // Note, when PA starts up, radio inserts a 01 at start before any user data + // we might need to pad away from this by sending a sync of many zero bits + // to prevent it being misinterpreted as a preamble, and prevent it causing + // the first bit of the preamble being twice the length it should be in the + // first packet. + // Also need to confirm this bit only occurs when transmit actually starts, + // and not on every FIFO load. + + /* manual preamble, 20 bit encoded address, 4 encoded data bits */ + static uint8_t payload[16] = { + 0x80, 0x00, 0x00, 0x00, // preamble pulse with timing violation gap + // Energenie 'random' 20 bit address is 0x6C6C6 + // 0110 1100 0110 1100 0110 + // 0 encoded as 8 (1000) + // 1 encoded as E (1110) + 0x8E, 0xE8, 0xEE, 0x88, 0x8E, 0xE8, 0xEE, 0x88, 0x8E, 0xE8, + // Energenie 'switch 1 ON' command F 1111 (0xEE, 0xEE) + 0xEE, 0xEE + // Energenie 'switch 1 OFF' command E 1110 (0xEE, 0xE8) + //0xEE, 0xE8 + }; +/* Last byte of the payload for switch 1 */ +#define ON 0xEE +#define OFF 0xE8 +// Limited by U8 size of PAYLOADLEN reg (15*16=240) +#define REPEATS 15 +// To get longer repeats, we'll have to design a new 'unlimited' +// payload sender, and use FIFOEMPTY as a way to detect end of transmit. + + int i; + uint8_t irqflags1; + uint8_t irqflags2; + + TRACE_OUTS("config\n"); + HRF_config(config_OOK, CONFIG_OOK_COUNT); + // the full packet/burst consists of repeated payloads + // packetsent will trigger when this number of bytes have been transmitted + HRF_writereg(HRF_ADDR_PAYLOADLEN, sizeof(payload) * REPEATS); + // but the FIFO is filled in 1 message (4+10+2=16 byte) sections + // level triggers when it 'strictly exceeds' level (i.e. 16 bytes starts tx, + // and <=15 bytes triggers fifolevel irqflag to be cleared) + HRF_writereg(HRF_ADDR_FIFOTHRESH, sizeof(payload)-1); + + uint8_t last_byte = ON; + + while (1) + { + /* Bring into transmitter mode and ramp up the PA */ + TRACE_OUTS("transmitter mode\n"); + HRF_change_mode(HRF_MODE_TRANSMITTER); + + TRACE_OUTS("wait for modeready,txready in irqflags1\n"); + HRF_pollreg(HRF_ADDR_IRQFLAGS1, HRF_MASK_MODEREADY|HRF_MASK_TXREADY, HRF_MASK_MODEREADY|HRF_MASK_TXREADY); + + irqflags1 = HRF_readreg(HRF_ADDR_IRQFLAGS1); + irqflags2 = HRF_readreg(HRF_ADDR_IRQFLAGS2); + TRACE_OUTS("irqflags1,2="); + TRACE_OUTN(irqflags1); + TRACE_OUTC(','); + TRACE_OUTN(irqflags2); + TRACE_NL(); + + /* Set this as alternate ON or OFF bursts */ + payload[sizeof(payload)-1] = last_byte; + + TRACE_OUTS("tx repeats in a single burst:"); + TRACE_OUTN(last_byte); + TRACE_NL(); + + // send a number of payload repeats for the whole packet burst + for (i=0; i