LOCAL uint8_t RF24_spiMultiByteTransfer(const uint8_t cmd, uint8_t* buf, uint8_t len, const bool aReadMode) { uint8_t status; uint8_t* current = buf; #if !defined(MY_SOFTSPI) _SPI.beginTransaction(SPISettings(MY_RF24_SPI_MAX_SPEED, MY_RF24_SPI_DATA_ORDER, MY_RF24_SPI_DATA_MODE)); #endif RF24_csn(LOW); // timing delayMicroseconds(10); #ifdef LINUX_SPI_BCM uint8_t * prx = spi_rxbuff; uint8_t * ptx = spi_txbuff; uint8_t size = len + 1; // Add register value to transmit buffer *ptx++ = cmd; while ( len-- ) { if (aReadMode) { *ptx++ = RF24_NOP; } else { *ptx++ = *current++; } } _SPI.transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, size); if (aReadMode) { if (size == 2) { status = *++prx; // result is 2nd byte of receive buffer } else { status = *prx++; // status is 1st byte of receive buffer // decrement before to skip status byte while (--size) { *buf++ = *prx++; } } } else { status = *prx; // status is 1st byte of receive buffer } #else status = _SPI.transfer(cmd); while ( len-- ) { if (aReadMode) { status = _SPI.transfer(RF24_NOP); if (buf != NULL) { *current++ = status; } } else { status = _SPI.transfer(*current++); } } #endif RF24_csn(HIGH); #if !defined(MY_SOFTSPI) _SPI.endTransaction(); #endif // timing delayMicroseconds(10); return status; }
uint8_t RF24_read_register(RF24* rf24, uint8_t reg) { RF24_csn(rf24, LOW); rf24->spi->transfer( R_REGISTER | ( REGISTER_MASK & reg ) ); uint8_t result = rf24->spi->transfer(0xff); RF24_csn(rf24, HIGH); return result; }
uint8_t RF24_get_status(RF24* rf24) { uint8_t status; RF24_csn(rf24, LOW); status = rf24->spi->transfer( NOP ); RF24_csn(rf24, HIGH); return status; }
uint8_t RF24_flush_tx(RF24* rf24) { uint8_t status; RF24_csn(rf24, LOW); status = rf24->spi->transfer( FLUSH_TX ); RF24_csn(rf24, HIGH); return status; }
uint8_t RF24_write_register(RF24* rf24, uint8_t reg, uint8_t value) { uint8_t status; IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value)); RF24_csn(rf24, LOW); status = rf24->spi->transfer( W_REGISTER | ( REGISTER_MASK & reg ) ); rf24->spi->transfer(value); RF24_csn(rf24, HIGH); return status; }
uint8_t RF24_write_register(RF24* rf24, uint8_t reg, const uint8_t* buf, uint8_t len) { uint8_t status; RF24_csn(rf24, LOW); status = rf24->spi->transfer( W_REGISTER | ( REGISTER_MASK & reg ) ); while ( len-- ) rf24->spi->transfer(*buf++); RF24_csn(rf24, HIGH); return status; }
uint8_t RF24_read_register(RF24* rf24, uint8_t reg, uint8_t* buf, uint8_t len) { uint8_t status; RF24_csn(rf24, LOW); status = rf24->spi->transfer( R_REGISTER | ( REGISTER_MASK & reg ) ); while ( len-- ) *buf++ = rf24->spi->transfer(0xff); RF24_csn(rf24, HIGH); return status; }
uint8_t RF24_read_payload(RF24* rf24, void* buf, uint8_t len) { uint8_t status; uint8_t* current = (uint8_t)(buf); uint8_t data_len = min(len,rf24->payload_size); uint8_t blank_len = rf24->dynamic_payloads_enabled ? 0 : rf24->payload_size - data_len; //printf("[Reading %u bytes %u blanks]",data_len,blank_len); RF24_csn(rf24, LOW); status = rf24->spi->transfer( R_RX_PAYLOAD ); while ( data_len-- ) *current++ = rf24->spi->transfer(0xff); while ( blank_len-- ) rf24->spi->transfer(0xff); RF24_csn(rf24, HIGH); return status; }
uint8_t RF24_write_payload(RF24* rf24, const void* buf, uint8_t len) { uint8_t status; const uint8_t* current = (uint8_t*)(buf); uint8_t data_len = min(len,rf24->payload_size); uint8_t blank_len = rf24->dynamic_payloads_enabled ? 0 : rf24->payload_size - data_len; //printf("[Writing %u bytes %u blanks]",data_len,blank_len); RF24_csn(rf24, LOW); status = rf24->spi->transfer( W_TX_PAYLOAD ); while ( data_len-- ) rf24->spi->transfer(*current++); while ( blank_len-- ) rf24->spi->transfer(0); RF24_csn(rf24, HIGH); return status; }
LOCAL uint8_t RF24_spiMultiByteTransfer(uint8_t cmd, uint8_t* buf, uint8_t len, bool aReadMode) { uint8_t* current = buf; #if !defined(MY_SOFTSPI) _SPI.beginTransaction(SPISettings(MY_RF24_SPI_MAX_SPEED, MY_RF24_SPI_DATA_ORDER, MY_RF24_SPI_DATA_MODE)); #endif RF24_csn(LOW); // timing delayMicroseconds(10); uint8_t status = _SPI.transfer( cmd ); while ( len-- ) { if (aReadMode) { status = _SPI.transfer( NOP ); if(buf != NULL) *current++ = status; } else status = _SPI.transfer(*current++); } RF24_csn(HIGH); #if !defined(MY_SOFTSPI) _SPI.endTransaction(); #endif // timing delayMicroseconds(10); return status; }
LOCAL bool RF24_initialize(void) { // Initialize pins pinMode(MY_RF24_CE_PIN,OUTPUT); pinMode(MY_RF24_CS_PIN,OUTPUT); // Initialize SPI _SPI.begin(); RF24_ce(LOW); RF24_csn(HIGH); // CRC and power up RF24_setRFConfiguration(MY_RF24_CONFIGURATION | _BV(PWR_UP) ) ; // settle >2ms delay(5); // set address width RF24_setAddressWidth(MY_RF24_ADDR_WIDTH); // auto retransmit delay 1500us, auto retransmit count 15 RF24_setRetries(RF24_ARD, RF24_ARC); // set channel RF24_setChannel(MY_RF24_CHANNEL); // set data rate and pa level RF24_setRFSetup(MY_RF24_RF_SETUP); // sanity check #if defined(MY_RF24_SANITY_CHECK) if (!RF24_sanityCheck()) { RF24_DEBUG(PSTR("RF24:Sanity check failed: configuration mismatch! Check wiring, replace module or non-P version\n")); return false; } #endif // toggle features (necessary on some clones) RF24_enableFeatures(); // enable ACK payload and dynamic payload RF24_setFeature(MY_RF24_FEATURE); // enable broadcasting pipe RF24_setPipe(_BV(ERX_P0 + BROADCAST_PIPE)); // disable AA on all pipes, activate when node pipe set RF24_setAutoACK(0x00); // enable dynamic payloads on used pipes RF24_setDynamicPayload(_BV(DPL_P0 + BROADCAST_PIPE) | _BV(DPL_P0)); // listen to broadcast pipe MY_RF24_BASE_ADDR[0] = BROADCAST_ADDRESS; RF24_setPipeAddress(RX_ADDR_P0 + BROADCAST_PIPE, (uint8_t*)&MY_RF24_BASE_ADDR, BROADCAST_PIPE > 1 ? 1 : MY_RF24_ADDR_WIDTH); // pipe 0, set full address, later only LSB is updated RF24_setPipeAddress(RX_ADDR_P0, (uint8_t*)&MY_RF24_BASE_ADDR, MY_RF24_ADDR_WIDTH); RF24_setPipeAddress(TX_ADDR, (uint8_t*)&MY_RF24_BASE_ADDR, MY_RF24_ADDR_WIDTH); // reset FIFO RF24_flushRX(); RF24_flushTX(); // reset interrupts RF24_setStatus(_BV(TX_DS) | _BV(MAX_RT) | _BV(RX_DR)); return true; }