Beispiel #1
0
/*****************************************************************************
  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
}
Beispiel #2
0
/*!
 * \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 );

}
Beispiel #3
0
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++;
    }
}
Beispiel #5
0
/**
 * 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 );
        }    
    }
}
Beispiel #6
0
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;
            }
        }
    }
}
Beispiel #7
0
/**
 * 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;
            }
        }
    }
}
Beispiel #8
0
/**
 * 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( );
	}
}
Beispiel #9
0
/**
 * 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( );
        }
    }
}