void setModeRX(void) { uint8_t val; writeRegPgmBuf((uint8_t *)RFM73_cmd_flush_rx, sizeof(RFM73_cmd_flush_rx)); val = readRegVal(RFM73_REG_STATUS); writeRegVal(RFM73_CMD_WRITE_REG | RFM73_REG_STATUS, val); CE_LOW; val = readRegVal(RFM73_REG_CONFIG); val |= RFM73_PIN_PRIM_RX; writeRegVal(RFM73_CMD_WRITE_REG | RFM73_REG_CONFIG, val); CE_HIGH; }
void setModeTX(void) { uint8_t val; writeRegPgmBuf((uint8_t *)RFM73_cmd_flush_tx, sizeof(RFM73_cmd_flush_tx)); val = readRegVal(RFM73_REG_STATUS); writeRegVal(RFM73_CMD_WRITE_REG | RFM73_REG_STATUS, val); CE_LOW; val = readRegVal(RFM73_REG_CONFIG); val &= ~RFM73_PIN_PRIM_RX; writeRegVal(RFM73_CMD_WRITE_REG | RFM73_REG_CONFIG, val); // Don't turn the radio on to save power //CE_HIGH; }
void RFM70::initRegisters() { // Init bank 0 registers selectBank(0); // The last two regs in the bank0Init list will be handled later for (int i = 0; i < 20; i++) { writeRegVal(pgm_read_byte(&RFM70_bank0Init[i][0]), pgm_read_byte(&RFM70_bank0Init[i][1])); } // Init address registers in bank 0 writeRegPgmBuf((uint8_t *) RFM70_cmd_adrRX0, sizeof(RFM70_cmd_adrRX0)); writeRegPgmBuf((uint8_t *) RFM70_cmd_adrRX1, sizeof(RFM70_cmd_adrRX1)); writeRegPgmBuf((uint8_t *) RFM70_cmd_adrTX, sizeof(RFM70_cmd_adrTX)); // Activate Feature register if (!readRegVal(RFM70_REG_FEATURE)) { writeRegPgmBuf((uint8_t *) RFM70_cmd_activate, sizeof(RFM70_cmd_activate)); } // Now set Registers 1D and 1C writeRegVal(pgm_read_byte(&RFM70_bank0Init[22][0]), pgm_read_byte(&RFM70_bank0Init[22][1])); writeRegVal(pgm_read_byte(&RFM70_bank0Init[21][0]), pgm_read_byte(&RFM70_bank0Init[21][1])); // Init bank 1 registers selectBank(1); for (int i = 0; i < 14; i++) { writeRegPgmBuf((uint8_t *) RFM70_bank1Init[i], sizeof(RFM70_bank1Init[i])); } // set ramp curve writeRegPgmBuf((uint8_t *) RFM70_bank1R0EInit, sizeof(RFM70_bank1R0EInit)); // do we have to toggle some bits here like in the example code? writeRegPgmBuf((uint8_t *) RFM70_cmd_tog1, sizeof(RFM70_cmd_tog1)); writeRegPgmBuf((uint8_t *) RFM70_cmd_tog2, sizeof(RFM70_cmd_tog2)); delayMs(RFM70_END_INIT_WAIT_MS); //Check the ChipID if (readRegVal(0x08) != 0x63) { debug(RFM70_DEBUG_WRONG_CHIP_ID); } selectBank(0); setModeRX(); }
bool initRegisters() { // init bank 0 registers selectBank(0); // !! The last two regs in the bank0Init list will be handled later for (int i = 0; i < 20; i++) writeRegVal(pgm_read_byte(&RFM73_bank0Init[i][0]), pgm_read_byte(&RFM73_bank0Init[i][1])); // init address registers in bank 0 writeRegPgmBuf((uint8_t *)RFM73_cmd_adrRX0, sizeof(RFM73_cmd_adrRX0)); writeRegPgmBuf((uint8_t *)RFM73_cmd_adrRX1, sizeof(RFM73_cmd_adrRX1)); writeRegPgmBuf((uint8_t *)RFM73_cmd_adrTX, sizeof(RFM73_cmd_adrTX)); // activate Feature register if (!readRegVal(RFM73_REG_FEATURE)) writeRegPgmBuf((uint8_t *)RFM73_cmd_activate, sizeof(RFM73_cmd_activate)); // now set Registers 1D and 1C writeRegVal(pgm_read_byte(&RFM73_bank0Init[22][0]), pgm_read_byte(&RFM73_bank0Init[22][1])); writeRegVal(pgm_read_byte(&RFM73_bank0Init[21][0]), pgm_read_byte(&RFM73_bank0Init[21][1])); // init bank 1 registers selectBank(1); for (int i = 0; i < 14; i++) writeRegPgmBuf((uint8_t *)RFM73_bank1Init[i], sizeof(RFM73_bank1Init[i])); // set ramp curve writeRegPgmBuf((uint8_t *)RFM73_bank1R0EInit, sizeof(RFM73_bank1R0EInit)); // do we have to toggle some bits here like in the example code? writeRegPgmBuf((uint8_t *)RFM73_cmd_tog1, sizeof(RFM73_cmd_tog1)); writeRegPgmBuf((uint8_t *)RFM73_cmd_tog2, sizeof(RFM73_cmd_tog2)); _delay_ms(RFM73_END_INIT_WAIT_MS); //Check the ChipID if (readRegVal(0x08) != 0x63) { return false; } selectBank(0); setModeRX(); return true; }
void turnOff() { uint8_t status = readRegVal(RFM73_REG_STATUS); status &= ~PWR_BIT; writeRegVal(RFM73_CMD_WRITE_REG | RFM73_REG_STATUS, status); CE_LOW; }
void RFM70::setModeRX(void) { uint8_t val; // Flush RX FIFO writeRegPgmBuf((uint8_t *) RFM70_cmd_flush_rx, sizeof(RFM70_cmd_flush_rx)); // Read Status val = readRegVal(RFM70_REG_STATUS); // Reset IRQ bits writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, val); // RFM chip disable digitalWrite(_ce, LOW); // set PRIM_RX bit to 1 val = readRegVal(RFM70_REG_CONFIG); val |= RFM70_PIN_PRIM_RX; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_CONFIG, val); // RFM chip enable digitalWrite(_ce, HIGH); }
void RFM70::configARC(uint8_t arc) { if (arc > 0x0f) { return; } uint8_t tmp = readRegVal(RFM70_REG_SETUP_RETR); tmp &= (arc | 0xF0); writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_SETUP_RETR, tmp); }
void RFM70::setPower(uint8_t pwr) { if (pwr > 1) { return; } uint8_t tmp = readRegVal(RFM70_REG_CONFIG); tmp &= (0xFD | (pwr << 1)); writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_CONFIG, tmp); }
void RFM70::configARD(uint8_t ard) { if (ard > 0x0f) { return; } uint8_t tmp = readRegVal(RFM70_REG_SETUP_RETR); tmp &= ((ard << 4) | 0x0F); writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_SETUP_RETR, tmp); }
void RFM70::confAddrWidth(uint8_t width) { if (width < 3 || width > 5) { return; } uint8_t tmp = readRegVal(RFM70_REG_SETUP_AW); tmp &= (0xF0 | (width - 2)); writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_SETUP_AW, tmp); }
void setPower(uint8_t pwr) { if (pwr > 3) return; uint8_t tmp = readRegVal(RFM73_REG_RF_SETUP); tmp &= 0xF9; tmp |= pwr << 1; writeRegVal(RFM73_CMD_WRITE_REG | RFM73_REG_RF_SETUP, tmp); }
void RFM70::configRfPower(uint8_t pwr) { if (pwr > 3) { return; } uint8_t tmp = readRegVal(RFM70_REG_RF_SETUP); tmp &= 0xF9; tmp |= pwr << 1; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_RF_SETUP, tmp); }
void RFM70::configLnaGain(uint8_t gain) { if (gain > 1) { return; } uint8_t tmp = readRegVal(RFM70_REG_RF_SETUP); tmp &= 0xFE; tmp |= gain; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_RF_SETUP, tmp); }
void RFM70::configSpeed(uint8_t speed) { if (speed > 2 || speed < 1) { return; } uint8_t tmp = readRegVal(RFM70_REG_RF_SETUP); tmp &= 0xF7; tmp |= speed << 3; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_RF_SETUP, tmp); }
TransmitResult internalSendPacket(const uint8_t *buff, const size_t &length, const uint32_t maxTimeoutUs, bool requestAck) { irq = false; const size_t toSendLength = MIN(length, RFM73_MAX_PACKET_LEN); sendPayload(buff, toSendLength, requestAck ? 1 : 0); TransmitResult result; uint32_t i = 0; uint8_t status = 0; bool readStatus = true; while (!irq && i++ < maxTimeoutUs) { delayMicroseconds(1); if (i >= 10 && i % 5 == 0) { if (checkStatusForMissingIRQ(status)) { readStatus = false; break; } } } if (readStatus) { status = readRegVal(RFM73_REG_STATUS); } if (status & RFM73_IRQ_STATUS_TX_DS) { result.status = Success; result.bytesSent = toSendLength; } else if (status & RFM73_IRQ_STATUS_MAX_RT) { result.status = MaxRT; result.bytesSent = 0; } else if (status & RFM73_IRQ_STATUS_TX_FULL) { result.status = FifoFull; result.bytesSent = 0; } if (i >= maxTimeoutUs) { result.status = Unknown; result.bytesSent = 0; } // Reset error flags writeRegVal(RFM73_CMD_WRITE_REG | RFM73_REG_STATUS, status); return result; }
void disableRxPipe(uint8_t pipe_nr) { uint8_t nr = pipe_nr - 1; if (nr > 5) return; uint8_t tmp; // set Enable pipe bit tmp = readRegVal(RFM73_REG_EN_RXADDR); tmp &= ~(1 << nr); writeRegVal(RFM73_CMD_WRITE_REG | RFM73_REG_EN_RXADDR, tmp); }
void RFM70::enableRxPipe(uint8_t pipe_nr) { uint8_t nr = pipe_nr - 1; if (nr > 5) { return; } uint8_t tmp; // set Enable pipe bit tmp = readRegVal(RFM70_REG_EN_RXADDR); tmp |= 1 << nr; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_EN_RXADDR, tmp); }
void RFM70::configCRC(uint8_t crc) { uint8_t tmp = readRegVal(RFM70_REG_CONFIG); //reset crc state tmp &= 0xF3; if (crc == CRC1) { tmp |= 0x08; } else if (crc == CRC2) { tmp |= 0x0C; } writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_CONFIG, tmp); }
void RFM70::confIRQ(uint8_t irq_pin, uint8_t reflectTX_DS, uint8_t reflectRX_DR, uint8_t reflectMAX_RT) { if (irq_pin != -1) { pinMode(irq_pin, INPUT); } uint8_t tmp = readRegVal(RFM70_REG_CONFIG) & 0x8F; tmp |= ((reflectTX_DS & 0x01) ^ 0x01) << 6; tmp |= ((reflectRX_DR & 0x01) ^ 0x01) << 5; tmp |= ((reflectMAX_RT & 0x01) ^ 0x01) << 4; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_CONFIG, tmp); }
// Important! adr has to be 5-bytes length even if MSB bytes are unused uint8_t configRxPipe(uint8_t pipe_nr, uint8_t *adr, uint8_t plLen, uint8_t en_aa) { uint8_t tmp; uint8_t nr = pipe_nr; if(plLen > 32 || nr > 5 || en_aa > 1){ return 0; } // write address if(nr<2) // full length for rx pipe 0 an 1 writeRegCmdBuf(RFM7x_CMD_WRITE_REG | (RFM7x_REG_RX_ADDR_P0 + nr), adr, 5); else // only LSB for pipes 2..5 writeRegVal(RFM7x_CMD_WRITE_REG | (RFM7x_REG_RX_ADDR_P0 + nr), adr[0]); // static if (plLen) { // set payload len writeRegVal(RFM7x_CMD_WRITE_REG | (RFM7x_REG_RX_PW_P0 + nr), plLen); // set EN_AA bit tmp = readRegVal(RFM7x_REG_EN_AA); if (en_aa) tmp |= 1 << nr; else tmp &= ~(1 << nr); writeRegVal(RFM7x_CMD_WRITE_REG | RFM7x_REG_EN_AA, tmp); // clear DPL bit tmp = readRegVal(RFM7x_REG_DYNPD); tmp &= ~(1 << nr); writeRegVal(RFM7x_CMD_WRITE_REG | RFM7x_REG_DYNPD, tmp); // set Enable pipe bit enableRxPipe(nr); } // dynamic else { // set payload len to default writeRegVal(RFM7x_CMD_WRITE_REG | (RFM7x_REG_RX_PW_P0 + nr), 0x20); // set EN_AA bit tmp = readRegVal(RFM7x_REG_EN_AA); tmp |= 1 << nr; writeRegVal(RFM7x_CMD_WRITE_REG | RFM7x_REG_EN_AA, tmp); // set DPL bit tmp = readRegVal(RFM7x_REG_DYNPD); tmp |= 1 << nr; writeRegVal(RFM7x_CMD_WRITE_REG | RFM7x_REG_DYNPD, tmp); // set Enable pipe bit enableRxPipe(nr); } return 1; }
uint8_t RFM70::configRxPipe(uint8_t pipe_nr, uint8_t * adr, uint8_t plLen, uint8_t en_aa) { uint8_t tmp; uint8_t nr = pipe_nr - 1; if (plLen > 32 || nr > 5 || en_aa > 1) { return 0; } // write address // full length for rx pipe 0 an 1 if (nr < 2) { writeRegCmdBuf(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_ADDR_P0 + nr), adr, sizeof(adr)); } else { // only LSB for pipes 2..5 writeRegVal(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_ADDR_P0 + nr), adr[0]); //ODO:check this } // static if (plLen) { // set payload len writeRegVal(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_PW_P0 + nr), plLen); // set EN_AA bit tmp = readRegVal(RFM70_REG_EN_AA); if (en_aa) { tmp |= 1 << nr; } else { tmp &= ~(1 << nr); } writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_EN_AA, tmp); // clear DPL bit tmp = readRegVal(RFM70_REG_DYNPD); tmp &= ~(1 << nr); writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_DYNPD, tmp); // set Enable pipe bit enableRxPipe(nr); } else { // set payload len to default writeRegVal(RFM70_CMD_WRITE_REG | (RFM70_REG_RX_PW_P0 + nr), 0x20); // set EN_AA bit tmp = readRegVal(RFM70_REG_EN_AA); tmp |= 1 << nr; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_EN_AA, tmp); // set DPL bit tmp = readRegVal(RFM70_REG_DYNPD); tmp |= 1 << nr; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_DYNPD, tmp); // set Enable pipe bit enableRxPipe(nr); } return 1; }
void RFM70::setModeTX(void) { uint8_t val; // Flush TX FIFO writeRegPgmBuf((uint8_t *) RFM70_cmd_flush_tx, sizeof(RFM70_cmd_flush_tx)); // RFM chip disable digitalWrite(_ce, LOW); // set PRIM_RX bit to 0 val = readRegVal(RFM70_REG_CONFIG); val &= ~RFM70_PIN_PRIM_RX; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_CONFIG, val); // RFM chip enable digitalWrite(_ce, HIGH); }
TransmitResult_t RFM75_Transmit_bytes(const uint8_t *buff, const uint32_t *length, const uint32_t maxTimeoutUs, bool requestAck) { TransmitResult_t result; const uint32_t toSendLength = *length; uint32_t i=0; uint8_t status = 0; bool readStatus = true; sendPayload(buff, toSendLength, (uint8_t)requestAck); rxtx_interrupt = 0; while((rxtx_interrupt == 0) && (i < maxTimeoutUs)){ _delay_us(20); if(checkStatusForMissingIRQ(&status)){ readStatus=false; break; } i++; } rxtx_interrupt = 0; /* Clear the status interrupt */ writeRegVal(RFM7x_CMD_WRITE_REG | RFM7x_REG_STATUS, status); if (readStatus){ status = readRegVal(RFM7x_REG_STATUS); } if (status & RFM7x_IRQ_STATUS_TX_DS){ result.status = SUCCESS; result.bytesSent = toSendLength; } else if (status & RFM7x_IRQ_STATUS_MAX_RT){ result.status = MAXRT; result.bytesSent = 0; } else if (status & RFM7x_IRQ_STATUS_TX_FULL){ result.status = FIFOFULL; result.bytesSent = 0; } if (i >= maxTimeoutUs){ result.status = UNKNOWN; result.bytesSent = 0; } return result; }
void configTxPipe(uint8_t * adr, uint8_t pltype) { // write TX address writeRegCmdBuf(RFM73_CMD_WRITE_REG | RFM73_REG_TX_ADDR, adr, 5); // write RX0 address writeRegCmdBuf(RFM73_CMD_WRITE_REG | RFM73_REG_RX_ADDR_P0, adr, 5); // set static or dynamic payload uint8_t tmp; tmp = readRegVal(RFM73_REG_DYNPD); if (pltype == TX_DPL) // dynamic tmp |= 1; else tmp &= ~(1 << 0); writeRegVal(RFM73_CMD_WRITE_REG | RFM73_REG_DYNPD, tmp); }
uint8_t RFM70::receivePayload(uint8_t *payload) { uint8_t len; // check RX_FIFO uint8_t status; status = readRegVal(RFM70_REG_STATUS); // RX_DR if (status & RFM70_IRQ_STATUS_RX_DR) { uint8_t fifo_sta; // Payload width len = readRegVal(RFM70_CMD_RX_PL_WID); readRegBuf(RFM70_CMD_RD_RX_PLOAD, payload, len); fifo_sta = readRegVal(RFM70_REG_FIFO_STATUS); if (fifo_sta & RFM70_FIFO_STATUS_RX_EMPTY) { // clear status bit rx_dr status |= 0x40 & 0xCF; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, status); } return len; } else { return 0; } }
void turnOn() { uint8_t status = readRegVal(RFM73_REG_STATUS); status |= PWR_BIT; writeRegVal(RFM73_CMD_WRITE_REG | RFM73_REG_STATUS, status); }
void setChannel(uint8_t cnum) { writeRegVal( RFM73_CMD_WRITE_REG | RFM73_REG_RF_CH, cnum); }
void RFM70::cliRxDr() { uint8_t tmp = readRegVal(RFM70_REG_STATUS) | 0x40 & 0xCF; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, tmp); }
void RFM70::cliTxDs() { uint8_t tmp = readRegVal(RFM70_REG_STATUS) | 0x20 & 0xAF; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, tmp); }
void RFM70::cliTimeout() { uint8_t tmp = readRegVal(RFM70_REG_STATUS) | 0x10 & 0x9F; writeRegVal(RFM70_CMD_WRITE_REG | RFM70_REG_STATUS, tmp); }