/*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; }
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; }
/*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_HAL_SetConfiguration * Description : Function set the whole TSI peripheral by handled configuration * *END**************************************************************************/ void TSI_HAL_SetConfiguration(TSI_Type * base, tsi_config_t *config) { assert(config != NULL); uint32_t is_enabled = TSI_HAL_IsModuleEnabled(base); uint32_t is_int_enabled = TSI_HAL_IsInterruptEnabled(base); if (is_enabled) { TSI_HAL_DisableModule(base); } if (is_int_enabled) { TSI_HAL_DisableInterrupt(base); } if(config->mode == kTsiAnalogModeSel_AutoNoise) { TSI_HAL_SetMode(base, config->mode); TSI_HAL_SetPrescaler(base, config->ps); TSI_HAL_SetNumberOfScans(base, config->nscn); TSI_HAL_SetReferenceChargeCurrent(base, config->refchrg); TSI_HAL_SetOscilatorVoltageRails(base, config->dvolt); TSI_HAL_SetElectrodeSeriesResistor(base, config->serres); TSI_HAL_SetFilterBits(base, config->filter); } else { TSI_HAL_SetPrescaler(base, config->ps); TSI_HAL_SetNumberOfScans(base, config->nscn); TSI_HAL_SetReferenceChargeCurrent(base, config->refchrg); TSI_HAL_SetElectrodeChargeCurrent(base, config->extchrg); TSI_HAL_SetMode(base, config->mode); TSI_HAL_SetOscilatorVoltageRails(base, config->dvolt); TSI_HAL_SetLowThreshold(base, config->thresl); TSI_HAL_SetHighThreshold(base, config->thresh); } if (is_enabled) { TSI_HAL_EnableModule(base); } if (is_int_enabled) { TSI_HAL_EnableInterrupt(base); } }
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(electrodes == 0) { return 0; } if (is_enabled) { TSI_HAL_DisableModule(base); } if (is_int_enabled) { TSI_HAL_DisableInterrupt(base); } if(parLimits == NULL) /* If NOISE mode calibration*/ { /* parLimits are not used in NOISE mode so this is calibration of noise mode. */ TSI_HAL_SetConfiguration(base, config); lowest_signal = 1; }else { // Normal capacitive mode calibration 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); for (uint32_t i = 0U; i < 16U; i++) { if ((uint32_t)(1 << i) & electrodes) { int32_t counter = TSI_HAL_MeasurementBlocking(base, i, 0); 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; }
/*FUNCTION********************************************************************** * * Function Name : TSI_DRV_EnableLowPower * Description : Enables/Disables the low power module. * *END**************************************************************************/ tsi_status_t TSI_DRV_EnableLowPower(uint32_t instance) { assert(instance < TSI_INSTANCE_COUNT); TSI_Type * base = g_tsiBase[instance]; tsi_state_t * tsiState = g_tsiStatePtr[instance]; tsi_status_t status; uint32_t i; int32_t channel = -1; /* Critical section. Access to global variable */ if (kStatus_OSA_Success != OSA_MutexLock(&tsiState->lock, OSA_WAIT_FOREVER)) { return kStatus_TSI_Error; } if((tsiState->opModesData[tsiState->opMode].config.thresl == 0) || (tsiState->opModesData[tsiState->opMode].config.thresh == 0)) { /* End of critical section. */ OSA_MutexUnlock(&tsiState->lock); return kStatus_TSI_Error; } if ((status = TSI_DRV_ChangeMode(instance, tsi_OpModeLowPower)) != kStatus_TSI_Success) { /* End of critical section. */ OSA_MutexUnlock(&tsiState->lock); return status; } if(tsiState->opModesData[tsiState->opMode].enabledElectrodes == 0) { /* End of critical section. */ OSA_MutexUnlock(&tsiState->lock); return kStatus_TSI_InvalidChannel; } /* Configurate the peripheral for next use */ TSI_HAL_EnableOutOfRangeInterrupt(base); TSI_HAL_EnableHardwareTriggerScan(base); for(i = 0; i < FSL_FEATURE_TSI_CHANNEL_COUNT; i++) { if((uint32_t)(1 << i) & tsiState->opModesData[tsiState->opMode].enabledElectrodes) { channel = i; break; } } if(channel == -1) { /* End of critical section. */ OSA_MutexUnlock(&tsiState->lock); return kStatus_TSI_InvalidChannel; } tsiState->status = kStatus_TSI_LowPower; TSI_HAL_EnableLowPower(base); TSI_HAL_SetMeasuredChannelNumber(base, channel); TSI_HAL_EnableInterrupt(base); TSI_HAL_EnableModule(base); /* End of critical section. */ OSA_MutexUnlock(&tsiState->lock); return kStatus_TSI_Success; }