diff options
author | Oxore <oxore@protonmail.com> | 2023-03-05 20:20:45 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2023-03-05 20:20:45 +0300 |
commit | ea807de65b0485ac58b6eae576209c64d4d5c4e9 (patch) | |
tree | b4264d20e1d700cfd9e0ece9d847a825dd1dfc03 /third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8tl5x.c | |
parent | dd01e7ed22cea652061f0d12cecf929e04b285e9 (diff) |
Split app code and third party libraries
Diffstat (limited to 'third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8tl5x.c')
-rw-r--r-- | third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8tl5x.c | 906 |
1 files changed, 906 insertions, 0 deletions
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8tl5x.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8tl5x.c new file mode 100644 index 0000000..9298122 --- /dev/null +++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8tl5x.c @@ -0,0 +1,906 @@ +/** + ****************************************************************************** + * @file tsl_acq_stm8tl5x.c + * @author MCD Application Team + * @version V1.4.4 + * @date 31-March-2014 + * @brief This file contains all functions to manage the PXS acquisition + * on STM8TL5x products. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "tsl_acq_stm8tl5x.h" +#include "tsl_globals.h" +#include "stm8tl5x_it.h" + +/* Private typedefs ----------------------------------------------------------*/ + +/* Private defines -----------------------------------------------------------*/ +#define EPCC_INIT_VALUE (0x80) +#define CS_MIDDLE_VALUE (17) +#define CS_MAX_VALUE (32) +#define MAX_MEASURE (0xFFFF) + +/* Private macros ------------------------------------------------------------*/ +#define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS))) +#define IS_SOURCE_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_CHANNELS))) +#define IS_EPCC_STATUS_OK(STATUS) ((STATUS & TSL_EPCC_CHANGE_MASK) != 0) +#define IS_CSSEL_OK(CSSEL) (((CSSEL) == 0) || (((CSSEL) > 0) && ((CSSEL) < CS_MAX_VALUE))) + +/* Private variables ---------------------------------------------------------*/ +TSL_BankConfig_T PXS_BankConfig[TSLPRM_TOTAL_BANKS]; +CONST uint8_t PXS_CSsorting[] = {0, 1, 2, 8, 3, 4, 5, 9, 6, 10, 16, 11, 7, 12, 17, 13, 18, 19, 14, 24, 15, 20, 25, 21, 26, 22, 27, 23, 28, 29, 30, 31}; + +/* Private functions prototype -----------------------------------------------*/ +void TSL_PXS_CS_CalibrateBank(TSL_tIndex_T idx_bk); +int8_t TSL_PXS_EPCC_CalibrateBank(TSL_tIndex_T bank); +TSL_Status_enum_T TSL_PXS_EPCC_CalibrateZone(CONST TSL_Zone_T *); +void SoftDelay(uint16_t val); + +/** + * @brief Initializes the acquisition module. + * @param None + * @retval Status + */ +TSL_Status_enum_T TSL_acq_Init(void) +{ + + TSL_Status_enum_T retval = TSL_STATUS_OK; + + TSL_tIndex_T i; + TSL_tIndex_T j; + TSL_tIndex_T idx_bk; // Bank index + uint16_t TxInUseMask = 0; + uint16_t RxInUseMask = 0; + CONST TSL_Bank_T *bank; + uint8_t *CSArray; + + // Enable the PXS IP clock + CLK->PCKENR1 |= CLK_PCKENR1_PXS; + + // Initialization of PXS IP + PXS->CKCR1 &= (uint8_t)~PXS_CKCR1_PRESC; + +#if (TSLPRM_PXS_HSI == 16000) + PXS->CKCR1 |= PXS_CKCR1_16MHZ; +#elif (TSLPRM_PXS_HSI == 8000) + PXS->CKCR1 |= PXS_CKCR1_8MHZ; +#elif (TSLPRM_PXS_HSI == 4000) + PXS->CKCR1 |= PXS_CKCR1_4MHZ; +#elif (TSLPRM_PXS_HSI == 2000) + PXS->CKCR1 |= PXS_CKCR1_2MHZ; +#elif (TSLPRM_PXS_HSI == 1000) + PXS->CKCR1 |= PXS_CKCR1_1MHZ; +#elif (TSLPRM_PXS_HSI == 500) + PXS->CKCR1 |= PXS_CKCR1_500KHZ; +#elif (TSLPRM_PXS_HSI == 250) + PXS->CKCR1 |= PXS_CKCR1_250KHZ; +#elif (TSLPRM_PXS_HSI == 125) + PXS->CKCR1 |= PXS_CKCR1_125KHZ; +#else + PXS->CKCR1 |= PXS_CKCR1_16MHZ; // Default +#endif + + PXS->CKCR2 = (uint8_t)(((uint8_t)TSLPRM_PXS_UP_LENGTH & 0x07) << 4) | ((uint8_t)TSLPRM_PXS_PASS_LENGTH & 0x07); + +#if TSLPRM_PXS_RF_DETECTION > 0 + enablePXSNoiseDetection(); +#endif + + setPXSStab(TSLPRM_PXS_STAB); + setPXSBias(TSLPRM_PXS_BIAS); + + // Initialization of the GPIO shared with the used TX + for (i = 0; i < TSLPRM_TOTAL_BANKS; i++) + { + bank = &(TSL_Globals.Bank_Array[i]); + CSArray = PXS_BankConfig[i].CSSEL; + TxInUseMask |= bank->msk_TX; + // Set the mask with the receivers use as receiver or as transmitter + RxInUseMask |= bank->msk_RXEN; + // Set the CS to 0 + for (j = 0; j <= TSLPRM_HIGH_CHANNEL_NB; j++) + { + *CSArray = 0; + CSArray++; + } + } + + GPIOD->ODR &= (uint8_t)(~(TxInUseMask & 0x00FF)); + // Set the port as output + GPIOD->DDR |= (uint8_t)(TxInUseMask & 0x00FF); + // Configure the port as open-drain + GPIOD->CR1 &= (uint8_t)(~(TxInUseMask & 0x00FF)); +#if TSLPRM_PXS_INACTIVE_TX > 0 + // Configure as floating + GPIOD->ODR |= (uint8_t)(TxInUseMask & 0x00FF); +#else + // Drive them to VSS + GPIOD->ODR &= (uint8_t)(~(TxInUseMask & 0x00FF)); +#endif + GPIOB->ODR &= (uint8_t)(~((TxInUseMask & 0xFF00) >> 8)); + // Set the port as output + GPIOB->DDR |= (uint8_t)((TxInUseMask & 0xFF00) >> 8); + // Configure the port as open-drain + GPIOB->CR1 &= (uint8_t)(~((TxInUseMask & 0xFF00) >> 8)); +#if TSLPRM_PXS_INACTIVE_TX > 0 + // Configure as floating + GPIOB->ODR |= (uint8_t)((TxInUseMask & 0xFF00) >> 8); +#else + // Drive it to VSS + GPIOB->ODR &= (uint8_t)(~((TxInUseMask & 0xFF00) >> 8)); +#endif + + enablePXS(); + +#if TSLPRM_PXS_INACTIVE_RX > 0 + PXS->RXINSR = 0x3FF; +#else + PXS->RXINSR = 0x0000; +#endif + +#if TSLPRM_PXS_RX_COUPLING > 0 + enablePXSCoupling(); +#else + disablePXSCoupling() +#endif + +#if TSLPRM_PXS_SYNCHRONIZE > 0 + enablePXSSync(); +#if TSLPRM_PXS_SYNCHRO_EDGE > 0 + selectPXSSyncRisingEdge(); +#else + selectPXSSyncFallingEdge(); +#endif +#else + disablePXSSync(); +#endif + +#if TSLPRM_USE_ACQ_INTERRUPT > 0 + enablePXSInterrupts(PXS_CR2_EOCITEN); +#endif + // Configure the acquisition mode + PXS->RXCR3 = (uint16_t)RxInUseMask; + PXS->RXCR2 = (uint16_t)RxInUseMask; + +#if TSLPRM_ACQ_MAX > 0 + PXS->MAXR = TSLPRM_ACQ_MAX; + PXS->MAXENR = 0x03FF; +#else + PXS->MAXENR = 0; +#endif + + // Calibrate the CS for all banks + for (idx_bk = 0;idx_bk < TSLPRM_TOTAL_BANKS;idx_bk++) + { + TSL_PXS_CS_CalibrateBank(idx_bk); + } + + + // Calibrate the EPCC for all banks + for (idx_bk = 0;idx_bk < TSLPRM_TOTAL_BANKS;idx_bk++) + { + if (TSL_PXS_EPCC_CalibrateBank(idx_bk) > 0) + { + retval = TSL_STATUS_ERROR; + } + } +#if TSLPRM_PXS_LOW_POWER_MODE > 0 + setPXSLowPower(); +#else + resetPXSLowPower(); +#endif + + return retval; + +} + +/** + * @brief Calibrate the CS for a selected acquisition bank + * @param[in] idx_bk Index of the bank + * @retval Number of Receivers not correctly calibrated + */ +void TSL_PXS_CS_CalibrateBank(TSL_tIndex_T idx_bk) +{ + TSL_tIndex_T idx_ch; + uint8_t currentCS = 24; + uint8_t CS_delta = 4; // Value to add/substract to/from the current CS + CONST TSL_Bank_T *bank; + CONST uint16_t targetCount = TSLPRM_KEY_TARGET_REFERENCE / TSLPRM_KEY_TARGET_ATTENUATION; + CONST uint16_t targetCountError = targetCount >> 3; + bool CalibrationDone = FALSE; + uint16_t measSup[TSLPRM_HIGH_CHANNEL_NB+1]; + uint16_t measInf[TSLPRM_HIGH_CHANNEL_NB+1]; + uint8_t CSsup[TSLPRM_HIGH_CHANNEL_NB+1]; + uint8_t CSinf[TSLPRM_HIGH_CHANNEL_NB+1]; + + // Check parameters (if USE_FULL_ASSERT is defined) + assert_param(IS_BANK_INDEX_OK(idx_bk)); +#if TSLPRM_USE_ACQ_INTERRUPT == 0 + enablePXSInterrupts(PXS_CR2_EOCITEN); +#endif + + bank = &(TSL_Globals.Bank_Array[idx_bk]); + resetPXSLowPower(); + TSL_acq_BankConfig(idx_bk); + + PXS->MAXR = TSLPRM_KEY_TARGET_REFERENCE; + + WFE->CR1 |= WFE_CR1_PXS_EV; + for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++) + { + PXS->RXEPCCSELR[idx_ch] = 0; + PXS->RXCSSELR[idx_ch] = currentCS; + CSsup[idx_ch] = 0; + CSinf[idx_ch] = 0; + measInf[idx_ch] = 0; + measSup[idx_ch] = 0xFFFF; + + } + do + { + startPXSAcquisition(); + wfe(); + clearPXS_ISR_EOCF; + for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++) + { + if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch)) + { + if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > targetCount - targetCountError)) + { + PXS->RXCSSELR[idx_ch] -= 8; + } + } + } + currentCS -= 8; + } + while (currentCS); + + + for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++) + { + PXS->RXCSSELR[idx_ch] += CS_delta; + } + + do + { + CS_delta >>= 1; + if ((CS_delta == 0) && (CalibrationDone == FALSE)) + { + CalibrationDone = TRUE; + CS_delta = 1; + } + + startPXSAcquisition(); + wfe(); + clearPXS_ISR_EOCF; + for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++) + { + if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch)) + { + if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > targetCount)) + { + measSup[idx_ch] = PXS->RXCNTR[idx_ch]; + CSsup[idx_ch] = PXS->RXCSSELR[idx_ch]; + PXS->RXCSSELR[idx_ch] -= CS_delta; + } + else //if (PXS->RXCNTR[idx_ch] < targetCount ) + { + measInf[idx_ch] = PXS->RXCNTR[idx_ch]; + CSinf[idx_ch] = PXS->RXCSSELR[idx_ch]; + PXS->RXCSSELR[idx_ch] += CS_delta; + } +// else +// { + // Do nothing (MISRA requirement) +// } + } + } + } + while ((CalibrationDone == FALSE) || (CS_delta != 0)); + + + // Restore configuration +#if TSLPRM_ACQ_MAX > 0 + PXS->MAXR = TSLPRM_ACQ_MAX; +#else + PXS->MAXENR = 0; +#endif + + WFE->CR1 &= (uint8_t)~WFE_CR1_PXS_EV; +#if TSLPRM_USE_ACQ_INTERRUPT == 0 + disablePXSInterrupts(PXS_CR2_EOCITEN); +#endif + + // Store the CS + for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++) + { + if ((measSup[idx_ch] == 0) || ((measSup[idx_ch] - targetCount) > (targetCount - measInf[idx_ch]))) + { + PXS_BankConfig[idx_bk].CSSEL[idx_ch] = CSinf[idx_ch]; + } + else + { + PXS_BankConfig[idx_bk].CSSEL[idx_ch] = CSsup[idx_ch]; + } + } +} + + +/** + * @brief Calibrate the EPCC for a selected acquisition bank + * @param[in] idx_bk Index of the bank + * @retval Number Number of Receivers not correctly calibrated + */ +int8_t TSL_PXS_EPCC_CalibrateBank(TSL_tIndex_T idx_bk) +{ + TSL_tIndex_T idx_ch; + uint8_t currentEPCC, trial, goodEPCC = 0; + uint8_t EPCCtoCompute = 0; // Used to define if all the EPCC have their final value + uint8_t EPCC_delta = EPCC_INIT_VALUE; // Value to add/substract to/from the current EPCC + CONST TSL_Bank_T *bank; + + // Check parameters (if USE_FULL_ASSERT is defined) + assert_param(IS_BANK_INDEX_OK(idx_bk)); +#if TSLPRM_USE_ACQ_INTERRUPT == 0 + enablePXSInterrupts(PXS_CR2_EOCITEN); +#endif + + bank = &(TSL_Globals.Bank_Array[idx_bk]); + resetPXSLowPower(); + TSL_acq_BankConfig(idx_bk); + + PXS->MAXR = 2 * TSLPRM_KEY_TARGET_REFERENCE; + + WFE->CR1 |= WFE_CR1_PXS_EV; + for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++) + { + PXS->RXEPCCSELR[idx_ch] = EPCC_delta; + if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch)) + { + EPCCtoCompute++; + } + } + do + { + EPCC_delta >>= 1; + startPXSAcquisition(); + wfe(); + clearPXS_ISR_EOCF; + for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++) + { + if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch)) + { + if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > TSLPRM_KEY_TARGET_REFERENCE)) + { + PXS->RXEPCCSELR[idx_ch] -= EPCC_delta; + } + else if (PXS->RXCNTR[idx_ch] < TSLPRM_KEY_TARGET_REFERENCE) + { + PXS->RXEPCCSELR[idx_ch] += EPCC_delta; + } + else + { + // Do nothing (MISRA requirement) + } + } + } + } + while (EPCC_delta >= 1); + // Second pass to fine-tune + trial = TSLPRM_PXS_EPCC_FINE_TUNING_ITERATION; + do + { + startPXSAcquisition(); + goodEPCC = 0; // Reset the goodEPCC variable + wfe(); + clearPXS_ISR_EOCF; + for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++) + { + if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch)) + { + currentEPCC = PXS->RXEPCCSELR[idx_ch]; //this affectation allow to avoid computation of the structure address + if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > (TSLPRM_KEY_TARGET_REFERENCE + TSLPRM_KEY_TARGET_REFERENCE_ERROR))) + { + if (currentEPCC > 0) + { + if ((currentEPCC & 0x07) != 0) + { + currentEPCC--; + } + else + { + currentEPCC -= 3; // This is due to the non linearity of the EPCC + } + } + } + else if (PXS->RXCNTR[idx_ch] < (TSLPRM_KEY_TARGET_REFERENCE - TSLPRM_KEY_TARGET_REFERENCE_ERROR)) + { + if (currentEPCC < 0xFF) + { + if ((currentEPCC & 0x07) != 0x07) + { + currentEPCC++; + } + else + { + currentEPCC += 2; // This is due to the non linearity of the EPCC + } + } + else // Invert the change in case the sorting is not reliable + { + currentEPCC--; + } + } + else + { + goodEPCC++; + } + PXS->RXEPCCSELR[idx_ch] = currentEPCC; + } + } + trial--; + } + while ((goodEPCC < EPCCtoCompute) && (trial)); + + // Restore configuration +#if TSLPRM_ACQ_MAX > 0 + PXS->MAXR = TSLPRM_ACQ_MAX; +#else + PXS->MAXENR = 0; +#endif + + WFE->CR1 &= (uint8_t)~WFE_CR1_PXS_EV; +#if TSLPRM_USE_ACQ_INTERRUPT == 0 + disablePXSInterrupts(PXS_CR2_EOCITEN); +#endif + + // Store the EPCC + for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++) + { + PXS_BankConfig[idx_bk].EPCCSEL[idx_ch] = PXS->RXEPCCSELR[idx_ch]; + } + + return((int8_t)(EPCCtoCompute - goodEPCC)); +} + + +#if TSLPRM_USE_ZONE > 0 +/** + * @brief Calibrate the EPCC for a set of acquisition banks. + * @param[in] zone Set of banks to calibrate the EPCC + * @retval Status + */ +TSL_Status_enum_T TSL_PXS_EPCC_CalibrateZone(CONST TSL_Zone_T *zone) +{ + uint16_t idx_bk; + TSL_Status_enum_T retval = TSL_STATUS_OK; + for (idx_bk = 0; idx_bk < zone->NbBanks; idx_bk++) + { + if (TSL_PXS_EPCC_CalibrateBank(zone->BankIndex[idx_bk]) > 0) + { + retval = TSL_STATUS_ERROR; + } + } + return(retval); +} +#endif + + +/** + * @brief Test the reference and update the EPCC/CS if needed + * @param[in] pCh pointer on the channel data information + * @retval Result + */ +TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh) +{ + uint16_t reference, target_error = 0; + TSL_Bool_enum_T result = TSL_FALSE; + + if (pCh->Flags.EPCCStatus != TSL_EPCC_STATUS_LOCKED) + { + reference = pCh->Ref; +#if TSLPRM_TOTAL_TKEYS > 0 + if (TSL_Globals.This_Obj->Type & TSL_OBJ_TYPE_TKEY_MASK) + { + target_error = TSLPRM_TOUCHKEY_REFERENCE_RANGE; + } +#endif + +#if TSLPRM_TOTAL_LNRTS > 0 + if (TSL_Globals.This_Obj->Type & TSL_OBJ_TYPE_LINROT_MASK) + { + target_error = TSLPRM_LINROT_REFERENCE_RANGE; + } +#endif + if ((reference != 0) && ((reference > (TSLPRM_KEY_TARGET_REFERENCE + target_error)) || (reference < (TSLPRM_KEY_TARGET_REFERENCE - target_error)))) + { + if (reference < (TSLPRM_KEY_TARGET_REFERENCE - target_error)) + { + pCh->Flags.EPCCStatus = TSL_EPCC_STATUS_INCREASE; + } + else if (reference > (TSLPRM_KEY_TARGET_REFERENCE + target_error)) + { + pCh->Flags.EPCCStatus = TSL_EPCC_STATUS_DECREASE; + } + else + { + // Do nothing (MISRA requirement) + } + result = TSL_TRUE; + } + } + return(result); +} + +/** + * @brief Test if the measure has crossed the reference target + * @param[in] pCh Pointer to the channel Data under test + * @param[in] new_meas Measure of the last acquisition on this channel + * @retval Result Result of the test + */ +TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas) +{ + TSL_Bool_enum_T result = TSL_TRUE; + TSL_EPCCStatus_enum_T EPCCStatus; + + EPCCStatus = pCh->Flags.EPCCStatus; + if (EPCCStatus & TSL_EPCC_CHANGE_MASK) + { + // If the previous reference and the new one are on each side of the reference target + // the EPCC is no more tested and the calibration continues. + if (((EPCCStatus == TSL_EPCC_STATUS_INCREASE) && (new_meas >= TSLPRM_KEY_TARGET_REFERENCE)) + || ((EPCCStatus == TSL_EPCC_STATUS_DECREASE) && (new_meas <= TSLPRM_KEY_TARGET_REFERENCE))) + { + pCh->Flags.EPCCStatus = TSL_EPCC_STATUS_UNLOCKED; + } + else + { + result = TSL_FALSE; + } + } + + return(result); +} + + +/** + * @brief Increase or decrease the CS value + * @param[in] pCSSEL Address of the CS to be modified + * @param[in] change Define if the Cs must be increased or decreased + * @retval None + */ +void TSL_acq_UpdateCS(uint8_t *pCSSEL, TSL_EPCCStatus_enum_T change) +{ + uint16_t indexCS; + + assert_param(IS_EPCC_STATUS_OK(change)); + assert_param(IS_CSSEL_OK(*pCSSEL)); + + if (*pCSSEL > CS_MIDDLE_VALUE) + { + indexCS = (CS_MIDDLE_VALUE - 1); + } + else + { + indexCS = 0; + } + while ((PXS_CSsorting[indexCS] != *pCSSEL) && (indexCS < CS_MAX_VALUE)) + { + indexCS++; + } + if (change == TSL_EPCC_STATUS_INCREASE) + { + *pCSSEL = PXS_CSsorting[indexCS + 1]; + } + else + { + *pCSSEL = PXS_CSsorting[indexCS - 1]; + } +} + + +/** + * @brief Configures a Bank. + * @param[in] idx_bk Index of the Bank to configure + * @retval Status + */ +TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk) +{ + TSL_Status_enum_T retval = TSL_STATUS_OK; + uint16_t idx_ch; + TSL_ChannelFlags_T flags; + CONST TSL_Bank_T *bank = &(TSL_Globals.Bank_Array[idx_bk]); + CONST TSL_ChannelSrc_T *pchSrc = bank->p_chSrc; + CONST TSL_ChannelDest_T *pchDest = bank->p_chDest; + TSL_tMaskRX enabledRX = 0; + uint8_t *pEPCCSEL, *pCSSEL; + + // Check parameters (if USE_FULL_ASSERT is defined) + assert_param(IS_BANK_INDEX_OK(idx_bk)); + + TSL_Globals.This_Bank = idx_bk; + + selectPXSRxGroup(bank->msk_group); + for (idx_ch = 0;idx_ch < bank->NbChannels;idx_ch++) + { + flags = bank->p_chData[pchDest->IdxDest].Flags; + if (flags.ObjStatus == TSL_OBJ_STATUS_ON) + { + enabledRX |= (1 << pchSrc->IdxSrc); + if (flags.EPCCStatus & TSL_EPCC_CHANGE_MASK) + { + pEPCCSEL = &PXS_BankConfig[idx_bk].EPCCSEL[pchSrc->IdxSrc]; + if (flags.EPCCStatus == TSL_EPCC_STATUS_INCREASE) + { + if ((*pEPCCSEL) < 0xFF) + { + if (((*pEPCCSEL) & 0x07) != 0x07) + { + (*pEPCCSEL)++; + } + else + { + if ((*pEPCCSEL) < 0xFE) + { + (*pEPCCSEL) += 2; // This is due to the non linearity of the PCC + } + else + { + (*pEPCCSEL)++; + } + } + + } + else + { + pCSSEL = &PXS_BankConfig[idx_bk].CSSEL[pchSrc->IdxSrc]; + if (*pCSSEL < 0x1F) + { + TSL_acq_UpdateCS(pCSSEL, TSL_EPCC_STATUS_INCREASE); + } + else + {} + } + } + else + { + if ((*pEPCCSEL) > 0) + { + if (((*pEPCCSEL) & 0x07) != 0) + { + (*pEPCCSEL)--; + } + else + { + if ((*pEPCCSEL) > 3) + { + (*pEPCCSEL) -= 3; // This is due to the non linearity of the PCC + } + else + { + (*pEPCCSEL)--; + } + } + } + else + { + pCSSEL = &PXS_BankConfig[idx_bk].CSSEL[pchSrc->IdxSrc]; + if (*pCSSEL > 0) + { + TSL_acq_UpdateCS(pCSSEL, TSL_EPCC_STATUS_DECREASE); + } + else + {} + } + } + } + } + + // Next channel + pchSrc++; + pchDest++; + } + + // The two following loops are more efficient than the two instructions in the same loop + for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++) + { + PXS->RXCSSELR[idx_ch] = PXS_BankConfig[idx_bk].CSSEL[idx_ch]; + } + for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++) + { + PXS->RXEPCCSELR[idx_ch] = PXS_BankConfig[idx_bk].EPCCSEL[idx_ch]; + } + + PXS->TXENR = bank->msk_TX; // Enable the Tx selected (if any) + PXS->RXCR1 = bank->msk_channels; // Configure the Rx and the Tx function modes + + // Enable the Rx which are not disabled including the potential Rx configured as Tx + PXS->RXENR = bank->msk_RXEN & ((uint16_t)(~bank->msk_channels) | enabledRX); + + if (enabledRX == 0) + { + retval = TSL_STATUS_ERROR; + } + + return(retval); + +} + + +/** + * @brief Test if EPCC are changing + * @param[in] pCh Channel to be processed + * @retval bool Test result + */ +TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh) +{ + if (pCh->Flags.EPCCStatus & TSL_EPCC_CHANGE_MASK) + { + return (TSL_FALSE); + } + else + { + return(TSL_TRUE); + } +} + + +/** + * @brief Start acquisition on a previously configured bank + * @param None + * @retval None + */ +void TSL_acq_BankStartAcq(void) +{ + // Start acquisition + startPXSAcquisition(); +} + + +/** + * @brief Wait end of acquisition + * @param None + * @retval Status + */ +TSL_Status_enum_T TSL_acq_BankWaitEOC(void) +{ + TSL_Status_enum_T retval = TSL_STATUS_BUSY; + + if (checkPXSInterruptStatusFlag(PXS_ISR_EOCF)) // Check EOC flag + { + if (PXS->RXSR != TSL_Globals.Bank_Array[TSL_Globals.This_Bank].msk_channels) // Check MCE flag + { + retval = TSL_STATUS_ERROR; + } + else + { + retval = TSL_STATUS_OK; + } + } + + return retval; +} + + +/** + * @brief Check noise detection + * @param None + * @retval Status + */ +TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void) +{ + TSL_AcqStatus_enum_T retval = TSL_ACQ_STATUS_OK; +#if TSLPRM_PXS_RF_DETECTION > 0 + if (checkPXSInterruptStatusFlag(PXS_ISR_NOISEDETF) == PXS_ISR_NOISEDETF) + { + retval = TSL_ACQ_STATUS_NOISE; + } +#endif + return(retval); +} + + +/** + * @brief Return the current measure + * @param[in] index Index of the measure source + * @retval Measure + */ +TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndexSrc_T index) +{ + uint16_t CurrentReceiver; + + // Check parameters (if USE_FULL_ASSERT is defined) + assert_param(IS_SOURCE_INDEX_OK(index)); + + CurrentReceiver = (uint16_t)(((uint16_t)1) << index); + + if (PXS->RXSR & CurrentReceiver) + { + return(PXS->RXCNTR[index]); + } + else + { + return(MAX_MEASURE); + } +} + + +/** + * @brief Process the PXS Interrupt routine + * @param None + * @retval None + */ +INTERRUPT_HANDLER(TSL_acq_ProcessIT, 2) +{ + clearPXS_ISR_EOCF; + + TSL_acq_BankGetResult(TSL_Globals.This_Bank, 0, 0); // No noise filter + +#if TSLPRM_USE_ZONE > 0 + if ((TSL_Globals.This_Zone == 0) || (TSL_Globals.Index_In_This_Zone >= TSL_Globals.This_Zone->NbBanks)) + { + CFG->GCR &= (uint8_t)(~CFG_GCR_AL); // Reset Activation level to resume main processing + PXS->RXENR = 0; // To reduce consumption + PXS->TXENR = 0; // To reduce consumption + TSL_Globals.This_Bank = 0; + } + else + { + if (TSL_acq_ZoneConfig(TSL_Globals.This_Zone, TSL_Globals.Index_In_This_Zone) != TSL_STATUS_ERROR) + { + // Start Bank acquisition + TSL_acq_BankStartAcq(); +#if TSLPRM_PXS_LOW_POWER_MODE > 0 + if (TSL_Globals.Index_In_This_Zone >= TSL_Globals.This_Zone->NbBanks) + { + setPXSLowPower(); + } +#endif + } + + } +#else + CFG->GCR &= (uint8_t)(~CFG_GCR_AL); // Reset Activation level to resume main processing + PXS->RXENR = 0; // To reduce consumption + PXS->TXENR = 0; // To reduce consumption +#endif +} + + +#if defined(__ICCSTM8__) +#pragma optimize=low +#endif +/** + * @brief Software delay (private routine) + * @param val Wait delay + * @retval None + */ +void SoftDelay(uint16_t val) +{ + __IO uint16_t idx; + for (idx = val; idx > 0; idx--) + { + nop(); + } +} + +/******************* (C) COPYRIGHT 2014 STMicroelectronics *****END OF FILE****/ |