This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC110L: CC110L reaches unknown MARCSTATE

Part Number: CC110L

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)

  1. Board1 starts up, initializes everything and read values from N sensors and wait for event SEND_DATA to transmit the data to Board2
  2. 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.
  3. Board2 parses de pkt, retrieves the data and returns the same pkt as an ACK. All pkts are 32byte long.
  4. 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?

  • I have never heard of any cases where something else has been read from the 3 MSB of MARCSTATE other than 000b. Have you made sure that:

    • your SPI are according to the spec. in the data sheet when it comes to meet all the timing requirements?
    • you are performing a proper reset at startup (a manual reset, as explained in Section 5.19.1.2 in the data sheet, is necessary if the requirements in Section 4.12 are not met)
    • you always remember to wait for CHIP_RDYn signal to go low before starting the SPI clock?
    • you handling error states in the code properly (for example, if you end up in overflow or underflow states, are the FIFOs flushed as they should?
    • you are not sending flush commands in other states than overflow/underflow state or in IDLE

    Siri

  • This case is closed due to lack of feedback. It will be re-opened if addition information is posted.