/** ****************************************************************************** * @file tsl_acq_stm32l1xx_sw.c * @author MCD Application Team * @version V1.4.4 * @date 31-March-2014 * @brief This file contains all functions to manage the acquisition * on STM32l1xx products using the software mode. ****************************************************************************** * @attention * *

© COPYRIGHT 2014 STMicroelectronics

* * 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_stm32l1xx_sw.h" #include "tsl_globals.h" /* Private typedefs ----------------------------------------------------------*/ // Register configuration typedef struct { unsigned int RI_ASCR : 3; unsigned int RI_ASCR_bit : 5; } TSL_RIConf_t; /* Private defines -----------------------------------------------------------*/ #define SIZEOFBANKCONF (17) //2 mask RIRs + 5 ports x 3 mask registers(MODER input, output, ODR) => 17 registers /* Private macros ------------------------------------------------------------*/ #define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS))) #define TSL_CHANNEL_PORT(channel) (channel >> 4) #define TSL_CHANNEL_IO(channel) (channel & 0x0F) #define TSL_RI_HYSCR_MASK(channel) (1 << TSL_CHANNEL_IO(channel)) #define TSL_RCC_AHBENR_Config(channel) (RCC->AHBENR |= TSL_GPIO_Clock_LookUpTable[TSL_CHANNEL_PORT(channel)]) #define TSL_RI_HYSCR_Config(channel) (*TSL_RI_HYSCR_LookUpTable[TSL_CHANNEL_PORT(channel)] |= TSL_RI_HYSCR_MASK(channel)) #define TSL_GPIO_MODER_IN_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->MODER &= (uint32_t)(~(3 << (2 * TSL_CHANNEL_IO(channel))))) #define TSL_GPIO_MODER_OUT_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->MODER = (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->MODER & (uint32_t)(~(3 << (2 * TSL_CHANNEL_IO(channel))))) | (1 << (2 * TSL_CHANNEL_IO(channel)))) #define TSL_GPIO_PUPDR_NO_PUPD_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->PUPDR &= (uint32_t)(~(3 << (2 * TSL_CHANNEL_IO(channel))))) #define TSL_GPIO_OTYPER_PP_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->OTYPER &= (uint32_t)(~(1 << TSL_CHANNEL_IO(channel)))) #define TSL_GPIO_OSPEEDR_VL_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->OSPEEDR &= (uint32_t)~(3 << (2 * TSL_CHANNEL_IO(channel)))) #define TSL_GPIO_BS_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->BSRRL = (uint16_t)(1 << (TSL_CHANNEL_IO(channel)))) #define TSL_GPIO_BR_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->BSRRH = (uint16_t)(1 << (TSL_CHANNEL_IO(channel)))) /* Private variables ---------------------------------------------------------*/ uint32_t TSL_BankSampleConf[SIZEOFBANKCONF]; uint32_t TSL_BankChannelConf[SIZEOFBANKCONF]; uint32_t tab_MeasurementCounter[11]; extern TSL_Params_T TSL_Params; CONST TSL_Bank_T *bank; TSL_tIndex_T NumberOfChannelOn = 0; TSL_tNb_T NumberOfChannels = 0; TSL_Status_enum_T TSL_Acq_Status = TSL_STATUS_BUSY; uint16_t GroupToCheck = 0; uint32_t TSL_GPIO_Clock_LookUpTable[] = {RCC_AHBPeriph_GPIOA, RCC_AHBPeriph_GPIOB, RCC_AHBPeriph_GPIOC, RCC_AHBPeriph_GPIOD, RCC_AHBPeriph_GPIOE, RCC_AHBPeriph_GPIOF, RCC_AHBPeriph_GPIOG, RCC_AHBPeriph_GPIOH}; GPIO_TypeDef *TSL_GPIO_LookUpTable[] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH}; uint16_t *TSL_RI_HYSCR_LookUpTable[] = { (uint16_t *)&RI->HYSCR1, (uint16_t *)&RI->HYSCR1 + 1, (uint16_t *)&RI->HYSCR2, (uint16_t *)&RI->HYSCR2 + 1, (uint16_t *)&RI->HYSCR3, (uint16_t *)&RI->HYSCR3 + 1, (uint16_t *)&RI->HYSCR4, (uint16_t *)&RI->HYSCR4 + 1 }; CONST TSL_RIConf_t TSL_RI_Conf_LookUpTable[101] = { {0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 0},//padding {0, 0},//padding {0, 6}, {0, 7}, {1, 9}, {1, 10}, {1, 11}, {1, 15}, {0, 0},//padding {1, 6}, {1, 7}, {1, 8}, {0, 8}, {0, 9}, {1, 16}, {0, 0},//padding {1, 4}, {1, 5}, {1, 27}, {1, 28}, {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 18}, {0, 19}, {0, 20}, {0, 21}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {0, 15}, {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 29}, {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 0},//padding {0, 27}, {0, 28}, {0, 29}, {0, 30}, {0, 16}, {1, 17}, {1, 18}, {1, 19}, {1, 20}, {1, 21}, {1, 22}, {1, 23}, {1, 24}, {1, 25}, {1, 26} }; #if (TSLPRM_USE_GPIOA) uint32_t GPIOA_IDR_Mask = 0; #endif #if (TSLPRM_USE_GPIOB) uint32_t GPIOB_IDR_Mask = 0; #endif #if (TSLPRM_USE_GPIOC) uint32_t GPIOC_IDR_Mask = 0; #endif #if (TSLPRM_USE_GPIOF) uint32_t GPIOF_IDR_Mask = 0; #endif #if (TSLPRM_USE_GPIOG) uint32_t GPIOG_IDR_Mask = 0; #endif #if (TSLPRM_USE_SPREAD_SPECTRUM > 0) uint8_t SpreadCounter = TSLPRM_SPREAD_MIN; #endif /* Private functions prototype -----------------------------------------------*/ void SoftDelay(uint16_t val); #if (TSLPRM_USE_SPREAD_SPECTRUM > 0) __INLINE void SwSpreadSpectrum(void); #endif void TSL_BankConf(uint32_t * BankConf, TSL_Conf_t Conf); void TSL_acq_GroupDone(uint16_t EndedGroup); /** * @brief Configures the acquisition module. * @param[in] BankConf Pointer to the bank to configure * @param[in] Conf Configuration * @retval None */ void TSL_BankConf(uint32_t *BankConf, TSL_Conf_t Conf) { BankConf[TSL_RI_Conf_LookUpTable[Conf].RI_ASCR] |= (1 << (TSL_RI_Conf_LookUpTable[Conf].RI_ASCR_bit)); switch (TSL_CHANNEL_PORT(Conf)) { case TSL_BANK_GPIOA: BankConf[2] |= (3 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER input BankConf[3] |= (1 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER output BankConf[4] |= (1 << (TSL_CHANNEL_IO(Conf))); //ODR break; case TSL_BANK_GPIOB: BankConf[5] |= (3 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER input BankConf[6] |= (1 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER output BankConf[7] |= (1 << (TSL_CHANNEL_IO(Conf))); //ODR break; case TSL_BANK_GPIOC: BankConf[8] |= (3 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER input BankConf[9] |= (1 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER output BankConf[10] |= (1 << (TSL_CHANNEL_IO(Conf))); //ODR break; case TSL_BANK_GPIOF: BankConf[11] |= (3 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER input BankConf[12] |= (1 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER output BankConf[13] |= (1 << (TSL_CHANNEL_IO(Conf))); //ODR break; case TSL_BANK_GPIOG: BankConf[14] |= (3 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER input BankConf[15] |= (1 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER output BankConf[16] |= (1 << (TSL_CHANNEL_IO(Conf))); //ODR break; default: break; } } /** * @brief Initializes the acquisition module. * @param None * @retval None */ TSL_Status_enum_T TSL_acq_Init(void) { CONST TSL_Bank_T *LocalBank = &(TSL_Globals.Bank_Array[0]); TSL_tNb_T NumberOfBanks = TSLPRM_TOTAL_BANKS; TSL_tNb_T LocalNumberOfChannels = 0; TSL_tIndex_T idx_bk; TSL_tIndex_T idx_ch; CONST TSL_ChannelSrc_T *p_chSrc = LocalBank->p_chSrc; // Pointer to the current channel /* Enables the comparator interface clock */ RCC->APB1ENR |= RCC_APB1Periph_COMP; //==================== // GPIOs configuration //==================== for (idx_bk = 0; idx_bk < NumberOfBanks; idx_bk++) { LocalBank = &(TSL_Globals.Bank_Array[idx_bk]); p_chSrc = LocalBank->p_chSrc; #if (TSLPRM_USE_SHIELD > 0) // Enables GPIOs clock TSL_RCC_AHBENR_Config(LocalBank->shield_sample); // Bank shield configuration /* Disables Hysteresis Register */ TSL_RI_HYSCR_Config(LocalBank->shield_sample); /* Output PP config */ TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_sample); TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_channel); /* 400kHz config */ TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_sample); TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_channel); /* No pull up/pull down config */ TSL_GPIO_PUPDR_NO_PUPD_Config(LocalBank->shield_sample); TSL_GPIO_PUPDR_NO_PUPD_Config(LocalBank->shield_channel); /* Set ODR */ TSL_GPIO_BR_Config(LocalBank->shield_sample); TSL_GPIO_BR_Config(LocalBank->shield_channel); /* Output mode */ TSL_GPIO_MODER_OUT_Config(LocalBank->shield_sample); TSL_GPIO_MODER_OUT_Config(LocalBank->shield_channel); #endif LocalNumberOfChannels = LocalBank->NbChannels; for (idx_ch = 0; idx_ch < LocalNumberOfChannels; idx_ch++) { /* Enables GPIOs clock */ TSL_RCC_AHBENR_Config(p_chSrc->t_sample); TSL_RCC_AHBENR_Config(p_chSrc->t_channel); // Bank/channel configuration /* Disables Hysteresis Register */ TSL_RI_HYSCR_Config(p_chSrc->t_sample); /* Output PP config */ TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_sample); TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_channel); /* 400kHz config */ TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_sample); TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_channel); /* No pull up/pull down config */ TSL_GPIO_PUPDR_NO_PUPD_Config(p_chSrc->t_sample); TSL_GPIO_PUPDR_NO_PUPD_Config(p_chSrc->t_channel); /* Set ODR */ TSL_GPIO_BR_Config(p_chSrc->t_sample); TSL_GPIO_BR_Config(p_chSrc->t_channel); /* Output mode */ TSL_GPIO_MODER_OUT_Config(p_chSrc->t_sample); TSL_GPIO_MODER_OUT_Config(p_chSrc->t_channel); p_chSrc++; } } /* Enable RI Switch */ RI->ASCR1 &= (uint32_t)(~0x80000000); // ADC analog switches open !!! return TSL_STATUS_OK; } /** * @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_tIndex_T index; TSL_tIndex_T idx_dest; TSL_tIndex_T idx_ch; CONST TSL_ChannelDest_T *p_chDest; // Pointer to the current channel CONST TSL_ChannelSrc_T *p_chSrc; // Pointer to the current channel // Check parameters (if USE_FULL_ASSERT is defined) assert_param(IS_BANK_INDEX_OK(idx_bk)); bank = &(TSL_Globals.Bank_Array[idx_bk]); for (index = 0;index < SIZEOFBANKCONF;index++) { TSL_BankSampleConf[index] = 0x00000000; TSL_BankChannelConf[index] = 0x00000000; } NumberOfChannels = bank->NbChannels; NumberOfChannelOn = 0; GroupToCheck = 0;//init group to check p_chDest = bank->p_chDest; p_chSrc = bank->p_chSrc; for (idx_ch = 0; idx_ch < NumberOfChannels; idx_ch++) { // Get index in the result array associated to the current channel idx_dest = p_chDest->IdxDest; if (bank->p_chData[idx_dest].Flags.ObjStatus != TSL_OBJ_STATUS_OFF) { TSL_BankConf(TSL_BankSampleConf, p_chSrc->t_sample); TSL_BankConf(TSL_BankChannelConf, p_chSrc->t_channel); GroupToCheck |= (1 << (p_chSrc->IdxSrc)); NumberOfChannelOn++; } p_chSrc++; p_chDest++; } #if (TSLPRM_USE_GPIOA) GPIOA_IDR_Mask = TSL_BankSampleConf[4]; #endif #if (TSLPRM_USE_GPIOB) GPIOB_IDR_Mask = TSL_BankSampleConf[7]; #endif #if (TSLPRM_USE_GPIOC) GPIOC_IDR_Mask = TSL_BankSampleConf[10]; #endif #if (TSLPRM_USE_GPIOF) GPIOF_IDR_Mask = TSL_BankSampleConf[13]; #endif #if (TSLPRM_USE_GPIOG) GPIOG_IDR_Mask = TSL_BankSampleConf[16]; #endif #if (TSLPRM_USE_SHIELD > 0) if (NumberOfChannelOn != 0) { TSL_BankConf(TSL_BankSampleConf, bank->shield_sample); TSL_BankConf(TSL_BankChannelConf, bank->shield_channel); } #endif return TSL_STATUS_OK; } /** * @brief Check which group is not over * @param[in] EndedGroup * @retval None */ void TSL_acq_GroupDone(uint16_t EndedGroup) { uint16_t i; for (i = 0;i < 11;i++) { if ((EndedGroup & (1 << i)) != (1 << i)) { tab_MeasurementCounter[i] = TSL_Params.AcqMax + 1; } } } /** * @brief Start acquisition on a previously configured bank * @param None * @retval None */ void TSL_acq_BankStartAcq(void) { CONST TSL_Bank_T *LocalBank = &(TSL_Globals.Bank_Array[0]); TSL_tNb_T NumberOfBanks = TSLPRM_TOTAL_BANKS; TSL_tNb_T LocalNumberOfChannels = 0; TSL_tIndex_T BankIndex; uint16_t MeasurementCounter = 0; CONST TSL_ChannelSrc_T *p_chSrc; TSL_tIndex_T idx_ch; uint16_t GroupToCheckMask = 0; uint32_t GPIO_IDR_Mask = 0; uint8_t Check_Input = 0; #if (TSLPRM_USE_GPIOA) uint16_t TSL_GPIOA_IDR = 0; #endif #if (TSLPRM_USE_GPIOB) uint16_t TSL_GPIOB_IDR = 0; #endif #if (TSLPRM_USE_GPIOC) uint16_t TSL_GPIOC_IDR = 0; #endif #if (TSLPRM_USE_GPIOF) uint16_t TSL_GPIOF_IDR = 0; #endif #if (TSLPRM_USE_GPIOG) uint16_t TSL_GPIOG_IDR = 0; #endif uint16_t GPIO_IDR = 0; #if (TSLPRM_PROTECT_IO_ACCESS > 0) __disable_irq(); #endif #if (TSLPRM_IODEF > 0) //============================ // All GPIOs in Input floating //============================ for (BankIndex = 0; BankIndex < NumberOfBanks; BankIndex++) { LocalBank = &(TSL_Globals.Bank_Array[BankIndex]); p_chSrc = LocalBank->p_chSrc; #if (TSLPRM_USE_SHIELD > 0) TSL_GPIO_MODER_IN_Config(LocalBank->shield_sample); TSL_GPIO_MODER_IN_Config(LocalBank->shield_channel); #endif LocalNumberOfChannels = LocalBank->NbChannels; for (idx_ch = 0; idx_ch < LocalNumberOfChannels; idx_ch++) { TSL_GPIO_MODER_IN_Config(p_chSrc->t_sample); TSL_GPIO_MODER_IN_Config(p_chSrc->t_channel); p_chSrc++; } } #endif #if (TSLPRM_PROTECT_IO_ACCESS > 0) __enable_irq(); #endif /* Open the analog switches */ RI->ASCR1 &= (uint32_t)(~(TSL_BankSampleConf[0] | TSL_BankChannelConf[0])); RI->ASCR2 &= (uint32_t)(~(TSL_BankSampleConf[1] | TSL_BankChannelConf[1])); /* All IO to pushpull LOW for discharging all capacitors (Ctouch and Csense) */ #if (TSLPRM_PROTECT_IO_ACCESS > 0) __disable_irq(); #endif /* Discharging sampling capacitor and CTouch */ #if (TSLPRM_USE_GPIOA) GPIOA->ODR &= (uint32_t)(~(TSL_BankSampleConf[4] | TSL_BankChannelConf[4])); GPIOA->MODER = (GPIOA->MODER & (uint32_t)(~(TSL_BankSampleConf[2] | TSL_BankChannelConf[2]))) | (TSL_BankSampleConf[3] | TSL_BankChannelConf[3]); #endif #if (TSLPRM_USE_GPIOB) GPIOB->ODR &= (uint32_t)(~(TSL_BankSampleConf[7] | TSL_BankChannelConf[7])); GPIOB->MODER = (GPIOB->MODER & (uint32_t)(~(TSL_BankSampleConf[5] | TSL_BankChannelConf[5]))) | (TSL_BankSampleConf[6] | TSL_BankChannelConf[6]); #endif #if (TSLPRM_USE_GPIOC) GPIOC->ODR &= (uint32_t)(~(TSL_BankSampleConf[10] | TSL_BankChannelConf[10])); GPIOC->MODER = (GPIOC->MODER & (uint32_t)(~(TSL_BankSampleConf[8] | TSL_BankChannelConf[8]))) | (TSL_BankSampleConf[9] | TSL_BankChannelConf[9]); #endif #if (TSLPRM_USE_GPIOF) GPIOF->ODR &= (uint32_t)(~(TSL_BankSampleConf[13] | TSL_BankChannelConf[13])); GPIOF->MODER = (GPIOF->MODER & (uint32_t)(~(TSL_BankSampleConf[11] | TSL_BankChannelConf[11]))) | (TSL_BankSampleConf[12] | TSL_BankChannelConf[12]); #endif #if (TSLPRM_USE_GPIOG) GPIOG->ODR &= (uint32_t)(~(TSL_BankSampleConf[16] | TSL_BankChannelConf[16])); GPIOG->MODER = (GPIOG->MODER & (uint32_t)(~(TSL_BankSampleConf[14] | TSL_BankChannelConf[14]))) | (TSL_BankSampleConf[15] | TSL_BankChannelConf[15]); #endif #if (TSLPRM_PROTECT_IO_ACCESS > 0) __enable_irq(); #endif /* Wait a while for a good discharging of all capacitors */ SoftDelay(50); // ~14µs with fHCLK = 32MHz //this time depends of the size of the sampling capacitor #if (TSLPRM_PROTECT_IO_ACCESS > 0) __disable_irq(); #endif /* All IO in input floating */ #if (TSLPRM_USE_GPIOA) GPIOA->MODER &= (uint32_t)(~(TSL_BankSampleConf[2] | TSL_BankChannelConf[2])); #endif #if (TSLPRM_USE_GPIOB) GPIOB->MODER &= (uint32_t)(~(TSL_BankSampleConf[5] | TSL_BankChannelConf[5])); #endif #if (TSLPRM_USE_GPIOC) GPIOC->MODER &= (uint32_t)(~(TSL_BankSampleConf[8] | TSL_BankChannelConf[8])); #endif #if (TSLPRM_USE_GPIOF) GPIOF->MODER &= (uint32_t)(~(TSL_BankSampleConf[11] | TSL_BankChannelConf[11])); #endif #if (TSLPRM_USE_GPIOG) GPIOG->MODER &= (uint32_t)(~(TSL_BankSampleConf[14] | TSL_BankChannelConf[14])); #endif /* set the IO to Vdd (io in push-pull HIGH when in output mode) */ #if (TSLPRM_USE_GPIOA) GPIOA->ODR |= (TSL_BankSampleConf[4] | TSL_BankChannelConf[4]); /* HIGH level */ #endif #if (TSLPRM_USE_GPIOB) GPIOB->ODR |= (TSL_BankSampleConf[7] | TSL_BankChannelConf[7]); /* HIGH level */ #endif #if (TSLPRM_USE_GPIOC) GPIOC->ODR |= (TSL_BankSampleConf[10] | TSL_BankChannelConf[10]); /* HIGH level */ #endif #if (TSLPRM_USE_GPIOF) GPIOF->ODR |= (TSL_BankSampleConf[13] | TSL_BankChannelConf[13]); /* HIGH level */ #endif #if (TSLPRM_USE_GPIOG) GPIOG->ODR |= (TSL_BankSampleConf[16] | TSL_BankChannelConf[16]); /* HIGH level */ #endif #if (TSLPRM_PROTECT_IO_ACCESS > 0) __enable_irq(); #endif /* Close the sampling capacitor analog switch */ RI->ASCR1 |= (TSL_BankSampleConf[0]); RI->ASCR2 |= (TSL_BankSampleConf[1]); /* Loop while all the 1st channel of each group have not reach the VIH level */ do { #if (TSLPRM_PROTECT_IO_ACCESS > 0) __disable_irq(); #endif /* Charging Ctouch by connecting the IO to Vdd (io in push-pull HIGH) */ #if (TSLPRM_USE_GPIOA) GPIOA->MODER |= (TSL_BankChannelConf[3]); /* Output push pull config */ #endif #if (TSLPRM_USE_GPIOB) GPIOB->MODER |= (TSL_BankChannelConf[6]); /* Output push pull config */ #endif #if (TSLPRM_USE_GPIOC) GPIOC->MODER |= (TSL_BankChannelConf[9]); /* Output push pull config */ #endif #if (TSLPRM_USE_GPIOF) GPIOF->MODER |= (TSL_BankChannelConf[12]); /* Output push pull config */ #endif #if (TSLPRM_USE_GPIOG) GPIOG->MODER |= (TSL_BankChannelConf[15]); /* Output push pull config */ #endif #if (TSLPRM_PROTECT_IO_ACCESS > 0) __enable_irq(); #endif /* Wait a while for a good charging (programmable delay) */ #if ( TSLPRM_DELAY_TRANSFER > 0 ) SoftDelay(TSLPRM_DELAY_TRANSFER); #endif /* Spread Spectrum */ #if (TSLPRM_USE_SPREAD_SPECTRUM > 0) SwSpreadSpectrum(); #endif /* test GPIOx->IDR bit + group configuration for each channel */ #if (TSLPRM_USE_GPIOA) TSL_GPIOA_IDR = GPIOA->IDR; if ((TSL_GPIOA_IDR & GPIOA_IDR_Mask) != 0) { Check_Input = 1; GPIOA_IDR_Mask &= (uint32_t)(~TSL_GPIOA_IDR); } #endif #if (TSLPRM_USE_GPIOB) TSL_GPIOB_IDR = GPIOB->IDR; if ((TSL_GPIOB_IDR & GPIOB_IDR_Mask) != 0) { Check_Input = (1 << 1); GPIOB_IDR_Mask &= (uint32_t)(~TSL_GPIOB_IDR); } #endif #if (TSLPRM_USE_GPIOC) TSL_GPIOC_IDR = GPIOC->IDR; if ((TSL_GPIOC_IDR & GPIOC_IDR_Mask) != 0) { Check_Input = (1 << 2); GPIOC_IDR_Mask &= (uint32_t)(~TSL_GPIOC_IDR); } #endif #if (TSLPRM_USE_GPIOF) TSL_GPIOF_IDR = GPIOF->IDR; if ((TSL_GPIOF_IDR & GPIOF_IDR_Mask) != 0) { Check_Input = (1 << 5); GPIOF_IDR_Mask &= (uint32_t)(~TSL_GPIOF_IDR); } #endif #if (TSLPRM_USE_GPIOG) TSL_GPIOG_IDR = GPIOG->IDR; if ((TSL_GPIOG_IDR & GPIOG_IDR_Mask) != 0) { Check_Input = (1 << 6); GPIOG_IDR_Mask &= (uint32_t)(~TSL_GPIOG_IDR); } #endif if (Check_Input) { p_chSrc = bank->p_chSrc; for (idx_ch = 0; idx_ch < NumberOfChannels; idx_ch++) { GroupToCheckMask = (1 << (p_chSrc->IdxSrc)); if ((GroupToCheck & GroupToCheckMask) == (GroupToCheckMask)) { GPIO_IDR_Mask = (1 << TSL_CHANNEL_IO(p_chSrc->t_sample)); switch (TSL_CHANNEL_PORT(p_chSrc->t_sample)) { #if (TSLPRM_USE_GPIOA) case 0: GPIO_IDR = TSL_GPIOA_IDR; break; #endif #if (TSLPRM_USE_GPIOB) case 1: GPIO_IDR = TSL_GPIOB_IDR; break; #endif #if (TSLPRM_USE_GPIOC) case 2: GPIO_IDR = TSL_GPIOC_IDR; break; #endif #if (TSLPRM_USE_GPIOF) case 5: GPIO_IDR = TSL_GPIOF_IDR; break; #endif #if (TSLPRM_USE_GPIOG) case 6: GPIO_IDR = TSL_GPIOG_IDR; break; #endif default: break; } if ((GPIO_IDR & GPIO_IDR_Mask) == GPIO_IDR_Mask) { tab_MeasurementCounter[p_chSrc->IdxSrc] = MeasurementCounter; GroupToCheck &= (uint32_t)(~(1 << (p_chSrc->IdxSrc))); Check_Input &= (uint32_t)(~(1 << TSL_CHANNEL_PORT(p_chSrc->t_sample))); } } p_chSrc++; } } MeasurementCounter++; #if (TSLPRM_PROTECT_IO_ACCESS > 0) __disable_irq(); #endif /* Configure All channels in input floating */ #if (TSLPRM_USE_GPIOA) GPIOA->MODER &= (uint32_t)(~(TSL_BankChannelConf[2])); #endif #if (TSLPRM_USE_GPIOB) GPIOB->MODER &= (uint32_t)(~(TSL_BankChannelConf[5])); #endif #if (TSLPRM_USE_GPIOC) GPIOC->MODER &= (uint32_t)(~(TSL_BankChannelConf[8])); #endif #if (TSLPRM_USE_GPIOF) GPIOF->MODER &= (uint32_t)(~(TSL_BankChannelConf[11])); #endif #if (TSLPRM_USE_GPIOG) GPIOG->MODER &= (uint32_t)(~(TSL_BankChannelConf[14])); #endif #if (TSLPRM_PROTECT_IO_ACCESS > 0) __enable_irq(); #endif /* Charging the Csense cap with connecting it to Ctouch by closing the analog switch */ RI->ASCR1 |= (TSL_BankChannelConf[0]); RI->ASCR2 |= (TSL_BankChannelConf[1]); /* Wait a while for a good charge transfering (programmable delay) */ #if ( TSLPRM_DELAY_TRANSFER > 0 ) SoftDelay(TSLPRM_DELAY_TRANSFER); #endif RI->ASCR1 &= (uint32_t)(~(TSL_BankChannelConf[0])); RI->ASCR2 &= (uint32_t)(~(TSL_BankChannelConf[1])); /*it's better to implement this like that because it's much more faster than to put this test in the "while test" below */ if (MeasurementCounter > TSL_Params.AcqMax) { TSL_acq_GroupDone(GroupToCheck); __NOP(); break; } } while (GroupToCheck != 0); #if (TSLPRM_PROTECT_IO_ACCESS > 0) __disable_irq(); #endif //==================== // All GPIOs in PP Low //==================== for (BankIndex = 0; BankIndex < NumberOfBanks; BankIndex++) { LocalBank = &(TSL_Globals.Bank_Array[BankIndex]); p_chSrc = LocalBank->p_chSrc; #if (TSLPRM_USE_SHIELD > 0) TSL_GPIO_BR_Config(LocalBank->shield_sample); TSL_GPIO_BR_Config(LocalBank->shield_channel); TSL_GPIO_MODER_OUT_Config(LocalBank->shield_sample); TSL_GPIO_MODER_OUT_Config(LocalBank->shield_channel); #endif LocalNumberOfChannels = LocalBank->NbChannels; for (idx_ch = 0; idx_ch < LocalNumberOfChannels; idx_ch++) { TSL_GPIO_BR_Config(p_chSrc->t_sample); TSL_GPIO_BR_Config(p_chSrc->t_channel); TSL_GPIO_MODER_OUT_Config(p_chSrc->t_sample); TSL_GPIO_MODER_OUT_Config(p_chSrc->t_channel); p_chSrc++; } } #if (TSLPRM_PROTECT_IO_ACCESS > 0) __enable_irq(); #endif } /** * @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; retval = TSL_STATUS_OK; return retval; } /** * @brief Return the current measure * @param[in] index Index of the measure source * @retval Measure */ TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndex_T index) { return(tab_MeasurementCounter[index]); } /** * @brief Check noise (not used) * @param None * @retval Status */ TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void) { return TSL_ACQ_STATUS_OK; } /** * @brief Process the TS Interrupt routine * @param None * @retval None */ void TSL_acq_ProcessIT(void) { } /** * @brief Check if a filter must be used on the current channel (not used) * @param[in] pCh Pointer on the channel data information * @retval Result TRUE if a filter can be applied */ TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh) { return TSL_TRUE; } /** * @brief Compute the Delta value * @param[in] ref Reference value * @param[in] meas Last Measurement value * @retval Delta value */ TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas) { return((TSL_tDelta_T)(ref - meas)); } /** * @brief Compute the Measurement value * @param[in] ref Reference value * @param[in] delta Delta value * @retval Measurement value */ TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta) { return((TSL_tMeas_T)(ref - delta)); } /** * @brief Test if the Reference is incorrect (not used) * @param[in] pCh Pointer on the channel data information * @retval Result TRUE if the Reference is out of range */ TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh) { return TSL_FALSE; } /** * @brief Test if the measure has crossed the reference target (not used) * @param[in] pCh Pointer on the channel data information * @param[in] new_meas Measure of the last acquisition on this channel * @retval Result TRUE if the Reference is valid */ TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas) { return TSL_TRUE; } #if defined(__IAR_SYSTEMS_ICC__) // IAR/EWARM #pragma optimize=medium #elif defined(__CC_ARM) // Keil/MDK-ARM #pragma O1 #pragma Ospace #elif defined(__TASKING__) // Altium/Tasking #pragma optimize O0 #elif defined(__GNUC__) // Atollic/True Studio + Raisonance/RKit #pragma GCC push_options #pragma GCC optimize ("O0") #endif /** * @brief Software delay (private routine) * @param val Wait delay * With fHCLK = 32MHz: 1 = ~1µs, 50 = ~14µs, 100 = ~25µs, 200 = ~50µs * @retval None */ void SoftDelay(uint16_t val) { __IO uint16_t idx; for (idx = val; idx > 0; idx--) {} } #if defined(__TASKING__) #pragma endoptimize #endif #if (TSLPRM_USE_SPREAD_SPECTRUM > 0) #if defined(__IAR_SYSTEMS_ICC__) // IAR/EWARM #pragma optimize=medium #elif defined(__CC_ARM) // Keil/MDK-ARM #pragma O1 #pragma Ospace #elif defined(__TASKING__) // Altium/Tasking #pragma optimize O0 #elif defined(__GNUC__) // Atollic/True Studio + Raisonance/RKit #pragma GCC push_options #pragma GCC optimize ("O0") #endif /** * @brief Spread Spectrum using a variable software delay. * @param None * @retval None */ __INLINE void SwSpreadSpectrum(void) { uint8_t idx; SpreadCounter++; if (SpreadCounter == TSLPRM_SPREAD_MAX) { SpreadCounter = TSLPRM_SPREAD_MIN; } idx = SpreadCounter; while (--idx) {} } #if defined(__TASKING__) #pragma endoptimize #endif #endif /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/