I have two custom boards (one CC110L each) that communicate by sending and receiving packets like this:
(For the sake of the explanation, I will call them Board1 and Board2)
- Board1 starts up, initializes everything and read values from N sensors and wait for event SEND_DATA to transmit the data to Board2
- Board2 starts up, initializes everything and waits until there's an IRQ from CC110L, meaning that it received something and that the CRC was ok.
- Board2 parses de pkt, retrieves the data and returns the same pkt as an ACK. All pkts are 32byte long.
- Board1 gets the ACK from Board2 and waits for N seconds to read data and transmit it again.
So far so good, no problems with this. Now the issue I'm facing is that after a random time, Board2 reaches an unkown state from which I can't exit/recover except by powering off the device (maybe I'm doing something wrong with the reset?).
My following (debug) foo returns a bool that says when a state that I don't like has been reached and the CC110L needs to be rebooted
bool __attribute__((optimize("-O0"))) cc110l::printkState(bool wait) { //void cc110l::printkState(bool wait) { uint8_t state; uint8_t old_state; bool is_ok = true; #ifndef DEBUG return; #endif state = readRegCS(REG_MARCSTATE); do { switch(state) { case 0x01: DEBUG_PRINTF("CC110L: IDLE\n"); break; case 0x02: DEBUG_PRINTF("CC110L: XOFF\n"); break; case 0x03: DEBUG_PRINTF("CC110L: VCOON_MC\n"); break; case 0x04: DEBUG_PRINTF("CC110L: REGON_MC\n"); break; case 0x05: DEBUG_PRINTF("CC110L: MANCAL\n"); break; case 0x06: DEBUG_PRINTF("CC110L: VCOON\n"); break; case 0x07: DEBUG_PRINTF("CC110L: REGON\n"); break; case 0x08: DEBUG_PRINTF("CC110L: STARTCAL\n"); break; case 0x09: DEBUG_PRINTF("CC110L: BWBOOST\n"); break; case 0x0A: DEBUG_PRINTF("CC110L: FS_LOCK\n"); break; case 0x0B: DEBUG_PRINTF("CC110L: IFADCON\n"); break; case 0x0C: DEBUG_PRINTF("CC110L: ENDCAL CALIBRATE\n"); break; case 0x0D: DEBUG_PRINTF("CC110L: RX\n"); break; case 0x0E: DEBUG_PRINTF("CC110L: RX_END\n"); break; case 0x0F: DEBUG_PRINTF("CC110L: RX_RST\n"); break; case 0x10: DEBUG_PRINTF("CC110L: TXRX_SWITCH\n"); break; case 0x11: DEBUG_PRINTF("CC110L: RXFIFO_OVERFL\n"); // Ha de devolver false is_ok = false; break; case 0x12: DEBUG_PRINTF("CC110L: FSTXON\n"); break; case 0x13: DEBUG_PRINTF("CC110L: TX\n"); break; case 0x14: DEBUG_PRINTF("CC110L: TX_END\n"); break; case 0x15: DEBUG_PRINTF("CC110L: RXTX_SWITCH\n"); break; case 0x16: DEBUG_PRINTF("CC110L: TXFIFO_UNDERF\n"); // Ha de devolver false is_ok = false; break; default: DEBUG_PRINTF("CC110L: UNKNOWN STATE 0x%x\n", state); // Ha de devolver false is_ok = false; break; } old_state = state; if (wait) { osDelay(2); state = readRegCS(REG_MARCSTATE); } } while (state != old_state); return is_ok; }
Such foo is called several times in my code just to print the state CC110L is in.
Now, imagine I want to go to IDLE state. I would call this foo:
void cc110l::idleMode() { sendCMD(CMD_SIDLE); // Go to idle mode. if (!printkState()) { DEBUG_PRINTF("REBOOTING CC110L\n"); sendCMD(CMD_SRES); osDelay(5); sendCMD(CMD_SFRX); sendCMD(CMD_SFTX); sendCMD(CMD_SIDLE); } }
This foo wouldn't need the if statement if it wasn't because of this output:
...
IRQ: Antenna
CC110L: UNKNOWN STATE 0x1f
CC110L: UNKNOWN STATE 0x17
IRQ: Antenna
CC110L: UNKNOWN STATE 0x1f
REBOOTING CC110L
IRQ: Antenna
...
According to the CC110L Reference document, MARCSTATE has state values from 0x00 to 0x16 since bits 7:5 aren't used. If so, why am I getting these state values and how can I avoid them/properly reset the CC110L?