Rev 1534 | Rev 1537 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1503 | myhrman | 1 | /*----------------------------------------------------------------------------- |
| 2 | * Includes |
||
| 3 | *---------------------------------------------------------------------------*/ |
||
| 4 | #include "act_protectedOutput.h" |
||
| 5 | |||
| 6 | |||
| 7 | /*----------------------------------------------------------------------------- |
||
| 8 | * Defines |
||
| 9 | *---------------------------------------------------------------------------*/ |
||
| 10 | |||
| 1532 | myhrman | 11 | // make sure all config params are present |
| 1528 | myhrman | 12 | |
| 1532 | myhrman | 13 | #ifndef act_protectedOutput_CH_COUNT |
| 14 | #error Config value missing: "act_protectedOutput_CH_COUNT" |
||
| 15 | #endif |
||
| 1528 | myhrman | 16 | |
| 1532 | myhrman | 17 | #ifndef act_protectedOutput_EEPROM_ENABLED |
| 18 | #error Config value missing: "act_protectedOutput_EEPROM_ENABLED" |
||
| 19 | #endif |
||
| 1528 | myhrman | 20 | |
| 1532 | myhrman | 21 | #if act_protectedOutput_CH_COUNT >= 1 |
| 22 | #ifndef act_protectedOutput_CH0 |
||
| 23 | #error Config value missing: "act_protectedOutput_CH0" |
||
| 24 | #endif |
||
| 25 | #ifndef act_protectedOutput_CH0_POLARITY |
||
| 26 | #error Config value missing: "act_protectedOutput_CH0_POLARITY" |
||
| 27 | #endif |
||
| 28 | #endif |
||
| 29 | |||
| 30 | #if act_protectedOutput_CH_COUNT >= 2 |
||
| 31 | #ifndef act_protectedOutput_CH1 |
||
| 32 | #error Config value missing: "act_protectedOutput_CH1" |
||
| 33 | #endif |
||
| 34 | #ifndef act_protectedOutput_CH1_POLARITY |
||
| 35 | #error Config value missing: "act_protectedOutput_CH1_POLARITY" |
||
| 36 | #endif |
||
| 37 | #endif |
||
| 38 | |||
| 39 | #if act_protectedOutput_CH_COUNT >= 3 |
||
| 40 | #ifndef act_protectedOutput_CH2 |
||
| 41 | #error Config value missing: "act_protectedOutput_CH2" |
||
| 42 | #endif |
||
| 43 | #ifndef act_protectedOutput_CH2_POLARITY |
||
| 44 | #error Config value missing: "act_protectedOutput_CH2_POLARITY" |
||
| 45 | #endif |
||
| 46 | #endif |
||
| 47 | |||
| 48 | #if act_protectedOutput_CH_COUNT >= 4 |
||
| 49 | #ifndef act_protectedOutput_CH3 |
||
| 50 | #error Config value missing: "act_protectedOutput_CH3" |
||
| 51 | #endif |
||
| 52 | #ifndef act_protectedOutput_CH3_POLARITY |
||
| 53 | #error Config value missing: "act_protectedOutput_CH3_POLARITY" |
||
| 54 | #endif |
||
| 55 | #endif |
||
| 56 | |||
| 57 | #if act_protectedOutput_CH_COUNT >= 5 |
||
| 58 | #error Config value out of range: "act_protectedOutput_CH_COUNT" |
||
| 59 | #endif |
||
| 60 | |||
| 61 | #define CH0_ON (act_protectedOutput_CH0_POLARITY) |
||
| 62 | #define CH0_OFF (1 - CH0_ON) |
||
| 63 | #define CH0_PIN act_protectedOutput_CH0 |
||
| 64 | |||
| 65 | #define CH1_ON (act_protectedOutput_CH1_POLARITY) |
||
| 66 | #define CH1_OFF (1 - CH1_ON) |
||
| 67 | #define CH1_PIN act_protectedOutput_CH1 |
||
| 68 | |||
| 69 | #define CH2_ON (act_protectedOutput_CH2_POLARITY) |
||
| 70 | #define CH2_OFF (1 - CH2_ON) |
||
| 71 | #define CH2_PIN act_protectedOutput_CH2 |
||
| 72 | |||
| 73 | #define CH3_ON (act_protectedOutput_CH3_POLARITY) |
||
| 74 | #define CH3_OFF (1 - CH3_ON) |
||
| 75 | #define CH3_PIN act_protectedOutput_CH3 |
||
| 76 | |||
| 77 | #define DIAG_ASSERTED (act_protectedOutput_DIAG_PIN_POLARITY) |
||
| 1503 | myhrman | 78 | #define DIAG_NORMAL (1 - DIAG_ASSERTED) |
| 79 | #define DIAG_PIN act_protectedOutput_DIAG_PIN |
||
| 80 | |||
| 81 | |||
| 82 | /*----------------------------------------------------------------------------- |
||
| 83 | * Types |
||
| 84 | *---------------------------------------------------------------------------*/ |
||
| 85 | |||
| 86 | |||
| 1532 | myhrman | 87 | #if act_protectedOutput_EEPROM_ENABLED == 1 |
| 88 | #include "act_protectedOutput_eeprom.h" |
||
| 89 | struct eeprom_act_protectedOutput EEMEM eeprom_act_protectedOutput = |
||
| 90 | { |
||
| 91 | { |
||
| 92 | ///TODO: Define initialization values on the EEPROM variables here, this will generate a *.eep file that can be used to store this values to the node, can in future be done with a EEPROM module and the make-scrips. Write the values in the exact same order as the struct is defined in the *.h file. |
||
| 93 | #if act_protectedOutput_CH_COUNT >= 1 |
||
| 94 | 0x00, |
||
| 95 | #endif |
||
| 96 | #if act_protectedOutput_CH_COUNT >= 2 |
||
| 97 | 0x00, |
||
| 98 | #endif |
||
| 99 | #if act_protectedOutput_CH_COUNT >= 3 |
||
| 100 | 0x00, |
||
| 101 | #endif |
||
| 102 | #if act_protectedOutput_CH_COUNT >= 4 |
||
| 103 | 0x00, |
||
| 104 | #endif |
||
| 105 | }, |
||
| 106 | |||
| 107 | }; |
||
| 108 | #endif |
||
| 109 | |||
| 110 | |||
| 1503 | myhrman | 111 | /*----------------------------------------------------------------------------- |
| 112 | * Variables |
||
| 113 | *---------------------------------------------------------------------------*/ |
||
| 1528 | myhrman | 114 | |
| 1532 | myhrman | 115 | static uint8_t outputStateTarget[act_protectedOutput_CH_COUNT]; |
| 1503 | myhrman | 116 | static uint8_t diagState = DIAG_NORMAL; |
| 117 | |||
| 118 | // is there a recent status change that we should report via CAN? |
||
| 119 | static uint8_t diagReportPending = 0; |
||
| 120 | |||
| 121 | |||
| 122 | /*----------------------------------------------------------------------------- |
||
| 123 | * Internal Function Prototypes |
||
| 124 | *---------------------------------------------------------------------------*/ |
||
| 125 | static void updateOutput(void); |
||
| 126 | static void readDiagPin(void); |
||
| 127 | static void pcIntCallback(uint8_t id, uint8_t status); |
||
| 128 | |||
| 129 | |||
| 130 | /*----------------------------------------------------------------------------- |
||
| 131 | * Function Implementations |
||
| 132 | *---------------------------------------------------------------------------*/ |
||
| 133 | |||
| 134 | static void updateOutput() { |
||
| 1528 | myhrman | 135 | |
| 1532 | myhrman | 136 | #if act_protectedOutput_CH_COUNT >= 1 |
| 1528 | myhrman | 137 | if (outputStateTarget[0] == 0) { |
| 1532 | myhrman | 138 | gpio_set_statement(CH0_OFF, CH0_PIN); |
| 1503 | myhrman | 139 | } |
| 1528 | myhrman | 140 | else if (outputStateTarget[0] == 1) { |
| 1503 | myhrman | 141 | if (diagState == DIAG_NORMAL) { |
| 1532 | myhrman | 142 | gpio_set_statement(CH0_ON, CH0_PIN); |
| 1503 | myhrman | 143 | } |
| 144 | else { |
||
| 145 | // DIAG override, we cannot set ON state right now |
||
| 1532 | myhrman | 146 | gpio_set_statement(CH0_OFF, CH0_PIN); |
| 1503 | myhrman | 147 | } |
| 148 | } |
||
| 1528 | myhrman | 149 | #endif |
| 150 | |||
| 1532 | myhrman | 151 | #if act_protectedOutput_CH_COUNT >= 2 |
| 1528 | myhrman | 152 | if (outputStateTarget[1] == 0) { |
| 1532 | myhrman | 153 | gpio_set_statement(CH1_OFF, CH1_PIN); |
| 1528 | myhrman | 154 | } |
| 155 | else if (outputStateTarget[1] == 1) { |
||
| 156 | if (diagState == DIAG_NORMAL) { |
||
| 1532 | myhrman | 157 | gpio_set_statement(CH1_ON, CH1_PIN); |
| 1528 | myhrman | 158 | } |
| 159 | else { |
||
| 160 | // DIAG override, we cannot set ON state right now |
||
| 1532 | myhrman | 161 | gpio_set_statement(CH1_OFF, CH1_PIN); |
| 1528 | myhrman | 162 | } |
| 163 | } |
||
| 164 | #endif |
||
| 165 | |||
| 1532 | myhrman | 166 | #if act_protectedOutput_CH_COUNT >= 3 |
| 1528 | myhrman | 167 | if (outputStateTarget[2] == 0) { |
| 1532 | myhrman | 168 | gpio_set_statement(CH2_OFF, CH2_PIN); |
| 1528 | myhrman | 169 | } |
| 170 | else if (outputStateTarget[2] == 1) { |
||
| 171 | if (diagState == DIAG_NORMAL) { |
||
| 1532 | myhrman | 172 | gpio_set_statement(CH2_ON, CH2_PIN); |
| 1528 | myhrman | 173 | } |
| 174 | else { |
||
| 175 | // DIAG override, we cannot set ON state right now |
||
| 1532 | myhrman | 176 | gpio_set_statement(CH2_OFF, CH2_PIN); |
| 1528 | myhrman | 177 | } |
| 178 | } |
||
| 179 | #endif |
||
| 180 | |||
| 1532 | myhrman | 181 | #if act_protectedOutput_CH_COUNT >= 4 |
| 1528 | myhrman | 182 | if (outputStateTarget[3] == 0) { |
| 1532 | myhrman | 183 | gpio_set_statement(CH3_OFF, CH3_PIN); |
| 1528 | myhrman | 184 | } |
| 185 | else if (outputStateTarget[3] == 1) { |
||
| 186 | if (diagState == DIAG_NORMAL) { |
||
| 1532 | myhrman | 187 | gpio_set_statement(CH3_ON, CH3_PIN); |
| 1528 | myhrman | 188 | } |
| 189 | else { |
||
| 190 | // DIAG override, we cannot set ON state right now |
||
| 1532 | myhrman | 191 | gpio_set_statement(CH3_OFF, CH3_PIN); |
| 1528 | myhrman | 192 | } |
| 193 | } |
||
| 194 | #endif |
||
| 1503 | myhrman | 195 | } |
| 196 | |||
| 197 | |||
| 198 | static void readDiagPin() { |
||
| 199 | diagState = gpio_get_state(DIAG_PIN); |
||
| 200 | } |
||
| 201 | |||
| 202 | |||
| 203 | static void pcIntCallback(uint8_t id, uint8_t status) { |
||
| 204 | // new state of the DIAG pin? |
||
| 205 | if (id == act_protectedOutput_DIAG_PIN_PCINT) { |
||
| 206 | diagState = status; |
||
| 207 | updateOutput(); |
||
| 208 | // DIAG asserted? |
||
| 209 | if (diagState == DIAG_ASSERTED) { |
||
| 210 | // if retry-timer mechanism is enabled, initiate timer |
||
| 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); |
||
| 213 | } |
||
| 214 | // if the retry-mechanism is disabled, change the target output state to OFF |
||
| 215 | else { |
||
| 1532 | myhrman | 216 | for (uint8_t i=0; i<act_protectedOutput_CH_COUNT; i++) { |
| 1528 | myhrman | 217 | outputStateTarget[i] = 0; |
| 218 | } |
||
| 1503 | myhrman | 219 | } |
| 220 | } |
||
| 221 | // something interesting obviously happened. let's report it |
||
| 222 | diagReportPending = 1; |
||
| 223 | } |
||
| 224 | } |
||
| 225 | |||
| 226 | |||
| 227 | void act_protectedOutput_Init() { |
||
| 1528 | myhrman | 228 | /* |
| 1532 | myhrman | 229 | * Init target state vector, in case EEPROM is disabled |
| 230 | */ |
||
| 231 | for (uint8_t i=0; i<act_protectedOutput_CH_COUNT; i++) { |
||
| 232 | outputStateTarget[i] = 0; |
||
| 233 | } |
||
| 234 | |||
| 235 | /* |
||
| 1528 | myhrman | 236 | * Configure DIAG input pin |
| 237 | */ |
||
| 1503 | myhrman | 238 | if (act_protectedOutput_DIAG_PIN_PULL_ENABLED) { |
| 239 | // if DIAG is asserted low, we need pull-up |
||
| 1532 | myhrman | 240 | gpio_set_statement(act_protectedOutput_DIAG_PIN_POLARITY == 0 ? 1 : 0, DIAG_PIN); |
| 1503 | myhrman | 241 | } |
| 242 | gpio_set_in(DIAG_PIN); |
||
| 243 | Pcint_SetCallbackPin(act_protectedOutput_DIAG_PIN_PCINT, DIAG_PIN, &pcIntCallback); |
||
| 244 | |||
| 1528 | myhrman | 245 | /* |
| 1532 | myhrman | 246 | * Read EEPROM data |
| 247 | */ |
||
| 1535 | myhrman | 248 | #if act_protectedOutput_EEPROM_ENABLED == 1 |
| 1534 | myhrman | 249 | if (EEDATA_OK) { |
| 1532 | myhrman | 250 | #if act_protectedOutput_CH_COUNT >= 1 |
| 251 | outputStateTarget[0] = eeprom_read_byte(EEDATA.ch0); |
||
| 252 | #endif |
||
| 253 | #if act_protectedOutput_CH_COUNT >= 2 |
||
| 254 | outputStateTarget[1] = eeprom_read_byte(EEDATA.ch1); |
||
| 255 | #endif |
||
| 256 | #if act_protectedOutput_CH_COUNT >= 3 |
||
| 257 | outputStateTarget[2] = eeprom_read_byte(EEDATA.ch2); |
||
| 258 | #endif |
||
| 259 | #if act_protectedOutput_CH_COUNT >= 4 |
||
| 260 | outputStateTarget[3] = eeprom_read_byte(EEDATA.ch3); |
||
| 261 | #endif |
||
| 262 | } |
||
| 263 | else { |
||
| 264 | //The CRC of the EEPROM is not correct, store default values and update CRC |
||
| 265 | #if act_protectedOutput_CH_COUNT >= 1 |
||
| 266 | eeprom_write_byte_crc(EEDATA.ch0, 0x00, WITHOUT_CRC); |
||
| 267 | #endif |
||
| 268 | #if act_protectedOutput_CH_COUNT >= 2 |
||
| 269 | eeprom_write_byte_crc(EEDATA.ch1, 0x00, WITHOUT_CRC); |
||
| 270 | #endif |
||
| 271 | #if act_protectedOutput_CH_COUNT >= 3 |
||
| 272 | eeprom_write_byte_crc(EEDATA.ch2, 0x00, WITHOUT_CRC); |
||
| 273 | #endif |
||
| 274 | #if act_protectedOutput_CH_COUNT >= 4 |
||
| 275 | eeprom_write_byte_crc(EEDATA.ch3, 0x00, WITHOUT_CRC); |
||
| 276 | #endif |
||
| 277 | EEDATA_UPDATE_CRC; |
||
| 278 | } |
||
| 279 | #endif |
||
| 280 | |||
| 281 | /* |
||
| 1528 | myhrman | 282 | * Configure OUTPUT pins |
| 283 | */ |
||
| 1532 | myhrman | 284 | #if act_protectedOutput_CH_COUNT >= 1 |
| 285 | gpio_set_statement(CH0_OFF, CH0_PIN); |
||
| 286 | gpio_set_out(act_protectedOutput_CH0); |
||
| 1528 | myhrman | 287 | #endif |
| 1503 | myhrman | 288 | |
| 1532 | myhrman | 289 | #if act_protectedOutput_CH_COUNT >= 2 |
| 290 | gpio_set_statement(CH1_OFF, CH1_PIN); |
||
| 291 | gpio_set_out(act_protectedOutput_CH1); |
||
| 1528 | myhrman | 292 | #endif |
| 293 | |||
| 1532 | myhrman | 294 | #if act_protectedOutput_CH_COUNT >= 3 |
| 295 | gpio_set_statement(CH2_OFF, CH2_PIN); |
||
| 296 | gpio_set_out(act_protectedOutput_CH2); |
||
| 1528 | myhrman | 297 | #endif |
| 298 | |||
| 1532 | myhrman | 299 | #if act_protectedOutput_CH_COUNT >= 4 |
| 300 | gpio_set_statement(CH3_OFF, CH3_PIN); |
||
| 301 | gpio_set_out(act_protectedOutput_CH3); |
||
| 1528 | myhrman | 302 | #endif |
| 303 | |||
| 1503 | myhrman | 304 | diagState = DIAG_NORMAL; |
| 305 | } |
||
| 306 | |||
| 307 | |||
| 308 | void act_protectedOutput_Process() { |
||
| 309 | |||
| 1535 | myhrman | 310 | #if act_protectedOutput_EEPROM_ENABLED == 1 |
| 1534 | myhrman | 311 | if (Timer_Expired(act_protectedOutput_STORE_VALUE_TIMEOUT)) { |
| 312 | #if act_protectedOutput_CH_COUNT >= 1 |
||
| 313 | eeprom_write_byte_crc(EEDATA.ch0, outputStateTarget[0], WITHOUT_CRC); |
||
| 314 | #endif |
||
| 315 | #if act_protectedOutput_CH_COUNT >= 2 |
||
| 316 | eeprom_write_byte_crc(EEDATA.ch1, outputStateTarget[1], WITHOUT_CRC); |
||
| 317 | #endif |
||
| 318 | #if act_protectedOutput_CH_COUNT >= 3 |
||
| 319 | eeprom_write_byte_crc(EEDATA.ch2, outputStateTarget[2], WITHOUT_CRC); |
||
| 320 | #endif |
||
| 321 | #if act_protectedOutput_CH_COUNT >= 4 |
||
| 322 | eeprom_write_byte_crc(EEDATA.ch3, outputStateTarget[3], WITHOUT_CRC); |
||
| 323 | #endif |
||
| 324 | EEDATA_UPDATE_CRC; |
||
| 325 | } |
||
| 1535 | myhrman | 326 | #endif |
| 1534 | myhrman | 327 | |
| 1503 | myhrman | 328 | // shall we retry to set target output state? |
| 329 | if (Timer_Expired(act_protectedOutput_RETRY_TIMER)) { |
||
| 330 | // read DIAG pin again and update outputs accordingly |
||
| 331 | readDiagPin(); |
||
| 332 | updateOutput(); |
||
| 1512 | myhrman | 333 | if (diagState == DIAG_ASSERTED) { |
| 334 | // 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); |
||
| 336 | } |
||
| 337 | else { |
||
| 338 | // things went back to normal. report this |
||
| 339 | diagReportPending = 1; |
||
| 340 | } |
||
| 1503 | myhrman | 341 | } |
| 342 | |||
| 343 | // shall we report diag status to CAN? |
||
| 344 | if (diagReportPending) { |
||
| 345 | StdCan_Msg_t txMsg; |
||
| 346 | StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS); |
||
| 347 | StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER); |
||
| 1511 | arune | 348 | txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_PROTECTEDOUTPUT; |
| 1504 | myhrman | 349 | txMsg.Header.ModuleId = act_protectedOutput_ID; |
| 1503 | myhrman | 350 | txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PINSTATUS; |
| 351 | txMsg.Length = 2; |
||
| 352 | txMsg.Data[0] = 0; //TODO: add support for more channels |
||
| 353 | // we follow the standard SNS_INPUT format, but the data corresponds to the "health" rather than physical level |
||
| 354 | if (diagState == DIAG_NORMAL) { |
||
| 355 | txMsg.Data[1] = 1; //healthy, target output state stable |
||
| 356 | } else { |
||
| 357 | txMsg.Data[1] = 0; //not healthy, DIAG pin ASSERTED, not in target output state |
||
| 358 | } |
||
| 359 | while (StdCan_Put(&txMsg) != StdCan_Ret_OK); |
||
| 360 | diagReportPending = 0; |
||
| 361 | } |
||
| 362 | } |
||
| 363 | |||
| 364 | |||
| 365 | void act_protectedOutput_HandleMessage(StdCan_Msg_t *rxMsg) { |
||
| 366 | if ( StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT && |
||
| 367 | StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER && |
||
| 1511 | arune | 368 | rxMsg->Header.ModuleType == CAN_MODULE_TYPE_SNS_PROTECTEDOUTPUT && |
| 1503 | myhrman | 369 | rxMsg->Header.ModuleId == act_protectedOutput_ID) |
| 370 | { |
||
| 371 | switch (rxMsg->Header.Command) { |
||
| 372 | |||
| 373 | case CAN_MODULE_CMD_PHYSICAL_SETPIN: |
||
| 1532 | myhrman | 374 | /* |
| 375 | * This message is used to activate/deactivate |
||
| 376 | * an output channel. |
||
| 377 | */ |
||
| 1503 | myhrman | 378 | if (rxMsg->Length == 2) { |
| 1528 | myhrman | 379 | uint8_t channel = rxMsg->Data[0]; |
| 1532 | myhrman | 380 | if (channel >= 0 && channel < act_protectedOutput_CH_COUNT) { |
| 1528 | myhrman | 381 | outputStateTarget[channel] = rxMsg->Data[1]; |
| 1503 | myhrman | 382 | readDiagPin(); |
| 383 | updateOutput(); |
||
| 1535 | myhrman | 384 | #if act_protectedOutput_EEPROM_ENABLED == 1 |
| 1534 | myhrman | 385 | // output states changed, store to EE after thie timer delay |
| 386 | Timer_SetTimeout(act_protectedOutput_STORE_VALUE_TIMEOUT, act_protectedOutput_STORE_VALUE_TIMEOUT_TIME_S*1000, TimerTypeOneShot, 0); |
||
| 1535 | myhrman | 387 | #endif |
| 1503 | myhrman | 388 | } |
| 389 | StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER); |
||
| 390 | rxMsg->Length = 2; |
||
| 391 | while (StdCan_Put(rxMsg) != StdCan_Ret_OK); |
||
| 392 | } |
||
| 393 | break; |
||
| 394 | } |
||
| 395 | } |
||
| 396 | } |
||
| 397 | |||
| 398 | |||
| 399 | void act_protectedOutput_List(uint8_t ModuleSequenceNumber) |
||
| 400 | { |
||
| 401 | StdCan_Msg_t txMsg; |
||
| 402 | StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT); |
||
| 403 | StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER); |
||
| 1511 | arune | 404 | txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_PROTECTEDOUTPUT; |
| 1503 | myhrman | 405 | txMsg.Header.ModuleId = act_protectedOutput_ID; |
| 406 | txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST; |
||
| 407 | txMsg.Length = 6; |
||
| 408 | |||
| 409 | txMsg.Data[0] = NODE_HW_ID_BYTE0; |
||
| 410 | txMsg.Data[1] = NODE_HW_ID_BYTE1; |
||
| 411 | txMsg.Data[2] = NODE_HW_ID_BYTE2; |
||
| 412 | txMsg.Data[3] = NODE_HW_ID_BYTE3; |
||
| 413 | |||
| 414 | txMsg.Data[4] = NUMBER_OF_MODULES; |
||
| 415 | txMsg.Data[5] = ModuleSequenceNumber; |
||
| 416 | |||
| 417 | while (StdCan_Put(&txMsg) != StdCan_Ret_OK); |
||
| 418 | } |
||
| 419 |