Rev 1535 | Rev 1538 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 1535 | Rev 1537 | ||
|---|---|---|---|
| Line 110... | Line 110... | ||
| 110 | 110 | ||
| 111 | /*----------------------------------------------------------------------------- |
111 | /*----------------------------------------------------------------------------- |
| 112 | * Variables |
112 | * Variables |
| 113 | *---------------------------------------------------------------------------*/ |
113 | *---------------------------------------------------------------------------*/ |
| 114 | 114 | ||
| 115 | static uint8_t |
115 | static uint8_t chTargetState[act_protectedOutput_CH_COUNT]; |
| 116 | static uint8_t diagState = DIAG_NORMAL; |
116 | static uint8_t diagState = DIAG_NORMAL; |
| 117 | 117 | ||
| 118 | // is there a recent status change that we should report via CAN? |
118 | // is there a recent status change that we should report via CAN? |
| 119 | static uint8_t diagReportPending = 0; |
119 | static uint8_t diagReportPending = 0; |
| 120 | 120 | ||
| 121 | 121 | ||
| 122 | /*----------------------------------------------------------------------------- |
122 | /*----------------------------------------------------------------------------- |
| 123 | * Internal Function Prototypes |
123 | * Internal Function Prototypes |
| 124 | *---------------------------------------------------------------------------*/ |
124 | *---------------------------------------------------------------------------*/ |
| 125 | static void updateOutput( |
125 | static void updateOutput(uint8_t skipDiagCheck); |
| 126 | static void readDiagPin(void); |
126 | static void readDiagPin(void); |
| 127 | static void pcIntCallback(uint8_t id, uint8_t status); |
127 | static void pcIntCallback(uint8_t id, uint8_t status); |
| 128 | 128 | ||
| 129 | 129 | ||
| 130 | /*----------------------------------------------------------------------------- |
130 | /*----------------------------------------------------------------------------- |
| 131 | * Function Implementations |
131 | * Function Implementations |
| 132 | *---------------------------------------------------------------------------*/ |
132 | *---------------------------------------------------------------------------*/ |
| 133 | 133 | ||
| 134 | static void updateOutput() { |
134 | static void updateOutput(uint8_t skipDiagCheck) { |
| 135 | 135 | ||
| 136 | #if act_protectedOutput_CH_COUNT >= 1 |
136 | #if act_protectedOutput_CH_COUNT >= 1 |
| 137 | if ( |
137 | if (chTargetState[0] == 0) { |
| 138 | gpio_set_statement(CH0_OFF, CH0_PIN); |
138 | gpio_set_statement(CH0_OFF, CH0_PIN); |
| 139 | } |
139 | } |
| 140 | else if ( |
140 | else if (chTargetState[0] == 1) { |
| 141 | if (diagState == DIAG_NORMAL) { |
141 | if (diagState == DIAG_NORMAL || skipDiagCheck) { |
| 142 | gpio_set_statement(CH0_ON, CH0_PIN); |
142 | gpio_set_statement(CH0_ON, CH0_PIN); |
| 143 | } |
143 | } |
| 144 | else { |
144 | else { |
| 145 | // DIAG override, we cannot set ON state right now |
145 | // DIAG override, we cannot set ON state right now |
| 146 | gpio_set_statement(CH0_OFF, CH0_PIN); |
146 | gpio_set_statement(CH0_OFF, CH0_PIN); |
| 147 | } |
147 | } |
| 148 | } |
148 | } |
| 149 | #endif |
149 | #endif |
| 150 | 150 | ||
| 151 | #if act_protectedOutput_CH_COUNT >= 2 |
151 | #if act_protectedOutput_CH_COUNT >= 2 |
| 152 | if ( |
152 | if (chTargetState[1] == 0) { |
| 153 | gpio_set_statement(CH1_OFF, CH1_PIN); |
153 | gpio_set_statement(CH1_OFF, CH1_PIN); |
| 154 | } |
154 | } |
| 155 | else if ( |
155 | else if (chTargetState[1] == 1) { |
| 156 | if (diagState == DIAG_NORMAL) { |
156 | if (diagState == DIAG_NORMAL || skipDiagCheck) { |
| 157 | gpio_set_statement(CH1_ON, CH1_PIN); |
157 | gpio_set_statement(CH1_ON, CH1_PIN); |
| 158 | } |
158 | } |
| 159 | else { |
159 | else { |
| 160 | // DIAG override, we cannot set ON state right now |
160 | // DIAG override, we cannot set ON state right now |
| 161 | gpio_set_statement(CH1_OFF, CH1_PIN); |
161 | gpio_set_statement(CH1_OFF, CH1_PIN); |
| 162 | } |
162 | } |
| 163 | } |
163 | } |
| 164 | #endif |
164 | #endif |
| 165 | 165 | ||
| 166 | #if act_protectedOutput_CH_COUNT >= 3 |
166 | #if act_protectedOutput_CH_COUNT >= 3 |
| 167 | if ( |
167 | if (chTargetState[2] == 0) { |
| 168 | gpio_set_statement(CH2_OFF, CH2_PIN); |
168 | gpio_set_statement(CH2_OFF, CH2_PIN); |
| 169 | } |
169 | } |
| 170 | else if ( |
170 | else if (chTargetState[2] == 1) { |
| 171 | if (diagState == DIAG_NORMAL) { |
171 | if (diagState == DIAG_NORMAL || skipDiagCheck) { |
| 172 | gpio_set_statement(CH2_ON, CH2_PIN); |
172 | gpio_set_statement(CH2_ON, CH2_PIN); |
| 173 | } |
173 | } |
| 174 | else { |
174 | else { |
| 175 | // DIAG override, we cannot set ON state right now |
175 | // DIAG override, we cannot set ON state right now |
| 176 | gpio_set_statement(CH2_OFF, CH2_PIN); |
176 | gpio_set_statement(CH2_OFF, CH2_PIN); |
| 177 | } |
177 | } |
| 178 | } |
178 | } |
| 179 | #endif |
179 | #endif |
| 180 | 180 | ||
| 181 | #if act_protectedOutput_CH_COUNT >= 4 |
181 | #if act_protectedOutput_CH_COUNT >= 4 |
| 182 | if ( |
182 | if (chTargetState[3] == 0) { |
| 183 | gpio_set_statement(CH3_OFF, CH3_PIN); |
183 | gpio_set_statement(CH3_OFF, CH3_PIN); |
| 184 | } |
184 | } |
| 185 | else if ( |
185 | else if (chTargetState[3] == 1) { |
| 186 | if (diagState == DIAG_NORMAL) { |
186 | if (diagState == DIAG_NORMAL || skipDiagCheck) { |
| 187 | gpio_set_statement(CH3_ON, CH3_PIN); |
187 | gpio_set_statement(CH3_ON, CH3_PIN); |
| 188 | } |
188 | } |
| 189 | else { |
189 | else { |
| 190 | // DIAG override, we cannot set ON state right now |
190 | // DIAG override, we cannot set ON state right now |
| 191 | gpio_set_statement(CH3_OFF, CH3_PIN); |
191 | gpio_set_statement(CH3_OFF, CH3_PIN); |
| 192 | } |
192 | } |
| 193 | } |
193 | } |
| 194 | #endif |
194 | #endif |
| 195 | } |
195 | } |
| 196 | 196 | ||
| 197 | 197 | ||
| 198 | static void readDiagPin() { |
198 | static void readDiagPin() { |
| 199 | diagState = gpio_get_state(DIAG_PIN); |
199 | diagState = gpio_get_state(DIAG_PIN); |
| 200 | } |
200 | } |
| 201 | 201 | ||
| 202 | 202 | ||
| 203 | static void pcIntCallback(uint8_t id, uint8_t status) { |
203 | static void pcIntCallback(uint8_t id, uint8_t status) { |
| 204 | // new state of the DIAG pin? |
204 | // new state of the DIAG pin? |
| 205 | if (id == act_protectedOutput_DIAG_PIN_PCINT) { |
205 | if (id == act_protectedOutput_DIAG_PIN_PCINT) { |
| 206 | diagState = status; |
206 | diagState = status; |
| 207 | updateOutput(); |
207 | updateOutput(0); |
| 208 | // DIAG asserted? |
208 | // DIAG asserted? |
| 209 | if (diagState == DIAG_ASSERTED) { |
209 | if (diagState == DIAG_ASSERTED) { |
| 210 | // if retry-timer mechanism is enabled, initiate timer |
210 | // if retry-timer mechanism is enabled, initiate timer |
| 211 | if (act_protectedOutput_RETRY_TIMER_TIME_S > 0) { |
211 | if (act_protectedOutput_RETRY_TIMER_TIME_S > 0) { |
| 212 | Timer_SetTimeout(act_protectedOutput_RETRY_TIMER, act_protectedOutput_RETRY_TIMER_TIME_S*1000, TimerTypeOneShot, 0); |
212 | Timer_SetTimeout(act_protectedOutput_RETRY_TIMER, act_protectedOutput_RETRY_TIMER_TIME_S*1000, TimerTypeOneShot, 0); |
| 213 | } |
213 | } |
| 214 | // if the retry-mechanism is disabled, change the target output state to OFF |
214 | // if the retry-mechanism is disabled, change the target output state to OFF |
| 215 | else { |
215 | else { |
| 216 | for (uint8_t i=0; i<act_protectedOutput_CH_COUNT; i++) { |
216 | for (uint8_t i=0; i<act_protectedOutput_CH_COUNT; i++) { |
| 217 |
|
217 | chTargetState[i] = 0; |
| 218 | } |
218 | } |
| - | 219 | #if act_protectedOutput_EEPROM_ENABLED == 1 |
|
| - | 220 | // output states changed, store to EE after this timer delay |
|
| - | 221 | Timer_SetTimeout(act_protectedOutput_STORE_VALUE_TIMEOUT, act_protectedOutput_STORE_VALUE_TIMEOUT_TIME_S*1000, TimerTypeOneShot, 0); |
|
| - | 222 | #endif |
|
| 219 | } |
223 | } |
| 220 | } |
224 | } |
| 221 | // something interesting obviously happened. let's report it |
225 | // something interesting obviously happened. let's report it |
| 222 | diagReportPending = 1; |
226 | diagReportPending = 1; |
| 223 | } |
227 | } |
| 224 | } |
228 | } |
| 225 | 229 | ||
| 226 | 230 | ||
| 227 | void act_protectedOutput_Init() { |
231 | void act_protectedOutput_Init() { |
| 228 | /* |
232 | /* |
| 229 | * Init target state vector, in case EEPROM is disabled |
233 | * Init target state vector, in case EEPROM is disabled |
| 230 | */ |
234 | */ |
| 231 | for (uint8_t i=0; i<act_protectedOutput_CH_COUNT; i++) { |
235 | for (uint8_t i=0; i<act_protectedOutput_CH_COUNT; i++) { |
| 232 |
|
236 | chTargetState[i] = 0; |
| 233 | } |
237 | } |
| 234 | 238 | ||
| 235 | /* |
239 | /* |
| 236 | * Configure DIAG input pin |
240 | * Configure DIAG input pin |
| 237 | */ |
241 | */ |
| 238 | if (act_protectedOutput_DIAG_PIN_PULL_ENABLED) { |
242 | if (act_protectedOutput_DIAG_PIN_PULL_ENABLED) { |
| 239 | // if DIAG is asserted low, we need pull-up |
243 | // if DIAG is asserted low, we need pull-up |
| 240 | gpio_set_statement(act_protectedOutput_DIAG_PIN_POLARITY == 0 ? 1 : 0, DIAG_PIN); |
244 | gpio_set_statement(act_protectedOutput_DIAG_PIN_POLARITY == 0 ? 1 : 0, DIAG_PIN); |
| 241 | } |
245 | } |
| 242 | gpio_set_in(DIAG_PIN); |
246 | gpio_set_in(DIAG_PIN); |
| Line 246... | Line 250... | ||
| 246 | * Read EEPROM data |
250 | * Read EEPROM data |
| 247 | */ |
251 | */ |
| 248 | #if act_protectedOutput_EEPROM_ENABLED == 1 |
252 | #if act_protectedOutput_EEPROM_ENABLED == 1 |
| 249 | if (EEDATA_OK) { |
253 | if (EEDATA_OK) { |
| 250 | #if act_protectedOutput_CH_COUNT >= 1 |
254 | #if act_protectedOutput_CH_COUNT >= 1 |
| 251 |
|
255 | chTargetState[0] = eeprom_read_byte(EEDATA.ch0); |
| 252 | #endif |
256 | #endif |
| 253 | #if act_protectedOutput_CH_COUNT >= 2 |
257 | #if act_protectedOutput_CH_COUNT >= 2 |
| 254 |
|
258 | chTargetState[1] = eeprom_read_byte(EEDATA.ch1); |
| 255 | #endif |
259 | #endif |
| 256 | #if act_protectedOutput_CH_COUNT >= 3 |
260 | #if act_protectedOutput_CH_COUNT >= 3 |
| 257 |
|
261 | chTargetState[2] = eeprom_read_byte(EEDATA.ch2); |
| 258 | #endif |
262 | #endif |
| 259 | #if act_protectedOutput_CH_COUNT >= 4 |
263 | #if act_protectedOutput_CH_COUNT >= 4 |
| 260 |
|
264 | chTargetState[3] = eeprom_read_byte(EEDATA.ch3); |
| 261 | #endif |
265 | #endif |
| 262 | } |
266 | } |
| 263 | else { |
267 | else { |
| 264 | //The CRC of the EEPROM is not correct, store default values and update CRC |
268 | //The CRC of the EEPROM is not correct, store default values and update CRC |
| 265 | #if act_protectedOutput_CH_COUNT >= 1 |
269 | #if act_protectedOutput_CH_COUNT >= 1 |
| 266 | eeprom_write_byte_crc(EEDATA.ch0, 0x00, WITHOUT_CRC); |
270 | eeprom_write_byte_crc(EEDATA.ch0, 0x00, WITHOUT_CRC); |
| 267 | #endif |
271 | #endif |
| 268 | #if act_protectedOutput_CH_COUNT >= 2 |
272 | #if act_protectedOutput_CH_COUNT >= 2 |
| 269 | eeprom_write_byte_crc(EEDATA.ch1, 0x00, WITHOUT_CRC); |
273 | eeprom_write_byte_crc(EEDATA.ch1, 0x00, WITHOUT_CRC); |
| 270 | #endif |
274 | #endif |
| 271 | #if act_protectedOutput_CH_COUNT >= 3 |
275 | #if act_protectedOutput_CH_COUNT >= 3 |
| 272 | eeprom_write_byte_crc(EEDATA.ch2, 0x00, WITHOUT_CRC); |
276 | eeprom_write_byte_crc(EEDATA.ch2, 0x00, WITHOUT_CRC); |
| 273 | #endif |
277 | #endif |
| Line 282... | Line 286... | ||
| 282 | * Configure OUTPUT pins |
286 | * Configure OUTPUT pins |
| 283 | */ |
287 | */ |
| 284 | #if act_protectedOutput_CH_COUNT >= 1 |
288 | #if act_protectedOutput_CH_COUNT >= 1 |
| 285 | gpio_set_statement(CH0_OFF, CH0_PIN); |
289 | gpio_set_statement(CH0_OFF, CH0_PIN); |
| 286 | gpio_set_out(act_protectedOutput_CH0); |
290 | gpio_set_out(act_protectedOutput_CH0); |
| 287 | #endif |
291 | #endif |
| 288 | 292 | ||
| 289 | #if act_protectedOutput_CH_COUNT >= 2 |
293 | #if act_protectedOutput_CH_COUNT >= 2 |
| 290 | gpio_set_statement(CH1_OFF, CH1_PIN); |
294 | gpio_set_statement(CH1_OFF, CH1_PIN); |
| 291 | gpio_set_out(act_protectedOutput_CH1); |
295 | gpio_set_out(act_protectedOutput_CH1); |
| 292 | #endif |
296 | #endif |
| 293 | 297 | ||
| 294 | #if act_protectedOutput_CH_COUNT >= 3 |
298 | #if act_protectedOutput_CH_COUNT >= 3 |
| 295 | gpio_set_statement(CH2_OFF, CH2_PIN); |
299 | gpio_set_statement(CH2_OFF, CH2_PIN); |
| 296 | gpio_set_out(act_protectedOutput_CH2); |
300 | gpio_set_out(act_protectedOutput_CH2); |
| 297 | #endif |
301 | #endif |
| 298 | 302 | ||
| 299 | #if act_protectedOutput_CH_COUNT >= 4 |
303 | #if act_protectedOutput_CH_COUNT >= 4 |
| 300 | gpio_set_statement(CH3_OFF, CH3_PIN); |
304 | gpio_set_statement(CH3_OFF, CH3_PIN); |
| 301 | gpio_set_out(act_protectedOutput_CH3); |
305 | gpio_set_out(act_protectedOutput_CH3); |
| 302 | #endif |
306 | #endif |
| Line 308... | Line 312... | ||
| 308 | void act_protectedOutput_Process() { |
312 | void act_protectedOutput_Process() { |
| 309 | 313 | ||
| 310 | #if act_protectedOutput_EEPROM_ENABLED == 1 |
314 | #if act_protectedOutput_EEPROM_ENABLED == 1 |
| 311 | if (Timer_Expired(act_protectedOutput_STORE_VALUE_TIMEOUT)) { |
315 | if (Timer_Expired(act_protectedOutput_STORE_VALUE_TIMEOUT)) { |
| 312 | #if act_protectedOutput_CH_COUNT >= 1 |
316 | #if act_protectedOutput_CH_COUNT >= 1 |
| 313 | eeprom_write_byte_crc(EEDATA.ch0, |
317 | eeprom_write_byte_crc(EEDATA.ch0, chTargetState[0], WITHOUT_CRC); |
| 314 | #endif |
318 | #endif |
| 315 | #if act_protectedOutput_CH_COUNT >= 2 |
319 | #if act_protectedOutput_CH_COUNT >= 2 |
| 316 | eeprom_write_byte_crc(EEDATA.ch1, |
320 | eeprom_write_byte_crc(EEDATA.ch1, chTargetState[1], WITHOUT_CRC); |
| 317 | #endif |
321 | #endif |
| 318 | #if act_protectedOutput_CH_COUNT >= 3 |
322 | #if act_protectedOutput_CH_COUNT >= 3 |
| 319 | eeprom_write_byte_crc(EEDATA.ch2, |
323 | eeprom_write_byte_crc(EEDATA.ch2, chTargetState[2], WITHOUT_CRC); |
| 320 | #endif |
324 | #endif |
| 321 | #if act_protectedOutput_CH_COUNT >= 4 |
325 | #if act_protectedOutput_CH_COUNT >= 4 |
| 322 | eeprom_write_byte_crc(EEDATA.ch3, |
326 | eeprom_write_byte_crc(EEDATA.ch3, chTargetState[3], WITHOUT_CRC); |
| 323 | #endif |
327 | #endif |
| 324 | EEDATA_UPDATE_CRC; |
328 | EEDATA_UPDATE_CRC; |
| 325 | } |
329 | } |
| 326 | #endif |
330 | #endif |
| 327 | 331 | ||
| 328 | // shall we retry to set target output state? |
332 | // shall we retry to set target output state? |
| 329 | if (Timer_Expired(act_protectedOutput_RETRY_TIMER)) { |
333 | if (Timer_Expired(act_protectedOutput_RETRY_TIMER)) { |
| 330 | // read DIAG pin again and update outputs accordingly |
334 | // read DIAG pin again and update outputs accordingly |
| 331 | readDiagPin(); |
335 | readDiagPin(); |
| - | 336 | #if act_protectedOutput_FORCED_RETRIES == 1 |
|
| - | 337 | // forced retry to set output states, regardless of DIAG |
|
| 332 | updateOutput(); |
338 | updateOutput(1); |
| - | 339 | // read DIAG pin again and hope we have a better flag |
|
| - | 340 | readDiagPin(); |
|
| - | 341 | #else |
|
| - | 342 | // if DIAG allows it, retry to set the output states |
|
| - | 343 | updateOutput(0); |
|
| - | 344 | #endif |
|
| 333 | if (diagState == DIAG_ASSERTED) { |
345 | if (diagState == DIAG_ASSERTED) { |
| 334 | // if DIAG was still asserted, initiate another timer run |
346 | // if DIAG was still asserted, initiate another timer run |
| 335 | Timer_SetTimeout(act_protectedOutput_RETRY_TIMER, act_protectedOutput_RETRY_TIMER_TIME_S*1000, TimerTypeOneShot, 0); |
347 | Timer_SetTimeout(act_protectedOutput_RETRY_TIMER, act_protectedOutput_RETRY_TIMER_TIME_S*1000, TimerTypeOneShot, 0); |
| 336 | } |
348 | } |
| 337 | else { |
349 | else { |
| Line 376... | Line 388... | ||
| 376 | * an output channel. |
388 | * an output channel. |
| 377 | */ |
389 | */ |
| 378 | if (rxMsg->Length == 2) { |
390 | if (rxMsg->Length == 2) { |
| 379 | uint8_t channel = rxMsg->Data[0]; |
391 | uint8_t channel = rxMsg->Data[0]; |
| 380 | if (channel >= 0 && channel < act_protectedOutput_CH_COUNT) { |
392 | if (channel >= 0 && channel < act_protectedOutput_CH_COUNT) { |
| 381 |
|
393 | chTargetState[channel] = rxMsg->Data[1]; |
| 382 | readDiagPin(); |
394 | readDiagPin(); |
| - | 395 | #if act_protectedOutput_FORCED_RETRIES == 1 |
|
| - | 396 | updateOutput(1); |
|
| - | 397 | #else |
|
| 383 | updateOutput(); |
398 | updateOutput(0); |
| - | 399 | #endif |
|
| 384 | #if act_protectedOutput_EEPROM_ENABLED == 1 |
400 | #if act_protectedOutput_EEPROM_ENABLED == 1 |
| 385 | // output states changed, store to EE after |
401 | // output states changed, store to EE after this timer delay |
| 386 | Timer_SetTimeout(act_protectedOutput_STORE_VALUE_TIMEOUT, act_protectedOutput_STORE_VALUE_TIMEOUT_TIME_S*1000, TimerTypeOneShot, 0); |
402 | Timer_SetTimeout(act_protectedOutput_STORE_VALUE_TIMEOUT, act_protectedOutput_STORE_VALUE_TIMEOUT_TIME_S*1000, TimerTypeOneShot, 0); |
| 387 | #endif |
403 | #endif |
| 388 | } |
404 | } |
| 389 | StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER); |
405 | StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER); |
| 390 | rxMsg->Length = 2; |
406 | rxMsg->Length = 2; |