void RFM69_send(const uint8_t* data, uint8_t len, uint8_t power) { // power is TX Power in dBmW (valid values are 2dBmW-20dBmW) if(power<2 || power >20) { // Could be dangerous, so let's check this return; } uint8_t oldMode = _mode; // Copy data into TX Buffer memcpy(_buf, data, len); // Update TX Buffer Size _bufLen = len; RFM69_clearFifo(); // Start Transmitter RFM69_setMode(RFM69_MODE_TX); // Set up PA if(power<=17) { // Set PA Level uint8_t paLevel = power + 14; spiWrite(RFM69_REG_11_PA_LEVEL, RF_PALEVEL_PA0_OFF | RF_PALEVEL_PA1_ON | RF_PALEVEL_PA2_ON | paLevel); } else { // Disable Over Current Protection spiWrite(RFM69_REG_13_OCP, RF_OCP_OFF); // Enable High Power Registers spiWrite(RFM69_REG_5A_TEST_PA1, 0x5D); spiWrite(RFM69_REG_5C_TEST_PA2, 0x7C); // Set PA Level uint8_t paLevel = power + 11; spiWrite(RFM69_REG_11_PA_LEVEL, RF_PALEVEL_PA0_OFF | RF_PALEVEL_PA1_ON | RF_PALEVEL_PA2_ON | paLevel); } // Wait for PA ramp-up while(!(spiRead(RFM69_REG_27_IRQ_FLAGS1) & RF_IRQFLAGS1_TXREADY)) { }; // Throw Buffer into FIFO, packet transmission will start automatically RFM69_spiFifoWrite(_buf, _bufLen); // Clear MCU TX Buffer _bufLen = 0; // Wait for packet to be sent while(!(spiRead(RFM69_REG_28_IRQ_FLAGS2) & RF_IRQFLAGS2_PACKETSENT)) {}; // Return Transceiver to original mode RFM69_setMode(RFM69_MODE_RX); // If we were in high power, switch off High Power Registers if(power>17) { // Disable High Power Registers spiWrite(RFM69_REG_5A_TEST_PA1, 0x55); spiWrite(RFM69_REG_5C_TEST_PA2, 0x70); // Enable Over Current Protection spiWrite(RFM69_REG_13_OCP, RF_OCP_ON | RF_OCP_TRIM_95); } }
/** * It processing incoming data by the radio or serial connection. This function * has to be continously called to keep the node running. This function also * adds a delay which is specified as 100ms per unit. Therefore 1000 = 100 sec * @param countdown delay added to this function */ void awaitData(int countdown) { uint8_t rx_len; //Clear buffer data_temp[0] = '\0'; RFM69_setMode(RFM69_MODE_RX); while(countdown > 0) { // Check rx buffer if(RFM69_checkRx() == 1) { RFM69_recv(data_temp, &rx_len); data_temp[rx_len - 1] = '\0'; #ifdef DEBUG //rssi = RFM69_lastRssi(); printf("rx: %s\r\n",data_temp); //printf("RSSI: %d\r\n, rssi"); #endif processData(rx_len); } #ifdef SERIAL_IN // Check tx buffer checkTxBuffer(); #endif countdown--; mrtDelay(100); } }
void sleepRadio(){ //printf("Sleeping"); RFM69_setMode(RFM69_MODE_SLEEP); init_sleep(); sleepMicro(TX_GAP * 100); //printf("Awake"); }
/** * Packet data transmission * @param Packet length */ void transmitData(uint8_t i) { #ifdef DEBUG printf("tx: %s\r\n", data_temp); #endif // Transmit the data (need to include the length of the packet and power in dbmW) RFM69_send(data_temp, i, POWER_OUTPUT); //Ensure we are in RX mode RFM69_setMode(RFM69_MODE_RX); }
/** * Packet data transmission * @param Packet length */ void transmitData(uint8_t i) { #ifdef GATEWAY printf("rx: %s|0\r\n", data_temp); #endif #ifdef ZOMBIE_MODE // Transmit the data (need to include the length of the packet and power in dbmW) RFM69_send(data_temp, i, POWER_OUTPUT); RFM69_setMode(RFM69_MODE_SLEEP); #else // Transmit the data (need to include the length of the packet and power in dbmW) RFM69_send(data_temp, i, POWER_OUTPUT); //Ensure we are in RX mode RFM69_setMode(RFM69_MODE_RX); #endif }
int RFM69_readTemp() { // Store current transceiver mode uint8_t oldMode = _mode; // Set mode into Standby (required for temperature measurement) RFM69_setMode(RFM69_MODE_STDBY); // Trigger Temperature Measurement spiWrite(RFM69_REG_4E_TEMP1, RF_TEMP1_MEAS_START); // Check Temperature Measurement has started if(!(RF_TEMP1_MEAS_RUNNING && spiRead(RFM69_REG_4E_TEMP1))){ return 255; } // Wait for Measurement to complete while(RF_TEMP1_MEAS_RUNNING && spiRead(RFM69_REG_4E_TEMP1)) { }; // Read raw ADC value uint8_t rawTemp = spiRead(RFM69_REG_4F_TEMP2); // Set transceiver back to original mode RFM69_setMode(oldMode); // Return processed temperature value int temperature = 168 - rawTemp; return temperature; }
/** * It processing incoming data by the radio or serial connection. This function * has to be continously called to keep the node running. This function also * adds a delay which is specified as 100ms per unit. Therefore 1000 = 100 sec * @param countdown delay added to this function */ void awaitData(int countdown) { uint8_t rx_len, flags1, old_flags1 = 0x90; //Clear buffer data_temp[0] = '\0'; RFM69_setMode(RFM69_MODE_RX); rx_restarts = 0; while(countdown > 0) { flags1 = spiRead(RFM69_REG_27_IRQ_FLAGS1); #ifdef DEBUG if (flags1 != old_flags1) { printf("f1: %02x\r\n", flags1); old_flags1 = flags1; } #endif if (flags1 & RF_IRQFLAGS1_TIMEOUT) { // restart the Rx process spiWrite(RFM69_REG_3D_PACKET_CONFIG2, spiRead(RFM69_REG_3D_PACKET_CONFIG2) | RF_PACKET2_RXRESTART); rx_restarts++; // reset the RSSI threshold floor_rssi = RFM69_sampleRssi(); #ifdef DEBUG // and print threshold printf("Restart Rx %d\r\n", RFM69_lastRssiThreshold()); #endif } // Check rx buffer if(RFM69_checkRx() == 1) { RFM69_recv(data_temp, &rx_len); data_temp[rx_len - 1] = '\0'; processData(rx_len); } countdown--; mrtDelay(100); } }
uint8_t RFM69_init() { mrtDelay(12); //Configure SPI spiInit(LPC_SPI0,24,0); mrtDelay(100); // Set up device uint8_t i; for (i = 0; CONFIG[i][0] != 255; i++) spiWrite(CONFIG[i][0], CONFIG[i][1]); RFM69_setMode(_mode); // Clear TX/RX Buffer _bufLen = 0; return 1; }
void RFM69_clearFifo() { // Must only be called in RX Mode // Apparently this works... found in HopeRF demo code RFM69_setMode(RFM69_MODE_STDBY); RFM69_setMode(RFM69_MODE_RX); }
int main(void) { #ifdef ZOMBIE_MODE LPC_SYSCON->BODCTRL = 0x11; //Should be set to Level 1 (Assertion 2.3V, De-assertion 2.4V) reset #endif #if defined(GATEWAY) || defined(DEBUG) // Initialise the UART0 block for printf output uart0Init(115200); #endif // Configure the multi-rate timer for 1ms ticks mrtInit(__SYSTEM_CLOCK/1000); /* Enable AHB clock to the Switch Matrix , UART0 , GPIO , IOCON, MRT , ACMP */ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7) | (1 << 14) /*| (1 << 6)*//* | (1 << 18)*/ | (1 << 10) | (1 << 19); // Configure the switch matrix (setup pins for UART0 and SPI) configurePins(); #ifdef DEBUG mrtDelay(100); printf("Node Booted\r\n"); mrtDelay(100); #endif RFM69_init(); #ifdef ZOMBIE_MODE //This is to allow the setup to recover from the initial boot and // avoid a loop RFM69_setMode(RFM69_MODE_SLEEP); init_sleep(); sleepMicro(20000); #endif #ifdef DEBUG printf("Node initialized, version %s\r\n",GIT_VER); #endif //Seed random number generator, we can use our 'unique' ID random_output = NODE_ID[0] + NODE_ID[1] + NODE_ID[2]; while(1) { /* #ifdef ZOMBIE_MODE adc_result = acmpVccEstimate(); // Before transmitting if the input V is too low we could sleep again if (adc_result < 3100 || adc_result > 10000) { sleepRadio(); } #endif */ incrementPacketCount(); //Clear buffer data_temp[0] = '\0'; uint8_t n; //Create the packet int int_temp; #ifdef ZOMBIE_MODE //This is to allow the setup to recover from the initial boot and // avoid a loop RFM69_setMode(RFM69_MODE_SLEEP); init_sleep(); sleepMicro(10000); #endif int_temp = RFM69_readTemp(); // Read transmitter temperature rx_rssi = RFM69_lastRssi(); // read the rssi threshold before re-sampling noise floor which will change it rssi_threshold = RFM69_lastRssiThreshold(); floor_rssi = RFM69_sampleRssi(); #ifdef ZOMBIE_MODE //This is to allow the setup to recover from the initial boot and // avoid a loop RFM69_setMode(RFM69_MODE_SLEEP); init_sleep(); sleepMicro(10000); #endif #ifdef ZOMBIE_MODE adc_result = acmpVccEstimate(); //sleepMicro(20000); #endif #ifdef DEBUG printf("ADC: %d\r\n", adc_result); #endif #ifdef ZOMBIE_MODE //This is to allow the setup to recover from the initial boot and // avoid a loop RFM69_setMode(RFM69_MODE_SLEEP); init_sleep(); sleepMicro(10000); #endif if(data_count == 97) { n = sprintf(data_temp, "%d%cL%s[%s]", NUM_REPEATS, data_count, LOCATION_STRING, NODE_ID); } else { #ifdef DEBUG //n = sprintf(data_temp, "%d%cT%dR%d,%dC%dX%d,%dV%d[%s]", NUM_REPEATS, data_count, int_temp, rx_rssi, floor_rssi, rx_packets, rx_restarts, rssi_threshold, adc_result, NODE_ID); n = sprintf(data_temp, "%d%cT%dV%d[%s]", NUM_REPEATS, data_count, int_temp, adc_result, NODE_ID); #elif defined(ZOMBIE_MODE) n = sprintf(data_temp, "%d%cT%dV%d[%s]", NUM_REPEATS, data_count, int_temp, adc_result, NODE_ID); #else n = sprintf(data_temp, "%d%cT%dR%d[%s]", NUM_REPEATS, data_count, int_temp, rx_rssi, NODE_ID); #endif } transmitData(n); #ifdef ZOMBIE_MODE sleepRadio(); #else awaitData(TX_GAP); #endif } }