/***************************************************************************** Function: void TickInit(void) Summary: Initializes the Tick manager module. Description: Configures the Tick module and any necessary hardware resources. Precondition: None Parameters: None Returns: None Remarks: This function is called only one during lifetime of the application. ***************************************************************************/ void TickInit(void) { #if defined(__18CXX) // Use Timer0 for 8 bit processors // Initialize the time TMR0H = 0; TMR0L = 0; // Set up the timer interrupt INTCON2bits.TMR0IP = 1; // High priority INTCONbits.TMR0IF = 0; INTCONbits.TMR0IE = 1; // Enable interrupt // Timer0 on, 16-bit, internal timer, 1:256 prescalar T0CON = 0x87; #else /* // Use Timer 1 for 16-bit and 32-bit processors // 1:1 prescale T1CONbits.TCKPS = 0; T1CONbits.TCS = 1; //T1CON = 0x0002; // Base PR1 = 0xFFFF; // Clear counter TMR1 = 0; // Enable timer interrupt #if defined(__C30__) IPC0bits.T1IP = 2; // Interrupt priority 2 (low) IFS0bits.T1IF = 0; IEC0bits.T1IE = 1; #else IPC1bits.T1IP = 2; // Interrupt priority 2 (low) IFS0CLR = _IFS0_T1IF_MASK; IEC0SET = _IEC0_T1IE_MASK; #endif // Start timer T1CONbits.TON = 1; */ TimerInit(TIMER1, CLOCK_SOURCE_EXTERNAL, GATED_DISABLE, PRE_1_1, IDLE_ENABLE, BIT_16, SYNC_ENABLE); TimerSetValue(TIMER1, 0x0000, 0xFFFF); TimerSetCallback(TIMER1, Timer1Callback); TimerSetInt(TIMER1, 7, TRUE); TimerSetState(TIMER1, TRUE); { DWORD RTCSec = GetTimeFromRTC(); dwInternalTicks = RTCSec / 2; if(RTCSec & 1){ TimerSetValue(TIMER1, TICKS_PER_SECOND, 0xFFFF); } } #endif }
/*! * \brief Function executed on ultrasonic sensor timeout event * If range and temperature readings not available in reasonable time * sends sensor data with range and temperature in error */ static void OnUltrasonicTimeout ( void ) { pc.printf("OnUltrasonicTimeout - Sensor FAULT\r\n"); SensorState = FAULT; NextTx = true; TimerSetValue( &TxNextPacketTimer, 100 ); // Schedule immediate transmission TimerStart( &TxNextPacketTimer ); }
int SetTickInSeconds(DWORD Seconds, WORD Milliseconds) { volatile DWORD S = 0; volatile DWORD m = 0; m = Milliseconds * TICKS_PER_SECOND; m = m / 1000ul; S = Seconds; m += S & 1; S = S >> 1; TimerSetValue(TIMER1, (WORD)m, 0xFFFF); dwInternalTicks = S; SetRTCTimeFromUTC(Seconds); return 0; }
static void OnRadioTxDone( void ) { TimerTime_t curTime = TimerGetCurrentTime(); LOG_TRACE("Transmitted successfully (%u ms).", (uint32_t)(curTime * portTICK_PERIOD_MS)); // Update Band Time OFF Bands[Channels[pLoRaDevice->currChannelIndex].Band].LastTxDoneTime = curTime; if ( pLoRaDevice->dbgFlags.Bits.dutyCycleCtrlOff == 0 ) { Bands[Channels[pLoRaDevice->currChannelIndex].Band].TimeOff = TxTimeOnAir * Bands[Channels[pLoRaDevice->currChannelIndex].Band].DCycle - TxTimeOnAir; } else { Bands[Channels[pLoRaDevice->currChannelIndex].Band].TimeOff = 0; } // Update Agregated Time OFF AggregatedLastTxDoneTime = curTime; AggregatedTimeOff = AggregatedTimeOff + (TxTimeOnAir * AggregatedDCycle - TxTimeOnAir); if ( phyFlags.Bits.TxType == LORAPHY_TXTYPE_ADVERTISING ) { /* Open advertising beacon reception window */ } else if ( phyFlags.Bits.TxType == LORAPHY_TXTYPE_REGULAR && pLoRaDevice->dbgFlags.Bits.rxWindowsDisabled != 1 ) { TimerSetValue(&RxWindow1Timer, pLoRaDevice->rxWindow1Delay); TimerStart(&RxWindow1Timer); TimerSetValue(&RxWindow2Timer, pLoRaDevice->rxWindow2Delay); TimerStart(&RxWindow2Timer); } else { phyFlags.Bits.TxDone = 1; } /* Uplink message repetition is only valid for unconfirmed messages */ if ( pLoRaDevice->ctrlFlags.Bits.ackPending == 0 ) { pLoRaDevice->nbRepCounter++; } }
/** * Main application entry point. */ int main( void ) { // Target board initialisation BoardInitMcu( ); BoardInitPeriph( ); // Radio initialization Radio.Init( NULL ); Radio.SetChannel( RF_FREQUENCY ); /**********************************************/ /* WARNING */ /* The below settings can damage the chipset */ /* if wrongly used. DO NOT CHANGE THE VALUES! */ /* */ /**********************************************/ #if ( defined( USE_BAND_433 ) || defined( USE_BAND_470 ) ) Radio.Write( 0x01, 0x88 ); Radio.Write( 0x3D, 0xA1 ); Radio.Write( 0x36, 0x01 ); Radio.Write( 0x1e, 0x08 ); #elif ( defined( USE_BAND_868 ) || defined( USE_BAND_915 ) ) Radio.Write( 0x01, 0x80 ); Radio.Write( 0x44, 0x7B ); Radio.Write( 0x3D, 0xA1 ); Radio.Write( 0x36, 0x01 ); Radio.Write( 0x1e, 0x08 ); Radio.Write( 0x45, 0xDF ); Radio.Write( 0x46, 0x03 ); Radio.Write( 0x4D, 0x87 ); Radio.Write( 0x52, 0x60 ); #endif Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, LORA_CODINGRATE, LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, true, LORA_IQ_INVERSION_ON, 3000000 ); TimerInit( &Led1Timer, OnLed1TimerEvent ); TimerSetValue( &Led1Timer, 90000 ); TimerInit( &Led2Timer, OnLed2TimerEvent ); TimerSetValue( &Led2Timer, 90000 ); TimerInit( &Led3Timer, OnLed3TimerEvent ); TimerSetValue( &Led3Timer, 90000 ); // Switch LED 1 ON GpioWrite( &Led1, 0 ); TimerStart( &Led1Timer ); // Sets the radio in Tx mode Radio.Send( NULL, 0 ); // Blink LEDs just to show some activity while( 1 ) { if( Led1TimerEvent == true ) { Led1TimerEvent = false; // Switch LED 1 OFF GpioWrite( &Led1, 1 ); // Switch LED 2 ON GpioWrite( &Led2, 0 ); TimerStart( &Led2Timer ); } if( Led2TimerEvent == true ) { Led2TimerEvent = false; // Switch LED 2 OFF GpioWrite( &Led2, 1 ); // Switch LED 3 ON GpioWrite( &Led3, 0 ); TimerStart( &Led3Timer ); } if( Led3TimerEvent == true ) { Led3TimerEvent = false; // Switch LED 3 OFF GpioWrite( &Led3, 1 ); // Switch LED 1 ON GpioWrite( &Led1, 0 ); TimerStart( &Led1Timer ); } } }
int main( void ) { HAL_EnableDBGStopMode(); LowPowerConfiguration(); pc.baud(115200); // print banner pc.printf("\r\n============== DEBUG STARTED ==============\r\n"); /** User button triggers the ultrasonic sensor */ //PinDetect button(PC_13,PullUp); //button.attach_asserted(&sensor, &UltraSonic::triggerSample); // callback routine to trigger usonic //button.setSampleFrequency(); LoRaMacPrimitives_t LoRaMacPrimitives; LoRaMacCallback_t LoRaMacCallbacks; MibRequestConfirm_t mibReq; //BoardInitMcu( ); //BoardInitPeriph( ); BoardInit( ); TimerInit( &mainLoopTimeout, onMainLoopTimeoutEvent ); DeviceState = DEVICE_STATE_INIT; while( 1 ) { wait(0.5); // This is a kind of watchdog on the main loop, if the timer isn't cancelled in x seconds then loop will enter INIT state TimerSetValue( &mainLoopTimeout, 3000000 ); TimerStart( &mainLoopTimeout ); switch( DeviceState ) { case DEVICE_STATE_INIT: { pc.printf("DEVICE_STATE_INIT\r\n"); LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm; LoRaMacPrimitives.MacMcpsIndication = McpsIndication; LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm; LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel; LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks ); TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); TimerInit( &ultrasonicTimer, OnUltrasonicTimeout ); mibReq.Type = MIB_ADR; mibReq.Param.AdrEnable = LORAWAN_ADR_ON; LoRaMacMibSetRequestConfirm( &mibReq ); // MAC information base service to set attributes of LoRaMac layer mibReq.Type = MIB_PUBLIC_NETWORK; mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; LoRaMacMibSetRequestConfirm( &mibReq ); sensor.distanceAvailable = false; // Ensure initialised to false after power up DeviceState = DEVICE_STATE_JOIN; break; } case DEVICE_STATE_JOIN: { pc.printf("DEVICE_STATE_JOIN\r\n"); #if( OVER_THE_AIR_ACTIVATION != 0 ) pc.printf("OTA\r\n"); MlmeReq_t mlmeReq; // Initialize LoRaMac device unique ID //BoardGetUniqueId( DevEui ); mlmeReq.Type = MLME_JOIN; // MAC management service types are MLME_JOIN or MLME_LINK_CHECK mlmeReq.Req.Join.DevEui = DevEui; mlmeReq.Req.Join.AppEui = AppEui; mlmeReq.Req.Join.AppKey = AppKey; if( NextTx == true ) { LoRaMacMlmeRequest( &mlmeReq ); // Sends a join request } // Schedule next packet transmission //TxDutyCycleTime = OVER_THE_AIR_ACTIVATION_DUTYCYCLE; //DeviceState = DEVICE_STATE_CYCLE; DeviceState = DEVICE_STATE_CYCLE; #else pc.printf("ABP\r\n"); // Choose a random device address if not already defined in Comissioning.h if( DevAddr == 0 ) { // Random seed initialization // srand1( BoardGetRandomSeed( ) ); // Choose a random device address DevAddr = randr( 0, 0x01FFFFFF ); } mibReq.Type = MIB_NET_ID; mibReq.Param.NetID = LORAWAN_NETWORK_ID; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_DEV_ADDR; mibReq.Param.DevAddr = DevAddr; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_NWK_SKEY; mibReq.Param.NwkSKey = NwkSKey; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_APP_SKEY; mibReq.Param.AppSKey = AppSKey; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_NETWORK_JOINED; mibReq.Param.IsNetworkJoined = true; LoRaMacMibSetRequestConfirm( &mibReq ); DeviceState = DEVICE_STATE_SEND; #endif break; } case DEVICE_STATE_SEND: { pc.printf("DEVICE_STATE_SEND\r\n"); if( NextTx == true ) { pc.printf("Sending\r\n"); PrepareTxFrame( AppPort ); NextTx = SendFrame( ); } } case DEVICE_STATE_CYCLE: { pc.printf("DEVICE_STATE_CYCLE\r\n"); pc.printf("SensorState = %d, distanceAvailable = ",SensorState); if (sensor.distanceAvailable) pc.printf("true\r\n"); else pc.printf("false\r\n"); pc.printf("LoRaMacState = %d\r\n",GetMacStatus()); if ((SensorState == SENT) || (SensorState == INIT)) { /** Range and Temperature readings have been sent so we can sleep */ TimerStop( &TxNextPacketTimer ); // Wait for MAC state to become idle before deep sleeping if (GetMacStatus() == 0) { // Ensure MAC state is idle before sleeping pc.printf("DeepSleep ..zzz.\r\n"); TimerStop(&mainLoopTimeout); // cancel main loop guard timeout WakeUp::set(DEEPSLEEP_SECONDS); // Set RTC alarm to wake up from deep sleep LowPowerPrep(); deepsleep(); // Deep sleep until wake up alarm from RTC LowPowerRestore(); SensorState = TRIGGERED; /* Trigger ultrasonic sensor and start sensor read failure timer */ sensor.triggerSample(); // Get Ultrasonic reading TimerSetValue( &ultrasonicTimer, 2000000 ); // 2s timeout TimerStart( &ultrasonicTimer ); DeviceState = DEVICE_STATE_SLEEP; // Cycle in sleep until sensor readings ready } else { // Cycle around until MAC state is idle DeviceState = DEVICE_STATE_CYCLE; } } else { // Error shouldn't get here pc.printf("Error State!!\r\n"); //TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); //TimerStart( &TxNextPacketTimer ); SensorState = INIT; DeviceState = DEVICE_STATE_SLEEP; } break; } case DEVICE_STATE_SLEEP: { pc.printf("DEVICE_STATE_SLEEP\r\n"); // Loop until sensor ready if ((SensorState == TRIGGERED) && (sensor.distanceAvailable)) { pc.printf("Xmit Reading..!\r\n"); TimerStop( &ultrasonicTimer ); // stop the sensor failure timer SensorState = SENDING; TimerSetValue( &TxNextPacketTimer, 10 ); // Schedule immediate transmission TimerStart( &TxNextPacketTimer ); } break; } default: { DeviceState = DEVICE_STATE_INIT; break; } } } }
/** * Main application entry point. */ int main( void ) { LoRaMacPrimitives_t LoRaMacPrimitives; LoRaMacCallback_t LoRaMacCallbacks; MibRequestConfirm_t mibReq; BoardInitMcu( ); BoardInitPeriph( ); DeviceState = DEVICE_STATE_INIT; while( 1 ) { switch( DeviceState ) { case DEVICE_STATE_INIT: { LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm; LoRaMacPrimitives.MacMcpsIndication = McpsIndication; LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm; LoRaMacPrimitives.MacMlmeIndication = MlmeIndication; LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel; LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks, ACTIVE_REGION ); TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); TimerInit( &Led1Timer, OnLed1TimerEvent ); TimerSetValue( &Led1Timer, 25 ); TimerInit( &Led2Timer, OnLed2TimerEvent ); TimerSetValue( &Led2Timer, 25 ); mibReq.Type = MIB_ADR; mibReq.Param.AdrEnable = LORAWAN_ADR_ON; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_PUBLIC_NETWORK; mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; LoRaMacMibSetRequestConfirm( &mibReq ); #if defined( REGION_EU868 ) LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON ); #endif mibReq.Type = MIB_DEVICE_CLASS; mibReq.Param.Class = CLASS_C; LoRaMacMibSetRequestConfirm( &mibReq ); DeviceState = DEVICE_STATE_JOIN; break; } case DEVICE_STATE_JOIN: { #if( OVER_THE_AIR_ACTIVATION != 0 ) MlmeReq_t mlmeReq; // Initialize LoRaMac device unique ID BoardGetUniqueId( DevEui ); mlmeReq.Type = MLME_JOIN; mlmeReq.Req.Join.DevEui = DevEui; mlmeReq.Req.Join.AppEui = AppEui; mlmeReq.Req.Join.AppKey = AppKey; mlmeReq.Req.Join.Datarate = LORAWAN_DEFAULT_DATARATE; if( LoRaMacMlmeRequest( &mlmeReq ) == LORAMAC_STATUS_OK ) { DeviceState = DEVICE_STATE_SLEEP; } else { DeviceState = DEVICE_STATE_CYCLE; } #else // Choose a random device address if not already defined in Commissioning.h if( DevAddr == 0 ) { // Random seed initialization srand1( BoardGetRandomSeed( ) ); // Choose a random device address DevAddr = randr( 0, 0x01FFFFFF ); } mibReq.Type = MIB_NET_ID; mibReq.Param.NetID = LORAWAN_NETWORK_ID; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_DEV_ADDR; mibReq.Param.DevAddr = DevAddr; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_NWK_SKEY; mibReq.Param.NwkSKey = NwkSKey; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_APP_SKEY; mibReq.Param.AppSKey = AppSKey; LoRaMacMibSetRequestConfirm( &mibReq ); mibReq.Type = MIB_NETWORK_JOINED; mibReq.Param.IsNetworkJoined = true; LoRaMacMibSetRequestConfirm( &mibReq ); DeviceState = DEVICE_STATE_SEND; #endif break; } case DEVICE_STATE_SEND: { if( NextTx == true ) { PrepareTxFrame( AppPort ); NextTx = SendFrame( ); } if( ComplianceTest.Running == true ) { // Schedule next packet transmission TxDutyCycleTime = 5000; // 5000 ms } else { // Schedule next packet transmission TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); } DeviceState = DEVICE_STATE_CYCLE; break; } case DEVICE_STATE_CYCLE: { DeviceState = DEVICE_STATE_SLEEP; // Schedule next packet transmission TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); TimerStart( &TxNextPacketTimer ); break; } case DEVICE_STATE_SLEEP: { // Wake up through events TimerLowPowerHandler( ); // Process Radio IRQ Radio.IrqProcess( ); break; } default: { DeviceState = DEVICE_STATE_INIT; break; } } } }
/** * Main application entry point. */ int main( void ) { uint8_t sendFrameStatus = 0; uint8_t batteryLevel = 0; BoardInitMcu( ); BoardInitPeriph( ); // Initialize LoRaMac device unique ID BoardGetUniqueId( DevEui ); LoRaMacEvents.MacEvent = OnMacEvent; LoRaMacInit( &LoRaMacEvents ); IsNetworkJoined = false; #if( OVER_THE_AIR_ACTIVATION == 0 ) // Random seed initialization srand( RAND_SEED ); // Choose a random device address // NwkID = 0 // NwkAddr rand [0, 33554431] DevAddr = randr( 0, 0x01FFFFFF ); LoRaMacInitNwkIds( 0x000000, DevAddr, NwkSKey, AppSKey ); IsNetworkJoined = true; #else // Sends a JoinReq Command every 5 seconds until the network is joined TimerInit( &JoinReqTimer, OnJoinReqTimerEvent ); TimerSetValue( &JoinReqTimer, OVER_THE_AIR_ACTIVATION_DUTYCYCLE ); TimerStart( &JoinReqTimer ); #endif TxNextPacket = true; TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); TimerInit( &Led1Timer, OnLed1TimerEvent ); TimerSetValue( &Led1Timer, 25000 ); TimerInit( &Led2Timer, OnLed2TimerEvent ); TimerSetValue( &Led2Timer, 25000 ); LoRaMacSetAdrOn( true ); while( 1 ) { while( IsNetworkJoined == false ) { #if( OVER_THE_AIR_ACTIVATION != 0 ) if( TxNextPacket == true ) { TxNextPacket = false; LoRaMacJoinReq( DevEui, AppEui, AppKey ); // Relaunch timer for next trial TimerStart( &JoinReqTimer ); } TimerLowPowerHandler( ); #endif } if( Led1TimerEvent == true ) { Led1TimerEvent = false; // Switch LED 1 OFF GpioWrite( &Led1, 1 ); } if( Led2TimerEvent == true ) { Led2TimerEvent = false; // Switch LED 2 OFF GpioWrite( &Led2, 1 ); } if( TxAckReceived == true ) { TxAckReceived = false; // Switch LED 2 ON GpioWrite( &Led2, 0 ); TimerStart( &Led2Timer ); } if( RxDone == true ) { RxDone = false; // Switch LED 2 ON GpioWrite( &Led2, 0 ); TimerStart( &Led2Timer ); if( AppLedStateOn == true ) { // Switch LED 3 ON GpioWrite( &Led2, 0 ); } else { // Switch LED 3 OFF GpioWrite( &Led2, 1 ); } } if( TxDone == true ) { TxDone = false; // Schedule next packet transmission TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); TimerStart( &TxNextPacketTimer ); } if( TxNextPacket == true ) { TxNextPacket = false; batteryLevel = BoardMeasureBatterieLevel( ); // 1 (very low) to 254 (fully charged) // Switch LED 1 ON GpioWrite( &Led1, 0 ); TimerStart( &Led1Timer ); AppData[0] = AppLedStateOn; // // // AppData[7] = batteryLevel; sendFrameStatus = LoRaMacSendFrame( 2, AppData, APP_DATA_SIZE ); //sendFrameStatus = LoRaMacSendConfirmedFrame( 2, AppData, APP_DATA_SIZE, 8 ); switch( sendFrameStatus ) { case 3: // LENGTH_PORT_ERROR case 4: // MAC_CMD_ERROR case 5: // NO_FREE_CHANNEL // Schedule a new transmission TxDone = true; break; default: break; } } TimerLowPowerHandler( ); } }
/** * Main application entry point. */ int main( void ) { // LC1 LC2 LC3 LC4 LC5 LC6 LC7 LC8 const uint32_t channelsFreq[] = { 868100000, 868300000, 868500000, 868650000, 868800000, 869100000, 869250000, 869400000 }; const uint8_t channelsDatarate[] = { DR_SF7, DR_SF10, DR_SF12 }; uint8_t channelNb = ( sizeof( channelsFreq ) / sizeof( uint32_t ) ); uint8_t tstState = 0; int16_t pktCnt = 15; ChannelParams_t channel; LoRaMacHeader_t macHdr; LoRaMacFrameCtrl_t fCtrl; uint8_t channelsIndex = 0; uint8_t datarateIndex = 0; BoardInitMcu( ); BoardInitPeriph( ); // Initialize LoRaMac device unique ID BoardGetUniqueId( DevEui ); LoRaMacEvents.MacEvent = OnMacEvent; LoRaMacInit( &LoRaMacEvents ); IsNetworkJoined = false; #if( OVER_THE_AIR_ACTIVATION == 0 ) // Random seed initialization srand( RAND_SEED ); // Choose a random device address // NwkID = 0 // NwkAddr rand [0, 33554431] DevAddr = randr( 0, 0x01FFFFFF ); LoRaMacInitNwkIds( 0x000000, DevAddr, NwkSKey, AppSKey ); IsNetworkJoined = true; #else // Sends a JoinReq Command every 5 seconds until the network is joined TimerInit( &JoinReqTimer, OnJoinReqTimerEvent ); TimerSetValue( &JoinReqTimer, OVER_THE_AIR_ACTIVATION_DUTYCYCLE ); #endif TxNextPacket = true; TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); TimerInit( &Led1Timer, OnLed1TimerEvent ); TimerSetValue( &Led1Timer, 25000 ); // Low power timer to be run when tests are finished. TimerInit( &StopTimer, OnStopTimerEvent ); TimerSetValue( &StopTimer, 3.6e9 ); // wakes up the microcontroller every hour // Initialize MAC frame macHdr.Value = 0; #if defined( LORAMAC_R3 ) macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP; #else macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED; #endif fCtrl.Value = 0; fCtrl.Bits.OptionsLength = 0; fCtrl.Bits.FPending = 0; fCtrl.Bits.Ack = false; fCtrl.Bits.AdrAckReq = false; fCtrl.Bits.Adr = false; // Initialize channel channel.DrRange.Fields.Min = DR_SF12; channel.DrRange.Fields.Min = DR_SF7; channel.DutyCycle = 0; LoRaMacSetChannelsTxPower( TX_POWER_14_DBM ); // Disable reception windows opening LoRaMacTestRxWindowsOn( false ); while( 1 ) { while( IsNetworkJoined == false ) { #if( OVER_THE_AIR_ACTIVATION != 0 ) if( TxNextPacket == true ) { TxNextPacket = false; LoRaMacJoinReq( DevEui, AppEui, AppKey ); // Relaunch timer for next trial TimerStart( &JoinReqTimer ); } TimerLowPowerHandler( ); #endif } for( datarateIndex = 0; datarateIndex < 3; datarateIndex++ ) { //for( channelsIndex = 0; channelsIndex < 3; channelsIndex++ ) { pktCnt = 15 * channelNb; while( pktCnt > 0 ) { switch( tstState ) { case 0: // Init AppData[0] = SelectorGetValue( ); channel.Frequency = channelsFreq[channelsIndex]; LoRaMacSetChannelsDatarate( channelsDatarate[datarateIndex] ); LoRaMacSendOnChannel( channel, &macHdr, &fCtrl, NULL, 15, AppData, 1 ); // Switch LED 1 ON GpioWrite( &Led1, 0 ); TimerStart( &Led1Timer ); channelsIndex = ( channelsIndex + 1 ) % channelNb; tstState = 1; break; case 1: // Wait for end of transmission if( Led1TimerEvent == true ) { Led1TimerEvent = false; // Switch LED 1 OFF GpioWrite( &Led1, 1 ); } if( TxDone == true ) { TxDone = false; pktCnt--; // Schedule next packet transmission after 100 ms TimerSetValue( &TxNextPacketTimer, 100000 ); TimerStart( &TxNextPacketTimer ); tstState = 2; } break; case 2: // Wait for next packet timer to expire if( TxNextPacket == true ) { TxNextPacket = false; tstState = 0; } break; } TimerLowPowerHandler( ); } } } TimerStart( &StopTimer ); while( 1 ) // Reset device to restart { if( StopTimerEvent == true ) { StopTimerEvent = false; TimerStart( &StopTimer ); } TimerLowPowerHandler( ); } } }