I have recently bought a few of these chips on boards along with some "adapter boards" which supposedly regulates the 5v to propper 3.3v with the required capacitors. So power supply shouldn't be a problem although I haven't tried with a separate power supply. Ok, so I like to build my stuff from scratch to really know everything that's going on so I'm not using a library for this chip but I've read the datasheet in it's entirety and have understood all the features. At first after going through every option one of the modules was successfully sending out packets as indicated by the TX_DS interrupt but nothing was showing up on the one in receiver mode, and after lots of checking I chose to disable every feature and managed to finally get some action as the receiver interrupted each time the transmitter sent out a packet with no CRC and no ACK.
But now there's an issue, the datasheet clearly states:
The RX_DR IRQ is asserted by a new packet arrival event. The procedure for handling this interrupt should be:
1) read payload through SPI,
2) clear RX_DR IRQ,
3) read FIFO_STATUS to check if there are more payloads available in RX FIFO,
4) if there are more data in RX FIFO, repeat from step 1).
However upon getting the interrupt and reading out 33 bytes with the command, the status register reads 4E (0100 1110) saying that the interrupt was indeed RX_DR but also the pipe number bits are all on meaning an empty RX FIFO. The following 32 bytes read 0.
How can this be? Has anyone experienced something similar?
UPDATE: Tested with separate power supply on RX side, issue still stands.
Pictures: https://1drv.ms/f/s!Ag6xBMoahJ8xkOkWMG89RIAa1m71Kw
Arduino code: (feel free to correct me I'm no expert in this language :p)
Main
void setup() {
attachInterrupt(digitalPinToInterrupt(radio.irq), interrupt, FALLING);
Serial.begin(9600) ;
Serial.write("\n ----Boot----\n\nInitializing radio...\n");
//Starts radio as PRX
//Sets channel
//Sets bitrate to 1Mbps
if (radio.init()) {
Serial.println("Radio ready.\n\n ----Boot complete----\n\n");
} else {
Serial.write("Couldn't initialize radio!\n\n ----Boot failed----\n");
return;
}
delay(10);
digitalWrite(9, HIGH);
}
void loop() {
}
void interrupt() {
Serial.write("\nINTERRUPT\n");
digitalWrite(9, LOW);
radio.readRegister(0x17, 2, true, BIN);
radio.readRXpayload(true);
radio.clearIRQ();
digitalWrite(9, HIGH);
}
Radio class
#include "BitUtils.h"
BitUtils utils;
uint8_t* tmp = (uint8_t*)malloc(sizeof(uint8_t) * 33);
uint8_t initialPipe0[5] = {0x28, 0x18, 0xdb, 0xc2, 0x86};
uint8_t beaconAddress[5] = {0x29, 0x26, 0x13, 0x12, 0x00};
class Radio {
public:
uint8_t nullmsg[1] = {0x00};
uint8_t rx_config[1] = {0b00100011}; //0x00
uint8_t tx_config[1] = {0b00100010}; //0x00
uint8_t aa_config[1] = {0b00000000}; //0x01
uint8_t ch_config[1] = {0b00110100}; //0x05
uint8_t rf_config[1] = {0b00000110}; //0x06
uint8_t features_config[1] = {0b00000000}; //0x1D
uint8_t clear_irq[1] = {0b01110000}; //0x07
uint8_t clk = 13;
uint8_t miso = 12;
uint8_t mosi = 11;
uint8_t slaveselect = 10;
uint8_t chipenable = 9;
uint8_t irq = 2;
SPISettings spiConfig = SPISettings(2000000, MSBFIRST, SPI_MODE0);
boolean init() {
noInterrupts();
pinMode(clk, OUTPUT);
pinMode(miso, INPUT);
pinMode(mosi, OUTPUT);
pinMode(slaveselect, OUTPUT);
pinMode(chipenable, OUTPUT);
pinMode(irq, INPUT);
digitalWrite(clk, LOW);
digitalWrite(slaveselect, HIGH);
digitalWrite(chipenable, LOW);
delay(11);
transfer(nullmsg, 1, tmp);
if (tmp[0] != 0b00001110) {
return false;
}
writeRegister(0x00, rx_config, 2); Serial.print("0x00: ");
readRegister(0x00, 2, true, BIN);
writeRegister(0x01, aa_config, 2); Serial.print("0x01: ");
readRegister(0x01, 2, true, BIN);
writeRegister(0x05, ch_config, 2); Serial.print("0x05: ");
readRegister(0x05, 2, true, BIN);
writeRegister(0x06, rf_config, 2); Serial.print("0x06: ");
readRegister(0x06, 2, true, BIN);
writeRegister(0x1D, features_config, 2); Serial.print("0x1D: ");
readRegister(0x1D, 2, true, BIN);
pipeAddress(initialPipe0, 0);
pipeAddress(beaconAddress, 1);
Serial.print("Pipe 0 address: ");
readRegister(0x0A, 6, true, HEX);
Serial.print("Pipe 1 address: ");
readRegister(0x0B, 6, true, HEX);
delay(2);
interrupts();
return true;
}
// -- Operations --
void clearIRQ() {
writeRegister(0x07, clear_irq, 2);
Serial.println("Cleared IRQ");
}
void sendTXpayload(uint8_t data[], boolean ack) {
uint8_t message[33] = {0b10100000};
if (!ack) {
message[0] = 0b10110000;
}
for (int i = 31; i > -1; i--) {
message[32 - i] = data[i];
}
transfer(message, 33, tmp);
pulseCE(12);
delay(2);
}
void readRXpayload(boolean report) {
uint8_t message[33] = {0b01100001};
transfer(message, 33, tmp);
if (report) {
utils.prtArr(tmp, 33, HEX);
}
}
void mode(char m) {
digitalWrite(chipenable, LOW);
if (m == 't') {
writeRegister(0x00, tx_config, 2);
Serial.println("Set tx mode.");
}
if (m == 'r') {
writeRegister(0x00, rx_config, 2);
Serial.println("Set rx mode.");
}
}
void pipeAddress(uint8_t* address, uint8_t number) {
uint8_t pipeNumber = 0x0A + number;
for (int i = 4; i > -1; i--) {tmp[4 - i] = address[i];}
if (number < 2) {
writeRegister(pipeNumber, tmp, 6);
}else{
writeRegister(pipeNumber, address, 2);
}
}
void sendTo(uint8_t* address) {
for (int i = 4; i > -1; i--) {
tmp[4 - i] = address[i];
}
writeRegister(0x10, tmp, 6);
Serial.print("TX Address: ");
readRegister(0x10, 6, true, HEX);
}
void setChannel(uint8_t ch) {
writeRegister(0b00000101, new uint8_t[1] {ch}, 2);
Serial.write("Frequency set to: ");
Serial.print(2400 + tmp[1], DEC);
Serial.println("MHz");
}
// -- Low operations --
void readStatus(boolean prt) {
transfer(nullmsg, 1, tmp);
if (prt) {
utils.prtArr(tmp, 2, BIN);
}
}
void readRegister(uint8_t address, uint8_t amount, boolean prt, uint8_t format) {
uint8_t message[amount] = {address};
transfer(message, amount, tmp);
if (prt) {
utils.prtArr(tmp, amount, format);
}
}
void writeRegister(uint8_t address, uint8_t* data, uint8_t amount) {
uint8_t message[amount] = {(uint8_t)(0b00100000 | address)};
for (uint8_t i = 1; i < amount; i++) {
message[i] = data[i - 1];
}
transfer(message, amount, tmp);
}
void pulseCE(int duration) {
digitalWrite(chipenable, HIGH);
delayMicroseconds(duration);
digitalWrite(chipenable, LOW);
}
// -- Bidirectional SPI bus --
void transfer(uint8_t* data, uint8_t amount, uint8_t* output) {
SPI.beginTransaction(spiConfig);
digitalWrite(slaveselect, LOW);
delayMicroseconds(1);
for (uint8_t i = 0; i < amount; i++) {
output[i] = SPI.transfer(data[i]);
}
delayMicroseconds(1);
digitalWrite(slaveselect, HIGH);
SPI.endTransaction();
}
};