Hello everybody,
In my application, a battery-operated transponder (slave) should communicate with a wired remote station (master) via radio. The CC1201 is used as the RF chip on both sides.
In order to be able to work in an energy-saving manner, the slave should be operated in sniff mode for approx. 500 ms after each message sent in order to be able to receive the acknowledgment or a command. The master sends with a preamble of 30 bytes.
Question 1.)
How must the sniff mode be set on the slave so that every message can be received?
When changing from transmit mode to sniff mode, the synthesizer (SCAL) and the rc oscillator (WOR_CFG0.RC_MODE = 0x02) are always calibrated. The calibration of the synthesizer often fails because the marcstate "IDLE" is not established. Instead, the marcstate 0x11 (RX_FIFO_ERROR) is read out.
Question 2.)
Why doesn't the calibration run without errors?
Question 3.)
Does the master answer too early under certain circumstances?
Register settings (default):
/* default register set */ CC1201_REG_ENTRY(PREAMBLE_CFG1 , 0x14), CC1201_REG_ENTRY(PREAMBLE_CFG0 , 0x8A), CC1201_REG_ENTRY(IQIC , 0xD8), CC1201_REG_ENTRY(CHAN_BW , 0x08), CC1201_REG_ENTRY(MDMCFG1 , 0x40), CC1201_REG_ENTRY(MDMCFG0 , 0x05), CC1201_REG_ENTRY(SYMBOL_RATE2 , 0xA4), CC1201_REG_ENTRY(SYMBOL_RATE1 , 0x7A), CC1201_REG_ENTRY(SYMBOL_RATE0 , 0xE1), CC1201_REG_ENTRY(AGC_REF , 0x2A), CC1201_REG_ENTRY(AGC_CS_THR , 0xF6), CC1201_REG_ENTRY(AGC_GAIN_ADJUST , 0x00), CC1201_REG_ENTRY(AGC_CFG3 , 0xB1), CC1201_REG_ENTRY(AGC_CFG2 , 0x20), CC1201_REG_ENTRY(AGC_CFG1 , 0x12), CC1201_REG_ENTRY(AGC_CFG0 , 0x80), CC1201_REG_ENTRY(FIFO_CFG , 0x00), CC1201_REG_ENTRY(DEV_ADDR , 0x00), CC1201_REG_ENTRY(SETTLING_CFG , 0x0B), CC1201_REG_ENTRY(FS_CFG , 0x12), CC1201_REG_ENTRY(WOR_CFG1 , 0x08), CC1201_REG_ENTRY(WOR_CFG0 , 0x21), CC1201_REG_ENTRY(WOR_EVENT0_MSB , 0x00), CC1201_REG_ENTRY(WOR_EVENT0_LSB , 0x00), CC1201_REG_ENTRY(RXDCM_TIME , 0x00), CC1201_REG_ENTRY(PKT_CFG2 , 0x00), CC1201_REG_ENTRY(PKT_CFG1 , 0x42), CC1201_REG_ENTRY(PKT_CFG0 , 0x20), CC1201_REG_ENTRY(RFEND_CFG1 , 0x0F), CC1201_REG_ENTRY(RFEND_CFG0 , 0x00),
Here my current code:
void EnterSniffMode(void) { cc1201.timeoutCalib = false; // flag: calibration timeout TimerStart(&TimeoutCalib, OnSignalTimeoutCalib, 10, TIMER_TYPE_ONESHOT, TIMER_CONTEXT_MAINLOOP); cc1201.sniff_state = STATE_SNIFF_WAIT_CALIB_SYNTH; /* set sniff-mode configuration */ SetRegisterValue(CC1201_REG_WOR_CFG0_RC_PD, 0); SetRegisterValue(CC1201_REG_WOR_EVENT0_MSB_EVENT0_15_8, 0x00); SetRegisterValue(CC1201_REG_WOR_EVENT0_LSB_EVENT0_7_0, 0x54); SetRegisterValue(CC1201_REG_SETTLING_CFG_FS_AUTOCAL, 0); SetRegisterValue(CC1201_REG_AGC_CS_THR_AGC_CS_TH, 8); SetRegisterValue(CC1201_REG_AGC_CFG1_AGC_WIN_SIZE, 0); SetRegisterValue(CC1201_REG_AGC_CFG1_AGC_SETTLE_WAIT, 0); SetRegisterValue(CC1201_REG_RFEND_CFG0_TERM_ON_BAD_PACKET_EN, 1); SetRegisterValue(CC1201_REG_RFEND_CFG0_ANT_DIV_RX_TERM_CFG, 1); SetRegisterValue(CC1201_REG_FS_DIG1_FS_DIG1_RESERVED5_0, 7); SetRegisterValue(CC1201_REG_FS_DSM1_FS_DSM1_RESERVED2_0, 2); SetRegisterValue(CC1201_REG_FS_DVC1_FS_DVC1_RESERVED7_0, 0xF3); SetRegisterValue(CC1201_REG_FS_DVC0_FS_DVC0_RESERVED4_0, 0x13); SetRegisterValue(CC1201_REG_FS_VCO0_FS_VCO0_RESERVED7_0, 0xB8); ChipConfigurate(); /* start calibration of synthesizer */ Cc1201Strobe(CC1201_STROBE_SCAL); cc1201.sniff_state = STATE_SNIFF_WAIT_CALIB_SYNTH; } void ExecuteSniffMode(void) { switch (cc1201.sniff_state) { case STATE_SNIFF_WAIT_CALIB_SYNTH: { /* wait for calibration of synthesizer */ if (CheckMarcstate(CC1201_MARCSTATE_IDLE)) { /* start calibration of rc osc (SWRA428A, page 6) */ uint8_t tmp = 0; Cc1201Read(CC1201_REG_WOR_CFG0, &tmp, sizeof(tmp)); tmp &= ~(0x03 << Cc1201RegDescTab[CC1201_REG_WOR_CFG0_RC_MODE].pos); // RC_MODE = 0 tmp |= (0x02 << Cc1201RegDescTab[CC1201_REG_WOR_CFG0_RC_MODE].pos); // RC_MODE = 2 Cc1201Write(CC1201_REG_WOR_CFG0, &tmp, sizeof(tmp)); Cc1201Strobe(CC1201_STROBE_SIDLE); tmp &= ~(0x03 << Cc1201RegDescTab[CC1201_REG_WOR_CFG0_RC_MODE].pos); // RC_MODE = 0 Cc1201Write(CC1201_REG_WOR_CFG0, &tmp, sizeof(tmp)); cc1201.sniff_state = STATE_SNIFF_WAIT_CALIB_RCOSC; cc1201.timeoutCalib = 0; TimerStart(&TimeoutCalib, OnSignalTimeoutCalib, 10, TIMER_TYPE_ONESHOT, TIMER_CONTEXT_MAINLOOP); } else if (cc1201.timeoutCalib) { /* ignore calibration */ /* **************************** */ /* this case enters very often! */ /* **************************** */ cc1201.timeoutCalib = 0; TimerStart(&TimeoutCalib, OnSignalTimeoutCalib, 10, TIMER_TYPE_ONESHOT, TIMER_CONTEXT_MAINLOOP); } } break; case STATE_SNIFF_WAIT_CALIB_RCOSC: { /* wait for calibration of rc osc */ if (CheckMarcstate(CC1201_MARCSTATE_IDLE)) { /* clear previous reception */ ClearEvent(CC1201_EVENT_RECEIVED); /* start rx for sniff mode */ Cc1201Strobe(CC1201_STROBE_SWOR); cc1201.sniff_state = STATE_SNIFF_WAIT_RX; } else if (cc1201.timeoutCalib) { /* ignore calibration */ Cc1201Strobe(CC1201_STROBE_SWOR); cc1201.sniff_state = STATE_SNIFF_WAIT_RX; } } break; case STATE_SNIFF_WAIT_RX: { /* wait for reception */ if (Machine.EventMask & CC1201_EVENT_RECEIVED) { ClearEvent(CC1201_EVENT_RECEIVED); HandleReception(); Cc1201Strobe(CC1201_STROBE_SCAL); cc1201.sniff_state = STATE_SNIFF_WAIT_CALIB_SYNTH; } else if (cc1201.txqueue.busy) { // go to machine state STATE_SEND } } } }
Can someone help me? Thank you very much