Welcome to mirror list, hosted at ThFree Co, Russian Federation.

tsl_acq.c « src « STM32_TouchSensing_Library « ST « Middlewares - github.com/Flipper-Zero/STM32CubeWB.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
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>&copy; 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****/