/** * @brief this function starts the TX process * @param None * @retval None */ void Spirit1StartTx(uint8_t *buffer, uint8_t size ) { /* fit the TX FIFO */ SpiritCmdStrobeFlushTxFifo(); SpiritSpiWriteLinearFifo(size, buffer); /* send the TX command */ SpiritCmdStrobeTx(); #if 0 do{ /* Delay for state transition */ for(volatile uint8_t i=0; i!=0xFF; i++); /* Reads the MC_STATUS register */ SpiritRefreshStatus(); } while(g_xStatus.MC_STATE!=MC_STATE_TX); #endif #if defined(P2P_DEMO) /* wait for TX done */ while(!xTxDoneFlag); xTxDoneFlag = RESET; #endif }
/** * @brief This function will turn on the radio and waits till it enters the Ready state. * @param Param:None. * @retval None * */ void RadioPowerON(void) { SpiritCmdStrobeReady(); do{ /* Delay for state transition */ for(volatile uint8_t i=0; i!=0xFF; i++); /* Reads the MC_STATUS register */ SpiritRefreshStatus(); } while(g_xStatus.MC_STATE!=MC_STATE_READY); }
/*---------------------------------------------------------------------------*/ static int spirit_radio_channel_clear(void) { float rssi_value; /* Local variable used to memorize the SPIRIT1 state */ uint8_t spirit_state = ON; PRINTF("CHANNEL CLEAR IN\n"); if(spirit_on == OFF) { /* Wakes up the SPIRIT1 */ spirit_radio_on(); spirit_state = OFF; } /* */ IRQ_DISABLE(); spirit1_strobe(SPIRIT1_STROBE_SABORT); /* SpiritCmdStrobeSabort();*/ SpiritIrqClearStatus(); IRQ_ENABLE(); { rtimer_clock_t timeout = RTIMER_NOW() + 5 * RTIMER_SECOND/1000; do { SpiritRefreshStatus(); } while((g_xStatus.MC_STATE != MC_STATE_READY) && (RTIMER_NOW() < timeout)); if(RTIMER_NOW() < timeout) { return 1; } } /* Stores the RSSI value */ rssi_value = SpiritQiGetRssidBm(); /* Puts the SPIRIT1 in its previous state */ if(spirit_state==OFF) { spirit_radio_off(); } else { spirit1_strobe(SPIRIT1_STROBE_RX); /* SpiritCmdStrobeRx();*/ BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5 * RTIMER_SECOND/1000); } PRINTF("CHANNEL CLEAR OUT\n"); /* Checks the RSSI value with the threshold */ if(rssi_value<CCA_THRESHOLD) { return 0; } else { return 1; } }
/** * @brief Identifies the SPIRIT1 Xtal frequency and version. * @param None * @retval Status */ void SpiritManagementIdentificationRFBoard(void) { do{ /* Delay for state transition */ for(volatile uint8_t i=0; i!=0xFF; i++); /* Reads the MC_STATUS register */ SpiritRefreshStatus(); }while(g_xStatus.MC_STATE!=MC_STATE_READY); SpiritRadioSetXtalFrequency(XTAL_FREQUENCY); //SpiritGeneralSetSpiritVersion(SPIRIT_VERSION); }
/** * @brief This function will put the radio in sleep state. * @param None. * @retval None * */ void RadioSleep(void) { SpiritCmdStrobeSleep(); #if 0 do{ /* Delay for state transition */ for(volatile uint8_t i=0; i!=0xFF; i++); /* Reads the MC_STATUS register */ SpiritRefreshStatus(); } while(g_xStatus.MC_STATE!=MC_STATE_SLEEP); #endif }
/** * @brief this function starts the RX process * @param None * @retval None */ void Spirit1StartRx(void) { /* RX command */ SpiritCmdStrobeRx(); #if 0 do{ /* Delay for state transition */ for(volatile uint8_t i=0; i!=0xFF; i++); /* Reads the MC_STATUS register */ SpiritRefreshStatus(); } while(g_xStatus.MC_STATE!=MC_STATE_RX); #endif }
uint8_t SpiritManagementWaVcoCalibration(void) { uint8_t s_cVcoWordRx; uint8_t s_cVcoWordTx; uint32_t nFreq; uint8_t cRestore = 0; uint8_t cStandby = 0; uint32_t xtal_frequency = SpiritRadioGetXtalFrequency(); /* Enable the reference divider if the XTAL is between 48 and 52 MHz */ if(xtal_frequency>26000000) { if(!SpiritRadioGetRefDiv()) { cRestore = 1; nFreq = SpiritRadioGetFrequencyBase(); SpiritRadioSetRefDiv(S_ENABLE); SpiritManagementSetFrequencyBase(nFreq); } } nFreq = SpiritRadioGetFrequencyBase(); /* Increase the VCO current */ uint8_t tmp = 0x19; SpiritSpiWriteRegisters(0xA1,1,&tmp); SpiritCalibrationVco(S_ENABLE); SpiritRefreshStatus(); if(g_xStatus.MC_STATE == MC_STATE_STANDBY) { cStandby = 1; SpiritCmdStrobeReady(); do{ SpiritRefreshStatus(); if(g_xStatus.MC_STATE == 0x13) { return 1; } }while(g_xStatus.MC_STATE != MC_STATE_READY); } SpiritCmdStrobeLockTx(); do{ SpiritRefreshStatus(); if(g_xStatus.MC_STATE == 0x13) { return 1; } }while(g_xStatus.MC_STATE != MC_STATE_LOCK); s_cVcoWordTx = SpiritCalibrationGetVcoCalData(); SpiritCmdStrobeReady(); do{ SpiritRefreshStatus(); }while(g_xStatus.MC_STATE != MC_STATE_READY); SpiritCmdStrobeLockRx(); do{ SpiritRefreshStatus(); if(g_xStatus.MC_STATE == 0x13) { return 1; } }while(g_xStatus.MC_STATE != MC_STATE_LOCK); s_cVcoWordRx = SpiritCalibrationGetVcoCalData(); SpiritCmdStrobeReady(); do{ SpiritRefreshStatus(); if(g_xStatus.MC_STATE == 0x13) { return 1; } }while(g_xStatus.MC_STATE != MC_STATE_READY); if(cStandby == 1) { SpiritCmdStrobeStandby(); } SpiritCalibrationVco(S_DISABLE); /* Disable the reference divider if the XTAL is between 48 and 52 MHz */ if(cRestore) { SpiritRadioSetRefDiv(S_DISABLE); SpiritManagementSetFrequencyBase(nFreq); } /* Restore the VCO current */ tmp = 0x11; SpiritSpiWriteRegisters(0xA1,1,&tmp); SpiritCalibrationSetVcoCalDataTx(s_cVcoWordTx); SpiritCalibrationSetVcoCalDataRx(s_cVcoWordRx); return 0; }
/** * @brief Identifies the SPIRIT1 Xtal frequency and version. * @param None * @retval Status */ void SpiritManagementIdentificationRFBoard(void) { do{ /* Delay for state transition */ for(volatile uint8_t i=0; i!=0xFF; i++); /* Reads the MC_STATUS register */ SpiritRefreshStatus(); }while(g_xStatus.MC_STATE!=MC_STATE_READY); SdkEvalSetHasEeprom(EepromIdentification()); if(!SdkEvalGetHasEeprom()) /* EEPROM is not present*/ { SpiritManagementComputeSpiritVersion(); SpiritManagementComputeXtalFrequency(); } else /* EEPROM found*/ { /*read the memory and set the variable*/ EepromRead(0x0000, 32, tmpBuffer); uint32_t xtal; if(tmpBuffer[0]==0 || tmpBuffer[0]==0xFF) { SpiritManagementComputeSpiritVersion(); SpiritManagementComputeXtalFrequency(); return; } switch(tmpBuffer[1]) { case 0: xtal = 24000000; SpiritRadioSetXtalFrequency(xtal); break; case 1: xtal = 25000000; SpiritRadioSetXtalFrequency(xtal); break; case 2: xtal = 26000000; SpiritRadioSetXtalFrequency(xtal); break; case 3: xtal = 48000000; SpiritRadioSetXtalFrequency(xtal); break; case 4: xtal = 50000000; SpiritRadioSetXtalFrequency(xtal); break; case 5: xtal = 52000000; SpiritRadioSetXtalFrequency(xtal); break; default: SpiritManagementComputeXtalFrequency(); break; } SpiritVersion spiritVersion; if(tmpBuffer[2]==0 || tmpBuffer[2]==1) { spiritVersion = SPIRIT_VERSION_2_1; //SpiritGeneralSetSpiritVersion(spiritVersion); } else if(tmpBuffer[2]==2) { spiritVersion = SPIRIT_VERSION_3_0; //SpiritGeneralSetSpiritVersion(spiritVersion); } else { SpiritManagementComputeSpiritVersion(); } if(tmpBuffer[14]==1) { spiritVersion = SPIRIT_VERSION_3_0_D1; // SpiritGeneralSetSpiritVersion(spiritVersion); } RangeExtType range; if(tmpBuffer[5]==0) { range = RANGE_EXT_NONE; } else if(tmpBuffer[5]==1) { range = RANGE_EXT_SKYWORKS_169; } else if(tmpBuffer[5]==2) { range = RANGE_EXT_SKYWORKS_868; } else { range = RANGE_EXT_NONE; } SpiritManagementSetRangeExtender(range); SpiritManagementSetBand(tmpBuffer[3]); } }
/** * @brief System main function. * @param None * @retval None */ void main (void) { SDK_SYSTEM_CONFIG(); #ifdef USE_VCOM #ifdef STM8L SdkEvalComInit(115200,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,(USART_Mode_TypeDef)(USART_Mode_Rx | USART_Mode_Tx)); #elif SDK /* VC config */ SdkEvalVCInit(); while(bDeviceState != CONFIGURED); #endif #endif /* Spirit ON */ SpiritEnterShutdown(); SpiritExitShutdown(); SpiritManagementWaExtraCurrent(); #ifdef STM8L /* Manually set the XTAL_FREQUENCY */ SpiritRadioSetXtalFrequency(XTAL_FREQUENCY); /* Initialize the frequency offset variable to compensate XTAL offset */ xRadioInit.lFrequencyBase = xRadioInit.lFrequencyBase + FREQUENCY_OFFSET; /* Initialize the signals to drive the range extender application board */ RANGE_EXT_INIT(RANGE_TYPE); #elif SDK SpiritManagementIdentificationRFBoard(); /* if the board has eeprom, we can compensate the offset calling SpiritManagementGetOffset (if eeprom is not present this fcn will return 0) */ xRadioInit.lFrequencyBase = xRadioInit.lFrequencyBase + SpiritManagementGetOffset(); /* Initialize the signals to drive the range extender application board */ SpiritManagementRangeExtInit(); #endif SdkEvalM2SGpioInit(M2S_GPIO_3,M2S_MODE_EXTI_IN); /* Spirit IRQ config */ SpiritGpioInit(&xGpioIRQ); /* Configure some output signals (to be probed with a scope to verify) */ SpiritGpioInit(&xGpio1Tx); SpiritGpioInit(&xGpio0Sleep); /* Spirit Radio config */ SpiritRadioInit(&xRadioInit); SpiritCalibrationRco(S_ENABLE); /* Spirit Radio set power */ SpiritRadioSetPALevelMaxIndex(7); SpiritRadioSetPALeveldBm(7,POWER_DBM); /* Spirit Packet config */ SpiritPktBasicInit(&xBasicInit); /* IRQ registers blanking */ SpiritIrqClearStatus(); #ifdef STM8L enableInterrupts(); #elif SDK SdkEvalM2SGpioInterruptCmd(M2S_GPIO_3,0x0A,0x0A,ENABLE); #endif /* Spirit IRQs enable */ SpiritIrqDeInit(&xIrqStatus); SpiritIrq(TX_DATA_SENT, S_ENABLE); /* payload length config */ SpiritPktBasicSetPayloadLength(20); /* Set the wake Up event every WAKEUP_TIMER ms */ SpiritTimerSetWakeUpTimerMs(WAKEUP_TIMER); SpiritCmdStrobeFlushTxFifo(); /* Enable the LDCR mode */ SpiritTimerLdcrMode(S_ENABLE); /* Send a Tx command */ SpiritCmdStrobeTx(); /* infinite loop */ while (1) { #ifdef USE_VCOM printf("A data to transmit: ["); for(uint8_t i=0 ; i<20 ; i++) printf("%d ", vectcTxBuff[i]); printf("]\n\r"); #endif /* Load the Tx FIFO with 20 bytes of data */ SpiritSpiWriteLinearFifo(20,vectcTxBuff); SpiritRefreshStatus(); /* Wait for the Tx done */ while(!xTxDoneFlag); xTxDoneFlag = RESET; } }