コード例 #1
0
ファイル: demo.c プロジェクト: KoltesDigital/gy85-raspberrypi
static int gConfigure(int gFile)
{
    CHECK(ITG3200_Init(gFile, ITG3200_ID, true));
    
    struct ITG3200_Acquisition confAcquisition = {
        .lowPassFilter = ITG3200_LOWPASSFILTER_42,
        .sampleRateDivider = 0,
    };
    CHECK(ITG3200_ConfigureAcquisition(gFile, &confAcquisition));
    
    struct ITG3200_Power confPower = {
        .clockSource = ITG3200_CLOCKSOURCE_PLL_X,
    };
    CHECK(ITG3200_ConfigurePower(gFile, &confPower));
    
    return 0;
}

int main(void)
{
	int adapter;
    char filename[20];

    for (adapter = 0; adapter < MAX_ADAPTERS; ++adapter)
    {
        snprintf(filename, 20, "/dev/i2c-%d", adapter);
		if (!access(filename, R_OK | W_OK))
			break;
    }

	if (adapter == MAX_ADAPTERS)
	{
		fprintf(stderr, "No I2C adapter found\n");
		return -1;
	}

    aFile = open(filename, O_RDWR);
    if (aConfigure(aFile))
    {
        fprintf(stderr, "Failed to initialize accelerometer\n");
        return closeAndExit(-1);
    }

    cFile = open(filename, O_RDWR);
    if (cConfigure(cFile))
    {
        fprintf(stderr, "Failed to initialize compass\n");
        return closeAndExit(-1);
    }

    gFile = open(filename, O_RDWR);
    if (gConfigure(gFile))
    {
        fprintf(stderr, "Failed to initialize gyroscope\n");
        return closeAndExit(-1);
    }

    ADXL345_ReadData(aFile, &aX.data, &aY.data, &aZ.data);
    HMC5883L_ReadData(cFile, &cX.data, &cY.data, &cZ.data);
    ITG3200_ReadData(gFile, &gX.data, &gY.data, &gZ.data);
    ITG3200_ReadTemperature(gFile, &gT.data);

	initCoordinate(&aX);
	initCoordinate(&aY);
	initCoordinate(&aZ);
	initCoordinate(&cX);
	initCoordinate(&cY);
	initCoordinate(&cZ);
	initCoordinate(&gX);
	initCoordinate(&gY);
    initCoordinate(&gZ);
    initCoordinate(&gT);

	setupHandlers();

	initscr();
	noecho();
	curs_set(false);

	running = 1;
	while (running)
	{
        ADXL345_ReadData(aFile, &aX.data, &aY.data, &aZ.data);
        HMC5883L_ReadData(cFile, &cX.data, &cY.data, &cZ.data);
        ITG3200_ReadData(gFile, &gX.data, &gY.data, &gZ.data);
        ITG3200_ReadTemperature(gFile, &gT.data);

        updateCoordinate(&aX);
        updateCoordinate(&aY);
        updateCoordinate(&aZ);
        updateCoordinate(&cX);
        updateCoordinate(&cY);
        updateCoordinate(&cZ);
        updateCoordinate(&gX);
        updateCoordinate(&gY);
        updateCoordinate(&gZ);
        updateCoordinate(&gT);

		clear();

		mvprintw(0, 0, "%16s: %8d X %8d Y %8d Z\n", "Accelerometer", aX.data, aY.data, aZ.data);
		mvprintw(1, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Smoothed", aX.smoothed, aY.smoothed, aZ.smoothed);
		mvprintw(2, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Min", aX.min, aY.min, aZ.min);
        mvprintw(3, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Max", aX.max, aY.max, aZ.max);
        mvprintw(4, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Normalized", aX.normalized, aY.normalized, aZ.normalized);

		mvprintw(6, 0, "%16s: %8d X %8d Y %8d Z\n", "Compass", cX.data, cY.data, cZ.data);
		mvprintw(7, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Smoothed", cX.smoothed, cY.smoothed, cZ.smoothed);
		mvprintw(8, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Min", cX.min, cY.min, cZ.min);
        mvprintw(9, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Max", cX.max, cY.max, cZ.max);
        mvprintw(10, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Normalized", cX.normalized, cY.normalized, cZ.normalized);

		mvprintw(12, 0, "%16s: %8d X %8d Y %8d Z\n", "Gyroscope", gX.data, gY.data, gZ.data);
		mvprintw(13, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Smoothed", gX.smoothed, gY.smoothed, gZ.smoothed);
		mvprintw(14, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Min", gX.min, gY.min, gZ.min);
        mvprintw(15, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Max", gX.max, gY.max, gZ.max);
        mvprintw(16, 0, "%16s: %8.1f X %8.1f Y %8.1f Z\n", "Normalized", gX.normalized, gY.normalized, gZ.normalized);

		mvprintw(18, 0, "%16s: %8d %8.1f °C\n", "Temperature", gT.data, ITG3200_ConvertTemperature(gT.data));
        mvprintw(19, 0, "%16s: %8.1f %8.1f °C\n", "Smoothed", gT.smoothed, ITG3200_ConvertTemperature(gT.smoothed));
        mvprintw(20, 0, "%16s: %8.1f %8.1f °C\n", "Min", gT.min, ITG3200_ConvertTemperature(gT.min));
        mvprintw(21, 0, "%16s: %8.1f %8.1f °C\n", "Max", gT.max, ITG3200_ConvertTemperature(gT.max));
        mvprintw(22, 0, "%16s: %8.1f\n", "Normalized", gT.normalized);

		refresh();

		usleep(DELAY);
	}

    endwin();
	
    close(aFile);
    close(cFile);
    close(gFile);

    return 0;
}
コード例 #2
0
ファイル: app.c プロジェクト: zyj408/Aircraft
void AppSampleTask(void *p_arg)
{
	(void)p_arg;
/* 监测MPU6050信息 */
	while(SensorCheckCnt < 5)
	{
		if(i2c_CheckDevice(MPU6050_SLAVE_ADDRESS) == 0)
		{
					bsp_InitMPU6050();  //初始化MPU6050
			MPU6050Flag |= NORMAL;
		}
		else
		{
			MPU6050Flag &= (~NORMAL);
		}
		
	/* 监测HMC5883L信息 */	
		if (i2c_CheckDevice(HMC5883L_SLAVE_ADDRESS) == 0)
		{
			bsp_InitHMC5883L();	/* 初始化HMC5883L */	
			HMC5883LFlag |= NORMAL;
		}
		else
		{
			HMC5883LFlag &= (~NORMAL);
		}
		SensorCheckCnt++;
	}
	
	if(SensorCheckCnt == 5)
	{
		
	}
	
	while(1)
	{
		/* 传感器采集数据 */
		MPU6050_ReadData();
		HMC5883L_ReadData();
		MPU6050_DataDeal();  //处理MPU6050获取的数据得到:MPU6050_H结构体
		HMC5883L_DataDeal();	//处理HMC5883L获取的数得到:HMC5883L_H结构体
		
		if(HMC5883LFlag & CALI_MODE)
		{
			
		}
		if(MPU6050Flag & CALI_MODE)
		{
			if(!(MPU6050FlagOld & CALI_MODE))  //进入校验模式
			{
				CaliTime = 200;
				
				MPU6050_H.Accel_X_Offset = g_tMPU6050.Accel_X;
				MPU6050_H.Accel_Y_Offset = g_tMPU6050.Accel_Y;
				MPU6050_H.Accel_Z_Offset = g_tMPU6050.Accel_Z  - 65536 / 4;
			
				MPU6050_H.GYRO_X_Offset = g_tMPU6050.GYRO_X;
				MPU6050_H.GYRO_Y_Offset = g_tMPU6050.GYRO_Y;
				MPU6050_H.GYRO_Z_Offset = g_tMPU6050.GYRO_Z;
				
			}
			if(CaliTime == 0)
			{			
				MPU6050Flag &= ~(CALI_MODE);
			}
			
			MPU6050_H.Accel_X_Offset = (float)(g_tMPU6050.Accel_X + MPU6050_H.Accel_X_Offset) / 2;
			MPU6050_H.Accel_Y_Offset = (float)(g_tMPU6050.Accel_Y + MPU6050_H.Accel_Y_Offset) / 2;
			MPU6050_H.Accel_Z_Offset = (float)(g_tMPU6050.Accel_Z + MPU6050_H.Accel_Z_Offset - 65536 / 4) / 2;
			
			MPU6050_H.GYRO_X_Offset = (float)(g_tMPU6050.GYRO_X + MPU6050_H.GYRO_X_Offset) / 2;
			MPU6050_H.GYRO_Y_Offset = (float)(g_tMPU6050.GYRO_Y + MPU6050_H.GYRO_Y_Offset) / 2;
			MPU6050_H.GYRO_Z_Offset = (float)(g_tMPU6050.GYRO_Z + MPU6050_H.GYRO_Z_Offset) / 2;
			
			CaliTime--;
			
			if(CaliTime > 200)
				CaliTime = 200;
		}
		
		if((HMC5883LFlag & NORMAL) && (MPU6050Flag & NORMAL))
		{
			FlyMain();
		}
		
	if(WifiStatus == CONNECTING)	
		
	{
		if((WIFI_Period++) % 5000 == 0)
		{
			
			Mem_Clr(send_data_buf, sizeof(send_data_buf));
			sprintf(send_data_buf, "sy:s1:d:%fd:%fd:%fd:%fd:%fd:%fd:%fd:%fd:%fd:%fd:%fd:%fd:%fd:%fd:%fd:%fd:%fd:%f",angleAx_temp, angleAy_temp, angleAz_temp,MPU6050_H.Accel_X,MPU6050_H.Accel_Y,MPU6050_H.Accel_Z, \
			MPU6050_H.GYRO_X,MPU6050_H.GYRO_Y,MPU6050_H.GYRO_Z,HMC5883L_H.X,HMC5883L_H.Y,HMC5883L_H.Z,MPU6050_H.Accel_X_Offset,MPU6050_H.Accel_Y_Offset,MPU6050_H.Accel_Z_Offset, \
			MPU6050_H.GYRO_X_Offset,MPU6050_H.GYRO_Y_Offset,MPU6050_H.GYRO_Z_Offset);
			ESP8266_send_data(send_data_buf);
			bsp_LedToggle(2);
		}
			
// 			if(CurrentGeneralReinforce != SetGeneralReinforce)
// 			{
// 				if(SetGeneralReinforce > 100)    //防止增益超出范围    
// 					SetGeneralReinforce = 100;             
// 			
// 				for(index=0; index<4; index++)
// 				{
// 					PwmTemp = (uint32_t)(CurrentPwmValue[index] * SetGeneralReinforce / 100);    //计算出当前的PWM实际值
// 					if(PwmTemp > 100)    //防止PWM占空比超出范围
// 						PwmTemp = 100;
// 					
// 					bsp_SetPWMDutyCycle(PwmTemp, index+1);				
// 				}
// 				
// 				CurrentGeneralReinforce = SetGeneralReinforce;  //增益赋值
// 			}
		
			for(index=0; index<4; index++)
			{
				if(CurrentPwmValue[index] != SetPwmValue[index])
				{
					if(SetPwmValue[index] > 100)    //防止增益超出范围    
						SetPwmValue[index] = 100;   				
					
					bsp_SetPWMDutyCycle(SetPwmValue[index], index+1);
					CurrentPwmValue[index] = SetPwmValue[index];
				}
				
// 				if(SetPwmDirection[index] != CurrentPwmDirection[index])
// 					SetPwmDirection[index] = CurrentPwmDirection[index];
			}
	}

	MPU6050FlagOld = MPU6050Flag;
	
	BSP_OS_TimeDlyMs(2);	

	
	
	}
}
コード例 #3
0
ファイル: main.c プロジェクト: KunYi/frdm-kl25z-marg-fusion
int main(void)
{
    /* initialize the core clock and the systick timer */
    InitClock();
    InitSysTick();

    /* initialize the RGB led */
    LED_Init();

    /* Initialize UART0 */
    InitUart0();

    /* double rainbow all across the sky */
    DoubleFlash();

    /* initialize the I2C bus */
    I2C_Init();

#if DATA_FUSE_MODE

    /* signaling for fusion */
    FusionSignal_Init();

#endif // DATA_FUSE_MODE

    /* initialize UART fifos */
    RingBuffer_Init(&uartInputFifo, &uartInputData, UART_RX_BUFFER_SIZE);
    RingBuffer_Init(&uartOutputFifo, &uartOutputData, UART_TX_BUFFER_SIZE);

    /* initialize UART0 interrupts */
    Uart0_InitializeIrq(&uartInputFifo, &uartOutputFifo);
    Uart0_EnableReceiveIrq();

    /* initialize I2C arbiter */
    InitI2CArbiter();

    /* initialize the IMUs */
    InitHMC5883L();
    InitMPU6050();
//    InitMPU6050();

#if ENABLE_MMA8451Q
    InitMMA8451Q();
#endif

    /* Wait for the config messages to get flushed */
    //TrafficLight();
    DoubleFlash();
    RingBuffer_BlockWhileNotEmpty(&uartOutputFifo);

#if ENABLE_MMA8451Q
    /* initialize the MMA8451Q data structure for accelerometer data fetching */
    mma8451q_acc_t acc;
    MMA8451Q_InitializeData(&acc);
#endif

    /* initialize the MPU6050 data structure */
    mpu6050_sensor_t accgyrotemp, previous_accgyrotemp;
    MPU6050_InitializeData(&accgyrotemp);
    MPU6050_InitializeData(&previous_accgyrotemp);

    /* initialize the HMC5883L data structure */
    hmc5883l_data_t compass, previous_compass;
    HMC5883L_InitializeData(&compass);
    HMC5883L_InitializeData(&previous_compass);

    /* initialize HMC5883L reading */
    uint32_t lastHMCRead = 0;
    const uint32_t readHMCEvery = 1000 / 75; /* at 75Hz, data come every (1000/75Hz) ms. */

    /************************************************************************/
    /* Fetch scaler values                                                  */
    /************************************************************************/

#if DATA_FUSE_MODE

    const fix16_t mpu6050_accelerometer_scaler = mpu6050_accelerometer_get_scaler();
    const fix16_t mpu6050_gyroscope_scaler = mpu6050_gyroscope_get_scaler();
    const fix16_t hmc5883l_magnetometer_scaler = hmc5883l_magnetometer_get_scaler();

#endif // DATA_FUSE_MODE

    /************************************************************************/
    /* Prepare data fusion                                                  */
    /************************************************************************/

#if DATA_FUSE_MODE

    uint32_t last_transmit_time = 0;
    uint32_t last_fusion_time = systemTime();

    fusion_initialize();

#endif // DATA_FUSE_MODE

    /************************************************************************/
    /* Main loop                                                            */
    /************************************************************************/

    for(;;)
    {
        /* helper variables to track data freshness */
        uint_fast8_t have_gyro_data = 0;
        uint_fast8_t have_acc_data = 0;
        uint_fast8_t have_mag_data = 0;

        /************************************************************************/
        /* Determine if sensor data fetching is required                        */
        /************************************************************************/

        /* helper variables for event processing */
        int eventsProcessed = 0;
        int readMPU, readHMC;
#if ENABLE_MMA8451Q
        int readMMA;
#endif

        /* atomic detection of fresh data */
        __disable_irq();
#if ENABLE_MMA8451Q
        readMMA = poll_mma8451q;
#endif
        readMPU = poll_mpu6050;
        poll_mma8451q = 0;
        poll_mpu6050 = 0;
        __enable_irq();

        /* detection of HMC read */
        /*
         * TODO: read synchronized with MPU
         */
        readHMC = 0;
        uint32_t time = systemTime();
        if ((time - lastHMCRead) >= readHMCEvery)
        {
            readHMC = 1;
            lastHMCRead = time;
        }

        /************************************************************************/
        /* Fetching MPU6050 sensor data if required                             */
        /************************************************************************/

        /* read accelerometer/gyro */
        if (readMPU)
        {
            LED_BlueOff();

            I2CArbiter_Select(MPU6050_I2CADDR);
            MPU6050_ReadData(&accgyrotemp);

            /* mark event as detected */
            eventsProcessed = 1;

            /* check for data freshness */
            have_acc_data = (accgyrotemp.accel.x != previous_accgyrotemp.accel.x)
                            || (accgyrotemp.accel.y != previous_accgyrotemp.accel.y)
                            || (accgyrotemp.accel.z != previous_accgyrotemp.accel.z);

            have_gyro_data = (accgyrotemp.gyro.x != previous_accgyrotemp.gyro.x)
                             || (accgyrotemp.gyro.y != previous_accgyrotemp.gyro.y)
                             || (accgyrotemp.gyro.z != previous_accgyrotemp.gyro.z);

            /* loop current data --> previous data */
            previous_accgyrotemp = accgyrotemp;
        }

        /************************************************************************/
        /* Fetching HMC5883L sensor data if required                            */
        /************************************************************************/

        /* read compass data */
        if (readHMC)
        {
            I2CArbiter_Select(HMC5883L_I2CADDR);
            HMC5883L_ReadData(&compass);

            /* mark event as detected */
            eventsProcessed = 1;

            /* check for data freshness */
            have_mag_data = (compass.x != previous_compass.x)
                            || (compass.y != previous_compass.y)
                            || (compass.z != previous_compass.z);

            /* loop current data --> previous data */
            previous_compass = compass;
        }

        /************************************************************************/
        /* Fetching MMA8451Q sensor data if required                            */
        /************************************************************************/

#if ENABLE_MMA8451Q
        /* read accelerometer */
        if (readMMA)
        {
            LED_RedOff();

            I2CArbiter_Select(MMA8451Q_I2CADDR);
            MMA8451Q_ReadAcceleration14bitNoFifo(&acc);

            /* mark event as detected */
            eventsProcessed = 1;
        }
#endif

        /************************************************************************/
        /* Raw sensor data output over serial                                   */
        /************************************************************************/

#if DATA_FETCH_MODE

        /* data availability + sanity check
         * This sent me on a long bug hunt: Sometimes the interrupt would be raised
         * even if not all data registers were written. This always resulted in a
         * z data register not being fully written which, in turn, resulted in
         * extremely jumpy measurements.
         */
        if (readMPU && accgyrotemp.status != 0)
        {
            /* write data */
            uint8_t type = 0x02;
            P2PPE_TransmissionPrefixed(&type, 1, (uint8_t*)accgyrotemp.data, sizeof(accgyrotemp.data), IO_SendByte);
        }

        /* data availability + sanity check */
        if (readHMC && (compass.status & HMC5883L_SR_RDY_MASK) != 0) /* TODO: check if not in lock state */
        {
            uint8_t type = 0x03;
            P2PPE_TransmissionPrefixed(&type, 1, (uint8_t*)compass.xyz, sizeof(compass.xyz), IO_SendByte);
        }

#if ENABLE_MMA8451Q
        /* data availability + sanity check */
        if (readMMA && acc.status != 0)
        {
            uint8_t type = 0x01;
            P2PPE_TransmissionPrefixed(&type, 1, (uint8_t*)acc.xyz, sizeof(acc.xyz), IO_SendByte);
        }
#endif

#endif // DATA_FETCH_MODE

        /************************************************************************/
        /* Sensor data fusion                                                   */
        /************************************************************************/

#if DATA_FUSE_MODE

        // if there were sensor data ...
        if (eventsProcessed)
        {
            v3d gyro, acc, mag;

            // convert, calibrate and store gyroscope data
            if (have_gyro_data)
            {
                sensor_prepare_mpu6050_gyroscope_data(&gyro, accgyrotemp.gyro.x, accgyrotemp.gyro.y, accgyrotemp.gyro.z, mpu6050_gyroscope_scaler);
                fusion_set_gyroscope_v3d(&gyro);
            }

            // convert, calibrate and store accelerometer data
            if (have_acc_data)
            {
                sensor_prepare_mpu6050_accelerometer_data(&acc, accgyrotemp.accel.x, accgyrotemp.accel.y, accgyrotemp.accel.z, mpu6050_accelerometer_scaler);
                fusion_set_accelerometer_v3d(&acc);
            }

            // convert, calibrate and store magnetometer data
            if (have_mag_data)
            {
                sensor_prepare_hmc5883l_data(&mag, compass.x, compass.y, compass.z, hmc5883l_magnetometer_scaler);
                fusion_set_magnetometer_v3d(&mag);
            }

            // get the time differential
            const uint32_t current_time = systemTime();
            const fix16_t deltaT_ms = fix16_from_int(current_time - last_fusion_time);
            const fix16_t deltaT = fix16_mul(deltaT_ms, F16(0.001));

            last_fusion_time = current_time;

            FusionSignal_Predict();

            // predict the current measurements
            fusion_predict(deltaT);

            FusionSignal_Update();

            // correct the measurements
            fusion_update(deltaT);


            FusionSignal_Clear();

#if 0

            fix16_t yaw, pitch, roll;
            fusion_fetch_angles(&roll, &pitch, &yaw);

#if 0
            float yawf = fix16_to_float(yaw),
                  pitchf = fix16_to_float(pitch),
                  rollf = fix16_to_float(roll);

            IO_SendInt16((int16_t)yawf);
            IO_SendInt16((int16_t)pitchf);
            IO_SendInt16((int16_t)rollf);

            IO_SendByteUncommited('\r');
            IO_SendByte('\n');
#else
            if (current_time - last_transmit_time >= 100)
            {
                /* write data */
                uint8_t type = 42;
                fix16_t buffer[3] = { roll, pitch, yaw };
                P2PPE_TransmissionPrefixed(&type, 1, (uint8_t*)buffer, sizeof(buffer), IO_SendByte);

                last_transmit_time = current_time;
            }
#endif
#else
            if (current_time - last_transmit_time >= 100)
            {
                /* write data */
                switch (output_mode)
                {
                case RPY:
                {
                    fix16_t roll, pitch, yaw;
                    fusion_fetch_angles(&roll, &pitch, &yaw);

                    /* write data */
                    uint8_t type = 42;
                    fix16_t buffer[3] = { roll, pitch, yaw };
                    P2PPE_TransmissionPrefixed(&type, 1, (uint8_t*)buffer, sizeof(buffer), IO_SendByte);
                    break;
                }
                case QUATERNION:
                {
                    qf16 orientation;
                    fusion_fetch_quaternion(&orientation);

                    uint8_t type = 43;
                    fix16_t buffer[4] = { orientation.a, orientation.b, orientation.c, orientation.d };
                    P2PPE_TransmissionPrefixed(&type, 1, (uint8_t*)buffer, sizeof(buffer), IO_SendByte);
                    break;
                }
                case QUATERNION_RPY:
                {
                    fix16_t roll, pitch, yaw;
                    fusion_fetch_angles(&roll, &pitch, &yaw);

                    qf16 orientation;
                    fusion_fetch_quaternion(&orientation);

                    uint8_t type = 44;
                    fix16_t buffer[7] = { orientation.a, orientation.b, orientation.c, orientation.d, roll, pitch, yaw };
                    P2PPE_TransmissionPrefixed(&type, 1, (uint8_t*)buffer, sizeof(buffer), IO_SendByte);
                    break;
                }
                case SENSORS_RAW:
                {
                    uint8_t type = 0;
                    fix16_t buffer[6] = { acc.x, acc.y, acc.z, mag.x, mag.y, mag.z };
                    P2PPE_TransmissionPrefixed(&type, 1, (uint8_t*)buffer, sizeof(buffer), IO_SendByte);
                    break;
                }
                }

                last_transmit_time = current_time;
            }
#endif

        }

#endif // DATA_FUSE_MODE

        /************************************************************************/
        /* Read user data input                                                 */
        /************************************************************************/

        /* as long as there is data in the buffer */
        while(!RingBuffer_Empty(&uartInputFifo))
        {
            /* light one led */
            LED_RedOn();

            /* fetch byte */
            uint8_t data = IO_ReadByte();

            output_mode = (output_mode_t)data;

            LED_RedOff();
#if 0
            /* echo to output */
            IO_SendByte(data);

            /* mark event as detected */
            eventsProcessed = 1;
#endif
        }

        /************************************************************************/
        /* Save energy if you like to                                           */
        /************************************************************************/

        /* in case of no events, allow a sleep */
        if (!eventsProcessed)
        {
            /*
             * Care must be taken with this instruction here, as it can lead
             * to a condition where after being woken up (e.g. by the SysTick)
             * and looping through, immediately before entering WFI again
             * an interrupt would yield a true condition for the branches below.
             * In this case this loop would be blocked until the next IRQ,
             * which, in case of a 1ms SysTick timer, could be too late.
             *
             * To counter this behaviour, SysTick has been speed up by factor
             * four (0.25ms).
             */
#if 0
            __WFI();
#endif
        }
    }

    return 0;
}