2 ******************************************************************************
\r
3 * @file tsl_acq_stm8tl5x.c
\r
4 * @author MCD Application Team
\r
6 * @date 22-January-2013
\r
7 * @brief This file contains all functions to manage the PXS acquisition
\r
8 * on STM8TL5x products.
\r
9 ******************************************************************************
\r
12 * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
\r
14 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
\r
15 * You may not use this file except in compliance with the License.
\r
16 * You may obtain a copy of the License at:
\r
18 * http://www.st.com/software_license_agreement_liberty_v2
\r
20 * Unless required by applicable law or agreed to in writing, software
\r
21 * distributed under the License is distributed on an "AS IS" BASIS,
\r
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
23 * See the License for the specific language governing permissions and
\r
24 * limitations under the License.
\r
26 ******************************************************************************
\r
29 /* Includes ------------------------------------------------------------------*/
\r
30 #include "tsl_acq_stm8tl5x.h"
\r
31 #include "tsl_globals.h"
\r
32 #include "stm8tl5x_it.h"
\r
34 /* Private typedefs ----------------------------------------------------------*/
\r
36 /* Private defines -----------------------------------------------------------*/
\r
37 #define EPCC_INIT_VALUE (0x80)
\r
38 #define CS_MIDDLE_VALUE (17)
\r
39 #define CS_MAX_VALUE (32)
\r
40 #define MAX_MEASURE (0xFFFF)
\r
42 /* Private macros ------------------------------------------------------------*/
\r
43 #define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS)))
\r
44 #define IS_SOURCE_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_CHANNELS)))
\r
45 #define IS_EPCC_STATUS_OK(STATUS) ((STATUS & TSL_EPCC_CHANGE_MASK) != 0)
\r
46 #define IS_CSSEL_OK(CSSEL) (((CSSEL) == 0) || (((CSSEL) > 0) && ((CSSEL) < CS_MAX_VALUE)))
\r
48 /* Private variables ---------------------------------------------------------*/
\r
49 TSL_BankConfig_T PXS_BankConfig[TSLPRM_TOTAL_BANKS];
\r
50 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};
\r
52 /* Private functions prototype -----------------------------------------------*/
\r
53 void TSL_PXS_CS_CalibrateBank(TSL_tIndex_T idx_bk);
\r
54 int8_t TSL_PXS_EPCC_CalibrateBank(TSL_tIndex_T bank);
\r
55 TSL_Status_enum_T TSL_PXS_EPCC_CalibrateZone(CONST TSL_Zone_T *);
\r
56 void SoftDelay(uint32_t val);
\r
59 * @brief Initializes the acquisition module.
\r
63 TSL_Status_enum_T TSL_acq_Init(void)
\r
66 TSL_Status_enum_T retval = TSL_STATUS_OK;
\r
70 TSL_tIndex_T idx_bk; // Bank index
\r
71 uint16_t TxInUseMask = 0;
\r
72 uint16_t RxInUseMask = 0;
\r
73 CONST TSL_Bank_T *bank;
\r
76 // Enable the PXS IP clock
\r
77 CLK->PCKENR1 |= CLK_PCKENR1_PXS;
\r
79 // Initialization of PXS IP
\r
80 PXS->CKCR1 &= (uint8_t)~PXS_CKCR1_PRESC;
\r
82 #if (TSLPRM_PXS_HSI == 16000)
\r
83 PXS->CKCR1 |= PXS_CKCR1_16MHZ;
\r
84 #elif (TSLPRM_PXS_HSI == 8000)
\r
85 PXS->CKCR1 |= PXS_CKCR1_8MHZ;
\r
86 #elif (TSLPRM_PXS_HSI == 4000)
\r
87 PXS->CKCR1 |= PXS_CKCR1_4MHZ;
\r
88 #elif (TSLPRM_PXS_HSI == 2000)
\r
89 PXS->CKCR1 |= PXS_CKCR1_2MHZ;
\r
90 #elif (TSLPRM_PXS_HSI == 1000)
\r
91 PXS->CKCR1 |= PXS_CKCR1_1MHZ;
\r
92 #elif (TSLPRM_PXS_HSI == 500)
\r
93 PXS->CKCR1 |= PXS_CKCR1_500KHZ;
\r
94 #elif (TSLPRM_PXS_HSI == 250)
\r
95 PXS->CKCR1 |= PXS_CKCR1_250KHZ;
\r
96 #elif (TSLPRM_PXS_HSI == 125)
\r
97 PXS->CKCR1 |= PXS_CKCR1_125KHZ;
\r
99 PXS->CKCR1 |= PXS_CKCR1_16MHZ; // Default
\r
102 PXS->CKCR2 = (uint8_t)(((uint8_t)TSLPRM_PXS_UP_LENGTH & 0x07) << 4) | ((uint8_t)TSLPRM_PXS_PASS_LENGTH & 0x07);
\r
104 #if TSLPRM_PXS_RF_DETECTION > 0
\r
105 enablePXSNoiseDetection();
\r
108 setPXSStab(TSLPRM_PXS_STAB);
\r
109 setPXSBias(TSLPRM_PXS_BIAS);
\r
111 // Initialization of the GPIO shared with the used TX
\r
112 for (i = 0; i < TSLPRM_TOTAL_BANKS; i++)
\r
114 bank = &(TSL_Globals.Bank_Array[i]);
\r
115 CSArray = PXS_BankConfig[i].CSSEL;
\r
116 TxInUseMask |= bank->msk_TX;
\r
117 // Set the mask with the receivers use as receiver or as transmitter
\r
118 RxInUseMask |= bank->msk_RXEN;
\r
120 for (j = 0; j <= TSLPRM_HIGH_CHANNEL_NB; j++)
\r
127 GPIOD->ODR &= (uint8_t)(~(TxInUseMask & 0x00FF));
\r
128 // Set the port as output
\r
129 GPIOD->DDR |= (uint8_t)(TxInUseMask & 0x00FF);
\r
130 // Configure the port as open-drain
\r
131 GPIOD->CR1 &= (uint8_t)(~(TxInUseMask & 0x00FF));
\r
132 #if TSLPRM_PXS_INACTIVE_TX > 0
\r
133 // Configure as floating
\r
134 GPIOD->ODR |= (uint8_t)(TxInUseMask & 0x00FF);
\r
136 // Drive them to VSS
\r
137 GPIOD->ODR &= (uint8_t)(~(TxInUseMask & 0x00FF));
\r
139 GPIOB->ODR &= (uint8_t)(~((TxInUseMask & 0xFF00) >> 8));
\r
140 // Set the port as output
\r
141 GPIOB->DDR |= (uint8_t)((TxInUseMask & 0xFF00) >> 8);
\r
142 // Configure the port as open-drain
\r
143 GPIOB->CR1 &= (uint8_t)(~((TxInUseMask & 0xFF00) >> 8));
\r
144 #if TSLPRM_PXS_INACTIVE_TX > 0
\r
145 // Configure as floating
\r
146 GPIOB->ODR |= (uint8_t)((TxInUseMask & 0xFF00) >> 8);
\r
149 GPIOB->ODR &= (uint8_t)(~((TxInUseMask & 0xFF00) >> 8));
\r
154 #if TSLPRM_PXS_INACTIVE_RX > 0
\r
155 PXS->RXINSR = 0x3FF;
\r
157 PXS->RXINSR = 0x0000;
\r
160 #if TSLPRM_PXS_RX_COUPLING > 0
\r
161 enablePXSCoupling();
\r
163 disablePXSCoupling()
\r
166 #if TSLPRM_PXS_SYNCHRONIZE > 0
\r
168 #if TSLPRM_PXS_SYNCHRO_EDGE > 0
\r
169 selectPXSSyncRisingEdge();
\r
171 selectPXSSyncFallingEdge();
\r
177 #if TSLPRM_USE_ACQ_INTERRUPT > 0
\r
178 enablePXSInterrupts(PXS_CR2_EOCITEN);
\r
180 // Configure the acquisition mode
\r
181 PXS->RXCR3 = (uint16_t)RxInUseMask;
\r
182 PXS->RXCR2 = (uint16_t)RxInUseMask;
\r
184 #if TSLPRM_ACQ_MAX > 0
\r
185 PXS->MAXR = TSLPRM_ACQ_MAX;
\r
186 PXS->MAXENR = 0x03FF;
\r
191 // Calibrate the CS for all banks
\r
192 for (idx_bk = 0;idx_bk < TSLPRM_TOTAL_BANKS;idx_bk++)
\r
194 TSL_PXS_CS_CalibrateBank(idx_bk);
\r
198 // Calibrate the EPCC for all banks
\r
199 for (idx_bk = 0;idx_bk < TSLPRM_TOTAL_BANKS;idx_bk++)
\r
201 if (TSL_PXS_EPCC_CalibrateBank(idx_bk) > 0)
\r
203 retval = TSL_STATUS_ERROR;
\r
206 #if TSLPRM_PXS_LOW_POWER_MODE > 0
\r
209 resetPXSLowPower();
\r
217 * @brief Calibrate the CS for a selected acquisition bank
\r
218 * @param[in] idx_bk Index of the bank
\r
219 * @retval Number of Receivers not correctly calibrated
\r
221 void TSL_PXS_CS_CalibrateBank(TSL_tIndex_T idx_bk)
\r
223 TSL_tIndex_T idx_ch;
\r
224 uint8_t currentCS = 24;
\r
225 uint8_t CS_delta = 4; // Value to add/substract to/from the current CS
\r
226 CONST TSL_Bank_T *bank;
\r
227 CONST uint16_t targetCount = TSLPRM_KEY_TARGET_REFERENCE / TSLPRM_KEY_TARGET_ATTENUATION;
\r
228 CONST uint16_t targetCountError = targetCount >> 3;
\r
229 bool CalibrationDone = FALSE;
\r
230 uint16_t measSup[TSLPRM_HIGH_CHANNEL_NB+1];
\r
231 uint16_t measInf[TSLPRM_HIGH_CHANNEL_NB+1];
\r
232 uint8_t CSsup[TSLPRM_HIGH_CHANNEL_NB+1];
\r
233 uint8_t CSinf[TSLPRM_HIGH_CHANNEL_NB+1];
\r
235 // Check parameters (if USE_FULL_ASSERT is defined)
\r
236 assert_param(IS_BANK_INDEX_OK(idx_bk));
\r
237 #if TSLPRM_USE_ACQ_INTERRUPT == 0
\r
238 enablePXSInterrupts(PXS_CR2_EOCITEN);
\r
241 bank = &(TSL_Globals.Bank_Array[idx_bk]);
\r
242 resetPXSLowPower();
\r
243 TSL_acq_BankConfig(idx_bk);
\r
245 PXS->MAXR = TSLPRM_KEY_TARGET_REFERENCE;
\r
247 WFE->CR1 |= WFE_CR1_PXS_EV;
\r
248 for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
\r
250 PXS->RXEPCCSELR[idx_ch] = 0;
\r
251 PXS->RXCSSELR[idx_ch] = currentCS;
\r
254 measInf[idx_ch] = 0;
\r
255 measSup[idx_ch] = 0xFFFF;
\r
260 startPXSAcquisition();
\r
263 for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
\r
265 if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch))
\r
267 if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > targetCount - targetCountError))
\r
269 PXS->RXCSSELR[idx_ch] -= 8;
\r
278 for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
\r
280 PXS->RXCSSELR[idx_ch] += CS_delta;
\r
286 if ((CS_delta == 0) && (CalibrationDone == FALSE))
\r
288 CalibrationDone = TRUE;
\r
292 startPXSAcquisition();
\r
295 for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
\r
297 if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch))
\r
299 if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > targetCount))
\r
301 measSup[idx_ch] = PXS->RXCNTR[idx_ch];
\r
302 CSsup[idx_ch] = PXS->RXCSSELR[idx_ch];
\r
303 PXS->RXCSSELR[idx_ch] -= CS_delta;
\r
305 else //if (PXS->RXCNTR[idx_ch] < targetCount )
\r
307 measInf[idx_ch] = PXS->RXCNTR[idx_ch];
\r
308 CSinf[idx_ch] = PXS->RXCSSELR[idx_ch];
\r
309 PXS->RXCSSELR[idx_ch] += CS_delta;
\r
313 // Do nothing (MISRA requirement)
\r
318 while ((CalibrationDone == FALSE) || (CS_delta != 0));
\r
321 // Restore configuration
\r
322 #if TSLPRM_ACQ_MAX > 0
\r
323 PXS->MAXR = TSLPRM_ACQ_MAX;
\r
328 WFE->CR1 &= (uint8_t)~WFE_CR1_PXS_EV;
\r
329 #if TSLPRM_USE_ACQ_INTERRUPT == 0
\r
330 disablePXSInterrupts(PXS_CR2_EOCITEN);
\r
334 for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++)
\r
336 if ((measSup[idx_ch] == 0) || ((measSup[idx_ch] - targetCount) > (targetCount - measInf[idx_ch])))
\r
338 PXS_BankConfig[idx_bk].CSSEL[idx_ch] = CSinf[idx_ch];
\r
342 PXS_BankConfig[idx_bk].CSSEL[idx_ch] = CSsup[idx_ch];
\r
349 * @brief Calibrate the EPCC for a selected acquisition bank
\r
350 * @param[in] idx_bk Index of the bank
\r
351 * @retval Number Number of Receivers not correctly calibrated
\r
353 int8_t TSL_PXS_EPCC_CalibrateBank(TSL_tIndex_T idx_bk)
\r
355 TSL_tIndex_T idx_ch;
\r
356 uint8_t currentEPCC, trial, goodEPCC = 0;
\r
357 uint8_t EPCCtoCompute = 0; // Used to define if all the EPCC have their final value
\r
358 uint8_t EPCC_delta = EPCC_INIT_VALUE; // Value to add/substract to/from the current EPCC
\r
359 CONST TSL_Bank_T *bank;
\r
361 // Check parameters (if USE_FULL_ASSERT is defined)
\r
362 assert_param(IS_BANK_INDEX_OK(idx_bk));
\r
363 #if TSLPRM_USE_ACQ_INTERRUPT == 0
\r
364 enablePXSInterrupts(PXS_CR2_EOCITEN);
\r
367 bank = &(TSL_Globals.Bank_Array[idx_bk]);
\r
368 resetPXSLowPower();
\r
369 TSL_acq_BankConfig(idx_bk);
\r
371 PXS->MAXR = 2 * TSLPRM_KEY_TARGET_REFERENCE;
\r
373 WFE->CR1 |= WFE_CR1_PXS_EV;
\r
374 for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
\r
376 PXS->RXEPCCSELR[idx_ch] = EPCC_delta;
\r
377 if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch))
\r
385 startPXSAcquisition();
\r
388 for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
\r
390 if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch))
\r
392 if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > TSLPRM_KEY_TARGET_REFERENCE))
\r
394 PXS->RXEPCCSELR[idx_ch] -= EPCC_delta;
\r
396 else if (PXS->RXCNTR[idx_ch] < TSLPRM_KEY_TARGET_REFERENCE)
\r
398 PXS->RXEPCCSELR[idx_ch] += EPCC_delta;
\r
402 // Do nothing (MISRA requirement)
\r
407 while (EPCC_delta >= 1);
\r
408 // Second pass to fine-tune
\r
409 trial = TSLPRM_PXS_EPCC_FINE_TUNING_ITERATION;
\r
412 startPXSAcquisition();
\r
413 goodEPCC = 0; // Reset the goodEPCC variable
\r
416 for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
\r
418 if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch))
\r
420 currentEPCC = PXS->RXEPCCSELR[idx_ch]; //this affectation allow to avoid computation of the structure address
\r
421 if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > (TSLPRM_KEY_TARGET_REFERENCE + TSLPRM_KEY_TARGET_REFERENCE_ERROR)))
\r
423 if (currentEPCC > 0)
\r
425 if ((currentEPCC & 0x07) != 0)
\r
431 currentEPCC -= 3; // This is due to the non linearity of the EPCC
\r
435 else if (PXS->RXCNTR[idx_ch] < (TSLPRM_KEY_TARGET_REFERENCE - TSLPRM_KEY_TARGET_REFERENCE_ERROR))
\r
437 if (currentEPCC < 0xFF)
\r
439 if ((currentEPCC & 0x07) != 0x07)
\r
445 currentEPCC += 2; // This is due to the non linearity of the EPCC
\r
448 else // Invert the change in case the sorting is not reliable
\r
457 PXS->RXEPCCSELR[idx_ch] = currentEPCC;
\r
462 while ((goodEPCC < EPCCtoCompute) && (trial));
\r
464 // Restore configuration
\r
465 #if TSLPRM_ACQ_MAX > 0
\r
466 PXS->MAXR = TSLPRM_ACQ_MAX;
\r
471 WFE->CR1 &= (uint8_t)~WFE_CR1_PXS_EV;
\r
472 #if TSLPRM_USE_ACQ_INTERRUPT == 0
\r
473 disablePXSInterrupts(PXS_CR2_EOCITEN);
\r
477 for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++)
\r
479 PXS_BankConfig[idx_bk].EPCCSEL[idx_ch] = PXS->RXEPCCSELR[idx_ch];
\r
482 return((int8_t)(EPCCtoCompute - goodEPCC));
\r
486 #if TSLPRM_USE_ZONE > 0
\r
488 * @brief Calibrate the EPCC for a set of acquisition banks.
\r
489 * @param[in] zone Set of banks to calibrate the EPCC
\r
492 TSL_Status_enum_T TSL_PXS_EPCC_CalibrateZone(CONST TSL_Zone_T *zone)
\r
495 TSL_Status_enum_T retval = TSL_STATUS_OK;
\r
496 for (idx_bk = 0; idx_bk < zone->NbBanks; idx_bk++)
\r
498 if (TSL_PXS_EPCC_CalibrateBank(zone->BankIndex[idx_bk]) > 0)
\r
500 retval = TSL_STATUS_ERROR;
\r
509 * @brief Test the reference and update the EPCC/CS if needed
\r
510 * @param[in] pCh pointer on the channel data information
\r
513 TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh)
\r
515 uint16_t reference, target_error = 0;
\r
516 TSL_Bool_enum_T result = TSL_FALSE;
\r
518 if (pCh->Flags.EPCCStatus != TSL_EPCC_STATUS_LOCKED)
\r
520 reference = pCh->Ref;
\r
521 #if TSLPRM_TOTAL_TKEYS > 0
\r
522 if (TSL_Globals.This_Obj->Type & TSL_OBJ_TYPE_TKEY_MASK)
\r
524 target_error = TSLPRM_TOUCHKEY_REFERENCE_RANGE;
\r
528 #if TSLPRM_TOTAL_LNRTS > 0
\r
529 if (TSL_Globals.This_Obj->Type & TSL_OBJ_TYPE_LINROT_MASK)
\r
531 target_error = TSLPRM_LINROT_REFERENCE_RANGE;
\r
534 if ((reference != 0) && ((reference > (TSLPRM_KEY_TARGET_REFERENCE + target_error)) || (reference < (TSLPRM_KEY_TARGET_REFERENCE - target_error))))
\r
536 if (reference < (TSLPRM_KEY_TARGET_REFERENCE - target_error))
\r
538 pCh->Flags.EPCCStatus = TSL_EPCC_STATUS_INCREASE;
\r
540 else if (reference > (TSLPRM_KEY_TARGET_REFERENCE + target_error))
\r
542 pCh->Flags.EPCCStatus = TSL_EPCC_STATUS_DECREASE;
\r
546 // Do nothing (MISRA requirement)
\r
555 * @brief Test if the measure has crossed the reference target
\r
556 * @param[in] pCh Pointer to the channel Data under test
\r
557 * @param[in] new_meas Measure of the last acquisition on this channel
\r
558 * @retval Result Result of the test
\r
560 TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas)
\r
562 TSL_Bool_enum_T result = TSL_TRUE;
\r
563 TSL_EPCCStatus_enum_T EPCCStatus;
\r
565 EPCCStatus = pCh->Flags.EPCCStatus;
\r
566 if (EPCCStatus & TSL_EPCC_CHANGE_MASK)
\r
568 // If the previous reference and the new one are on each side of the reference target
\r
569 // the EPCC is no more tested and the calibration continues.
\r
570 if (((EPCCStatus == TSL_EPCC_STATUS_INCREASE) && (new_meas >= TSLPRM_KEY_TARGET_REFERENCE))
\r
571 || ((EPCCStatus == TSL_EPCC_STATUS_DECREASE) && (new_meas <= TSLPRM_KEY_TARGET_REFERENCE)))
\r
573 pCh->Flags.EPCCStatus = TSL_EPCC_STATUS_UNLOCKED;
\r
577 result = TSL_FALSE;
\r
586 * @brief Increase or decrease the CS value
\r
587 * @param[in] pCSSEL Address of the CS to be modified
\r
588 * @param[in] change Define if the Cs must be increased or decreased
\r
591 void TSL_acq_UpdateCS(uint8_t *pCSSEL, TSL_EPCCStatus_enum_T change)
\r
595 assert_param(IS_EPCC_STATUS_OK(change));
\r
596 assert_param(IS_CSSEL_OK(*pCSSEL));
\r
598 if (*pCSSEL > CS_MIDDLE_VALUE)
\r
600 indexCS = (CS_MIDDLE_VALUE - 1);
\r
606 while ((PXS_CSsorting[indexCS] != *pCSSEL) && (indexCS < CS_MAX_VALUE))
\r
610 if (change == TSL_EPCC_STATUS_INCREASE)
\r
612 *pCSSEL = PXS_CSsorting[indexCS + 1];
\r
616 *pCSSEL = PXS_CSsorting[indexCS - 1];
\r
622 * @brief Configures a Bank.
\r
623 * @param[in] idx_bk Index of the Bank to configure
\r
626 TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk)
\r
628 TSL_Status_enum_T retval = TSL_STATUS_OK;
\r
630 TSL_ChannelFlags_T flags;
\r
631 CONST TSL_Bank_T *bank = &(TSL_Globals.Bank_Array[idx_bk]);
\r
632 CONST TSL_ChannelSrc_T *pchSrc = bank->p_chSrc;
\r
633 CONST TSL_ChannelDest_T *pchDest = bank->p_chDest;
\r
634 TSL_tMaskRX enabledRX = 0;
\r
635 uint8_t *pEPCCSEL, *pCSSEL;
\r
637 // Check parameters (if USE_FULL_ASSERT is defined)
\r
638 assert_param(IS_BANK_INDEX_OK(idx_bk));
\r
640 TSL_Globals.This_Bank = idx_bk;
\r
642 selectPXSRxGroup(bank->msk_group);
\r
643 for (idx_ch = 0;idx_ch < bank->NbChannels;idx_ch++)
\r
645 flags = bank->p_chData[pchDest->IdxDest].Flags;
\r
646 if (flags.ObjStatus == TSL_OBJ_STATUS_ON)
\r
648 enabledRX |= (1 << pchSrc->IdxSrc);
\r
649 if (flags.EPCCStatus & TSL_EPCC_CHANGE_MASK)
\r
651 pEPCCSEL = &PXS_BankConfig[idx_bk].EPCCSEL[pchSrc->IdxSrc];
\r
652 if (flags.EPCCStatus == TSL_EPCC_STATUS_INCREASE)
\r
654 if ((*pEPCCSEL) < 0xFF)
\r
656 if (((*pEPCCSEL) & 0x07) != 0x07)
\r
662 if ((*pEPCCSEL) < 0xFE)
\r
664 (*pEPCCSEL) += 2; // This is due to the non linearity of the PCC
\r
675 pCSSEL = &PXS_BankConfig[idx_bk].CSSEL[pchSrc->IdxSrc];
\r
676 if (*pCSSEL < 0x1F)
\r
678 TSL_acq_UpdateCS(pCSSEL, TSL_EPCC_STATUS_INCREASE);
\r
686 if ((*pEPCCSEL) > 0)
\r
688 if (((*pEPCCSEL) & 0x07) != 0)
\r
694 if ((*pEPCCSEL) > 3)
\r
696 (*pEPCCSEL) -= 3; // This is due to the non linearity of the PCC
\r
706 pCSSEL = &PXS_BankConfig[idx_bk].CSSEL[pchSrc->IdxSrc];
\r
709 TSL_acq_UpdateCS(pCSSEL, TSL_EPCC_STATUS_DECREASE);
\r
723 // The two following loops are more efficient than the two instructions in the same loop
\r
724 for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++)
\r
726 PXS->RXCSSELR[idx_ch] = PXS_BankConfig[idx_bk].CSSEL[idx_ch];
\r
728 for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++)
\r
730 PXS->RXEPCCSELR[idx_ch] = PXS_BankConfig[idx_bk].EPCCSEL[idx_ch];
\r
733 PXS->TXENR = bank->msk_TX; // Enable the Tx selected (if any)
\r
734 PXS->RXCR1 = bank->msk_channels; // Configure the Rx and the Tx function modes
\r
736 // Enable the Rx which are not disabled including the potential Rx configured as Tx
\r
737 PXS->RXENR = bank->msk_RXEN & ((uint16_t)(~bank->msk_channels) | enabledRX);
\r
739 if (enabledRX == 0)
\r
741 retval = TSL_STATUS_ERROR;
\r
750 * @brief Test if EPCC are changing
\r
751 * @param[in] pCh Channel to be processed
\r
752 * @retval bool Test result
\r
754 TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh)
\r
756 if (pCh->Flags.EPCCStatus & TSL_EPCC_CHANGE_MASK)
\r
758 return (TSL_FALSE);
\r
768 * @brief Start acquisition on a previously configured bank
\r
772 void TSL_acq_BankStartAcq(void)
\r
774 // Start acquisition
\r
775 startPXSAcquisition();
\r
780 * @brief Wait end of acquisition
\r
784 TSL_Status_enum_T TSL_acq_BankWaitEOC(void)
\r
786 TSL_Status_enum_T retval = TSL_STATUS_BUSY;
\r
788 if (checkPXSInterruptStatusFlag(PXS_ISR_EOCF)) // Check EOC flag
\r
790 if (PXS->RXSR != TSL_Globals.Bank_Array[TSL_Globals.This_Bank].msk_channels) // Check MCE flag
\r
792 retval = TSL_STATUS_ERROR;
\r
796 retval = TSL_STATUS_OK;
\r
805 * @brief Check noise detection
\r
809 TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void)
\r
811 TSL_AcqStatus_enum_T retval = TSL_ACQ_STATUS_OK;
\r
812 #if TSLPRM_PXS_RF_DETECTION > 0
\r
813 if (checkPXSInterruptStatusFlag(PXS_ISR_NOISEDETF) == PXS_ISR_NOISEDETF)
\r
815 retval = TSL_ACQ_STATUS_NOISE;
\r
823 * @brief Return the current measure
\r
824 * @param[in] index Index of the measure source
\r
827 TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndexSrc_T index)
\r
829 uint16_t CurrentReceiver;
\r
831 // Check parameters (if USE_FULL_ASSERT is defined)
\r
832 assert_param(IS_SOURCE_INDEX_OK(index));
\r
834 CurrentReceiver = (uint16_t)(((uint16_t)1) << index);
\r
836 if (PXS->RXSR & CurrentReceiver)
\r
838 return(PXS->RXCNTR[index]);
\r
842 return(MAX_MEASURE);
\r
848 * @brief Process the PXS Interrupt routine
\r
852 INTERRUPT_HANDLER(TSL_acq_ProcessIT, 2)
\r
856 TSL_acq_BankGetResult(TSL_Globals.This_Bank, 0, 0); // No noise filter
\r
858 #if TSLPRM_USE_ZONE > 0
\r
859 if ((TSL_Globals.This_Zone == 0) || (TSL_Globals.Index_In_This_Zone >= TSL_Globals.This_Zone->NbBanks))
\r
861 CFG->GCR &= (uint8_t)(~CFG_GCR_AL); // Reset Activation level to resume main processing
\r
862 PXS->RXENR = 0; // To reduce consumption
\r
863 PXS->TXENR = 0; // To reduce consumption
\r
864 TSL_Globals.This_Bank = 0;
\r
868 if (TSL_acq_ZoneConfig(TSL_Globals.This_Zone, TSL_Globals.Index_In_This_Zone) != TSL_STATUS_ERROR)
\r
870 // Start Bank acquisition
\r
871 TSL_acq_BankStartAcq();
\r
872 #if TSLPRM_PXS_LOW_POWER_MODE > 0
\r
873 if (TSL_Globals.Index_In_This_Zone >= TSL_Globals.This_Zone->NbBanks)
\r
882 CFG->GCR &= (uint8_t)(~CFG_GCR_AL); // Reset Activation level to resume main processing
\r
883 PXS->RXENR = 0; // To reduce consumption
\r
884 PXS->TXENR = 0; // To reduce consumption
\r
889 #ifdef __IAR_SYSTEMS_ICC__
\r
890 #pragma optimize=low
\r
891 #elif defined (__CC_ARM)
\r
896 * @brief Software delay (private routine)
\r
897 * @param val Wait delay
\r
900 void SoftDelay(uint32_t val)
\r
903 for (i = val; i > 0; i--)
\r
907 /******************* (C) COPYRIGHT 2013 STMicroelectronics *****END OF FILE****/
\r