cancel
Showing results for 
Search instead for 
Did you mean: 

SPSGRF-868 configuration, SPIRIT1 VCO calibration not working

DTomi.1
Senior
/* 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?

0 REPLIES 0