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_stm32l1xx_hw.c | |
parent | dd01e7ed22cea652061f0d12cecf929e04b285e9 (diff) |
Split app code and third party libraries
Diffstat (limited to 'third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_hw.c')
-rw-r--r-- | third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_hw.c | 862 |
1 files changed, 862 insertions, 0 deletions
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_hw.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_hw.c new file mode 100644 index 0000000..dd7048f --- /dev/null +++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_hw.c @@ -0,0 +1,862 @@ +/** + ****************************************************************************** + * @file tsl_acq_stm32l1xx_hw.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 Hardware mode (with Timers). + ****************************************************************************** + * @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_stm32l1xx_hw.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 -----------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ + +#define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS))) + +// Acquisition pulses period +/** Master timer reload value for HW acquisition only (range=4..65534, even number) + --> Period for Charge/Transfer cycle = ((TSLPRM_TIM_RELOAD*2)/FTimer) +*/ +#define TIM_RELOAD ((TSLPRM_CT_PERIOD * TSLPRM_TIMER_FREQ) / 2) +#define TIM9_PWM_CH1_WIDTH ((TIM_RELOAD >> 1) + 1) // Configure channel 1 Pulse Width +#define TIM9_PWM_CH2_WIDTH ((TIM_RELOAD >> 1) - 1) // Configure channel 2 Pulse Width + +#define TSL_CHANNEL_PORT(channel) (channel >> 4) +#define TSL_CHANNEL_IO(channel) (channel & 0x0F) + +#define TSL_GPIO_AFR(channel) ((TSL_CHANNEL_IO(channel) < 8) ? 0 : 1) +#define TSL_GPIO_AFR_Shift(channel) ((TSL_CHANNEL_IO(channel) < 8) ? (4 * TSL_CHANNEL_IO(channel)) : (4 * (TSL_CHANNEL_IO(channel) - 8))) + +#define TSL_RI_HYSCR_MASK(channel) (1 << TSL_CHANNEL_IO(channel)) +#define TSL_RI_ASMR_MASK(channel) (1 << TSL_CHANNEL_IO(channel)) +#define TSL_RI_CMR_MASK(channel) (1 << TSL_CHANNEL_IO(channel)) +#define TSL_RI_CICR_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_ASCR_Config(channel) (*TSL_RI_ASCR_LookUpTable[TSL_RI_Conf_LookUpTable[channel].RI_ASCR] |= (1 << (TSL_RI_Conf_LookUpTable[channel].RI_ASCR_bit))) +#define TSL_RI_HYSCR_Config(channel) (*TSL_RI_HYSCR_LookUpTable[TSL_CHANNEL_PORT(channel)] |= TSL_RI_HYSCR_MASK(channel)) +#define TSL_RI_ASMR_Config(channel) (*TSL_RI_ASMR_LookUpTable[TSL_CHANNEL_PORT(channel)] |= TSL_RI_ASMR_MASK(channel)) +#define TSL_RI_ASMR_Config_Clear(channel) (*TSL_RI_ASMR_LookUpTable[TSL_CHANNEL_PORT(channel)] &= (uint32_t)(~TSL_RI_ASMR_MASK(channel))) +#define TSL_RI_CMR_Config(channel) (*TSL_RI_CMR_LookUpTable[TSL_CHANNEL_PORT(channel)] |= TSL_RI_CMR_MASK(channel)) +#define TSL_RI_CMR_Config_Clear(channel) (*TSL_RI_CMR_LookUpTable[TSL_CHANNEL_PORT(channel)] &= (uint32_t)(~TSL_RI_CMR_MASK(channel))) +#define TSL_RI_CICR_Config(channel) (*TSL_RI_CICR_LookUpTable[TSL_CHANNEL_PORT(channel)] |= TSL_RI_CICR_MASK(channel)) +#define TSL_RI_CICR_Config_Clear(channel) (*TSL_RI_CICR_LookUpTable[TSL_CHANNEL_PORT(channel)] &= (uint32_t)(~TSL_RI_CICR_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_AF_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))))) | (2 << (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_AFR_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->AFR[TSL_GPIO_AFR(channel)] |= (0x0E << (TSL_GPIO_AFR_Shift(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)))) + +#define TSL_GPIO_AFR_NOAF_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->AFR[TSL_GPIO_AFR(channel)] &= (uint32_t)(~(0x0F << (TSL_GPIO_AFR_Shift(channel))))) + +#define TSL_GPIO_IDR_XOR_RI_CMR(channel) ((TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->IDR)^(*TSL_RI_CMR_LookUpTable[TSL_CHANNEL_PORT(channel)])) +#define TSL_GPIO_IDR_AND_RI_CMR(channel) ((TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->IDR)&(*TSL_RI_CMR_LookUpTable[TSL_CHANNEL_PORT(channel)])) + +/* Private variables ---------------------------------------------------------*/ +CONST TSL_Bank_T *bank; +TSL_tIndex_T NumberOfChannelOn = 0; +TSL_tNb_T NumberOfChannels = 0; +uint32_t tab_MeasurementCounter[11]; +TSL_Status_enum_T TSL_Acq_Status = TSL_STATUS_BUSY; +static uint16_t GroupToCheck = 0; +static TSL_tIndex_T NumberOfChannelChecked = 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}; + +uint32_t *TSL_RI_ASCR_LookUpTable[] = {(uint32_t *)&RI->ASCR1, (uint32_t *)&RI->ASCR2}; + +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 +}; + +uint32_t *TSL_RI_ASMR_LookUpTable[] = {(uint32_t *)&RI->ASMR1, (uint32_t *)&RI->ASMR2, (uint32_t *)&RI->ASMR3, 0, 0, (uint32_t *)&RI->ASMR4, (uint32_t *)&RI->ASMR5}; +uint32_t *TSL_RI_CMR_LookUpTable[] = {(uint32_t *)&RI->CMR1, (uint32_t *)&RI->CMR2, (uint32_t *)&RI->CMR3, 0, 0, (uint32_t *)&RI->CMR4, (uint32_t *)&RI->CMR5}; +uint32_t *TSL_RI_CICR_LookUpTable[] = {(uint32_t *)&RI->CICR1, (uint32_t *)&RI->CICR2, (uint32_t *)&RI->CICR3, 0, 0, (uint32_t *)&RI->CICR4, (uint32_t *)&RI->CICR5}; + +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} +}; + +/* Private functions prototype -----------------------------------------------*/ +void TSL_Init_GPIOs(void); +void TSL_Init_TIMs(void); +void TSL_Init_RI(void); +uint8_t TSL_Check_GPIO_IDR(uint8_t sample); +void SoftDelay(uint16_t val); + + +/** + * @brief Initializes the TouchSensing GPIOs. + * @param None + * @retval None + */ +void TSL_Init_GPIOs(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 + + 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 + TSL_GPIO_OTYPER_PP_Config(LocalBank->shield_channel); + TSL_GPIO_OSPEEDR_VL_Config(LocalBank->shield_channel); + TSL_GPIO_PUPDR_NO_PUPD_Config(LocalBank->shield_channel); + TSL_GPIO_AFR_Config(LocalBank->shield_channel); + + TSL_GPIO_OSPEEDR_VL_Config(LocalBank->shield_sample); + TSL_GPIO_BR_Config(LocalBank->shield_sample); + TSL_GPIO_OTYPER_PP_Config(LocalBank->shield_sample); + TSL_GPIO_PUPDR_NO_PUPD_Config(LocalBank->shield_sample); + + 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_RCC_AHBENR_Config(p_chSrc->t_sample); + TSL_RCC_AHBENR_Config(p_chSrc->t_channel); + + TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_channel); + TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_channel); + TSL_GPIO_PUPDR_NO_PUPD_Config(p_chSrc->t_channel); + TSL_GPIO_AFR_Config(p_chSrc->t_channel); + + TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_sample); + TSL_GPIO_BR_Config(p_chSrc->t_sample); + TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_sample); + TSL_GPIO_PUPDR_NO_PUPD_Config(p_chSrc->t_sample); + + TSL_GPIO_MODER_OUT_Config(p_chSrc->t_sample); + TSL_GPIO_MODER_OUT_Config(p_chSrc->t_channel); + + p_chSrc++; + } + } +} + +/** + * @brief Initializes the TouchSensing timers. + * @param None + * @retval None + */ +// Acquisition pulses period +/** Master timer reload value for HW acquisition only (range=4..65534, even number) + --> Period for Charge/Transfer cycle = ((TSLPRM_TIM_RELOAD*2)/FTimer) +*/ +void TSL_Init_TIMs(void) +{ + // Enable Timers clocks + RCC->APB2ENR |= ((1 << 4) | (1 << 2)); // TIM11, TIM9 + + //============================== + // TIMER 9 configuration: Master + //============================== + // Set the option register to redirect RI_tim9_itr_O to TIM9_itr + TIM9->OR |= 4; + // Set the Autoreload value (signal frequency) + //TIM9->ARR = 64; // freq = (64*2)*31.25ns = 1us + TIM9->ARR = TIM_RELOAD; // freq = (64*2)*31.25ns = 1us + // Set the Prescaler value + //TIM9->PSC = 0; // fCK_CNT = 32MHz/(0+1) = 32MHz --> T=31.25ns + //TIM9->PSC = TSLPRM_TIM_PRESCALER; // fCK_CNT = 32MHz/(1+1) = 32MHz --> T=31.25ns + TIM9->PSC = 0; // fCK_CNT = 32MHz/(1+1) = 32MHz --> T=31.25ns + // Set UP counter, Center-Aligned mode 1 + TIM9->CR1 = 0x20; + // OC1REF used as TRGO + TIM9->CR2 |= 0x40; // MMS=100 + // Select Master mode + TIM9->SMCR = 0x95; + // Set Update generation + TIM9->EGR |= 0x01; + + // Channel 1 PWM configuration + // Set the Output Compare Mode, PWM2 + TIM9->CCMR1 |= 0x0070; + // Set the Pulse value + //TIM9->CCR1 = 34; // duty cycle + TIM9->CCR1 = TIM9_PWM_CH1_WIDTH; // duty cycle + // Compare output enable, active high + TIM9->CCER |= 0x01; + + // Channel 2 PWM configuration + // Set the Output Compare Mode, PWM2 + TIM9->CCMR1 |= 0x6000; + // Set the Pulse value + //TIM9->CCR2 = 30; + TIM9->CCR2 = TIM9_PWM_CH2_WIDTH; + // Compare output enable, active high + TIM9->CCER |= 0x10; + + //============================== + // TIMER 11 configuration: slave + //============================== + // Set the option register to redirect TIM11_ic_o to TIM11_ti + TIM11->OR |= 8; + // Set the option register to redirect TIM9_tgo_cktim to TIM11_etri + TIM11->OR |= 4; + // Set the Prescaler value + TIM11->PSC = 0; + // Set UP counter, edge-aligned mode + TIM11->CR1 = 0; + // Select Slave mode, Internal Trigger 2 (ITR2 = TIM9), External clock mode 1 + TIM11->SMCR = 0x4000; // ECE bit + // Channel 1 configured in Input capture mode + TIM11->CCMR1 = 0x01; // No prescaler, no filter + // Channel 1 capture enable (CCE1 = 1) + TIM11->CCER = 0x01; + // Set auto reload regarding the max count +#if (TSLPRM_ACQ_MAX < 16534) + TIM11->ARR = TSLPRM_ACQ_MAX+1; +#endif + // Interrupt Enable, active high, Enable interrupt when counter reaches max count (ARR) + TIM11->DIER |= 0x03; + // Start slave timer + TIM11->CR1 |= 0x01; +} + + +/** + * @brief Init TS routing interface. + * @param None + * @retval None + */ +void TSL_Init_RI(void) +{ + CONST TSL_Bank_T *LocalBank; + 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; // Pointer to the current channel + + RCC->APB1ENR |= (uint32_t)((uint32_t)1 << 31); // COMP enable + + for (idx_bk = 0; idx_bk < NumberOfBanks; idx_bk++) + { + LocalBank = &(TSL_Globals.Bank_Array[idx_bk]); + +#if (TSLPRM_USE_SHIELD > 0) + TSL_RI_HYSCR_Config(LocalBank->shield_sample); + TSL_RI_CICR_Config(LocalBank->shield_sample); + TSL_RI_CICR_Config_Clear(LocalBank->shield_channel); + + TSL_RI_ASCR_Config(LocalBank->shield_sample); +#endif + + LocalNumberOfChannels = LocalBank->NbChannels; + + p_chSrc = LocalBank->p_chSrc; + for (idx_ch = 0; idx_ch < LocalNumberOfChannels; idx_ch++) + { + TSL_RI_HYSCR_Config(p_chSrc->t_sample); + TSL_RI_CICR_Config(p_chSrc->t_sample); + TSL_RI_CICR_Config_Clear(p_chSrc->t_channel); + TSL_RI_ASCR_Config(p_chSrc->t_sample); + p_chSrc++; + } + } + + // Reset TSUSP bit, TIM9 ITR enabled to suspend OC TIM9 generation + COMP->CSR &= (uint32_t)(~0x80000000); + +} + + +/** + * @brief Initializes the acquisition module. + * @param None + * @retval retval + */ +TSL_Status_enum_T TSL_acq_Init(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; + + NVIC_InitStructure.NVIC_IRQChannel = TIM11_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + TSL_Init_GPIOs(); + TSL_Init_TIMs(); + TSL_Init_RI(); + + 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 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]); + + NumberOfChannels = bank->NbChannels; + + GroupToCheck = 0;//init group to check + NumberOfChannelOn = 0;//init number of channel on + + // init RI ASMR + RI->ASMR1 = 0; + RI->ASMR2 = 0; + RI->ASMR3 = 0; + RI->ASMR4 = 0; + RI->ASMR5 = 0; + + 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_RI_CMR_Config(p_chSrc->t_sample); + TSL_RI_ASMR_Config(p_chSrc->t_channel); + GroupToCheck |= (1 << (p_chSrc->IdxSrc)); + NumberOfChannelOn++; + } + p_chDest++; + p_chSrc++; + } + + return TSL_STATUS_OK; + +} + + +/** + * @brief Start acquisition on a previously configured bank + * @param None + * @retval None + */ +void TSL_acq_BankStartAcq(void) +{ +#if (TSLPRM_IODEF > 0) + 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; +#endif + CONST TSL_ChannelSrc_T *p_chSrc; + CONST TSL_ChannelDest_T *p_chDest; + TSL_tIndex_T idx_dest; + TSL_tIndex_T idx_ch; + + if (NumberOfChannelOn) + { +#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 + + + // Reset count + TIM11->CNT = 0; + + // Discharge sample capacitors + 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_GPIO_MODER_OUT_Config(p_chSrc->t_sample); + } + p_chDest++; + p_chSrc++; + } + +#if (TSLPRM_USE_SHIELD > 0) + // Discharge shield sample capacitor + TSL_GPIO_MODER_OUT_Config(bank->shield_sample); +#endif + + // Wait for capa discharge + SoftDelay(0x80); + +#if (TSLPRM_USE_SHIELD > 0) + // Init sample shield in floating input + TSL_GPIO_MODER_IN_Config(bank->shield_sample); + TSL_GPIO_MODER_AF_Config(bank->shield_channel); + + TSL_RI_ASMR_Config(bank->shield_channel); +#endif + + // Init samples in floating input and channels in alternate + 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_GPIO_MODER_IN_Config(p_chSrc->t_sample); + TSL_GPIO_MODER_AF_Config(p_chSrc->t_channel); + } + + p_chDest++; + p_chSrc++; + } + + /* Start acquisition */ + TSL_Acq_Status = TSL_STATUS_BUSY; + TIM9 ->CR1 |= 0x01; // Master + } + else + { + TSL_Acq_Status = TSL_STATUS_OK; + } +} + + +/** + * @brief Wait end of acquisition + * @param None + * @retval status + */ +TSL_Status_enum_T TSL_acq_BankWaitEOC(void) +{ + return TSL_Acq_Status; +} + + +/** + * @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 Check GPIO IDR for the sample + * @param[in] sample + * @retval Status + */ +uint8_t TSL_Check_GPIO_IDR(uint8_t sample) +{ + GPIO_TypeDef *GPIO; + uint32_t GPIO_IDR_Mask = 0; + + GPIO = TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(sample)]; + + GPIO_IDR_Mask = (1 << (sample & 0x0F)); + + if (((GPIO->IDR) & GPIO_IDR_Mask) == GPIO_IDR_Mask) + { + return 1; + } + else + { + return 0; + } +} + + +/** + * @brief Process the TS Interrupt routine + * @param None + * @retval None + */ +void TSL_acq_ProcessIT(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; + + CONST TSL_ChannelSrc_T *p_chSrc; + CONST TSL_ChannelDest_T *p_chDest; + TSL_tIndex_T idx_dest; + TSL_tIndex_T idx_ch; + TSL_tNb_T CounterOverflowFlag = 0; + + CounterOverflowFlag = TIM11->SR & TIM_SR_UIF; + + // Reset flags + TIM11->SR = 0; + idx_ch = 0; + + p_chDest = bank->p_chDest; + p_chSrc = bank->p_chSrc; + do + { + // 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) + { + if ((TSL_Check_GPIO_IDR(p_chSrc->t_sample)) && + ((GroupToCheck & (1 << (p_chSrc->IdxSrc))) == (1 << (p_chSrc->IdxSrc)))) + { + tab_MeasurementCounter[p_chSrc->IdxSrc] = TIM11->CCR1; + NumberOfChannelChecked++; + GroupToCheck &= (uint32_t)(~(1 << (p_chSrc->IdxSrc))); + + // Reset CMR register to restart the timer + TSL_RI_CMR_Config_Clear(p_chSrc->t_sample); + } + // Manage Overflow + else if((CounterOverflowFlag) && + ((GroupToCheck & (1 << (p_chSrc->IdxSrc))) == (1 << (p_chSrc->IdxSrc)))) + { + tab_MeasurementCounter[p_chSrc->IdxSrc] = TSLPRM_ACQ_MAX + 1; + GroupToCheck &= (uint32_t)(~(1 << (p_chSrc->IdxSrc))); + + // Reset CMR register to restart the timer + TSL_RI_CMR_Config_Clear(p_chSrc->t_sample); + } + } + p_chDest++; + p_chSrc++; + idx_ch++; + } + while (idx_ch < NumberOfChannels); + + if (NumberOfChannelChecked >= NumberOfChannelOn) + { + NumberOfChannelOn = 0; + NumberOfChannelChecked = 0; + + // Disable master counter + TIM9->CR1 &= (uint16_t)(~0x01); + + //==================== + // 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++; + } + } + TSL_Acq_Status = TSL_STATUS_OK; + } +} + + +/** + * @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 + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |