Skip to main content
DTomi.1
Senior
October 26, 2020
Question

SPSGRF-868 configuration, SPIRIT1 VCO calibration not working

  • October 26, 2020
  • 0 replies
  • 571 views
/* This is the function that initializes the SPIRIT with the configuration 
that the user has exported using the GUI */
void SpiritBaseConfiguration(void)
{
 uint8_t tmp[7];
 
 /* Be sure that the registers config is default */
 SpiritSpiCommandStrobes(COMMAND_SRES);
 
 /* Extra current in after power on fix.
 In some samples, when a supply voltage below 2.6 V is applied to SPIRIT1 from a no power condition,
 an extra current is added to the typical current consumption.
 With this sequence, the extra current is erased.
 */
 tmp[0]=0xCA;SpiritSpiWriteRegisters(0xB2, 1, tmp); 
 tmp[0]=0x04;SpiritSpiWriteRegisters(0xA8, 1, tmp); 
 SpiritSpiReadRegisters(0xA8, 1, tmp);
 tmp[0]=0x00;SpiritSpiWriteRegisters(0xA8, 1, tmp);
 
 tmp[0] = 0x36; /* reg. IF_OFFSET_ANA (0x07) */
 tmp[1] = 0x06; /* reg. SYNT3 (0x08) */
 tmp[2] = 0x82; /* reg. SYNT2 (0x09) */
 tmp[3] = 0x8F; /* reg. SYNT1 (0x0A) */
 tmp[4] = 0x59; /* reg. SYNT0 (0x0B) */
 tmp[5] = 0x01; /* reg. CH_SPACE (0x0C) */
 tmp[6] = 0xAC; /* reg. IF_OFFSET_DIG (0x0D) */
 SpiritSpiWriteRegisters(0x07, 7, tmp);
 tmp[0] = 0x17; /* reg. PA_POWER[8] (0x10) */
 SpiritSpiWriteRegisters(0x10, 1, tmp);
 tmp[0] = 0x06; /* reg. MOD1 (0x1A) */
 tmp[1] = 0x1C; /* reg. MOD0 (0x1B) */
 tmp[2] = 0x60; /* reg. FDEV0 (0x1C) */
 tmp[3] = 0x12; /* reg. CHFLT (0x1D) */
 tmp[4] = 0xC8; /* reg. AFC2 (0x1E) */
 SpiritSpiWriteRegisters(0x1A, 5, tmp);
 tmp[0] = 0x62; /* reg. AGCCTRL1 (0x25) */
 SpiritSpiWriteRegisters(0x25, 1, tmp);
 tmp[0] = 0x15; /* reg. ANT_SELECT_CONF (0x27) */
 SpiritSpiWriteRegisters(0x27, 1, tmp);
 tmp[0] = 0x17; /* reg. PCKTCTRL2 (0x32) */
 tmp[1] = 0x00; /* reg. PCKTCTRL1 (0x33) */
 SpiritSpiWriteRegisters(0x32, 2, tmp);
 tmp[0] = 0xDE; /* reg. SYNC4 (0x36) */
 tmp[1] = 0x51; /* reg. SYNC3 (0x37) */
 tmp[2] = 0x0B; /* reg. SYNC2 (0x38) */
 tmp[3] = 0x93; /* reg. SYNC1 (0x39) */
 SpiritSpiWriteRegisters(0x36, 4, tmp);
 tmp[0] = 0x40; /* reg. PCKT_FLT_OPTIONS (0x4F) */
 tmp[1] = 0x40; /* reg. PROTOCOL[2] (0x50) */
 tmp[2] = 0x01; /* reg. PROTOCOL[1] (0x51) */
 SpiritSpiWriteRegisters(0x4F, 3, tmp);
 tmp[0] = 0x00; /* reg. RCO_VCO_CALIBR_IN[1] (0x6E) */
 tmp[1] = 0x00; /* reg. RCO_VCO_CALIBR_IN[0] (0x6F) */
 SpiritSpiWriteRegisters(0x6E, 2, tmp);
 tmp[0] = 0xA0; /* reg. SYNTH_CONFIG[0] (0x9F) */
 SpiritSpiWriteRegisters(0x9F, 1, tmp);
 tmp[0] = 0x25; /* reg. VCO_CONFIG (0xA1) */
 SpiritSpiWriteRegisters(0xA1, 1, tmp);
 tmp[0] = 0x35; /* reg. DEM_CONFIG (0xA3) */
 SpiritSpiWriteRegisters(0xA3, 1, tmp);
 
 /* VCO unwanted calibration workaround. 
 With this sequence, the PA is on after the eventual VCO calibration expires.
 */
 tmp[0]=0x22;SpiritSpiWriteRegisters(0xBC, 1, tmp);
 
}
 
/* This is a VCO calibration routine used to recalibrate the VCO of SPIRIT1 in a safe way.
 IMPORTANT: It must be called from READY state. */
void SpiritVcoCalibration(void)
{
 uint8_t tmp[4];
 uint8_t cal_words[2];
 uint8_t state;
 
 
 
 SpiritSpiReadRegisters(0x9E, 1, tmp);
 tmp[0] |= 0x80;
 SpiritSpiWriteRegisters(0x9E, 1, tmp); /* REFDIV bit set (to be restored) */
 
 /* As a consequence we need to double the SYNT word to generate the target frequency */
 tmp[0] = 0x0D;
 tmp[1] = 0x05;
 tmp[2] = 0x1E;
 tmp[3] = 0xB1;
 SpiritSpiWriteRegisters(0x08, 4, tmp);
 
 
 tmp[0] = 0x25; SpiritSpiWriteRegisters(0xA1,1,tmp); /* increase VCO current (restore to 0x11) */
 
 SpiritSpiReadRegisters(0x50,1,tmp);
 tmp[0] |= 0x02; 
 SpiritSpiWriteRegisters(0x50,1,tmp); /* enable VCO calibration (to be restored) */
 
 SpiritSpiCommandStrobes(COMMAND_LOCKTX);
 do{
 SpiritSpiReadRegisters(0xC1, 1, &state);
 }while((state&0xFE) != 0x1E); /* wait until LOCK (MC_STATE = 0x0F <<1) */
 SpiritSpiReadRegisters(0xE5, 1, &cal_words[0]); /* calib out word for TX */
 
 SpiritSpiCommandStrobes(COMMAND_READY);
 do{
 SpiritSpiReadRegisters(0xC1, 1, &state);
 }while((state&0xFE) != 0x06); /* wait until READY (MC_STATE = 0x03 <<1) */
 
 SpiritSpiCommandStrobes(COMMAND_LOCKRX);
 do{
 SpiritSpiReadRegisters(0xC1, 1, &state);
 }while((state&0xFE) != 0x1E); /* wait until LOCK (MC_STATE = 0x0F <<1) */
 SpiritSpiReadRegisters(0xE5, 1, &cal_words[1]); /* calib out word for RX */
 
 SpiritSpiCommandStrobes(COMMAND_READY);
 do{
 SpiritSpiReadRegisters(0xC1, 1, &state);
 }while((state&0xFE) != 0x06); /* wait until READY (MC_STATE = 0x03 <<1) */
 
 SpiritSpiReadRegisters(0x50,1,tmp);
 tmp[0] &= 0xFD; 
 SpiritSpiWriteRegisters(0x50,1,tmp); /* VCO calib restored to 0 */
 
 SpiritSpiReadRegisters(0x9E, 1, tmp);
 tmp[0] &= 0x7F;
 SpiritSpiWriteRegisters(0x9E, 1, tmp); /* REFDIV bit reset */
 
 
 tmp[0] = 0x06;
 tmp[1] = 0x82;
 tmp[2] = 0x8F;
 tmp[3] = 0x59;
 SpiritSpiWriteRegisters(0x08, 4, tmp); /* SYNTH WORD restored */
 
 
 SpiritSpiWriteRegisters(0x6E,2,cal_words); /* write both calibration words */
 
}

This is the generated code from the SPIRIT1 DK. SpiritBaseConfiguration and SpiritVcoCalibration executes fine, state after it is MC_STATE[1] = 0x02, MC_STATE[0] = 0x07, but additional LOCKTX after calibration doesn't. It gets stuck on wait until lock for TX returning 0x27 for state. I have checked state right before SpiritSpiCommandStrobes(COMMAND_LOCKRX); is called, and it's MC_STATE[0] = 0x07. Can someone help me with this?

EDIT: There was a implementation error whereupon fixing it, I can now successfully enter lock state after calibration. However, when I set modulation to CW (MOD1 = 0x06, MOD0 = 0xAC) and start TX command, after TX command the state is 0x02, 0x67, meaning it enters RX mode, and no carrier is visible on SA. What am I doing wrong, how can I stay in TX mode, i.e. get CW?

    This topic has been closed for replies.