blob: 788d1e56d688038db2edd7bbdb05819f7f09f037 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
|
/**
******************************************************************************
* @file tsl_acq.c
* @author MCD Application Team
* @brief This file contains all functions to manage the acquisition.
******************************************************************************
* @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.h"
#include "tsl_globals.h"
/* Private typedefs ----------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private functions prototype -----------------------------------------------*/
/**
* @brief Read all channels measurement of a Bank, calculate Delta
* @param[in] idx_bk Index of the Bank to access
* @param[in] mfilter Pointer to the Measure filter function
* @param[in] dfilter Pointer to the Delta filter function
* @retval Status
*/
TSL_Status_enum_T TSL_acq_BankGetResult(TSL_tIndex_T idx_bk, TSL_pFuncMeasFilter_T mfilter, TSL_pFuncDeltaFilter_T dfilter)
{
TSL_Status_enum_T retval = TSL_STATUS_OK;
TSL_tIndex_T idx_ch;
TSL_tIndexDest_T idx_dest;
TSL_tMeas_T old_meas, new_meas;
TSL_tDelta_T new_delta;
CONST TSL_Bank_T *bank = &(TSL_Globals.Bank_Array[idx_bk]);
CONST TSL_ChannelDest_T *pchDest = bank->p_chDest;
CONST TSL_ChannelSrc_T *pchSrc = bank->p_chSrc;
if (idx_bk >= TSLPRM_TOTAL_BANKS)
{
return TSL_STATUS_ERROR;
}
// For all channels in the bank copy the measure + calculate delta and store them.
for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)
{
// Get the Destination Index of the current channel
idx_dest = pchDest->IdxDest;
if (bank->p_chData[idx_dest].Flags.ObjStatus == TSL_OBJ_STATUS_ON)
{
// Initialize flag to inform the Object of that a new data is ready
bank->p_chData[idx_dest].Flags.DataReady = TSL_DATA_READY;
// Get the new measure (the access is different between acquisitions)
new_meas = TSL_acq_GetMeas(pchSrc->IdxSrc);
// Store last measure for the filter below
#if TSLPRM_USE_MEAS > 0
old_meas = bank->p_chData[idx_dest].Meas;
#else
old_meas = new_meas;
#endif
// Store the new measure
#if TSLPRM_USE_MEAS > 0
bank->p_chData[idx_dest].Meas = new_meas;
#endif
// Check acquisition value min/max and set acquisition status flag
if (new_meas < TSL_Params.AcqMin)
{
bank->p_chData[idx_dest].Flags.AcqStatus = TSL_ACQ_STATUS_ERROR_MIN;
bank->p_chData[idx_dest].Delta = 0;
retval = TSL_STATUS_ERROR;
}
else
{
if (new_meas >= TSL_Params.AcqMax)
{
bank->p_chData[idx_dest].Flags.AcqStatus = TSL_ACQ_STATUS_ERROR_MAX;
bank->p_chData[idx_dest].Delta = 0;
retval = TSL_STATUS_ERROR;
}
else // The measure is OK
{
if (TSL_acq_UseFilter(&bank->p_chData[idx_dest]))
{
// Apply Measure filter if it exists
if (mfilter)
{
new_meas = mfilter(old_meas, new_meas);
// Store the measure (optional - used for debug purpose)
#if TSLPRM_USE_MEAS > 0
bank->p_chData[idx_dest].Meas = new_meas;
#endif
}
// Calculate the new Delta
new_delta = TSL_acq_ComputeDelta(bank->p_chData[idx_dest].Ref, new_meas);
// Check Noise (TSL_ACQ_STATUS_OK if no Noise or if Noise detection is not supported)
bank->p_chData[idx_dest].Flags.AcqStatus = TSL_acq_CheckNoise();
// Apply Delta filter if it exists
if (dfilter)
{
bank->p_chData[idx_dest].Delta = dfilter(new_delta);
}
else
{
bank->p_chData[idx_dest].Delta = new_delta;
}
}
else
{
// Calculate the new Delta
bank->p_chData[idx_dest].Delta = TSL_acq_ComputeDelta(bank->p_chData[idx_dest].Ref, new_meas);
// Check Noise (TSL_ACQ_STATUS_OK if no Noise or if Noise detection is not supported)
bank->p_chData[idx_dest].Flags.AcqStatus = TSL_acq_CheckNoise();
}
}
}
}
// Next channel
pchDest++;
pchSrc++;
}
return retval;
}
/**
* @brief Calibrate a Bank
* @param[in] idx_bk Index of the Bank to access
* @retval Status
*/
TSL_Status_enum_T TSL_acq_BankCalibrate(TSL_tIndex_T idx_bk)
{
TSL_Status_enum_T retval;
TSL_Status_enum_T acq_status;
TSL_tIndex_T idx_ch;
TSL_tIndexDest_T idx_dest;
TSL_tMeas_T new_meas;
static TSL_tIndex_T calibration_ongoing = 0;
static TSL_tNb_T calibration_done = 0;
static TSL_tNb_T div;
CONST TSL_Bank_T *bank;
CONST TSL_ChannelDest_T *pchDest; // Pointer to the current channel
CONST TSL_ChannelSrc_T *pchSrc; // Pointer to the current channel
if (idx_bk >= TSLPRM_TOTAL_BANKS)
{
return TSL_STATUS_ERROR;
}
bank = &(TSL_Globals.Bank_Array[idx_bk]);
if (calibration_ongoing == 0)
{
switch (TSL_Params.NbCalibSamples)
{
case 4:
div = 2;
break;
case 16:
div = 4;
break;
default:
TSL_Params.NbCalibSamples = 8;
div = 3;
break;
}
// Clear data for all channels of the bank
TSL_acq_BankClearData(idx_bk);
// Configure bank
if (TSL_acq_BankConfig(idx_bk) == TSL_STATUS_OK)
{
// Start acquisition
TSL_acq_BankStartAcq();
calibration_ongoing = 1; // Calibration started
calibration_done = TSL_Params.NbCalibSamples;
retval = TSL_STATUS_BUSY;
}
else
{
// Stop calibration
// Clear data for all channels of the bank
TSL_acq_BankClearData(idx_bk);
calibration_ongoing = 0;
retval = TSL_STATUS_ERROR;
}
}
else // Calibration is on-going
{
// Check End of Acquisition
acq_status = TSL_acq_BankWaitEOC();
if (acq_status == TSL_STATUS_OK)
{
// Get the first channel of the bank
pchDest = bank->p_chDest;
pchSrc = bank->p_chSrc;
// Get new measurement for all channels of the bank
for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)
{
// Get index of the current channel
idx_dest = pchDest->IdxDest;
// Get the new measure (the access is different between acquisitions)
new_meas = TSL_acq_GetMeas(pchSrc->IdxSrc);
// Check min/max and set status flag
if ((new_meas < TSL_Params.AcqMin) || (new_meas >= TSL_Params.AcqMax))
{
// Stop calibration
// Clear data for all channels of the bank
TSL_acq_BankClearData(idx_bk);
calibration_ongoing = 0;
return TSL_STATUS_ERROR;
}
else
{
// Add the measure
bank->p_chData[idx_dest].Ref += new_meas;
}
// Next channel
pchDest++;
pchSrc++;
}
// Check that we have all the needed measurements
calibration_done--;
if (calibration_done == 0)
{
// Get the first channel of the bank
pchDest = bank->p_chDest;
// Calculate the Reference for all channels of the bank
for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)
{
// Get index of the current channel
idx_dest = pchDest->IdxDest;
// Divide the Reference by the number of samples
bank->p_chData[idx_dest].Ref >>= div;
// Next channel
pchDest++;
}
// End
calibration_ongoing = 0;
retval = TSL_STATUS_OK;
}
else // Restart a new measurement on the bank
{
TSL_acq_BankStartAcq();
retval = TSL_STATUS_BUSY;
}
}
else
if (acq_status == TSL_STATUS_ERROR)
{
// Stop calibration
// Clear data for all channels of the bank
TSL_acq_BankClearData(idx_bk);
calibration_ongoing = 0;
retval = TSL_STATUS_ERROR;
}
else
{
retval = TSL_STATUS_BUSY;
}
}
return retval;
}
/**
* @brief Clear Reference and Delta on all channels of a Bank
* @param[in] idx_bk Index of the Bank to access
* @retval None
*/
void TSL_acq_BankClearData(TSL_tIndex_T idx_bk)
{
TSL_tIndex_T idx_ch;
TSL_tIndexDest_T idx_Dest;
CONST TSL_Bank_T *bank = &(TSL_Globals.Bank_Array[idx_bk]);
CONST TSL_ChannelDest_T *pchDest = bank->p_chDest;
if (idx_bk >= TSLPRM_TOTAL_BANKS)
{
return;
}
// For all channels of the bank
for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)
{
idx_Dest = pchDest->IdxDest;
bank->p_chData[idx_Dest].Ref = 0;
bank->p_chData[idx_Dest].Delta = 0;
pchDest++; // Next channel
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|