Mercurial > public > ostc4
comparison Small_CPU/Src/externalInterface.c @ 729:d646a0f724a7
Added auto detection functionality for sensors connected to the external interface:
O2 sensors may be connected to the analog input as well as to the UART. The GUI visualization provides three slots for ppo2 display. Beside detection of sensor kind the task of the function is to place the available sensor in this three slots. CO2 has its own communication slot outside the ppo2 channel.
The result of the automatic detection is communicated via the sensor map.
author | Ideenmodellierer |
---|---|
date | Sat, 14 Jan 2023 20:46:17 +0100 |
parents | 045ff7800501 |
children | 2a801cfe23ab |
comparison
equal
deleted
inserted
replaced
728:5143e927219f | 729:d646a0f724a7 |
---|---|
63 static uint16_t externalCO2SignalStrength; | 63 static uint16_t externalCO2SignalStrength; |
64 static uint16_t externalCO2Status = 0; | 64 static uint16_t externalCO2Status = 0; |
65 | 65 |
66 static uint8_t sensorDataId = 0; | 66 static uint8_t sensorDataId = 0; |
67 static SSensorDataDiveO2 sensorDataDiveO2; | 67 static SSensorDataDiveO2 sensorDataDiveO2; |
68 static externalInterfaceAutoDetect_t externalAutoDetect = DETECTION_OFF; | |
69 static externalInterfaceSensorType SensorMap[EXT_INTERFACE_SENSOR_CNT] ={ SENSOR_ANALOG, SENSOR_ANALOG, SENSOR_ANALOG, SENSOR_NONE, SENSOR_NONE}; | |
70 static externalInterfaceSensorType tmpSensorMap[EXT_INTERFACE_SENSOR_CNT]; | |
71 static externalInterfaceSensorType MasterSensorMap[EXT_INTERFACE_SENSOR_CNT]; | |
68 | 72 |
69 | 73 |
70 void externalInterface_Init(void) | 74 void externalInterface_Init(void) |
71 { | 75 { |
72 activeChannel = 0; | 76 activeChannel = 0; |
82 /* init data values */ | 86 /* init data values */ |
83 externalV33_On = 0; | 87 externalV33_On = 0; |
84 externalCO2Value = 0; | 88 externalCO2Value = 0; |
85 externalCO2SignalStrength = 0; | 89 externalCO2SignalStrength = 0; |
86 externalCO2Status = 0; | 90 externalCO2Status = 0; |
91 externalAutoDetect = DETECTION_OFF; | |
87 } | 92 } |
88 | 93 |
89 | 94 |
90 uint8_t externalInterface_StartConversion(uint8_t channel) | 95 uint8_t externalInterface_StartConversion(uint8_t channel) |
91 { | 96 { |
103 | 108 |
104 /* Check if conversion is done and trigger measurement of next channel */ | 109 /* Check if conversion is done and trigger measurement of next channel */ |
105 uint8_t externalInterface_ReadAndSwitch() | 110 uint8_t externalInterface_ReadAndSwitch() |
106 { | 111 { |
107 uint8_t retval = EXTERNAL_ADC_NO_DATA; | 112 uint8_t retval = EXTERNAL_ADC_NO_DATA; |
108 | 113 uint8_t nextChannel; |
109 if(externalInterfacePresent) | 114 uint8_t* psensorMap = externalInterface_GetSensorMapPointer(); |
115 | |
116 if(externalADC_On) | |
110 { | 117 { |
111 if(I2C_Master_Receive(DEVICE_EXTERNAL_ADC, recBuf, ADC_ANSWER_LENGTH) == HAL_OK) | 118 if(I2C_Master_Receive(DEVICE_EXTERNAL_ADC, recBuf, ADC_ANSWER_LENGTH) == HAL_OK) |
112 { | 119 { |
113 if((recBuf[ANSWER_CONFBYTE_INDEX] & ADC_START_CONVERSION) == 0) /* !ready set => received data contains new value */ | 120 if((recBuf[ANSWER_CONFBYTE_INDEX] & ADC_START_CONVERSION) == 0) /* !ready set => received data contains new value */ |
114 { | 121 { |
115 retval = activeChannel; /* return channel number providing new data */ | 122 retval = activeChannel; /* return channel number providing new data */ |
116 activeChannel++; | 123 nextChannel = activeChannel + 1; |
117 if(activeChannel == MAX_ADC_CHANNEL) | 124 if(nextChannel == MAX_ADC_CHANNEL) |
118 { | 125 { |
119 if(externalUART_Protocol == (EXT_INTERFACE_UART_O2 >> 8)) /* mixed mode digital and analog o2 sensors => channel 0 is reserved for digital sensor */ | 126 nextChannel = 0; |
127 } | |
128 | |
129 while((psensorMap[nextChannel] != SENSOR_ANALOG) && (nextChannel != activeChannel)) | |
130 { | |
131 if(nextChannel == MAX_ADC_CHANNEL) | |
120 { | 132 { |
121 activeChannel = 1; | 133 nextChannel = 0; |
122 } | 134 } |
123 else | 135 else |
124 { | 136 { |
125 activeChannel = 0; | 137 nextChannel++; |
126 } | 138 } |
127 } | 139 } |
140 | |
141 activeChannel = nextChannel; | |
128 externalInterface_StartConversion(activeChannel); | 142 externalInterface_StartConversion(activeChannel); |
129 timeoutCnt = 0; | 143 timeoutCnt = 0; |
130 } | 144 } |
131 else | 145 else |
132 { | 146 { |
256 void externalInterface_SwitchADC(uint8_t state) | 270 void externalInterface_SwitchADC(uint8_t state) |
257 { | 271 { |
258 uint8_t loop = 0; | 272 uint8_t loop = 0; |
259 if((state) && (externalInterfacePresent)) | 273 if((state) && (externalInterfacePresent)) |
260 { | 274 { |
261 externalInterface_StartConversion(activeChannel); | 275 if(externalADC_On == 0) |
262 externalADC_On = 1; | 276 { |
277 activeChannel = 0; | |
278 externalInterface_StartConversion(activeChannel); | |
279 externalADC_On = 1; | |
280 } | |
263 } | 281 } |
264 else | 282 else |
265 { | 283 { |
266 externalADC_On = 0; | 284 if(externalAutoDetect == DETECTION_OFF) /* block deactivation requests if auto detection is active */ |
267 for(loop = 0; loop < MAX_ADC_CHANNEL; loop++) | 285 { |
268 { | 286 externalADC_On = 0; |
269 externalChannel_mV[loop] = 0; | 287 for(loop = 0; loop < MAX_ADC_CHANNEL; loop++) |
288 { | |
289 externalChannel_mV[loop] = 0; | |
290 } | |
270 } | 291 } |
271 } | 292 } |
272 } | 293 } |
273 | 294 |
274 void externalInterface_SwitchUART(uint8_t protocol) | 295 void externalInterface_SwitchUART(uint8_t protocol) |
275 { | 296 { |
276 if(protocol < 0x08) | 297 switch(protocol) |
277 { | 298 { |
278 sensorDataId = 0; | 299 case 0: |
279 externalUART_Protocol = protocol; | 300 case (EXT_INTERFACE_UART_CO2 >> 8): |
280 MX_USART1_UART_DeInit(); | 301 case (EXT_INTERFACE_UART_O2 >> 8): |
281 if( protocol != 0) | 302 if((externalAutoDetect == DETECTION_OFF) || ((protocol == EXT_INTERFACE_UART_CO2 >> 8) && (externalAutoDetect == DETECTION_CO2)) |
282 { | 303 || ((protocol == EXT_INTERFACE_UART_O2 >> 8) && (externalAutoDetect == DETECTION_DIGO2))) |
283 MX_USART1_UART_Init(); | 304 { |
284 } | 305 sensorDataId = 0; |
285 } | 306 externalUART_Protocol = protocol; |
286 } | 307 MX_USART1_UART_DeInit(); |
287 | 308 if( protocol != 0) |
288 void externalInterface_SetCO2Value(uint16_t CO2_ppm) | 309 { |
289 { | 310 MX_USART1_UART_Init(); |
290 externalCO2Value = CO2_ppm; | 311 } |
291 } | 312 } |
292 | |
293 void externalInterface_SetCO2SignalStrength(uint16_t LED_qa) | |
294 { | |
295 externalCO2SignalStrength = LED_qa; | |
296 } | |
297 | |
298 uint16_t externalInterface_GetCO2Value(void) | |
299 { | |
300 return externalCO2Value; | |
301 } | |
302 | |
303 uint16_t externalInterface_GetCO2SignalStrength(void) | |
304 { | |
305 return externalCO2SignalStrength; | |
306 } | |
307 | |
308 | |
309 void externalInterface_SetCO2State(uint16_t state) | |
310 { | |
311 externalCO2Status = state; | |
312 } | |
313 | |
314 uint16_t externalInterface_GetCO2State(void) | |
315 { | |
316 return externalCO2Status; | |
317 } | |
318 | |
319 | |
320 uint8_t externalInterface_GetSensorData(uint8_t* pDataStruct) | |
321 { | |
322 | |
323 if((pDataStruct != NULL) && sensorDataId != 0) | |
324 { | |
325 memcpy(pDataStruct, &sensorDataDiveO2, sizeof(sensorDataDiveO2)); | |
326 } | |
327 return sensorDataId; | |
328 } | |
329 | |
330 void externalInterface_SetSensorData(uint8_t dataId, uint8_t* pDataStruct) | |
331 { | |
332 if(pDataStruct != NULL) | |
333 { | |
334 if(dataId != 0) | |
335 { | |
336 memcpy(&sensorDataDiveO2, pDataStruct, sizeof(sensorDataDiveO2)); | |
337 } | |
338 else | |
339 { | |
340 memset(&sensorDataDiveO2,0,sizeof(sensorDataDiveO2)); | |
341 } | |
342 sensorDataId = dataId; | |
343 } | |
344 } | |
345 | |
346 void externalInterface_ExecuteCmd(uint16_t Cmd) | |
347 { | |
348 char cmdString[10]; | |
349 uint8_t cmdLength = 0; | |
350 | |
351 switch(Cmd & 0x00FF) /* lower byte is reserved for commands */ | |
352 { | |
353 case EXT_INTERFACE_CO2_CALIB: cmdLength = snprintf(cmdString, 10, "G\r\n"); | |
354 break; | 313 break; |
355 default: | 314 default: |
356 break; | 315 break; |
357 } | 316 } |
317 } | |
318 | |
319 void externalInterface_SetCO2Value(uint16_t CO2_ppm) | |
320 { | |
321 externalCO2Value = CO2_ppm; | |
322 } | |
323 | |
324 void externalInterface_SetCO2SignalStrength(uint16_t LED_qa) | |
325 { | |
326 externalCO2SignalStrength = LED_qa; | |
327 } | |
328 | |
329 uint16_t externalInterface_GetCO2Value(void) | |
330 { | |
331 return externalCO2Value; | |
332 } | |
333 | |
334 uint16_t externalInterface_GetCO2SignalStrength(void) | |
335 { | |
336 return externalCO2SignalStrength; | |
337 } | |
338 | |
339 | |
340 void externalInterface_SetCO2State(uint16_t state) | |
341 { | |
342 externalCO2Status = state; | |
343 } | |
344 | |
345 uint16_t externalInterface_GetCO2State(void) | |
346 { | |
347 return externalCO2Status; | |
348 } | |
349 | |
350 | |
351 uint8_t externalInterface_GetSensorData(uint8_t* pDataStruct) | |
352 { | |
353 | |
354 if((pDataStruct != NULL) && sensorDataId != 0) | |
355 { | |
356 memcpy(pDataStruct, &sensorDataDiveO2, sizeof(sensorDataDiveO2)); | |
357 } | |
358 return sensorDataId; | |
359 } | |
360 | |
361 void externalInterface_SetSensorData(uint8_t dataId, uint8_t* pDataStruct) | |
362 { | |
363 if(pDataStruct != NULL) | |
364 { | |
365 if(dataId != 0) | |
366 { | |
367 memcpy(&sensorDataDiveO2, pDataStruct, sizeof(sensorDataDiveO2)); | |
368 } | |
369 else | |
370 { | |
371 memset(&sensorDataDiveO2,0,sizeof(sensorDataDiveO2)); | |
372 } | |
373 sensorDataId = dataId; | |
374 } | |
375 } | |
376 | |
377 void externalInface_SetSensorMap(uint8_t* pMap) | |
378 { | |
379 if(pMap != NULL) | |
380 { | |
381 memcpy(MasterSensorMap, pMap, 5); /* the map is not directly copied. Copy is done via cmd request */ | |
382 } | |
383 | |
384 } | |
385 uint8_t* externalInterface_GetSensorMapPointer() | |
386 { | |
387 uint8_t* pret; | |
388 | |
389 if(externalAutoDetect != DETECTION_OFF) | |
390 { | |
391 pret = tmpSensorMap; | |
392 } | |
393 else | |
394 { | |
395 pret = SensorMap; | |
396 } | |
397 return pret; | |
398 } | |
399 | |
400 void externalInterface_AutodetectSensor() | |
401 { | |
402 static uint8_t sensorIndex = 0; | |
403 uint8_t index = 0; | |
404 | |
405 if(externalAutoDetect != DETECTION_OFF) | |
406 { | |
407 switch(externalAutoDetect) | |
408 { | |
409 case DETECTION_INIT: sensorIndex = 0; | |
410 tmpSensorMap[0] = SENSOR_ANALOG; | |
411 tmpSensorMap[1] = SENSOR_ANALOG; | |
412 tmpSensorMap[2] = SENSOR_ANALOG; | |
413 tmpSensorMap[3] = SENSOR_NONE; | |
414 tmpSensorMap[4] = SENSOR_NONE; | |
415 | |
416 externalInterface_SwitchADC(1); | |
417 externalAutoDetect = DETECTION_ANALOG; | |
418 break; | |
419 case DETECTION_ANALOG: for(index = 0; index < MAX_ADC_CHANNEL; index++) | |
420 { | |
421 if(externalChannel_mV[index] > MIN_ADC_VOLTAGE_MV) | |
422 { | |
423 tmpSensorMap[sensorIndex++] = SENSOR_ANALOG; | |
424 } | |
425 else | |
426 { | |
427 tmpSensorMap[sensorIndex++] = SENSOR_NONE; | |
428 } | |
429 } | |
430 externalAutoDetect = DETECTION_DIGO2; | |
431 externalInterface_SwitchUART(EXT_INTERFACE_UART_O2 >> 8); | |
432 break; | |
433 case DETECTION_DIGO2: if(UART_isDigO2Connected()) | |
434 { | |
435 for(index = 0; index < 3; index++) /* lookup a channel which may be used by digO2 */ | |
436 { | |
437 if(tmpSensorMap[index] == SENSOR_NONE) | |
438 { | |
439 break; | |
440 } | |
441 } | |
442 if(index == 3) | |
443 { | |
444 tmpSensorMap[2] = SENSOR_DIGO2; /* digital sensor overwrites ADC */ | |
445 } | |
446 else | |
447 { | |
448 tmpSensorMap[index] = SENSOR_DIGO2; | |
449 } | |
450 | |
451 UART_setTargetChannel(index); | |
452 /* tmpSensorMap[sensorIndex++] = SENSOR_DIGO2; */ | |
453 } | |
454 externalAutoDetect = DETECTION_CO2; | |
455 externalInterface_SwitchUART(EXT_INTERFACE_UART_CO2 >> 8); | |
456 break; | |
457 case DETECTION_CO2: if(UART_isCO2Connected()) | |
458 { | |
459 for(index = 0; index < 3; index++) /* lookup a channel which may be used by CO2*/ | |
460 { | |
461 if(tmpSensorMap[index] == SENSOR_NONE) | |
462 { | |
463 break; | |
464 } | |
465 } | |
466 if(index == 3) | |
467 { | |
468 tmpSensorMap[sensorIndex++] = SENSOR_CO2; /* place Co2 sensor behind O2 sensors (not visible) */ | |
469 } | |
470 else | |
471 { | |
472 tmpSensorMap[index] = SENSOR_CO2; | |
473 } | |
474 | |
475 } | |
476 externalAutoDetect = DETECTION_DONE; | |
477 break; | |
478 case DETECTION_DONE: while(sensorIndex < 5) | |
479 { | |
480 tmpSensorMap[sensorIndex++] = SENSOR_NONE; | |
481 } | |
482 memcpy(SensorMap, tmpSensorMap, sizeof(tmpSensorMap)); | |
483 externalAutoDetect = DETECTION_OFF; | |
484 break; | |
485 default: | |
486 break; | |
487 } | |
488 } | |
489 } | |
490 | |
491 | |
492 void externalInterface_ExecuteCmd(uint16_t Cmd) | |
493 { | |
494 char cmdString[10]; | |
495 uint8_t cmdLength = 0; | |
496 uint8_t index; | |
497 | |
498 switch(Cmd & 0x00FF) /* lower byte is reserved for commands */ | |
499 { | |
500 case EXT_INTERFACE_AUTODETECT: externalAutoDetect = DETECTION_INIT; | |
501 break; | |
502 case EXT_INTERFACE_CO2_CALIB: cmdLength = snprintf(cmdString, 10, "G\r\n"); | |
503 break; | |
504 case EXT_INTERFACE_COPY_SENSORMAP: if(externalAutoDetect == DETECTION_OFF) | |
505 { | |
506 memcpy(SensorMap, MasterSensorMap, 5); | |
507 for(index = 0; index < 3; index++) | |
508 { | |
509 if(SensorMap[index] == SENSOR_DIGO2) | |
510 { | |
511 break; | |
512 } | |
513 } | |
514 UART_setTargetChannel(index); /* if no slot for digO2 is found then the function will be called with an invalid parameter causing the overwrite function to fail */ | |
515 } | |
516 break; | |
517 default: | |
518 break; | |
519 } | |
358 if(cmdLength != 0) | 520 if(cmdLength != 0) |
359 { | 521 { |
360 HAL_UART_Transmit(&huart1,(uint8_t*)cmdString,cmdLength,10); | 522 HAL_UART_Transmit(&huart1,(uint8_t*)cmdString,cmdLength,10); |
361 } | 523 } |
362 return; | 524 return; |