Exemplo n.º 1
0
/*FUNCTION**********************************************************************
*
* Function Name : TSI_HAL_MeasurementBlocking
* Description   : Function do blocking measurement of enabled electrodes
*                 It used just for recalibration process
*END**************************************************************************/
static int32_t TSI_HAL_MeasurementBlocking(TSI_Type * base)
{
  int32_t result = -1;
  uint32_t timeout = 10000000; /* Big timeout */ 
  
  if (TSI_RD_PEN(base)) {

    /* measure only if at least one electrode is enabled */
    TSI_HAL_EnableSoftwareTriggerScan(base);
    TSI_HAL_EnableModule(base);
    TSI_HAL_StartSoftwareTrigger(base);

    while((TSI_HAL_GetEndOfScanFlag(base) == 0U) && (timeout--))
    {
      /* Do nothing, just to meet MISRA C 2004 rule 14.3 . */
    }
    TSI_HAL_ClearEndOfScanFlag(base);
    TSI_HAL_DisableModule(base);

    if(timeout)
    {
      result = 0;
    }
  }
  return result;
}
/*FUNCTION**********************************************************************
*
* Function Name : TSI_HAL_MeasurementBlocking
* Description   : Function do blocking measurement of enabled electrodes
*                 It used just for recalibration process
*END**************************************************************************/
static int32_t TSI_HAL_MeasurementBlocking(TSI_Type * base, uint32_t electrode, uint32_t noise_mode)
{
    int32_t result;
    uint32_t timeout = 1000000;
    /* measure only if at least one electrode is enabled */
    TSI_HAL_EnableSoftwareTriggerScan(base);
    TSI_HAL_SetMeasuredChannelNumber(base, electrode);
    TSI_HAL_SetMode(base, TSI_HAL_GetMode(base)); /* force to HW right analog mode. */    
    TSI_HAL_EnableModule(base);
    TSI_HAL_StartSoftwareTrigger(base);
    
    while((TSI_HAL_GetEndOfScanFlag(base) == 0U) && (--timeout))
    {
      /* Do nothing, just to meet MISRA C 2004 rule 14.3 . */
    }
    
    if(timeout == 0)
    {
      result = 0;
    }else
    {
      if(noise_mode)
      {
        result = TSI_HAL_GetNoiseResult(base);
      }else
      {
        result = TSI_HAL_GetCounter(base);
      }
    }
    
    TSI_HAL_ClearEndOfScanFlag(base);
    TSI_HAL_DisableModule(base);
    
    return result;
}
/*FUNCTION**********************************************************************
*
* Function Name : TSI_DRV_Measure
* Description   : This function gets (measure) capacitance of enabled electrodes
*               from the TSI module using a non-blocking method.
*
*END**************************************************************************/
tsi_status_t TSI_DRV_Measure(uint32_t instance)
{
    assert(instance < TSI_INSTANCE_COUNT);

    TSI_Type * base = g_tsiBase[instance];
    tsi_state_t * tsiState = g_tsiStatePtr[instance];

    /* Critical section. Access to global variable */
    if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER))
    {
        return kStatus_TSI_Error;
    }

    if (tsiState->status != kStatus_TSI_Initialized)
    {
        /* End of critical section. */
        OSA_MutexUnlock(&tsiState->lock);

        return tsiState->status;
    }

    tsiState->status = kStatus_TSI_Busy;

    /* End of critical section. */
    OSA_MutexUnlock(&tsiState->lock);

    TSI_HAL_DisableModule(base);
    TSI_HAL_EnableSoftwareTriggerScan(base);
    TSI_HAL_EnableModule(base);
    TSI_HAL_StartSoftwareTrigger(base);

    return kStatus_TSI_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : TSI_DRV_Measure
* Description   : This function gets (measure) capacitance of enabled electrodes
*               from the TSI module using a non-blocking method.
*
*END**************************************************************************/
tsi_status_t TSI_DRV_Measure(uint32_t instance)
{
    assert(instance < TSI_INSTANCE_COUNT);

    TSI_Type * base = g_tsiBase[instance];
    tsi_state_t * tsiState = g_tsiStatePtr[instance];
    uint32_t    first_pen, pen;
    
    /* Critical section. Access to global variable */
    if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER))
    {
        return kStatus_TSI_Error;
    }

    if (tsiState->status != kStatus_TSI_Initialized)
    {
        /* End of critical section. */
        OSA_MutexUnlock(&tsiState->lock);

        return tsiState->status;
    }

    if(!tsiState->opModesData[tsiState->opMode].enabledElectrodes)
    {
        /* End of critical section. */
        OSA_MutexUnlock(&tsiState->lock);

        return kStatus_TSI_InvalidChannel;
    }
    
    tsiState->status = kStatus_TSI_Busy;

    first_pen = 0U;
    pen = tsiState->opModesData[tsiState->opMode].enabledElectrodes;
    while (((pen >> first_pen) & 0x1U) == 0U) {
        first_pen++;
    }
    
    /* End of critical section. */
    OSA_MutexUnlock(&tsiState->lock);

    TSI_HAL_DisableModule(base);
    TSI_HAL_SetMeasuredChannelNumber(base, first_pen);
    TSI_HAL_EnableSoftwareTriggerScan(base);
    TSI_HAL_EnableModule(base);
    TSI_HAL_StartSoftwareTrigger(base);

    return kStatus_TSI_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : TSI_DRV_DisableLowPower
* Description   : Enables/Disables the low power module.
*
*END**************************************************************************/
tsi_status_t TSI_DRV_DisableLowPower(uint32_t instance, const tsi_modes_t mode)
{
    assert(instance < TSI_INSTANCE_COUNT);

    TSI_Type * base = g_tsiBase[instance];
    tsi_state_t * tsiState = g_tsiStatePtr[instance];
    tsi_status_t status;

    /* Critical section. Access to global variable */
    if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER))
    {
        return kStatus_TSI_Error;
    }

    if (tsiState->status != kStatus_TSI_LowPower)
    {
        /* End of critical section. */
        OSA_MutexUnlock(&tsiState->lock);

        return tsiState->status;
    }

    TSI_HAL_DisableLowPower(base);
    TSI_HAL_EnableInterrupt(base);
    TSI_HAL_EnableEndOfScanInterrupt(base);
    TSI_HAL_EnableSoftwareTriggerScan(base);

    tsiState->status = kStatus_TSI_Initialized;

    /* End of critical section. */
    OSA_MutexUnlock(&tsiState->lock);

    status = TSI_DRV_ChangeMode(instance, mode);

    return status;
}
/*FUNCTION**********************************************************************
*
* Function Name : TSI_DRV_Init
* Description   : Initialize whole the TSI peripheral to be ready to read capacitance changes
* To initialize the TSI driver, the configuration structure should be handled.
*
*END**************************************************************************/
tsi_status_t TSI_DRV_Init(uint32_t instance, tsi_state_t * tsiState, const tsi_user_config_t * tsiUserConfig)
{
    assert(instance < TSI_INSTANCE_COUNT);

    TSI_Type * base = g_tsiBase[instance];
    tsi_state_t * tsiSt = g_tsiStatePtr[instance];

    /* Critical section. */
    OSA_EnterCritical(kCriticalDisableInt);

    /* Exit if current instance is already initialized. */
    if(tsiSt)
    {
        /* End of critical section. */
        OSA_ExitCritical(kCriticalDisableInt);
        return kStatus_TSI_Initialized;
    }
    /* Save runtime structure pointer.*/
    tsiSt = g_tsiStatePtr[instance] = tsiState;

    /* Clear the state structure for this instance. */
    memset(tsiSt, 0, sizeof(tsi_state_t));

    /* Create the mutex used by whole driver. */
    OSA_MutexCreate(&tsiSt->lock);
    /* Create the mutex used by change mode function. */
    OSA_MutexCreate(&tsiSt->lockChangeMode);
    
    /* Critical section. Access to global variable */
    if (kStatus_OSA_Success != OSA_MutexLock(&tsiSt->lock, OSA_WAIT_FOREVER))
    {
        /* End of critical section. */
        OSA_ExitCritical(kCriticalDisableInt);  
        return kStatus_TSI_Error;
    }

    /* End of critical section. */
    OSA_ExitCritical(kCriticalDisableInt);

    tsiSt->opMode = tsi_OpModeNormal;

    tsiSt->opModesData[tsiSt->opMode].config = *tsiUserConfig->config; /* Store the hardware configuration. */

    tsiSt->pCallBackFunc = tsiUserConfig->pCallBackFunc;
    tsiSt->usrData = tsiUserConfig->usrData;
    tsiSt->isBlockingMeasure = false;
    /* Un-gate TSI module clock */
    CLOCK_SYS_EnableTsiClock(instance);

    /* Initialize the interrupt sync object. */
    OSA_SemaCreate(&tsiSt->irqSync, 0);

    TSI_HAL_Init(base);
    TSI_HAL_SetConfiguration(base, &tsiSt->opModesData[tsiSt->opMode].config);
    TSI_HAL_EnableInterrupt(base);
    TSI_HAL_EnableEndOfScanInterrupt(base);
    TSI_HAL_EnableSoftwareTriggerScan(base);

    /* Disable all electrodes */
    tsiState->opModesData[tsiState->opMode].enabledElectrodes = 0;

    /* Enable TSI interrupt on NVIC level. */
    INT_SYS_EnableIRQ(g_tsiIrqId[instance]);

    tsiSt->status = kStatus_TSI_Initialized;

    /* End of critical section. */
    OSA_MutexUnlock(&tsiSt->lock);

    return kStatus_TSI_Success;
}