2020-10-26 09:47 AM
/* 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?