/// @details /// This call provides direct access to the RFM12B registers. If you're careful /// to avoid configuring the wireless module in a way which stops the driver /// from functioning, this can be used to adjust frequencies, power levels, /// RSSI threshold, etc. See the RFM12B wireless module documentation. /// /// This call will briefly disable interrupts to avoid clashes on the SPI bus. /// /// Returns the 16-bit value returned by SPI. Probably only useful with a /// "0x0000" status poll command. /// @param cmd RF12 command, topmost bits determines which register is affected. uint16_t rf12_control(uint16_t cmd) { #ifdef EIMSK #if PINCHG_IRQ #if RFM_IRQ < 8 bitClear(PCICR, PCIE0); #elif RFM_IRQ < 16 bitClear(PCICR, PCIE1); #else bitClear(PCICR, PCIE2); #endif #else bitClear(EIMSK, INT0); #endif uint16_t r = rf12_xferSlow(cmd); #if PINCHG_IRQ #if RFM_IRQ < 8 bitSet(PCICR, PCIE0); #elif RFM_IRQ < 16 bitSet(PCICR, PCIE1); #else bitSet(PCICR, PCIE2); #endif #else bitSet(EIMSK, INT0); #endif #else // ATtiny bitClear(GIMSK, INT0); uint16_t r = rf12_xferSlow(cmd); bitSet(GIMSK, INT0); #endif return r; }
/// @details /// This call provides direct access to the RFM12B registers. If you're careful /// to avoid configuring the wireless module in a way which stops the driver /// from functioning, this can be used to adjust frequencies, power levels, /// RSSI threshold, etc. See the RFM12B wireless module documentation. /// /// This call will briefly disable interrupts to avoid clashes on the SPI bus. /// /// Returns the 16-bit value returned by SPI. Probably only useful with a /// "0x0000" status poll command. /// @param cmd RF12 command, topmost bits determines which register is affected. uint16_t rf12_control(uint16_t cmd) { #ifdef EIMSK bitClear(EIMSK, INT0); uint16_t r = rf12_xferSlow(cmd); bitSet(EIMSK, INT0); #else // ATtiny bitClear(GIMSK, INT0); uint16_t r = rf12_xferSlow(cmd); bitSet(GIMSK, INT0); #endif return r; }
static void rf12_interrupt () { // a transfer of 2x 16 bits @ 2 MHz over SPI takes 2x 8 us inside this ISR // correction: now takes 2 + 8 µs, since sending can be done at 8 MHz rf12_xfer(0x0000); if (rxstate == TXRECV) { uint8_t in = rf12_xferSlow(RF_RX_FIFO_READ); if (rxfill == 0 && group != 0) rf12_buf[rxfill++] = group; rf12_buf[rxfill++] = in; rf12_crc = _crc16_update(rf12_crc, in); if (rxfill >= rf12_len + 5 || rxfill >= RF_MAX) rf12_xfer(RF_IDLE_MODE); } else { uint8_t out; if (rxstate < 0) { uint8_t pos = 3 + rf12_len + rxstate++; out = rf12_buf[pos]; rf12_crc = _crc16_update(rf12_crc, out); } else switch (rxstate++) { case TXSYN1: out = 0x2D; break; case TXSYN2: out = group; rxstate = - (2 + rf12_len); break; case TXCRC1: out = rf12_crc; break; case TXCRC2: out = rf12_crc >> 8; break; case TXDONE: rf12_xfer(RF_IDLE_MODE); // fall through default: out = 0xAA; } rf12_xfer(RF_TXREG_WRITE + out); } }