/*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; }
/*! * @brief Interrupt handler for TSI. * This handler uses the tsi State structure to handle the instance depend data. * This is not a public API as it is called whenever an interrupt occurs. */ void TSI_DRV_IRQHandler(uint32_t instance) { TSI_Type * base = g_tsiBase[instance]; tsi_state_t * tsiState = g_tsiStatePtr[instance]; uint32_t channels = tsiState->opModesData[tsiState->opMode].enabledElectrodes; uint32_t curr_channel = TSI_HAL_GetMeasuredChannelNumber(base); uint32_t next_pen, pen; /* Check if a measure is running and wanted. */ TSI_HAL_ClearOutOfRangeFlag(base); TSI_HAL_ClearEndOfScanFlag(base); if((uint32_t)(1 << curr_channel) & channels) { /* Am I in noise mode? */ if(tsiState->opMode == tsi_OpModeNoise) { tsiState->counters[curr_channel] = TSI_HAL_GetMode(base); } else { tsiState->counters[curr_channel] = TSI_HAL_GetCounter(base); } } next_pen = curr_channel + 1; pen = channels; while (((((pen >> next_pen) & 0x1U)) == 0U) && (next_pen < 16)) { next_pen++; } if(next_pen < 16) { /* Measurement must continue on next channel. */ TSI_HAL_SetMeasuredChannelNumber(base, next_pen); TSI_HAL_StartSoftwareTrigger(base); return; } if(tsiState->isBlockingMeasure) { /* Signal the synchronous completion object. */ OSA_SemaPost(&tsiState->irqSync); tsiState->isBlockingMeasure = false; } else if(tsiState->pCallBackFunc) { tsiState->pCallBackFunc(instance, tsiState->usrData); } if(tsiState->status != kStatus_TSI_LowPower) { /* Return status of the driver to initialized state */ tsiState->status = kStatus_TSI_Initialized; } }
uint32_t TSI_HAL_Recalibrate(TSI_Type * base, tsi_config_t *config, const uint32_t electrodes, const tsi_parameter_limits_t *parLimits) { assert(config != NULL); uint32_t is_enabled = TSI_HAL_IsModuleEnabled(base); uint32_t is_int_enabled = TSI_HAL_IsInterruptEnabled(base); uint32_t lowest_signal = TSI_RECALIBRATE_MAX_SIGNAL_VAL; if (is_enabled) { TSI_HAL_DisableModule(base); } if (is_int_enabled) { TSI_HAL_DisableInterrupt(base); } TSI_HAL_SetNumberOfScans(base, config->nscn); TSI_HAL_SetPrescaler(base, config->ps); TSI_HAL_SetElectrodeChargeCurrent(base, config->extchrg); TSI_HAL_SetReferenceChargeCurrent(base, config->refchrg); TSI_HAL_EnableModule(base); if (TSI_HAL_MeasurementBlocking(base) == 0) { for (uint32_t i = 0U; i < 16U; i++) { if (TSI_HAL_GetEnabledChannel(base, i)) { int32_t counter = TSI_HAL_GetCounter(base, i); if (counter < lowest_signal) { lowest_signal = counter; } } } } if (!is_enabled) { TSI_HAL_EnableModule(base); } if (is_int_enabled) { TSI_HAL_EnableInterrupt(base); } if (lowest_signal == TSI_RECALIBRATE_MAX_SIGNAL_VAL) { lowest_signal = 0U; /* not valid */ } return lowest_signal; }
/*! * @brief Interrupt handler for TSI. * This handler uses the tsi State structure to handle the instance depend data. * This is not a public API as it is called whenever an interrupt occurs. */ void TSI_DRV_IRQHandler(uint32_t instance) { TSI_Type * base = g_tsiBase[instance]; uint32_t channels = TSI_HAL_GetEnabledChannels(base); uint32_t i; tsi_state_t * tsiState = g_tsiStatePtr[instance]; /* Check if a measure is running and wanted. */ if(tsiState->status != kStatus_TSI_Busy) { return; } TSI_HAL_ClearOutOfRangeFlag(base); TSI_HAL_ClearEndOfScanFlag(base); for(i = 0; i < FSL_FEATURE_TSI_CHANNEL_COUNT; i++) { if((uint32_t)(1 << i) & channels) { tsiState->counters[i] = TSI_HAL_GetCounter(base, i); } } if(tsiState->isBlockingMeasure) { /* Signal the synchronous completion object. */ OSA_SemaPost(&tsiState->irqSync); tsiState->isBlockingMeasure = false; } else if(tsiState->pCallBackFunc) { tsiState->pCallBackFunc(instance, tsiState->usrData); } if(tsiState->status != kStatus_TSI_LowPower) { /* Return status of the driver to initialized state */ tsiState->status = kStatus_TSI_Initialized; } }