Example #1
0
//*****************************************************************************
//
//! Draws a filled rectangle.
//!
//! \param pContext is a pointer to the drawing context to use.
//! \param pRect is a pointer to the structure containing the extents of the
//! rectangle.
//!
//! This function draws a filled rectangle.  The rectangle will extend from
//! \e lXMin to \e lXMax and \e lYMin to \e lYMax, inclusive.  The clipping of
//! the rectangle to the clipping rectangle is performed within this routine;
//! the display driver's rectangle fill routine is used to perform the actual
//! rectangle fill.
//!
//! \return None.
//
//*****************************************************************************
void
GrRectFill(const tContext *pContext, const tRectangle *pRect)
{
    tRectangle sTemp;

    //
    // Check the arguments.
    //
    assert(pContext);
    assert(pRect);

    //
    // Swap the X coordinates if sXMin is greater than sXMax.
    //
    if(pRect->sXMin > pRect->sXMax)
    {
        sTemp.sXMin = pRect->sXMax;
        sTemp.sXMax = pRect->sXMin;
    }
    else
    {
        sTemp.sXMin = pRect->sXMin;
        sTemp.sXMax = pRect->sXMax;
    }

    //
    // Swap the Y coordinates if sYMin is greater than sYMax.
    //
    if(pRect->sYMin > pRect->sYMax)
    {
        sTemp.sYMin = pRect->sYMax;
        sTemp.sYMax = pRect->sYMin;
    }
    else
    {
        sTemp.sYMin = pRect->sYMin;
        sTemp.sYMax = pRect->sYMax;
    }

    //
    // Now that the coordinates are ordered, return without drawing anything if
    // the entire rectangle is out of the clipping region.
    //
    if((sTemp.sXMin > pContext->sClipRegion.sXMax) ||
            (sTemp.sXMax < pContext->sClipRegion.sXMin) ||
            (sTemp.sYMin > pContext->sClipRegion.sYMax) ||
            (sTemp.sYMax < pContext->sClipRegion.sYMin))
    {
        return;
    }

    //
    // Clip the X coordinates to the edges of the clipping region if necessary.
    //
    if(sTemp.sXMin < pContext->sClipRegion.sXMin)
    {
        sTemp.sXMin = pContext->sClipRegion.sXMin;
    }
    if(sTemp.sXMax > pContext->sClipRegion.sXMax)
    {
        sTemp.sXMax = pContext->sClipRegion.sXMax;
    }

    //
    // Clip the Y coordinates to the edges of the clipping region if necessary.
    //
    if(sTemp.sYMin < pContext->sClipRegion.sYMin)
    {
        sTemp.sYMin = pContext->sClipRegion.sYMin;
    }
    if(sTemp.sYMax > pContext->sClipRegion.sYMax)
    {
        sTemp.sYMax = pContext->sClipRegion.sYMax;
    }

    //
    // Call the low level rectangle fill routine.
    //
    DpyRectFill(pContext->pDisplay, &sTemp, pContext->ulForeground);
}
Example #2
0
//*****************************************************************************
//
// Main function to handler motion events that are triggered by the MPU9150
// data ready interrupt.
//
//*****************************************************************************
void
MotionMain(void)
{
    switch(g_ui8MotionState) {
        //
        // This is our initial data set from the MPU9150, start the DCM.
        //
        case MOTION_STATE_INIT: {
            //
            // Check the read data buffer of the MPU9150 to see if the
            // Magnetometer data is ready and present. This may not be the case
            // for the first few data captures.
            //
            if(g_sMPU9150Inst.pui8Data[14] & AK8975_ST1_DRDY) {
                //
                // Get local copy of Accel and Mag data to feed to the DCM
                // start.
                //
                MPU9150DataAccelGetFloat(&g_sMPU9150Inst, g_pfAccel,
                                         g_pfAccel + 1, g_pfAccel + 2);
                MPU9150DataMagnetoGetFloat(&g_sMPU9150Inst, g_pfMag,
                                           g_pfMag + 1, g_pfMag + 2);
                MPU9150DataGyroGetFloat(&g_sMPU9150Inst, g_pfGyro,
                                        g_pfGyro + 1, g_pfGyro + 2);

                //
                // Feed the initial measurements to the DCM and start it.
                // Due to the structure of our MotionMagCallback function,
                // the floating point magneto data is already in the local
                // data buffer.
                //
                CompDCMMagnetoUpdate(&g_sCompDCMInst, g_pfMag[0], g_pfMag[1],
                                     g_pfMag[2]);
                CompDCMAccelUpdate(&g_sCompDCMInst, g_pfAccel[0], g_pfAccel[1],
                                   g_pfAccel[2]);
                CompDCMStart(&g_sCompDCMInst);

                //
                // Proceed to the run state.
                //
                g_ui8MotionState = MOTION_STATE_RUN;
            }

            //
            // Finished
            //
            break;
        }

        //
        // DCM has been started and we are ready for normal operations.
        //
        case MOTION_STATE_RUN: {
            //
            // Get the latest Euler data from the DCM. DCMUpdate is done
            // inside the interrupt routine to insure it is not skipped and
            // that the timing is consistent.
            //
            CompDCMComputeEulers(&g_sCompDCMInst, g_pfEulers,
                                 g_pfEulers + 1, g_pfEulers + 2);

            //
            // Pass the latest sensor data back to the Gesture system for
            // classification.  What state do i think i am in?
            //
            GestureEmitClassify(&g_sGestureInst, g_pfEulers, g_pfAccel,
                                g_pfGyro);

            //
            // Update best guess state based on past history and current
            // estimate.
            //
            GestureUpdate(&g_sGestureInst, g_sGestureInst.ui16Emit);

            //
            // This tick counter and blink mechanism may not be safe across
            // rollovers of the g_ui32SysTickCount variable.  This rollover
            // only occurs after 1.3+ years of continuous operation.
            //
            if(g_ui32SysTickCount > (g_ui32MotionBlinkCounter + 10)) {
                //
                // 10 ticks have expired since we last toggled so toggle the
                // blue LED and reset the counter.
                //
                g_ui32MotionBlinkCounter = g_ui32SysTickCount;
                MAP_GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_4,
                                 ((GPIOPinRead(GPIO_PORTQ_BASE, GPIO_PIN_4)) ^
                                  GPIO_PIN_4));
            }

            //
            // Finished
            //
            break;
        }

        //
        // An I2C error has occurred at some point. Usually these are due to
        // asynchronous resets of the main MCU and the I2C peripherals. This
        // can cause the slave to hold the bus and the MCU to think it cannot
        // send.  In practice there are ways to clear this condition.  They are
        // not implemented here.  To clear power cycle the board.
        //
        case MOTION_STATE_ERROR: {
            //
            // Display this error and how to clear.
            //
            DpyRectFill(g_sContext.psDisplay, &g_sUserInfoRect, ClrBlack);
            GrContextForegroundSet(&g_sContext, ClrGray);
            GrContextFontSet(&g_sContext, g_psFontCmss16b);
            GrStringDraw(&g_sContext, "I2C Error has occurred. Power cycle",
                         -1, 10, 140, 1);
            GrStringDraw(&g_sContext, "board to clear this error.", -1, 10,
                         160, 1);
            GrContextForegroundSet(&g_sContext, ClrWhite);
            GrContextFontSet(&g_sContext, g_psFontCm18b);

            break;
        }
    }
}