554
|
1 /**
|
|
2 ******************************************************************************
|
|
3 * @file externalInterface.c
|
|
4 * @author heinrichs weikamp gmbh
|
|
5 * @version V0.0.1
|
|
6 * @date 07-Nov-2020
|
|
7 * @brief Interface functionality to proceed external analog signal via i2c connection
|
|
8 *
|
|
9 @verbatim
|
|
10 ==============================================================================
|
|
11 ##### stm32f4xx_hal_i2c.c modification #####
|
|
12 ==============================================================================
|
|
13 The LTC2942 requires an repeated start condition without stop condition
|
|
14 for data reception.
|
|
15
|
|
16 @endverbatim
|
|
17 ******************************************************************************
|
|
18 * @attention
|
|
19 *
|
|
20 * <h2><center>© COPYRIGHT(c) 2014 heinrichs weikamp</center></h2>
|
|
21 *
|
|
22 ******************************************************************************
|
|
23 */
|
|
24 /* Includes ------------------------------------------------------------------*/
|
|
25
|
|
26 #include <math.h>
|
|
27 #include "i2c.h"
|
|
28 #include "externalInterface.h"
|
|
29 #include "scheduler.h"
|
662
|
30 #include "uart.h"
|
|
31 #include "data_exchange.h"
|
554
|
32
|
|
33 extern SGlobal global;
|
662
|
34 extern UART_HandleTypeDef huart1;
|
554
|
35
|
|
36 #define ADC_ANSWER_LENGTH (5u) /* 3424 will provide addr + 4 data bytes */
|
|
37 #define ADC_TIMEOUT (10u) /* conversion stuck for unknown reason => restart */
|
|
38 #define ADC_REF_VOLTAGE_MV (2048.0f) /* reference voltage of MPC3424*/
|
|
39
|
|
40 #define ADC_START_CONVERSION (0x80)
|
|
41 #define ADC_GAIN_4 (0x02)
|
|
42 #define ADC_GAIN_4_VALUE (4.0f)
|
|
43 #define ADC_GAIN_8 (0x03)
|
|
44 #define ADC_GAIN_8_VALUE (8.0f)
|
|
45 #define ADC_RESOLUTION_16BIT (0x08)
|
|
46 #define ADC_RESOLUTION_16BIT_VALUE (16u)
|
|
47 #define ADC_RESOLUTION_18BIT (0x0C)
|
|
48 #define ADC_RESOLUTION_18BIT_VALUE (18u)
|
|
49
|
|
50 #define ANSWER_CONFBYTE_INDEX (4u)
|
|
51
|
|
52 static uint8_t activeChannel = 0; /* channel which is in request */
|
|
53 static uint8_t recBuf[ADC_ANSWER_LENGTH];
|
|
54 static uint8_t timeoutCnt = 0;
|
|
55 static uint8_t externalInterfacePresent = 0;
|
|
56
|
|
57 float externalChannel_mV[MAX_ADC_CHANNEL];
|
662
|
58 static uint8_t externalV33_On = 0;
|
|
59 static uint16_t externalCO2Value;
|
|
60 static uint16_t externalCO2SignalStrength;
|
|
61 static uint16_t externalCO2Status = 0;
|
554
|
62
|
|
63
|
|
64 void externalInterface_Init(void)
|
|
65 {
|
|
66 activeChannel = 0;
|
|
67 timeoutCnt = 0;
|
|
68 externalInterfacePresent = 0;
|
|
69 if(externalInterface_StartConversion(activeChannel) == HAL_OK)
|
|
70 {
|
|
71 externalInterfacePresent = 1;
|
|
72 global.deviceDataSendToMaster.hw_Info.extADC = 1;
|
|
73 }
|
559
|
74 global.deviceDataSendToMaster.hw_Info.checkADC = 1;
|
662
|
75
|
|
76 /* init data values */
|
|
77 externalV33_On = 0;
|
|
78 externalCO2Value = 0;
|
|
79 externalCO2SignalStrength = 0;
|
|
80 externalCO2Status = 0;
|
554
|
81 }
|
|
82
|
|
83
|
|
84 uint8_t externalInterface_StartConversion(uint8_t channel)
|
|
85 {
|
|
86 uint8_t retval = 0;
|
|
87 uint8_t confByte = 0;
|
|
88
|
|
89 if(channel < MAX_ADC_CHANNEL)
|
|
90 {
|
|
91 confByte = ADC_START_CONVERSION | ADC_RESOLUTION_16BIT | ADC_GAIN_8;
|
|
92 confByte |= channel << 5;
|
|
93 retval = I2C_Master_Transmit(DEVICE_EXTERNAL_ADC, &confByte, 1);
|
|
94 }
|
|
95 return retval;
|
|
96 }
|
|
97
|
|
98 /* Check if conversion is done and trigger measurement of next channel */
|
|
99 uint8_t externalInterface_ReadAndSwitch()
|
|
100 {
|
|
101 uint8_t retval = EXTERNAL_ADC_NO_DATA;
|
|
102
|
|
103 if(externalInterfacePresent)
|
|
104 {
|
|
105 if(I2C_Master_Receive(DEVICE_EXTERNAL_ADC, recBuf, ADC_ANSWER_LENGTH) == HAL_OK)
|
|
106 {
|
|
107 if((recBuf[ANSWER_CONFBYTE_INDEX] & ADC_START_CONVERSION) == 0) /* !ready set => received data contains new value */
|
|
108 {
|
|
109 retval = activeChannel; /* return channel number providing new data */
|
|
110 activeChannel++;
|
|
111 if(activeChannel == MAX_ADC_CHANNEL)
|
|
112 {
|
|
113 activeChannel = 0;
|
|
114 }
|
|
115 externalInterface_StartConversion(activeChannel);
|
|
116 timeoutCnt = 0;
|
|
117 }
|
|
118 else
|
|
119 {
|
|
120 if(timeoutCnt++ >= ADC_TIMEOUT)
|
|
121 {
|
|
122 externalInterface_StartConversion(activeChannel);
|
|
123 timeoutCnt = 0;
|
|
124 }
|
|
125 }
|
|
126 }
|
581
|
127 else /* take also i2c bus disturb into account */
|
|
128 {
|
|
129 if(timeoutCnt++ >= ADC_TIMEOUT)
|
|
130 {
|
|
131 externalInterface_StartConversion(activeChannel);
|
|
132 timeoutCnt = 0;
|
|
133 }
|
|
134 }
|
554
|
135 }
|
|
136 return retval;
|
|
137 }
|
|
138 float externalInterface_CalculateADCValue(uint8_t channel)
|
|
139 {
|
|
140 int32_t rawvalue = 0;
|
|
141 float retValue = 0.0;
|
|
142 if(channel < MAX_ADC_CHANNEL)
|
|
143 {
|
|
144
|
|
145 rawvalue = ((recBuf[0] << 16) | (recBuf[1] << 8) | (recBuf[2]));
|
|
146
|
|
147 switch(recBuf[3] & 0x0C) /* confbyte => Resolution bits*/
|
|
148 {
|
|
149 case ADC_RESOLUTION_16BIT: rawvalue = rawvalue >> 8; /* only 2 databytes received shift out confbyte*/
|
|
150 if(rawvalue & (0x1 << (ADC_RESOLUTION_16BIT_VALUE-1))) /* MSB set => negative number */
|
|
151 {
|
|
152 rawvalue |= 0xFFFF0000; /* set MSB for int32 */
|
|
153 }
|
|
154 else
|
|
155 {
|
|
156 rawvalue &= 0x0000FFFF;
|
|
157 }
|
|
158 externalChannel_mV[channel] = ADC_REF_VOLTAGE_MV * 2.0 / (float) pow(2,ADC_RESOLUTION_16BIT_VALUE); /* calculate bit resolution */
|
|
159 break;
|
|
160 case ADC_RESOLUTION_18BIT: if(rawvalue & (0x1 << (ADC_RESOLUTION_18BIT_VALUE-1))) /* MSB set => negative number */
|
|
161 {
|
|
162 rawvalue |= 0xFFFE0000; /* set MSB for int32 */
|
|
163 }
|
|
164 externalChannel_mV[channel] = ADC_REF_VOLTAGE_MV * 2.0 / (float) pow(2,ADC_RESOLUTION_18BIT_VALUE); /* calculate bit resolution */
|
|
165 break;
|
|
166 default: rawvalue = 0;
|
|
167 break;
|
|
168 }
|
|
169 externalChannel_mV[channel] = externalChannel_mV[channel] * rawvalue / ADC_GAIN_8_VALUE;
|
|
170 retValue = externalChannel_mV[channel];
|
|
171 }
|
|
172 return retValue;
|
|
173 }
|
|
174 float getExternalInterfaceChannel(uint8_t channel)
|
|
175 {
|
|
176 float retval = 0;
|
|
177
|
|
178 if(channel < MAX_ADC_CHANNEL)
|
|
179 {
|
|
180 retval = externalChannel_mV[channel];
|
|
181 }
|
|
182 return retval;
|
|
183 }
|
662
|
184
|
|
185 void externalInterface_InitPower33(void)
|
|
186 {
|
|
187 GPIO_InitTypeDef GPIO_InitStructure;
|
|
188
|
|
189 GPIO_InitStructure.Pin = GPIO_PIN_7;
|
|
190 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
|
191 GPIO_InitStructure.Pull = GPIO_PULLUP;
|
|
192 GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
|
|
193 HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
|
|
194 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,GPIO_PIN_SET);
|
|
195 }
|
|
196
|
|
197
|
|
198 uint8_t externalInterface_isEnabledPower33()
|
|
199 {
|
|
200 return externalV33_On;
|
|
201 }
|
|
202 void externalInterface_SwitchPower33(uint8_t state)
|
|
203 {
|
|
204 if(state != externalV33_On)
|
|
205 {
|
|
206 if(state)
|
|
207 {
|
|
208 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,GPIO_PIN_RESET);
|
|
209 externalV33_On = 1;
|
|
210 MX_USART1_UART_Init();
|
|
211 }
|
|
212 else
|
|
213 {
|
|
214 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,GPIO_PIN_SET);
|
|
215 externalV33_On = 0;
|
|
216 externalInterface_SetCO2Value(0);
|
|
217 externalInterface_SetCO2SignalStrength(0);
|
|
218 MX_USART1_UART_DeInit();
|
|
219 }
|
|
220 }
|
|
221 }
|
|
222
|
|
223 void externalInterface_SetCO2Value(uint16_t CO2_ppm)
|
|
224 {
|
|
225 externalCO2Value = CO2_ppm;
|
|
226 }
|
|
227
|
|
228 void externalInterface_SetCO2SignalStrength(uint16_t LED_qa)
|
|
229 {
|
|
230 externalCO2SignalStrength = LED_qa;
|
|
231 }
|
|
232
|
|
233 uint16_t externalInterface_GetCO2Value(void)
|
|
234 {
|
|
235 return externalCO2Value;
|
|
236 }
|
|
237
|
|
238 uint16_t externalInterface_GetCO2SignalStrength(void)
|
|
239 {
|
|
240 return externalCO2SignalStrength;
|
|
241 }
|
|
242
|
|
243
|
|
244 void externalInterface_SetCO2State(uint16_t state)
|
|
245 {
|
|
246 externalCO2Status = state;
|
|
247 }
|
|
248
|
|
249 uint16_t externalInterface_GetCO2State(void)
|
|
250 {
|
|
251 return externalCO2Status;
|
|
252 }
|
|
253
|
|
254 void externalInterface_ExecuteCmd(uint16_t Cmd)
|
|
255 {
|
|
256 char cmdString[10];
|
|
257 uint8_t cmdLength = 0;
|
|
258
|
|
259 switch(Cmd & 0x00FF) /* lower byte is reserved for commands */
|
|
260 {
|
|
261 case EXT_INTERFACE_CO2_CALIB: cmdLength = snprintf(cmdString, 10, "G\r\n");
|
|
262 break;
|
|
263 default:
|
|
264 break;
|
|
265 }
|
|
266 if(cmdLength != 0)
|
|
267 {
|
|
268 HAL_UART_Transmit(&huart1,(uint8_t*)cmdString,cmdLength,10);
|
|
269 }
|
|
270 return;
|
|
271 }
|
|
272
|