void SPIRIT_INIT(void) { NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000); // Use STM32L1xx_flash.icf RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE ); SdkEvalIdentification(); SdkStartSysTick(); SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); SdkEvalLedInit(LED1); SdkEvalLedInit(LED2); SdkEvalM2SGpioInit(M2S_GPIO_SDN,M2S_MODE_GPIO_OUT); SpiritSpiInit(); USART1_Init(); SpiritEnterShutdown(); SpiritExitShutdown(); SpiritManagementIdentificationRFBoard(); SdkEvalM2SGpioInit(M2S_GPIO_0, M2S_MODE_EXTI_IN); SdkEvalM2SGpioInterruptCmd(M2S_GPIO_0,0x0F,0x0F,ENABLE); SpiritGpioInit(&xGpioIRQ); SpiritRadioInit(&xRadioInit); SpiritPktBasicInit(&xBasicInit); SpiritPktBasicAddressesInit(&xAddressInit); SpiritIrqDeInit(&xIrqStatus); SpiritIrq(RX_DATA_DISC, S_ENABLE); SpiritIrq(RX_DATA_READY, S_ENABLE); // testy dla odbioru komend !!!!! SpiritIrq(TX_DATA_SENT, S_ENABLE); SpiritIrq(TX_FIFO_ERROR, S_ENABLE); // Declare Length of Payload SpiritPktBasicSetPayloadLength(PAYLOAD_LENGTH); SpiritQiSetSqiThreshold(SQI_TH_0); SpiritQiSqiCheck(S_ENABLE); SpiritIrqClearStatus(); // SET_INFINITE_RX_TIMEOUT(); SpiritTimerSetRxTimeoutMs(RX_TIMEOUT); //SpiritTimerSetRxTimeoutStopCondition(TIMEOUT_ALWAYS_STOPPED); SpiritTimerSetRxTimeoutStopCondition(SQI_ABOVE_THRESHOLD); SpiritIrqClearStatus(); //USART_Conf(); //*** For test purposes only: create unsigned, 16-bit counter vectcTxBuff[0] = 0; // Clear Counter to overwrite initial values vectcTxBuff[1] = 0; SdkDelayMs(2000); //wait till the tested board FW active // IWDG_Init(); // let the dogs out, }
/*---------------------------------------------------------------------------*/ static int spirit_radio_off(void) { PRINTF("Spirit1: ->off\n"); if(spirit_on == ON) { /* Disables the mcu to get IRQ from the SPIRIT1 */ IRQ_DISABLE(); /* first stop rx/tx */ spirit1_strobe(SPIRIT1_STROBE_SABORT); /* Clear any pending irqs */ SpiritIrqClearStatus(); BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5 * RTIMER_SECOND/1000); if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) { PRINTF("Spirit1: failed off->ready\n"); return 1; } /* Puts the SPIRIT1 in STANDBY */ spirit1_strobe(SPIRIT1_STROBE_STANDBY); BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 5 * RTIMER_SECOND/1000); if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) { PRINTF("Spirit1: failed off->stdby\n"); return 1; } spirit_on = OFF; CLEAR_TXBUF(); CLEAR_RXBUF(); } PRINTF("Spirit1: off.\n"); return 0; }
/*---------------------------------------------------------------------------*/ static int spirit_radio_transmit(unsigned short payload_len) { /* This function blocks until the packet has been transmitted */ rtimer_clock_t rtimer_txdone, rtimer_rxack; PRINTF("TRANSMIT IN\n"); if(!packet_is_prepared) { return RADIO_TX_ERR; } /* Stores the length of the packet to send */ /* Others spirit_radio_prepare will be in hold */ spirit_txbuf[0] = payload_len; /* Puts the SPIRIT1 in TX state */ receiving_packet = 0; SpiritSetReadyState(); spirit1_strobe(SPIRIT1_STROBE_TX); just_got_an_ack = 0; BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_TX, 5 * RTIMER_SECOND/1000); BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 50 * RTIMER_SECOND/1000); /* Reset radio - needed for immediate RX of ack */ CLEAR_TXBUF(); CLEAR_RXBUF(); SpiritIrqClearStatus(); spirit1_strobe(SPIRIT1_STROBE_SABORT); BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1 * RTIMER_SECOND/1000); spirit1_strobe(SPIRIT1_STROBE_READY); BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1 * RTIMER_SECOND/1000); spirit1_strobe(SPIRIT1_STROBE_RX); BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1 * RTIMER_SECOND/1000); #if NULLRDC_CONF_802154_AUTOACK if (wants_an_ack) { rtimer_txdone = RTIMER_NOW(); BUSYWAIT_UNTIL(just_got_an_ack, 15 * RTIMER_SECOND/1000); rtimer_rxack = RTIMER_NOW(); if(just_got_an_ack) { ACKPRINTF("debug_ack: ack received after %u/%u ticks\n", (uint32_t)(rtimer_rxack - rtimer_txdone), 15 * RTIMER_SECOND/1000); } else { ACKPRINTF("debug_ack: no ack received\n"); } } #endif /* NULLRDC_CONF_802154_AUTOACK */ PRINTF("TRANSMIT OUT\n"); CLEAR_TXBUF(); packet_is_prepared = 0; return RADIO_TX_OK; }
/** * @brief Puts the SPIRIT1 in READY state. * @param None * @retval None */ void SpiritSetReadyState(void) { PRINTF("READY IN\n"); SpiritIrqClearStatus(); IRQ_DISABLE(); if(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY) { spirit1_strobe(SPIRIT1_STROBE_READY); /* SpiritCmdStrobeReady();*/ } else if(SPIRIT1_STATUS() == SPIRIT1_STATE_RX) { spirit1_strobe(SPIRIT1_STROBE_SABORT); /* SpiritCmdStrobeSabort();*/ SpiritIrqClearStatus(); } IRQ_ENABLE(); PRINTF("READY OUT\n"); }
/*---------------------------------------------------------------------------*/ 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 System main function. * @param None * @retval None */ void main (void) { //*** DiZiC SPIRIT1 Demo NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000); // Use STM32L1xx_flash.icf RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE ); SdkEvalIdentification(); SdkStartSysTick(); SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); SdkEvalLedInit(LED1); SdkEvalLedInit(LED2); SdkEvalM2SGpioInit(M2S_GPIO_SDN,M2S_MODE_GPIO_OUT); SpiritSpiInit(); WUKPIN1_Init(); /*********************/ /* Allow access to RTC Domain */ // PWR_RTCAccessCmd(ENABLE); /* Clear WakeUp flag */ // PWR_ClearFlag(PWR_FLAG_WU); /* Check if the StandBy flag is set */ // if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET) // { /* Clear StandBy flag */ // PWR_ClearFlag(PWR_FLAG_SB); /* Wait for RTC APB registers synchronisation */ // RTC_WaitForSynchro(); /* No need to configure the RTC as the RTC config(clock source, enable, prescaler,...) are kept after wake-up from STANDBY */ // } /* RTC Configuration */ /* Reset RTC Domain */ // RCC_RTCResetCmd(ENABLE); // RCC_RTCResetCmd(DISABLE); /* Enable the LSE OSC */ // RCC_LSICmd(ENABLE); /* Wait till LSE is ready */ // while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) // {} /* Select the RTC Clock Source */ // RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); /* Enable the RTC Clock */ // RCC_RTCCLKCmd(ENABLE); /* Wait for RTC APB registers synchronisation */ // RTC_WaitForSynchro(); /* RTC domain*/ // RTC_WakeUpCmd(DISABLE); // RTC_ITConfig(RTC_IT_WUT , ENABLE); // RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div4); // RTC_SetWakeUpCounter(0xFF00); // PWR_WakeUpPinCmd(PWR_WakeUpPin_1 , DISABLE); #ifdef USE_VCOM /* VC config */ // SdkEvalVCInit(); // while(bDeviceState != CONFIGURED); #endif /* Spirit ON */ SpiritEnterShutdown(); SpiritExitShutdown(); SpiritManagementIdentificationRFBoard(); SdkEvalM2SGpioInit(M2S_GPIO_0,M2S_MODE_EXTI_IN); /* Spirit IRQ config */ SpiritGpioInit(&xGpioIRQ); SdkEvalM2SGpioInterruptCmd(M2S_GPIO_0,0x0F,0x0F,ENABLE); //*** SdkEvalLedOn(LED1); /* Spirit Radio config */ SpiritRadioInit(&xRadioInit); /* Spirit Packet config */ SpiritPktBasicInit(&xBasicInit); SpiritPktBasicAddressesInit(&xAddressInit); /* Spirit IRQs enable */ SpiritIrqDeInit(&xIrqStatus); SpiritIrq(RX_DATA_DISC,S_ENABLE); SpiritIrq(RX_DATA_READY,S_ENABLE); SpiritIrq(TX_DATA_SENT , S_ENABLE); /* payload length config */ SpiritPktBasicSetPayloadLength(512); /* enable SQI check */ SpiritQiSetSqiThreshold(SQI_TH_0); SpiritQiSqiCheck(S_ENABLE); /* RX timeout config */ SpiritTimerSetRxTimeoutMs(200.0); SpiritTimerSetRxTimeoutStopCondition(SQI_ABOVE_THRESHOLD); /* IRQ registers blanking */ SpiritIrqClearStatus(); /* RX command */ SpiritCmdStrobeRx(); // PWR_PVDCmd(DISABLE); // RCC_MSIRangeConfig(RCC_MSIRange_0); // RCC_AdjustMSICalibrationValue(0x00); // RCC_MSICmd(DISABLE); // RCC_HSICmd(DISABLE); // PWR_EnterSTOPMode(PWR_Regulator_LowPower , PWR_STOPEntry_WFI); // PWR_UltraLowPowerCmd(ENABLE); // PWR_FastWakeUpCmd(ENABLE); //////////////////////////////////////////////////////////////////////////////// // ErrorStatus HSE_Status; // RCC_HSEConfig(RCC_HSE_ON); // HSE_Status = RCC_WaitForHSEStartUp(); // FLASH_SetLatency(FLASH_Latency_1); // FLASH_PrefetchBufferCmd(ENABLE); // RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // RCC_HCLKConfig(RCC_SYSCLK_Div1); // RCC_PLLConfig(RCC_PLLSource_HSE, RCC_PLLMul_12, RCC_PLLDiv_3); // RCC_PCLK1Config(RCC_HCLK_Div1); // RCC_PCLK2Config(RCC_HCLK_Div1); ///////////////////////////////////////////////////////////////////////////////// /* infinite loop */ while (1){ printf("123"); SpiritCmdStrobeRx(); if(PressButtom) { PressButtom = FALSE; NOPdelay(2000); // fit the TX FIFO SpiritCmdStrobeFlushTxFifo(); SpiritSpiWriteLinearFifo(500, vectcTxBuff2); // send the TX command SpiritCmdStrobeTx(); // wait for TX done SdkEvalLedToggle(LED_GREEN); while(!xTxDoneFlag); SdkEvalLedToggle(LED_GREEN); xTxDoneFlag = RESET; // fit the TX FIFO SpiritCmdStrobeFlushTxFifo(); SpiritSpiWriteLinearFifo(500, vectcTxBuff2); // send the TX command SpiritCmdStrobeTx(); // wait for TX done SdkEvalLedToggle(LED_GREEN); while(!xTxDoneFlag); SdkEvalLedToggle(LED_GREEN); xTxDoneFlag = RESET; // fit the TX FIFO SpiritCmdStrobeFlushTxFifo(); SpiritSpiWriteLinearFifo(500, vectcTxBuff2); // send the TX command SpiritCmdStrobeTx(); // wait for TX done SdkEvalLedToggle(LED_GREEN); while(!xTxDoneFlag); SdkEvalLedToggle(LED_GREEN); xTxDoneFlag = RESET; } } }
/*---------------------------------------------------------------------------*/ void spirit1_interrupt_callback(void) { #define INTPRINTF // PRINTF SpiritIrqs xIrqStatus; if (SpiritSPIBusy() || interrupt_callback_in_progress) { process_poll(&spirit_radio_process); interrupt_callback_wants_poll = 1; return; } interrupt_callback_wants_poll = 0; interrupt_callback_in_progress = 1; /* get interrupt source from radio */ SpiritIrqGetStatus(&xIrqStatus); SpiritIrqClearStatus(); if(xIrqStatus.IRQ_RX_FIFO_ERROR) { receiving_packet = 0; interrupt_callback_in_progress = 0; spirit1_strobe(SPIRIT1_STROBE_FRX); return; } if(xIrqStatus.IRQ_TX_FIFO_ERROR) { receiving_packet = 0; interrupt_callback_in_progress = 0; spirit1_strobe(SPIRIT1_STROBE_FTX); return; } /* The IRQ_VALID_SYNC is used to notify a new packet is coming */ if(xIrqStatus.IRQ_VALID_SYNC) { INTPRINTF("SYNC\n"); receiving_packet = 1; } /* The IRQ_TX_DATA_SENT notifies the packet received. Puts the SPIRIT1 in RX */ if(xIrqStatus.IRQ_TX_DATA_SENT) { spirit1_strobe(SPIRIT1_STROBE_RX); /* SpiritCmdStrobeRx();*/ INTPRINTF("SENT\n"); CLEAR_TXBUF(); interrupt_callback_in_progress = 0; return; } /* The IRQ_RX_DATA_READY notifies a new packet arrived */ if(xIrqStatus.IRQ_RX_DATA_READY) { SpiritSpiReadLinearFifo(SpiritLinearFifoReadNumElementsRxFifo(), &spirit_rxbuf[1]); spirit_rxbuf[0] = SpiritPktBasicGetReceivedPktLength(); spirit1_strobe(SPIRIT1_STROBE_FRX); INTPRINTF("RECEIVED\n"); process_poll(&spirit_radio_process); receiving_packet = 0; #if NULLRDC_CONF_802154_AUTOACK if (spirit_rxbuf[0] == ACK_LEN) { /* For debugging purposes we assume this is an ack for us */ just_got_an_ack = 1; } #endif /* NULLRDC_CONF_802154_AUTOACK */ interrupt_callback_in_progress = 0; return; } if(xIrqStatus.IRQ_RX_DATA_DISC) { spirit1_strobe(SPIRIT1_STROBE_FRX); CLEAR_RXBUF(); INTPRINTF("DISC\n"); receiving_packet = 0; } interrupt_callback_in_progress = 0; }
/*---------------------------------------------------------------------------*/ static int spirit_radio_init(void) { PRINTF("RADIO INIT IN\n"); SpiritSpiInit(); /* Configure radio shut-down (SDN) pin and activate radio */ SdkEvalM2SGpioInit(M2S_GPIO_SDN, M2S_MODE_GPIO_OUT); /* Configures the SPIRIT1 library */ SpiritRadioSetXtalFrequency(XTAL_FREQUENCY); SpiritManagementSetVersion(SPIRIT1_VERSION); SpiritGeneralSetSpiritVersion(SPIRIT1_VERSION); SpiritManagementSetXtalFrequency(XTAL_FREQUENCY); /* wake up to READY state */ /* weirdly enough, this *should* actually *set* the pin, not clear it! The pins is declared as GPIO_pin13 == 0x2000 */ M2S_GPIO_SDN_PORT->BSRRL = M2S_GPIO_SDN_PIN; /* GPIOC->BSRRL = M2S_GPIO_SDN_PIN;*/ GPIO_ResetBits(M2S_GPIO_SDN_PORT, M2S_GPIO_SDN_PIN); /* wait minimum 1.5 ms to allow SPIRIT1 a proper boot-up sequence */ BUSYWAIT_UNTIL(0, 3 * RTIMER_SECOND/2000); /* Soft reset of core */ spirit1_strobe(SPIRIT1_STROBE_SRES); /* SpiritCmdStrobeSres();*/ /* Configures the SPIRIT1 radio part */ SRadioInit xRadioInit = { XTAL_FREQUENCY, XTAL_OFFSET_PPM, BASE_FREQUENCY, CHANNEL_SPACE, CHANNEL_NUMBER, MODULATION_SELECT, DATARATE, FREQ_DEVIATION, BANDWIDTH }; SpiritRadioInit(&xRadioInit); SpiritRadioSetPALeveldBm(0,POWER_DBM); SpiritRadioSetPALevelMaxIndex(0); /* Configures the SPIRIT1 packet handler part*/ PktBasicInit xBasicInit = { PREAMBLE_LENGTH, SYNC_LENGTH, SYNC_WORD, LENGTH_TYPE, LENGTH_WIDTH, CRC_MODE, CONTROL_LENGTH, EN_ADDRESS, EN_FEC, EN_WHITENING }; SpiritPktBasicInit(&xBasicInit); /* Enable the following interrupt sources, routed to GPIO */ SpiritIrqDeInit(NULL); SpiritIrqClearStatus(); SpiritIrq(TX_DATA_SENT, S_ENABLE); SpiritIrq(RX_DATA_READY,S_ENABLE); SpiritIrq(VALID_SYNC,S_ENABLE); SpiritIrq(RX_DATA_DISC, S_ENABLE); SpiritIrq(TX_FIFO_ERROR, S_ENABLE); SpiritIrq(RX_FIFO_ERROR, S_ENABLE); /* Configure Spirit1 */ SpiritRadioPersistenRx(S_ENABLE); SpiritQiSetSqiThreshold(SQI_TH_0); SpiritQiSqiCheck(S_ENABLE); SpiritQiSetRssiThresholddBm(CCA_THRESHOLD); SpiritTimerSetRxTimeoutStopCondition(SQI_ABOVE_THRESHOLD); SET_INFINITE_RX_TIMEOUT(); SpiritRadioAFCFreezeOnSync(S_ENABLE); /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */ spirit1_strobe(SPIRIT1_STROBE_STANDBY); /* SpiritCmdStrobeCommand(SPIRIT1_STROBE_STANDBY);*/ /* SpiritCmdStrobeStandby();*/ spirit_on = OFF; CLEAR_RXBUF(); CLEAR_TXBUF(); /* Initializes the mcu pin as input, used for IRQ */ SdkEvalM2SGpioInit(M2S_GPIO_0, M2S_MODE_EXTI_IN); SdkEvalM2SGpioInit(M2S_GPIO_1, M2S_MODE_EXTI_IN); SdkEvalM2SGpioInit(M2S_GPIO_2, M2S_MODE_EXTI_IN); SdkEvalM2SGpioInit(M2S_GPIO_3, M2S_MODE_EXTI_IN); /* Configure the radio to route the IRQ signal to its GPIO 3 */ SpiritGpioInit(&(SGpioInit){SPIRIT_GPIO_3, SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP, SPIRIT_GPIO_DIG_OUT_IRQ}); process_start(&spirit_radio_process, NULL); PRINTF("Spirit1 init done\n"); return 0; }
/** * @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_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 /* Initialize the signals to drive the range extender application board */ SpiritManagementRangeExtInit(); SdkEvalM2SGpioInit(M2S_GPIO_3,M2S_MODE_EXTI_IN); SdkEvalM2SGpioInterruptCmd(M2S_GPIO_3,0x0A,0x0A,ENABLE); /* Spirit IRQ config */ SpiritGpioInit(&xGpioIRQ); /* Spirit Radio config */ SpiritRadioInit(&xRadioInit); /* Spirit Radio set power */ SpiritRadioSetPALevelMaxIndex(7); SpiritRadioSetPALeveldBm(7,POWER_DBM); /* Spirit Packet config */ SpiritPktStackInit(&xStackInit); SpiritPktStackAddressesInit(&xAddressInit); SpiritPktStackLlpInit(&xStackLLPInit); /* Spirit IRQs enable */ SpiritIrqDeInit(NULL); SpiritIrq(TX_DATA_SENT, S_ENABLE); SpiritIrq(RX_DATA_READY, S_ENABLE); SpiritIrq(RX_DATA_DISC, S_ENABLE); /* RX timeout config */ SET_INFINITE_RX_TIMEOUT(); SpiritTimerSetRxTimeoutStopCondition(SQI_ABOVE_THRESHOLD); /* Payload length config */ SpiritPktStackSetPayloadLength(20); /* Destination address */ SpiritPktStackSetDestinationAddress(DESTINATION_ADDRESS); /* IRQ registers blanking */ SpiritIrqClearStatus(); /* infinite loop */ while (1){ /* RX command */ SpiritCmdStrobeRx(); /* wait for data received */ while(!xRxDoneFlag); xRxDoneFlag=RESET; /* when rx data ready read the number of received bytes */ cRxData=SpiritLinearFifoReadNumElementsRxFifo(); /* read the RX FIFO */ SpiritSpiReadLinearFifo(cRxData, vectcBallBuff); SpiritCmdStrobeFlushRxFifo(); /* A simple way to control if the received data sequence is correct. Use a local block. */ { SpiritBool correct=S_TRUE; /* control all the received bytes and verify that they are sequential numbers from 1 to 20. If one of them is not an expected value then stop the communication. */ for(uint8_t i=0 ; i<cRxData ; i++) if(vectcBallBuff[i] != i+1) correct=S_FALSE; #ifdef USE_VCOM /* send messages via COM */ if(correct) { printf("B Rx data: ["); for(uint8_t i=0 ; i<cRxData ; i++) printf("%d ", vectcBallBuff[i]); printf("]\r\n"); } else { printf("data error! ping pong stopped\n\r"); } #endif /* stop communication if an incorrect sequence has been received */ if(!correct){ SdkEvalLedOn(LED4); while(1); } } /* pause between RX and TX */ SdkDelayMs(500); /* fit the TX FIFO */ SpiritCmdStrobeFlushTxFifo(); SpiritSpiWriteLinearFifo(20, vectcBallBuff); /* send the TX command */ SpiritCmdStrobeTx(); /* wait for TX done */ while(!xTxDoneFlag); xTxDoneFlag = RESET; #ifdef USE_VCOM /* send messages via COM */ printf("B Tx data: ["); for(uint8_t i=0 ; i<cRxData ; i++) printf("%d ", vectcBallBuff[i]); printf("]\n\r"); #endif } }
/** * @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 /* Spirit IRQ config */ SpiritGpioInit(&xGpioIRQ); /* Spirit Radio config */ SpiritRadioInit(&xRadioInit); /* Spirit Radio set power */ SpiritRadioSetPALeveldBm(0,POWER_DBM); SpiritRadioSetPALevelMaxIndex(0); /* Spirit Packet config */ SpiritPktStackInit(&xStackInit); //SpiritPktStackAddressesInit(&xAddressInit); SpiritPktStackLlpInit(&xStackLLPInit); /* Spirit IRQs enable */ SpiritIrqDeInit(&xIrqStatus); SpiritIrq(RX_DATA_DISC,S_ENABLE); SpiritIrq(RX_DATA_READY,S_ENABLE); SpiritIrq(TX_DATA_SENT , S_ENABLE); EXTI_ClearITPendingBit(M2S_GPIO_3_EXTI_LINE); SdkEvalM2SGpioInit(M2S_GPIO_3,M2S_MODE_EXTI_IN); /* enable SQI check */ SpiritQiSetSqiThreshold(SQI_TH_0); SpiritQiSqiCheck(S_ENABLE); /* rx timeout config */ SpiritTimerSetRxTimeoutMs(1000.0); //SET_INFINITE_RX_TIMEOUT(); SpiritTimerSetRxTimeoutStopCondition(SQI_ABOVE_THRESHOLD); /* IRQ registers blanking */ SpiritIrqClearStatus(); #ifdef PIGGYBACKING /* payload length config */ SpiritPktStackSetPayloadLength(20); /* write piggybacking data */ SpiritSpiWriteLinearFifo(20, vectcTxBuff); #endif #ifdef STM8L enableInterrupts(); #elif SDK SdkEvalM2SGpioInterruptCmd(M2S_GPIO_3,0x0A,0x0A,ENABLE); #endif /* RX command */ SpiritCmdStrobeRx(); while (1){ } }
/** * @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_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); #ifdef STM8L enableInterrupts(); #elif SDK SdkEvalM2SGpioInterruptCmd(M2S_GPIO_3,0x0A,0x0A,ENABLE); #endif /* Spirit Radio config */ SpiritRadioInit(&xRadioInit); /* Spirit Radio set power */ SpiritRadioSetPALeveldBm(7,POWER_DBM); SpiritRadioSetPALevelMaxIndex(7); /* Spirit Packet config */ SpiritPktStackInit(&xStackInit); SpiritPktStackAddressesInit(&xAddressInit); /* Spirit IRQs enable */ SpiritIrqDeInit(NULL); SpiritIrq(TX_DATA_SENT , S_ENABLE); /* payload length config */ SpiritPktStackSetPayloadLength(20); /* destination address */ SpiritPktStackSetDestinationAddress(DESTINATION_ADDRESS); /* IRQ registers blanking */ SpiritIrqClearStatus(); /* 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 /* fit the TX FIFO */ SpiritCmdStrobeFlushTxFifo(); SpiritSpiWriteLinearFifo(20, vectcTxBuff); /* send the TX command */ SpiritCmdStrobeTx(); /* wait for TX done */ while(!xTxDoneFlag); xTxDoneFlag = RESET; /* pause between two transmissions */ SdkDelayMs(500); } }
/** * @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 /* Reset Spirit registers to default */ SpiritCmdStrobeSres(); 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(&xGpio1Rx); SpiritGpioInit(&xGpio0Sleep); /* Spirit Radio config */ SpiritRadioInit(&xRadioInit); SpiritCalibrationRco(S_ENABLE); /* Spirit Packet config */ SpiritPktBasicInit(&xBasicInit); /* IRQ registers blanking */ SpiritIrqClearStatus(); #ifdef STM8L enableInterrupts(); #elif SDK SdkEvalM2SGpioInterruptCmd(M2S_GPIO_3,0x0A,0x0A,ENABLE); #endif SpiritQiSetSqiThreshold(SQI_TH_0); SpiritQiSqiCheck(S_ENABLE); /* Spirit IRQs enable */ SpiritIrqDeInit(&xIrqStatus); SpiritIrq(RX_DATA_READY,S_ENABLE); SpiritIrq(RX_DATA_DISC,S_ENABLE); /* Payload length config */ SpiritPktBasicSetPayloadLength(20); /* RX timeout config */ SET_INFINITE_RX_TIMEOUT(); SpiritTimerSetRxTimeoutStopCondition(SQI_ABOVE_THRESHOLD); float fWuTimer; uint8_t cWuPrescaler,cWuCounter,cWuReloadCounter; /* Set the wake Up event every WAKEUP_TIMER ms */ SpiritTimerSetWakeUpTimerMs(WAKEUP_TIMER); /* Get the counter and the prescaler of the WU timer */ SpiritTimerGetWakeUpTimer(&fWuTimer,&cWuCounter,&cWuPrescaler); /* Compute the rephasing timer to be reloaded on sync. This value will be equal to: WAKE_UP_TIMER - (PREAMB_TIME + SYNC_TIME) - GUARD_TIME, where: - (PREAMB_TIME + SYNC_TIME) is the time needed to transmit preamble and sync. - GUARD_TIME is a security bound to make the Rx awake before the Tx. */ float fReloadMs = WAKEUP_TIMER-1000.0*(float)(SpiritPktBasicGetPreambleLength()+SpiritPktBasicGetSyncLength())*8.0/DATARATE-10.0; /* In order to have not lack of accuracy it is recommended that the reload timer has the same prescaler of the WakeUp timer. So compute the counter using the WU prescaler previously computed. */ cWuReloadCounter=(uint8_t)(fReloadMs*(float)SpiritTimerGetRcoFrequency()/1000/(cWuPrescaler+1))-1; /* Set the Wake up reload timer */ SpiritTimerSetWakeUpTimerReload(cWuReloadCounter,cWuPrescaler); /* Enable the auto reload on sync */ SpiritTimerLdcrAutoReload(S_ENABLE); /* Enable the LDCR mode */ SpiritTimerLdcrMode(S_ENABLE); SpiritCmdStrobeFlushRxFifo(); /* Set Spirit in Rx state */ SpiritCmdStrobeRx(); /* infinite loop */ while (1) { while(!xRxDataReadyFlag); xRxDataReadyFlag=RESET; if(xFirstReception==RESET) { SpiritTimerSetRxTimeoutMs(80.0); xFirstReception=SET; SdkEvalLedToggle(LED1); } } }
/** * @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 /* Spirit IRQ config */ SpiritGpioInit(&xGpioIRQ); /* Spirit Radio config */ SpiritRadioInit(&xRadioInit); /* Spirit Radio set power */ SpiritRadioSetPALeveldBm(7,POWER_DBM); SpiritRadioSetPALevelMaxIndex(7); /* Spirit Packet config */ SpiritPktStackInit(&xStackInit); SpiritPktStackLlpInit(&xStackLLPInit); /* Spirit IRQs enable */ SpiritIrqDeInit(NULL); SpiritIrq(TX_DATA_SENT , S_ENABLE); SpiritIrq(RX_DATA_READY, S_ENABLE); SpiritIrq(MAX_RE_TX_REACH, S_ENABLE); EXTI_ClearITPendingBit(M2S_GPIO_3_EXTI_LINE); SdkEvalM2SGpioInit(M2S_GPIO_3,M2S_MODE_EXTI_IN); /* payload length config */ SpiritPktStackSetPayloadLength(20); /* enable SQI check */ SpiritQiSetSqiThreshold(SQI_TH_0); SpiritQiSqiCheck(S_ENABLE); /* rx timeout config */ SpiritTimerSetRxTimeoutMs(200.0); SpiritTimerSetRxTimeoutStopCondition(SQI_ABOVE_THRESHOLD); /* require ack from the receiver */ SpiritPktStackRequireAck(S_ENABLE); /* IRQ registers blanking */ SpiritIrqClearStatus(); #ifdef STM8L enableInterrupts(); #elif SDK SdkEvalM2SGpioInterruptCmd(M2S_GPIO_3,0x0A,0x0A,ENABLE); #endif /* 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("]\r\n"); #endif /* fit the TX FIFO */ SpiritCmdStrobeFlushTxFifo(); SpiritSpiWriteLinearFifo(20, vectcTxBuff); /* send the TX command */ SpiritCmdStrobeTx(); /* wait for TX done */ while(!xTxDoneFlag); xTxDoneFlag = RESET; /* Delay after reset */ SdkDelayMs(500); } }
/** * @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 /* uC IRQ config */ SdkEvalM2SGpioInit(M2S_GPIO_3,M2S_MODE_EXTI_IN); /* Spirit IRQ config */ SpiritGpioInit(&xGpioIRQ); /* uC IRQ enable */ #ifdef STM8L enableInterrupts(); #elif SDK SdkEvalM2SGpioInterruptCmd(M2S_GPIO_3,0x0A,0x0A,ENABLE); #endif /* Spirit Radio config */ SpiritRadioInit(&xRadioInit); /* Spirit Packet config */ SpiritPktBasicInit(&xBasicInit); SpiritPktBasicAddressesInit(&xAddressInit); /* Spirit IRQs enable */ SpiritIrqDeInit(&xIrqStatus); SpiritIrq(RX_DATA_DISC,S_ENABLE); SpiritIrq(RX_DATA_READY,S_ENABLE); /* payload length config */ SpiritPktBasicSetPayloadLength(20); /* enable SQI check */ SpiritQiSetSqiThreshold(SQI_TH_0); SpiritQiSqiCheck(S_ENABLE); /* RX timeout config */ SpiritTimerSetRxTimeoutMs(1000.0); SpiritTimerSetRxTimeoutStopCondition(SQI_ABOVE_THRESHOLD); /* IRQ registers blanking */ SpiritIrqClearStatus(); /* RX command */ SpiritCmdStrobeRx(); /* infinite loop */ while (1){ } }
/** * @brief this function clear the IRQ status * @param None * @retval None */ void Spirit1ClearIRQ(void) { SpiritIrqClearStatus(); }
/** * @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; } }