]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/ST_Code/Libraries/STMTouch_Driver/src/tsl_acq.c
Add STM32L Discovery board project as a starting point to adapt to an RTOS demo.
[freertos] / FreeRTOS / Demo / CORTEX_STM32L152_Discovery_IAR / ST_Code / Libraries / STMTouch_Driver / src / tsl_acq.c
1 /**\r
2   ******************************************************************************\r
3   * @file    tsl_acq.c\r
4   * @author  MCD Application Team\r
5   * @version V1.3.2\r
6   * @date    22-January-2013\r
7   * @brief   This file contains all functions to manage the acquisition in general.\r
8   ******************************************************************************\r
9   * @attention\r
10   *\r
11   * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>\r
12   *\r
13   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");\r
14   * You may not use this file except in compliance with the License.\r
15   * You may obtain a copy of the License at:\r
16   *\r
17   *        http://www.st.com/software_license_agreement_liberty_v2\r
18   *\r
19   * Unless required by applicable law or agreed to in writing, software\r
20   * distributed under the License is distributed on an "AS IS" BASIS,\r
21   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
22   * See the License for the specific language governing permissions and\r
23   * limitations under the License.\r
24   *\r
25   ******************************************************************************\r
26   */\r
27 \r
28 /* Includes ------------------------------------------------------------------*/\r
29 #include "tsl_acq.h"\r
30 #include "tsl_globals.h"\r
31 \r
32 /* Private typedefs ----------------------------------------------------------*/\r
33 /* Private defines -----------------------------------------------------------*/\r
34 \r
35 /* Private macros ------------------------------------------------------------*/\r
36 #define IS_BANK_INDEX_OK(INDEX)  (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS)))\r
37 \r
38 /* Private variables ---------------------------------------------------------*/\r
39 /* Private functions prototype -----------------------------------------------*/\r
40 \r
41 /**\r
42   * @brief Read all channels measurement of a Bank, calculate Delta\r
43   * @param[in]  idx_bk  Index of the Bank to access\r
44   * @param[in]  mfilter Pointer to the Measure filter function\r
45   * @param[in]  dfilter Pointer to the Delta filter function\r
46   * @retval Status\r
47   */\r
48 TSL_Status_enum_T TSL_acq_BankGetResult(TSL_tIndex_T idx_bk, TSL_pFuncMeasFilter_T mfilter, TSL_pFuncDeltaFilter_T dfilter)\r
49 {\r
50   TSL_Status_enum_T retval = TSL_STATUS_OK;\r
51   TSL_tIndex_T idx_ch;\r
52   TSL_tIndexDest_T idx_dest;\r
53   TSL_tMeas_T old_meas, new_meas;\r
54   TSL_tDelta_T new_delta;\r
55   CONST TSL_Bank_T *bank = &(TSL_Globals.Bank_Array[idx_bk]);\r
56   CONST TSL_ChannelDest_T *pchDest = bank->p_chDest;\r
57   CONST TSL_ChannelSrc_T *pchSrc = bank->p_chSrc;\r
58 \r
59   // Check parameters (if USE_FULL_ASSERT is defined)\r
60   assert_param(IS_BANK_INDEX_OK(idx_bk));\r
61 \r
62   // For all channels in the bank copy the measure + calculate delta and store them.\r
63   for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)\r
64   {\r
65 \r
66     // Get the Destination Index of the current channel\r
67     idx_dest = pchDest->IdxDest;\r
68 \r
69     if (bank->p_chData[idx_dest].Flags.ObjStatus == TSL_OBJ_STATUS_ON)\r
70     {\r
71 \r
72       // Initialize flag to inform the Object of that a new data is ready\r
73       bank->p_chData[idx_dest].Flags.DataReady = TSL_DATA_READY;\r
74 \r
75       // Get the new measure (the access is different between acquisitions)\r
76       new_meas = TSL_acq_GetMeas(pchSrc->IdxSrc);\r
77 \r
78       // Store last measure for the filter below\r
79 #if TSLPRM_USE_MEAS > 0\r
80       old_meas = bank->p_chData[idx_dest].Meas;\r
81 #else\r
82       old_meas = new_meas;\r
83 #endif\r
84 \r
85       // Store the new measure\r
86 #if TSLPRM_USE_MEAS > 0\r
87       bank->p_chData[idx_dest].Meas = new_meas;\r
88 #endif\r
89 \r
90       // Check acquisition value min/max and set acquisition status flag\r
91       if (new_meas < TSL_Params.AcqMin)\r
92       {\r
93         bank->p_chData[idx_dest].Flags.AcqStatus = TSL_ACQ_STATUS_ERROR_MIN;\r
94         bank->p_chData[idx_dest].Delta = 0;\r
95         retval = TSL_STATUS_ERROR;\r
96       }\r
97       else\r
98       {\r
99         if (new_meas > TSL_Params.AcqMax)\r
100         {\r
101           bank->p_chData[idx_dest].Flags.AcqStatus = TSL_ACQ_STATUS_ERROR_MAX;\r
102           bank->p_chData[idx_dest].Delta = 0;\r
103           retval = TSL_STATUS_ERROR;\r
104         }\r
105         else // The measure is OK\r
106         {\r
107           if (TSL_acq_UseFilter(&bank->p_chData[idx_dest]))\r
108           {\r
109             // Apply Measure filter if it exists\r
110             if (mfilter)\r
111             {\r
112               new_meas = mfilter(old_meas, new_meas);\r
113               // Store the measure (optional - used for debug purpose)\r
114 #if TSLPRM_USE_MEAS > 0\r
115               bank->p_chData[idx_dest].Meas = new_meas;\r
116 #endif\r
117             }\r
118 \r
119             // Calculate the new Delta\r
120             new_delta = TSL_acq_ComputeDelta(bank->p_chData[idx_dest].Ref, new_meas);\r
121 \r
122             // Check Noise (TSL_ACQ_STATUS_OK if no Noise or if Noise detection is not supported)\r
123             bank->p_chData[idx_dest].Flags.AcqStatus = TSL_acq_CheckNoise();\r
124 \r
125             // Apply Delta filter if it exists\r
126             if (dfilter)\r
127             {\r
128               bank->p_chData[idx_dest].Delta = dfilter(new_delta);\r
129             }\r
130             else\r
131             {\r
132               bank->p_chData[idx_dest].Delta = new_delta;\r
133             }\r
134           }\r
135           else\r
136           {\r
137             // Calculate the new Delta\r
138             bank->p_chData[idx_dest].Delta = TSL_acq_ComputeDelta(bank->p_chData[idx_dest].Ref, new_meas);\r
139 \r
140             // Check Noise (TSL_ACQ_STATUS_OK if no Noise or if Noise detection is not supported)\r
141             bank->p_chData[idx_dest].Flags.AcqStatus = TSL_acq_CheckNoise();\r
142           }\r
143         }\r
144       }\r
145     }\r
146 \r
147     // Next channel\r
148     pchDest++;\r
149     pchSrc++;\r
150 \r
151   }\r
152 \r
153   return retval;\r
154 }\r
155 \r
156 \r
157 /**\r
158   * @brief Calibrate a Bank\r
159   * @param[in] idx_bk  Index of the Bank to access\r
160   * @retval Status\r
161   */\r
162 TSL_Status_enum_T TSL_acq_BankCalibrate(TSL_tIndex_T idx_bk)\r
163 {\r
164   TSL_Status_enum_T retval;\r
165   TSL_Status_enum_T acq_status;\r
166   TSL_tIndex_T idx_ch;\r
167   TSL_tIndexDest_T idx_dest;\r
168   TSL_tMeas_T new_meas;\r
169   static TSL_tIndex_T calibration_ongoing = 0;\r
170   static TSL_tNb_T calibration_done = 0;\r
171   static TSL_tNb_T div;\r
172   CONST TSL_Bank_T *bank;\r
173   CONST  TSL_ChannelDest_T *pchDest; // Pointer to the current channel\r
174   CONST TSL_ChannelSrc_T *pchSrc; // Pointer to the current channel\r
175 \r
176   // Check parameters (if USE_FULL_ASSERT is defined)\r
177   assert_param(IS_BANK_INDEX_OK(idx_bk));\r
178 \r
179   bank = &(TSL_Globals.Bank_Array[idx_bk]);\r
180 \r
181   if (calibration_ongoing == 0)\r
182   {\r
183     switch (TSL_Params.NbCalibSamples)\r
184     {\r
185       case 4:\r
186         div = 2;\r
187         break;\r
188       case 16:\r
189         div = 4;\r
190         break;\r
191       default:\r
192         TSL_Params.NbCalibSamples =  8;\r
193         div = 3;\r
194         break;\r
195     }\r
196     // Clear data for all channels of the bank\r
197     TSL_acq_BankClearData(idx_bk);\r
198     // Configure bank\r
199     if (TSL_acq_BankConfig(idx_bk) == TSL_STATUS_OK)\r
200     {\r
201       // Start acquisition\r
202       TSL_acq_BankStartAcq();\r
203       calibration_ongoing = 1; // Calibration started\r
204       calibration_done = TSL_Params.NbCalibSamples;\r
205       retval = TSL_STATUS_BUSY;\r
206     }\r
207     else\r
208     {\r
209       // Stop calibration\r
210       // Clear data for all channels of the bank\r
211       TSL_acq_BankClearData(idx_bk);\r
212       calibration_ongoing = 0;\r
213       retval = TSL_STATUS_ERROR;\r
214     }\r
215 \r
216   }\r
217   else // Calibration is on-going\r
218   {\r
219     // Check End of Acquisition\r
220     acq_status = TSL_acq_BankWaitEOC();\r
221     if (acq_status == TSL_STATUS_OK)\r
222     {\r
223 \r
224       // Get the first channel of the bank\r
225       pchDest = bank->p_chDest;\r
226       pchSrc = bank->p_chSrc;\r
227 \r
228       // Get new measurement for all channels of the bank\r
229       for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)\r
230       {\r
231 \r
232         // Get index of the current channel\r
233         idx_dest = pchDest->IdxDest;\r
234 \r
235         // Get the new measure (the access is different between acquisitions)\r
236         new_meas = TSL_acq_GetMeas(pchSrc->IdxSrc);\r
237 \r
238         // Check min/max and set status flag\r
239         if ((new_meas < TSL_Params.AcqMin) || (new_meas > TSL_Params.AcqMax))\r
240         {\r
241           // Stop calibration\r
242           // Clear data for all channels of the bank\r
243           TSL_acq_BankClearData(idx_bk);\r
244           calibration_ongoing = 0;\r
245           return TSL_STATUS_ERROR;\r
246         }\r
247         else\r
248         {\r
249           // Add the measure\r
250           bank->p_chData[idx_dest].Ref += new_meas;\r
251         }\r
252 \r
253         // Next channel\r
254         pchDest++;\r
255         pchSrc++;\r
256       }\r
257 \r
258       // Check that we have all the needed measurements\r
259       calibration_done--;\r
260       if (calibration_done == 0)\r
261       {\r
262 \r
263         // Get the first channel of the bank\r
264         pchDest = bank->p_chDest;\r
265 \r
266         // Calculate the Reference for all channels of the bank\r
267         for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)\r
268         {\r
269           // Get index of the current channel\r
270           idx_dest = pchDest->IdxDest;\r
271           // Divide the Reference by the number of samples\r
272           bank->p_chData[idx_dest].Ref >>= div;\r
273           // Next channel\r
274           pchDest++;\r
275         }\r
276 \r
277         // End\r
278         calibration_ongoing = 0;\r
279         retval = TSL_STATUS_OK;\r
280       }\r
281       else // Restart a new measurement on the bank\r
282       {\r
283         TSL_acq_BankStartAcq();\r
284         retval = TSL_STATUS_BUSY;\r
285       }\r
286     }\r
287     else\r
288       if (acq_status == TSL_STATUS_ERROR)\r
289       {\r
290         // Stop calibration\r
291         // Clear data for all channels of the bank\r
292         TSL_acq_BankClearData(idx_bk);\r
293         calibration_ongoing = 0;\r
294         retval = TSL_STATUS_ERROR;\r
295       }\r
296       else\r
297       {\r
298         retval = TSL_STATUS_BUSY;\r
299       }\r
300   }\r
301 \r
302   return retval;\r
303 }\r
304 \r
305 \r
306 /**\r
307   * @brief Clear Reference and Delta on all channels of a Bank\r
308   * @param[in] idx_bk  Index of the Bank to access\r
309   * @retval None\r
310   */\r
311 void TSL_acq_BankClearData(TSL_tIndex_T idx_bk)\r
312 {\r
313   TSL_tIndex_T idx_ch;\r
314   TSL_tIndexDest_T idx_Dest;\r
315   CONST TSL_Bank_T *bank = &(TSL_Globals.Bank_Array[idx_bk]);\r
316   CONST TSL_ChannelDest_T *pchDest = bank->p_chDest;\r
317 \r
318   // Check parameters (if USE_FULL_ASSERT is defined)\r
319   assert_param(IS_BANK_INDEX_OK(idx_bk));\r
320 \r
321   // For all channels of the bank\r
322   for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)\r
323   {\r
324     idx_Dest = pchDest->IdxDest;\r
325     bank->p_chData[idx_Dest].Ref = 0;\r
326     bank->p_chData[idx_Dest].Delta = 0;\r
327     pchDest++; // Next channel\r
328   }\r
329 }\r
330 \r
331 \r
332 #if TSLPRM_USE_ZONE > 0\r
333 \r
334 /**\r
335   * @brief Configures a Zone.\r
336   * @param[in] zone  Zone to configure\r
337   * @param[in] idx_bk  Bank index in the zone to configure\r
338   * @retval Status\r
339   */\r
340 TSL_Status_enum_T TSL_acq_ZoneConfig(CONST TSL_Zone_T *zone, TSL_tIndex_T idx_bk)\r
341 {\r
342   TSL_Status_enum_T retval;\r
343 \r
344   // Check parameters (if USE_FULL_ASSERT is defined)\r
345   assert_param(IS_BANK_INDEX_OK(idx_bk));\r
346 \r
347   TSL_Globals.This_Zone = zone;\r
348 \r
349   do\r
350   {\r
351     retval = TSL_acq_BankConfig(zone->BankIndex[idx_bk]);\r
352     TSL_Globals.This_Bank = zone->BankIndex[idx_bk];\r
353     idx_bk++;\r
354   }\r
355   while ((idx_bk < zone->NbBanks) && (retval == TSL_STATUS_ERROR));\r
356 \r
357   TSL_Globals.Index_In_This_Zone = idx_bk;\r
358 \r
359 #if TSLPRM_PXS_LOW_POWER_MODE > 0\r
360   if (idx_bk < zone->NbBanks)\r
361   {\r
362     resetPXSLowPower();\r
363   }\r
364 #endif\r
365 \r
366   return(retval);\r
367 \r
368 }\r
369 \r
370 #endif\r
371 \r
372 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r