ESOS32
ESOSOn32-bitProcessors
esos_sensor.c
1 /*
2  * "Copyright (c) 2020 J. W. Bruce ("AUTHOR(S)")"
3  * All rights reserved.
4  * (J. W. Bruce, jwbruce_AT_tntech.edu, Tennessee Tech University)
5  *
6  * Permission to use, copy, modify, and distribute this software and its
7  * documentation for any purpose, without fee, and without written agreement is
8  * hereby granted, provided that the above copyright notice, the following
9  * two paragraphs and the authors appear in all copies of this software.
10  *
11  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
12  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
13  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
14  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15  *
16  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
17  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
19  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
20  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
21  *
22  * Please maintain this header in its entirety when copying/modifying
23  * these files.
24  *
25  *
26  */
27 
28 #include "esos_sensor.h"
29 #include <esos.h>
30 #include <stdlib.h>
31 
45 ESOS_CHILD_TASK(_WAIT_ON_AVAILABLE_SENSOR, esos_sensor_ch_t e_senCh, esos_sensor_vref_t e_senVRef)
46 {
48 
49  // Wait for and then grab the ADC.
50  ESOS_TASK_WAIT_WHILE(__esos_IsSystemFlagSet(__ESOS_SYS_ADC_IS_BUSY));
51  __esos_SetSystemFlag(__ESOS_SYS_ADC_IS_BUSY);
52 
53  esos_sensor_config_hw(e_senCh, e_senVRef);
54 
55  ESOS_TASK_END();
56 }
57 
65 ESOS_CHILD_TASK(_WAIT_SENSOR_QUICK_READ, uint16_t* pu16_data)
66 {
68 
69  esos_sensor_initiate_hw();
71  *pu16_data = esos_sensor_getvalue_u16_hw();
72 
73  ESOS_TASK_END();
74 }
75 
84 int compareUint16(const void *pv_a, const void *pv_b)
85 {
86  return *((uint16_t*)pv_a) - *((uint16_t*)pv_b);
87 }
88 
97 uint16_t medianOfBuffer(uint16_t *pu16_buf, uint8_t u8_nelem)
98 {
99  qsort(pu16_buf, u8_nelem, sizeof(uint16_t), compareUint16);
100 
101  // Always assumes buflen is even, and that the inputs are max 12 bit!
102  return (pu16_buf[u8_nelem / 2 - 1] + pu16_buf[u8_nelem / 2]) / 2;
103 }
104 
113 uint16_t maxOfBuffer(uint16_t *pu16_buf, uint8_t u8_nelem)
114 {
115  uint16_t max = 0;
116  uint8_t i = 0;
117 
118  for(;i<u8_nelem;i++){
119  if(max < pu16_buf[i]){
120  max = pu16_buf[i];
121  }
122  }
123  return max;
124 }
125 
135 ESOS_CHILD_TASK(_WAIT_SENSOR_READ, uint16_t* pu16_data, uint8_t e_senProcess, esos_sensor_format_t e_senFMT)
136 {
137  ESOS_TASK_BEGIN();
138 
139  static uint8_t FMT_CONSTANT;
140  static uint8_t vRef;
141 
142  static uint16_t au16_dataArr[64] = {0};
143  static uint8_t arrayCount = 0;
144  uint16_t u16_oneShot = *pu16_data;
145  static uint32_t u32_algData;
146 
147  arrayCount = 0;
148  u32_algData = 0;
149  //Decompose e_senFMT to determine Vref and Format Constant
150  FMT_CONSTANT = e_senFMT & 0b11110000;
151  vRef = e_senFMT & 0b00001111;
152 
153  //2 Samples
154  if((e_senProcess & 0b00001111) == 1){
155  while(arrayCount < 2){
156  esos_sensor_initiate_hw();
158  au16_dataArr[arrayCount++] = esos_sensor_getvalue_u16_hw();
159  }
160  }
161  //4 Samples
162  else if((e_senProcess & 0b00001111) == 2){
163  while(arrayCount < 4){
164  esos_sensor_initiate_hw();
166  au16_dataArr[arrayCount++] = esos_sensor_getvalue_u16_hw();
167  }
168  }
169  //8 Samples
170  else if((e_senProcess & 0b00001111) == 3){
171  while(arrayCount < 8){
172  esos_sensor_initiate_hw();
174  au16_dataArr[arrayCount++] = esos_sensor_getvalue_u16_hw();
175  }
176  }
177  //16 Samples
178  else if((e_senProcess & 0b00001111) == 4){
179  while(arrayCount < 16){
180  esos_sensor_initiate_hw();
182  au16_dataArr[arrayCount++] = esos_sensor_getvalue_u16_hw();
183  }
184  }
185  //32 Samples
186  else if((e_senProcess & 0b00001111) == 5){
187  while(arrayCount < 32){
188  esos_sensor_initiate_hw();
190  au16_dataArr[arrayCount++] = esos_sensor_getvalue_u16_hw();
191  }
192  }
193  //64 Samples
194  else if((e_senProcess & 0b00001111) == 6){
195  while(arrayCount < 64){
196  esos_sensor_initiate_hw();
198  au16_dataArr[arrayCount++] = esos_sensor_getvalue_u16_hw();
199  }
200  }
201 
202  //Reset *pu16_data to zero since everything is now in the array
203  *pu16_data = 0;
204  arrayCount = 0; // resetting to zero before reusing in process algorithms.
205 
206 
207 
208  //Do Nothing
209  if(e_senProcess == ESOS_SENSOR_ONE_SHOT){
210  esos_sensor_initiate_hw();
212  *pu16_data = esos_sensor_getvalue_u16_hw();
213  }
214  //Average
215  else if(e_senProcess == ESOS_SENSOR_AVG2){
216  while(arrayCount < 2){
217  u32_algData += au16_dataArr[arrayCount];
218  arrayCount ++;
219  }
220  u32_algData = u32_algData/arrayCount;
221  *pu16_data = (uint16_t)u32_algData;
222  }
223  else if(e_senProcess == ESOS_SENSOR_AVG4){
224  while(arrayCount < 4){
225  u32_algData += au16_dataArr[arrayCount];
226  arrayCount ++;
227  }
228  u32_algData = u32_algData/arrayCount;
229  *pu16_data = (uint16_t)u32_algData;
230  }
231  else if(e_senProcess == ESOS_SENSOR_AVG8){
232  while(arrayCount < 8){
233  u32_algData += au16_dataArr[arrayCount];
234  arrayCount ++;
235  }
236  u32_algData = u32_algData/arrayCount;
237  *pu16_data = (uint16_t)u32_algData;
238  }
239  else if(e_senProcess == ESOS_SENSOR_AVG16){
240  while(arrayCount < 16){
241  u32_algData += au16_dataArr[arrayCount];
242  arrayCount ++;
243  }
244  u32_algData = u32_algData/arrayCount;
245  *pu16_data = (uint16_t)u32_algData;
246  }
247  else if(e_senProcess == ESOS_SENSOR_AVG32){
248  while(arrayCount < 32){
249  u32_algData += au16_dataArr[arrayCount];
250  arrayCount ++;
251  }
252  u32_algData = u32_algData/arrayCount;
253  *pu16_data = (uint16_t)u32_algData;
254  }
255  else if(e_senProcess == ESOS_SENSOR_AVG64){
256  while(arrayCount < 64){
257  u32_algData += au16_dataArr[arrayCount];
258  arrayCount ++;
259  }
260  u32_algData = u32_algData/arrayCount;
261  *pu16_data = (uint16_t)u32_algData;
262  }
263  //Minimum
264  else if(e_senProcess == ESOS_SENSOR_MIN2){
265  *pu16_data = ESOS_SENSOR_MAX16; // default to maximum 16 bit value.
266  while(arrayCount < 2){
267  if (au16_dataArr[arrayCount] < *pu16_data){
268  *pu16_data = au16_dataArr[arrayCount];
269  }
270  arrayCount ++;
271  }
272  }
273  else if(e_senProcess == ESOS_SENSOR_MIN4){
274  *pu16_data = ESOS_SENSOR_MAX16; // default to maximum 16 bit value.
275  while(arrayCount < 4){
276  if (au16_dataArr[arrayCount] < *pu16_data){
277  *pu16_data = au16_dataArr[arrayCount];
278  }
279  arrayCount ++;
280  }
281  }
282  else if(e_senProcess == ESOS_SENSOR_MIN8){
283  *pu16_data = ESOS_SENSOR_MAX16; // default to maximum 16 bit value.
284  while(arrayCount < 8){
285  if (au16_dataArr[arrayCount] < *pu16_data){
286  *pu16_data = au16_dataArr[arrayCount];
287  }
288  arrayCount ++;
289  }
290  }
291  else if(e_senProcess == ESOS_SENSOR_MIN16){
292  *pu16_data = ESOS_SENSOR_MAX16; // default to maximum 16 bit value.
293  while(arrayCount < 16){
294  if (au16_dataArr[arrayCount] < *pu16_data){
295  *pu16_data = au16_dataArr[arrayCount];
296  }
297  arrayCount ++;
298  }
299  }
300  else if(e_senProcess == ESOS_SENSOR_MIN32){
301  *pu16_data = ESOS_SENSOR_MAX16; // default to maximum 16 bit value.
302  while(arrayCount < 32){
303  if (au16_dataArr[arrayCount] < *pu16_data){
304  *pu16_data = au16_dataArr[arrayCount];
305  }
306  arrayCount ++;
307  }
308  }
309  else if(e_senProcess == ESOS_SENSOR_MIN64){
310  *pu16_data = ESOS_SENSOR_MAX16; // default to maximum 16 bit value.
311  while(arrayCount < 64){
312  if (au16_dataArr[arrayCount] < *pu16_data){
313  *pu16_data = au16_dataArr[arrayCount];
314  }
315  arrayCount ++;
316  }
317  }
318  //Maximum
319  else if(e_senProcess == ESOS_SENSOR_MAX2){
320  *pu16_data = maxOfBuffer(au16_dataArr, 2);
321  }
322  else if(e_senProcess == ESOS_SENSOR_MAX4){
323  *pu16_data = maxOfBuffer(au16_dataArr, 4);
324  }
325  else if(e_senProcess == ESOS_SENSOR_MAX8){
326  *pu16_data = maxOfBuffer(au16_dataArr, 8);
327  }
328  else if(e_senProcess == ESOS_SENSOR_MAX16){
329  *pu16_data = maxOfBuffer(au16_dataArr, 16);
330  }
331  else if(e_senProcess == ESOS_SENSOR_MAX32){
332  *pu16_data = maxOfBuffer(au16_dataArr, 32);
333  }
334  else if(e_senProcess == ESOS_SENSOR_MAX64){
335  *pu16_data = maxOfBuffer(au16_dataArr, 64);
336  }
337  //Median
338  else if(e_senProcess == ESOS_SENSOR_MEDIAN2){
339  *pu16_data = medianOfBuffer(au16_dataArr, 2);
340  }
341  else if(e_senProcess == ESOS_SENSOR_MEDIAN4){
342  *pu16_data = medianOfBuffer(au16_dataArr, 4);
343  }
344  else if(e_senProcess == ESOS_SENSOR_MEDIAN8){
345  *pu16_data = medianOfBuffer(au16_dataArr, 8);
346  }
347  else if(e_senProcess == ESOS_SENSOR_MEDIAN16){
348  *pu16_data = medianOfBuffer(au16_dataArr, 16);
349  }
350  else if(e_senProcess == ESOS_SENSOR_MEDIAN32){
351  *pu16_data = medianOfBuffer(au16_dataArr, 32);
352  }
353  else if(e_senProcess == ESOS_SENSOR_MEDIAN64){
354  *pu16_data = medianOfBuffer(au16_dataArr, 64);
355  }
356  else{}
357 
358  //Export as Voltage
359  if(FMT_CONSTANT & ESOS_SENSOR_FORMAT_VOLTAGE){
360  const uint32_t u32_maxDeciMilliVolts =
361  vRef == ESOS_SENSOR_VREF_1V0 ? 10000
362  : vRef == ESOS_SENSOR_VREF_1V024 ? 10240
363  : vRef == ESOS_SENSOR_VREF_2V0 ? 20000
364  : vRef == ESOS_SENSOR_VREF_2V048 ? 20480
365  : vRef == ESOS_SENSOR_VREF_3V0 ? 30000
366  : vRef == ESOS_SENSOR_VREF_3V3 ? 33000
367  : vRef == ESOS_SENSOR_VREF_4V0 ? 40000
368  : vRef == ESOS_SENSOR_VREF_4V096 ? 40960
369  : vRef == ESOS_SENSOR_VREF_5V0 ? 50000
370  : 0;
371  const uint32_t u32_divDeciMillivolts = (uint32_t)(*pu16_data) * u32_maxDeciMilliVolts;
372  const uint32_t u32_DeciMillivolts = u32_divDeciMillivolts / 4096;
373  *pu16_data = (uint16_t)u32_DeciMillivolts;
374  }
375 
376  //Export as Percent
377  else if(FMT_CONSTANT & ESOS_SENSOR_FORMAT_PERCENT) {
378  *pu16_data = (uint32_t)(*pu16_data) * 100 / 4096;
379  }
380 
381 
382  ESOS_TASK_END();
383 }
384 
391 {
393  // Release the flag
394  __esos_ClearSystemFlag(__ESOS_SYS_ADC_IS_BUSY);
395 
396  return TRUE;
397 }
esos_sensor_getvalue_u16_hw
uint16_t esos_sensor_getvalue_u16_hw(void)
Definition: esos_hwxxx_sensor.c:84
esos_sensor_ch_t
esos_sensor_ch_t
Definition: esos_sensor.h:51
esos_sensor_vref_t
esos_sensor_vref_t
Definition: esos_sensor.h:73
maxOfBuffer
uint16_t maxOfBuffer(uint16_t *pu16_buf, uint8_t u8_nelem)
Definition: esos_sensor.c:113
esos_sensor_format_t
esos_sensor_format_t
Definition: esos_sensor.h:119
esos.h
ESOS_TASK_END
#define ESOS_TASK_END()
Definition: esos_task.h:271
esos_sensor_release_hw
void esos_sensor_release_hw(void)
Definition: esos_hwxxx_sensor.c:92
esos_sensor_is_converting_hw
BOOL esos_sensor_is_converting_hw(void)
Definition: esos_hwxxx_sensor.c:68
medianOfBuffer
uint16_t medianOfBuffer(uint16_t *pu16_buf, uint8_t u8_nelem)
Definition: esos_sensor.c:97
BOOL
enum _BOOL BOOL
ESOS_SENSOR_CLOSE
BOOL ESOS_SENSOR_CLOSE(void)
Definition: esos_sensor.c:390
TRUE
@ TRUE
Definition: all_generic.h:410
ESOS_TASK_WAIT_WHILE
#define ESOS_TASK_WAIT_WHILE(cond)
Definition: esos_task.h:363
compareUint16
int compareUint16(const void *pv_a, const void *pv_b)
Definition: esos_sensor.c:84
ESOS_TASK_BEGIN
#define ESOS_TASK_BEGIN()
Definition: esos_task.h:259
ESOS_CHILD_TASK
ESOS_CHILD_TASK(_WAIT_ON_AVAILABLE_SENSOR, esos_sensor_ch_t e_senCh, esos_sensor_vref_t e_senVRef)
Definition: esos_sensor.c:45
esos_sensor_config_hw
void esos_sensor_config_hw(esos_sensor_ch_t e_senCh, esos_sensor_vref_t e_senVRef)
Definition: esos_hwxxx_sensor.c:60
esos_sensor.h