/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_MsgQGet
 * Description   : This function checks the queue's status, if it is not empty,
 * get message from it and return kStatus_OSA_Success, otherwise, timeout will
 * be used for wait. The parameter timeout indicates how long should wait in
 * milliseconds. Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will return
 * kStatus_OSA_Timeout immediately if queue is empty.
 * This function returns kStatus_OSA_Success if message is got successfully,
 * returns kStatus_OSA_Timeout if message queue is empty within the specified
 * 'timeout', returns kStatus_OSA_Error if any errors occur during waiting,
 * returns kStatus_OSA_Idle if message queue is empty and 'timeout' is
 * not exhausted, because wait functions should not block with bare metal.
 *
 *END**************************************************************************/
osa_status_t OSA_MsgQGet(msg_queue_handler_t handler,
                           void               *pMessage,
                           uint32_t            timeout)
{
    assert(handler);
    osa_status_t retVal = kStatus_OSA_Error;
    uint32_t *from_ptr, *to_ptr;
    uint16_t msgSize;

    INT_SYS_DisableIRQGlobal();
    /* Check if the queue is not empty */
    if(!handler->isEmpty)
    {
        from_ptr = &handler->queueMem[handler->head * handler->size];
        to_ptr   = (uint32_t*)(pMessage);

        /* Copy entire message into the queue, based on the size configured at creation */
        msgSize = handler->size;
        while(msgSize--)
        {
            *to_ptr++ = *from_ptr++;
        }

        /* Adjust head pointer and wrap in case the end of the buffer is reached */
        ++handler->head;
        if(handler->head == handler->number)
        {
            handler->head = 0;
        }

        /* If queue is empty, clear the semaphore. */
        if(handler->head == handler->tail)
        {
            handler->isEmpty = true;
            /* Set semapohre to 0 because the queue is empty. */
            (void)OSA_SemaWait(&handler->queueSem, 0);
        }
        INT_SYS_EnableIRQGlobal();

        retVal = kStatus_OSA_Success;
    }
    else
    {
        INT_SYS_EnableIRQGlobal();
        /* Wait for the semaphore if the queue was empty */
        retVal = OSA_SemaWait(&handler->queueSem, timeout);
    }

    return retVal;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_MutexLock
 * Description   : This function checks the mutex's status, if it is unlocked,
 * lock it and returns kStatus_OSA_Success, otherwise, timeout will be used for
 * wait. The parameter timeout indicates how long should wait in milliseconds.
 * Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will return the value
 * kStatus_OSA_Timeout immediately if mutex is locked.
 * This function returns kStatus_OSA_Success if the mutex is obtained, returns
 * kStatus_OSA_Timeout if the mutex is not obtained within the specified
 * 'timeout', returns kStatus_OSA_Error if any errors occur during waiting,
 * returns kStatus_OSA_Idle if the mutex is not available and 'timeout' is
 * not exhausted, because wait functions should not block with bare metal.
 *
 *END**************************************************************************/
osa_status_t OSA_MutexLock(mutex_t *pMutex, uint32_t timeout)
{
    uint32_t currentTime;

    assert(pMutex);

    /* Always check first. Deal with timeout only if not available. */
    if (pMutex->isLocked == false)
    {
        /* Get the lock and return success */
        INT_SYS_DisableIRQGlobal();
        pMutex->isLocked = true;
        pMutex->isWaiting = false;
        INT_SYS_EnableIRQGlobal();
        return kStatus_OSA_Success;
    }
    else
    {
        if (0 == timeout)
        {
            /* If timeout is 0 and mutex is not available, return kStatus_OSA_Timeout. */
            return kStatus_OSA_Timeout;
        }
#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
        else if (pMutex->isWaiting)
        {
            /* Check for timeout */
            currentTime = OSA_TimeGetMsec();
            if (pMutex->timeout < OSA_TimeDiff(pMutex->time_start, currentTime))
            {
                INT_SYS_DisableIRQGlobal();
                pMutex->isWaiting = false;
                INT_SYS_EnableIRQGlobal();
                return kStatus_OSA_Timeout;
            }
        }
        else if (timeout != OSA_WAIT_FOREVER)    /* If dont't wait forever, start timer. */
        {
            /* Start the timeout counter */
            INT_SYS_DisableIRQGlobal();
            pMutex->isWaiting = true;
            INT_SYS_EnableIRQGlobal();
            pMutex->time_start = OSA_TimeGetMsec();
            pMutex->timeout = timeout;
        }
#endif
    }

    return kStatus_OSA_Idle;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_SemaWait
 * Description   : This function checks the semaphore's counting value, if it is
 * positive, decreases it and returns kStatus_OSA_Success, otherwise, timeout
 * will be used for wait. The parameter timeout indicates how long should wait
 * in milliseconds. Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will
 * return kStatus_OSA_Timeout immediately if semaphore is not positive.
 * This function returns kStatus_OSA_Success if the semaphore is received, returns
 * kStatus_OSA_Timeout if the semaphore is not received within the specified
 * 'timeout', returns kStatus_OSA_Error if any errors occur during waiting,
 * returns kStatus_OSA_Idle if the semaphore is not available and 'timeout' is
 * not exhausted, because wait functions should not block with bare metal.
 *
 *END**************************************************************************/
osa_status_t OSA_SemaWait(semaphore_t *pSem, uint32_t timeout)
{
    uint32_t currentTime;

    assert(pSem);

    /* Check the sem count first. Deal with timeout only if not already set */
    if (pSem->semCount)
    {
        INT_SYS_DisableIRQGlobal();
        pSem->semCount --;
        pSem->isWaiting = false;
        INT_SYS_EnableIRQGlobal();
        return kStatus_OSA_Success;
    }
    else
    {
        if (0 == timeout)
        {
            /* If timeout is 0 and semaphore is not available, return kStatus_OSA_Timeout. */
            return kStatus_OSA_Timeout;
        }
#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
        else if (pSem->isWaiting)
        {
            /* Check for timeout */
            currentTime = OSA_TimeGetMsec();
            if (pSem->timeout < OSA_TimeDiff(pSem->time_start, currentTime))
            {
                INT_SYS_DisableIRQGlobal();
                pSem->isWaiting = false;
                INT_SYS_EnableIRQGlobal();
                return kStatus_OSA_Timeout;
            }
        }
        else if (timeout != OSA_WAIT_FOREVER)    /* If don't wait forever, start the timer */
        {
            /* Start the timeout counter */
            INT_SYS_DisableIRQGlobal();
            pSem->isWaiting = true;
            INT_SYS_EnableIRQGlobal();
            pSem->time_start = OSA_TimeGetMsec();
            pSem->timeout = timeout;
        }
#endif
    }

    return kStatus_OSA_Idle;
}
Exemple #4
0
/*!
 * @brief Get inup from user about wakeup timeout
 */
uint8_t setWakeUpTimeOut(void)
{
    uint8_t val0;
    uint8_t val1;

    while(1)
    {
        PRINTF("Select the wake up timeout in format DD. Possible decimal value is from range 01 - 60 seconds. Eg. 05 means 5 seconds delay");
        PRINTF("\r\nWaiting for key press..\r\n\r\n");
        val0 = GETCHAR();
        if( (val0 >= '0') && (val0 <= '6') )
        {
            val1 = GETCHAR();
            if( (val1 >= '0') && (val1 <= '9') )
            {
                val0 = (val0-'0')*10 + (val1-'0');
                if( (val0!=0) && (val0<=60) )
                {
                    INT_SYS_DisableIRQGlobal();
                    LLWU_HAL_SetInternalModuleCmd(LLWU_BASE_PTR,kLlwuWakeupModule5,true);
                    INT_SYS_EnableIRQGlobal();
                    cmd_alarm(val0);
                    return val0;
                }
            }
        }

        PRINTF("Wrong value!\r\n");
    }
}
/*FUNCTION****************************************************************
 *
 * Function Name : WDOG_DRV_Unlock
 * Description   : Unlock watchdog register written
 * This function is used to unlock the WDOG register written because WDOG register
 * will lock automatically after 256 bus clock. Written while the register is
 * locked has no affect.
 *
 *END*********************************************************************/
static void WDOG_DRV_Unlock(void)
{
    INT_SYS_DisableIRQGlobal();

    WDOG_HAL_Unlock(g_wdogBaseAddr[0]);

    INT_SYS_EnableIRQGlobal();
}
/*FUNCTION****************************************************************
 *
 * Function Name : WDOG_DRV_Refresh
 * Description   : Refresh watchdog.
 * This function is used to feed the WDOG, it will set the WDOG timer count to zero and 
 * should be called before watchdog timer is timeout, otherwise a RESET will assert.
 *
  *END*********************************************************************/
void WDOG_DRV_Refresh(void)
{
    INT_SYS_DisableIRQGlobal();

    WDOG_HAL_Refresh(g_wdogBaseAddr[0]);

    INT_SYS_EnableIRQGlobal();
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_MsgQPut
 * Description   : This function is used to put a message to a message queue.
 * Return kStatus_OSA_Success if the message is put successfully, otherwise
 * return kStatus_OSA_Error.
 *
 *END**************************************************************************/
osa_status_t OSA_MsgQPut(msg_queue_handler_t handler, void* pMessage)
{
    assert(handler);
    uint32_t *from_ptr, *to_ptr;
    uint16_t msgSize;

    /* Check that there is room in the queue */
    INT_SYS_DisableIRQGlobal();
    if((handler->tail != handler->head) || (handler->isEmpty))
    {
        from_ptr = (uint32_t*)pMessage;
        to_ptr   = &handler->queueMem[handler->tail * handler->size];

        /* Copy entire message into the queue, based on the size configured at creation */
        msgSize = handler->size;
        while(msgSize--)
        {
            *to_ptr++ = *from_ptr++;
        }

        /* Adjust tail pointer and wrap in case the end of the buffer is reached */
        ++handler->tail;
        if(handler->tail == handler->number)
        {
            handler->tail = 0;
        }

        /* If queue was empty, clear the empty flag and signal that it is not empty anymore */
        if(handler->isEmpty)
        {
            handler->isEmpty = false;
            OSA_SemaPost(&handler->queueSem);
        }
        INT_SYS_EnableIRQGlobal();

        return kStatus_OSA_Success;
    }
    else
    {
        INT_SYS_EnableIRQGlobal();
        return kStatus_OSA_Error;
    }
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_EventClear
 * Description   : Clear one or more event flags of an event object.
 * Return kStatus_OSA_Success if clear successfully, kStatus_OSA_Error if failed.
 *
 *END**************************************************************************/
osa_status_t OSA_EventClear(event_t *pEvent, event_flags_t flagsToClear)
{
    assert(pEvent);
    /* Clear flags ensuring atomic operation */
    INT_SYS_DisableIRQGlobal();
    pEvent->flags &= ~flagsToClear;
    INT_SYS_EnableIRQGlobal();

    return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_EventSet
 * Description   : Set one or more event flags of an event object.
 * Return kStatus_OSA_Success if set successfully, kStatus_OSA_Error if failed.
 *
 *END**************************************************************************/
osa_status_t OSA_EventSet(event_t *pEvent, event_flags_t flagsToSet)
{
    assert(pEvent);
    /* Set flags ensuring atomic operation */
    INT_SYS_DisableIRQGlobal();
    pEvent->flags |= flagsToSet;
    INT_SYS_EnableIRQGlobal();

    return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_MutexUnlock
 * Description   : This function is used to unlock a mutex.
 *
 *END**************************************************************************/
osa_status_t OSA_MutexUnlock(mutex_t *pMutex)
{
    assert(pMutex);

    INT_SYS_DisableIRQGlobal();
    pMutex->isLocked = false;
    INT_SYS_EnableIRQGlobal();

    return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_ExitCritical
 * Description   : This function is used to exit critical section.
 *
 *END**************************************************************************/
void OSA_ExitCritical(osa_critical_section_mode_t mode)
{
    if (kCriticalDisableInt == mode)
    {
        INT_SYS_EnableIRQGlobal();
    }
    else
    {
        return;
    }
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_SemaPost
 * Description   : This function is used to wake up one task that wating on the
 * semaphore. If no task is waiting, increase the semaphore. The function returns
 * kStatus_OSA_Success if the semaphre is post successfully, otherwise returns
 * kStatus_OSA_Error.
 *
 *END**************************************************************************/
osa_status_t OSA_SemaPost(semaphore_t *pSem)
{
    assert(pSem);
    /* The max value is 0xFF */
    if (0xFF == pSem->semCount)
    {
        return kStatus_OSA_Error;
    }
    INT_SYS_DisableIRQGlobal();
    ++pSem->semCount;
    INT_SYS_EnableIRQGlobal();

    return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
 *
 * Function Name : OSA_EventWait
 * Description   : This function checks the event's status, if it meets the wait
 * condition, return kStatus_OSA_Success, otherwise, timeout will be used for
 * wait. The parameter timeout indicates how long should wait in milliseconds.
 * Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will return the value
 * kStatus_OSA_Timeout immediately if wait condition is not met. The event flags
 * will be cleared if the event is auto clear mode. Flags that wakeup waiting
 * task could be obtained from the parameter setFlags.
 * This function returns kStatus_OSA_Success if wait condition is met, returns
 * kStatus_OSA_Timeout if wait condition is not met within the specified
 * 'timeout', returns kStatus_OSA_Error if any errors occur during waiting,
 * returns kStatus_OSA_Idle if wait condition is not met  and 'timeout' is
 * not exhausted, because wait functions should not block with bare metal.
 *
 *END**************************************************************************/
osa_status_t OSA_EventWait(event_t       *pEvent,
                        event_flags_t  flagsToWait,
                        bool           waitAll,
                        uint32_t       timeout,
                        event_flags_t *setFlags)
{
    uint32_t currentTime;

    assert(pEvent);
    assert(setFlags);

    osa_status_t retVal = kStatus_OSA_Idle;

    *setFlags = pEvent->flags & flagsToWait;

    /* Check the event flag first, if does not meet wait condition, deal with timeout. */
    if ((((!waitAll) && (*setFlags))) || (*setFlags == flagsToWait))
    {
        INT_SYS_DisableIRQGlobal();
        pEvent->isWaiting = false;
        if(kEventAutoClear == pEvent->clearMode)
        {
            pEvent->flags &= ~flagsToWait;
        }
        INT_SYS_EnableIRQGlobal();
        return kStatus_OSA_Success;
    }
    else
    {
        if (0 == timeout)
        {
            /* If timeout is 0 and wait condition is not met, return kStatus_OSA_Timeout. */
            return kStatus_OSA_Timeout;
        }
#if (FSL_OSA_BM_TIMER_CONFIG != FSL_OSA_BM_TIMER_NONE)
        else if (pEvent->isWaiting)
        {
            /* Check for timeout */
            currentTime = OSA_TimeGetMsec();
            if (pEvent->timeout < OSA_TimeDiff(pEvent->time_start, currentTime))
            {
                INT_SYS_DisableIRQGlobal();
                pEvent->isWaiting = false;
                INT_SYS_EnableIRQGlobal();
                retVal = kStatus_OSA_Timeout;
            }
        }
        else if(timeout != OSA_WAIT_FOREVER)    /* If no timeout, don't start the timer */
        {
            /* Start the timeout counter */
            INT_SYS_DisableIRQGlobal();
            pEvent->isWaiting = true;
            INT_SYS_EnableIRQGlobal();
            pEvent->time_start = OSA_TimeGetMsec();
            pEvent->timeout = timeout;
        }
#endif
    }

    return retVal;
}
Exemple #14
0
/*!
 * @brief Main demo function.
 */
int main (void)
{
    ftm_pwm_param_t xAxisParams, yAxisParams;
    accel_dev_t accDev;
    accel_dev_interface_t accDevice;
    accel_sensor_data_t accelData;
    accel_i2c_interface_t i2cInterface;
    int16_t xData, yData;
    int16_t xAngle, yAngle;
    uint32_t ftmModulo;

    // Register callback func for I2C
    i2cInterface.i2c_init       =  I2C_DRV_MasterInit;
    i2cInterface.i2c_read       =  I2C_DRV_MasterReceiveDataBlocking;
    i2cInterface.i2c_write      =  I2C_DRV_MasterSendDataBlocking;

    accDev.i2c = &i2cInterface;
    accDev.accel = &accDevice;

    accDev.slave.baudRate_kbps  = BOARD_ACCEL_BAUDRATE;
    accDev.slave.address        = BOARD_ACCEL_ADDR;
    accDev.bus                  = BOARD_ACCEL_I2C_INSTANCE;

    // Initialize standard SDK demo application pins.
    hardware_init();

    // Accel device driver utilizes the OSA, so initialize it.
    OSA_Init();

    // Initialize the LEDs used by this application.
    LED2_EN;
    LED3_EN;

    // Print the initial banner.
    PRINTF("Bubble Level Demo!\r\n\r\n");

    // Initialize the Accel.
    accel_init(&accDev);

    // Turn on the clock to the FTM.
    CLOCK_SYS_EnableFtmClock(BOARD_FTM_INSTANCE);

    // Initialize the FTM module.
    FTM_HAL_Init(BOARD_FTM_BASE);

    // Configure the sync mode to software.
    FTM_HAL_SetSyncMode(BOARD_FTM_BASE, kFtmUseSoftwareTrig);

    // Enable the overflow interrupt.
    FTM_HAL_EnableTimerOverflowInt(BOARD_FTM_BASE);

    // Set the FTM clock divider to /16.
    FTM_HAL_SetClockPs(BOARD_FTM_BASE, kFtmDividedBy16);

    // Configure the FTM channel used for the X-axis.  Initial duty cycle is 0%.
    xAxisParams.mode = kFtmEdgeAlignedPWM;
    xAxisParams.edgeMode = kFtmHighTrue;

    FTM_HAL_EnablePwmMode(BOARD_FTM_BASE, &xAxisParams, BOARD_FTM_X_CHANNEL);
    FTM_HAL_SetChnCountVal(BOARD_FTM_BASE, BOARD_FTM_X_CHANNEL, 0);

    // Configure the FTM channel used for the Y-axis.  Initial duty cycle is 0%.
    yAxisParams.mode = kFtmEdgeAlignedPWM;
    yAxisParams.edgeMode = kFtmHighTrue;

    FTM_HAL_EnablePwmMode(BOARD_FTM_BASE, &yAxisParams, BOARD_FTM_Y_CHANNEL);
    FTM_HAL_SetChnCountVal(BOARD_FTM_BASE, BOARD_FTM_Y_CHANNEL, 0);

    // Get the FTM reference clock and calculate the modulo value.
    ftmModulo = (CLOCK_SYS_GetFtmSystemClockFreq(BOARD_FTM_INSTANCE) /
                  (1 << FTM_HAL_GetClockPs(BOARD_FTM_BASE))) /
                  (BOARD_FTM_PERIOD_HZ - 1);

    // Initialize the FTM counter.
    FTM_HAL_SetCounterInitVal(BOARD_FTM_BASE, 0);
    FTM_HAL_SetMod(BOARD_FTM_BASE, ftmModulo);

    // Set the clock source to start the FTM.
    FTM_HAL_SetClockSource(BOARD_FTM_BASE, kClock_source_FTM_SystemClk);

    // Enable the FTM interrupt at the NVIC level.
    INT_SYS_EnableIRQ(BOARD_FTM_IRQ_VECTOR);

    // Main loop.  Get sensor data and update globals for the FTM timer update.
    while(1)
    {
        // Wait 5 ms in between samples (accelerometer updates at 200Hz).
        OSA_TimeDelay(5);

        // Get new accelerometer data.
          accDev.accel->accel_read_sensor_data(&accDev,&accelData);

        // Turn off interrupts (FTM) while updating new duty cycle values.
        INT_SYS_DisableIRQGlobal();

        // Get the X and Y data from the sensor data structure.
        xData = (int16_t)((accelData.data.accelXMSB << 8) | accelData.data.accelXLSB);
        yData = (int16_t)((accelData.data.accelYMSB << 8) | accelData.data.accelYLSB);

        // Convert raw data to angle (normalize to 0-90 degrees).  No negative
        // angles.
        xAngle = abs((int16_t)(xData * 0.011));
        yAngle = abs((int16_t)(yData * 0.011));

        // Set values for next FTM ISR udpate.  Use 5 degrees as the threshold
        // for whether to turn the LED on or not.
        g_xValue = (xAngle > 5) ? (uint16_t)((xAngle / 90.0) * ftmModulo) : 0;
        g_yValue = (yAngle > 5) ? (uint16_t)((yAngle / 90.0) * ftmModulo) : 0;

        // Re-enable interrupts.
        INT_SYS_EnableIRQGlobal();

        // Print out the raw accelerometer data.
        PRINTF("x= %d y = %d\r\n", xData, yData);
    }
}