LOCAL bool RF24_sendMessage(const uint8_t recipient, const void* buf, const uint8_t len) { uint8_t RF24_status; RF24_stopListening(); RF24_openWritingPipe( recipient ); RF24_DEBUG(PSTR("RF24:SND:TO=%d,LEN=%d\n"),recipient,len); // send message // flush TX FIFO RF24_flushTX(); // this command is affected in clones (e.g. Si24R1): flipped NoACK bit when using W_TX_PAYLOAD_NO_ACK / W_TX_PAYLOAD // AutoACK is disabled on the broadcasting pipe - NO_ACK prevents resending RF24_spiMultiByteTransfer(recipient == BROADCAST_ADDRESS ? RF24_WRITE_TX_PAYLOAD_NO_ACK : RF24_WRITE_TX_PAYLOAD, (uint8_t*)buf, len, false ); // go, TX starts after ~10us RF24_ce(HIGH); // timeout counter to detect HW issues uint16_t timeout = 0xFFFF; do { RF24_status = RF24_getStatus(); } while (!(RF24_status & ( _BV(RF24_MAX_RT) | _BV(RF24_TX_DS) )) && timeout--); // timeout value after successful TX on 16Mhz AVR ~ 65500, i.e. msg is transmitted after ~36 loop cycles RF24_ce(LOW); // reset interrupts RF24_setStatus(_BV(RF24_TX_DS) | _BV(RF24_MAX_RT) ); // Max retries exceeded if(RF24_status & _BV(RF24_MAX_RT)) { // flush packet RF24_DEBUG(PSTR("!RF24:SND:MAX_RT\n")); // max retries, no ACK RF24_flushTX(); } RF24_startListening(); // true if message sent return (RF24_status & _BV(RF24_TX_DS)); }
LOCAL uint8_t RF24_readMessage( void* buf) { const uint8_t len = RF24_getDynamicPayloadSize(); RF24_DEBUG(PSTR("RF24:read message, len=%d\n"), len); RF24_spiMultiByteTransfer( R_RX_PAYLOAD , (uint8_t*)buf, len, true ); // clear RX interrupt RF24_setStatus(_BV(RX_DR) ); return len; }
LOCAL uint8_t RF24_getDynamicPayloadSize(void) { uint8_t result = RF24_spiMultiByteTransfer(R_RX_PL_WID, NULL, 1, true); // check if payload size invalid if(result > 32) { RF24_DEBUG(PSTR("RF24:invalid payload length = %d\n"),result); RF24_flushRX(); result = 0; } return result; }
LOCAL uint8_t RF24_getDynamicPayloadSize(void) { uint8_t result = RF24_spiMultiByteTransfer(RF24_READ_RX_PL_WID, NULL, 1, true); // check if payload size invalid if(result > 32) { RF24_DEBUG(PSTR("!RF24:GDP:PAYL LEN INVALID=%d\n"),result); // payload len invalid RF24_flushRX(); result = 0; } return result; }
LOCAL uint8_t RF24_RAW_writeByteRegister(const uint8_t cmd, uint8_t value) { RF24_DEBUG(PSTR("RF24:write register, reg=%d, value=%d\n"), cmd & RF24_REGISTER_MASK, value); return RF24_spiMultiByteTransfer( cmd , &value, 1, false); }
LOCAL uint8_t RF24_RAW_readByteRegister(const uint8_t cmd) { const uint8_t value = RF24_spiMultiByteTransfer(cmd, NULL, 1, true); RF24_DEBUG(PSTR("RF24:read register, reg=%d, value=%d\n"), cmd & RF24_REGISTER_MASK, value); return value; }
LOCAL uint8_t RF24_spiByteTransfer(const uint8_t cmd) { return RF24_spiMultiByteTransfer(cmd, NULL, 0, false); }