Subversion Repositories HomeAutomation

Rev

Rev 1978 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1.  
  2. #include "sns_counter.h"
  3.  
  4. #ifdef sns_counter_CH0_DEBOUNCE_TIME_MS==1 | sns_counter_CH1_DEBOUNCE_TIME_MS==1 | sns_counter_CH2_DEBOUNCE_TIME_MS==1 | sns_counter_CH3_DEBOUNCE_TIME_MS==1 | sns_counter_CH4_DEBOUNCE_TIME_MS==1 | sns_counter_CH5_DEBOUNCE_TIME_MS==1 | sns_counter_CH6_DEBOUNCE_TIME_MS==1 | sns_counter_CH7_DEBOUNCE_TIME_MS==1
  5. static uint32_t volatile PreviousTimerValue[8];
  6. #endif
  7. #if sns_counter_USEEEPROM==1
  8. static uint8_t volatile StoreInEEPROM = 0;
  9. #endif
  10. static uint8_t sns_counter_ReportInterval = (uint8_t)sns_counter_SEND_PERIOD;
  11. static uint32_t volatile Count[8];
  12.  
  13. #define IO_LOW      0
  14.  
  15. #if sns_counter_USEEEPROM==1
  16. #include "sns_counter_eeprom.h"
  17. struct eeprom_sns_counter EEMEM eeprom_sns_counter =
  18. {
  19.     {
  20.         (uint8_t)sns_counter_SEND_PERIOD,   // reportInterval
  21. #ifdef sns_counter_CH0
  22.         0,                  // Count[0]
  23. #endif
  24. #ifdef sns_counter_CH1
  25.         0,                  // Count[1]
  26. #endif
  27. #ifdef sns_counter_CH2
  28.         0,                  // Count[2]
  29. #endif
  30. #ifdef sns_counter_CH3
  31.         0,                  // Count[3]
  32. #endif
  33. #ifdef sns_counter_CH4
  34.         0,                  // Count[4]
  35. #endif
  36. #ifdef sns_counter_CH5
  37.         0,                  // Count[5]
  38. #endif
  39. #ifdef sns_counter_CH6
  40.         0,                  // Count[6]
  41. #endif
  42. #ifdef sns_counter_CH7
  43.         0,                  // Count[7]
  44. #endif
  45.     },
  46.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  47. };
  48. #endif
  49.  
  50. uint8_t sns_counter_save_data(void)
  51. {
  52. #if sns_counter_USEEEPROM==1
  53.     eeprom_write_byte_crc(EEDATA.reportInterval, sns_counter_SEND_PERIOD, WITHOUT_CRC);
  54. #ifdef sns_counter_CH0
  55.     eeprom_write_dword_crc(EEDATA32.Count[0], 0, WITHOUT_CRC);
  56. #endif
  57. #ifdef sns_counter_CH1
  58.     eeprom_write_dword_crc(EEDATA32.Count[1], 0, WITHOUT_CRC);
  59. #endif
  60. #ifdef sns_counter_CH2
  61.     eeprom_write_dword_crc(EEDATA32.Count[2], 0, WITHOUT_CRC);
  62. #endif
  63. #ifdef sns_counter_CH3
  64.     eeprom_write_dword_crc(EEDATA32.Count[3], 0, WITHOUT_CRC);
  65. #endif
  66. #ifdef sns_counter_CH4
  67.     eeprom_write_dword_crc(EEDATA32.Count[4], 0, WITHOUT_CRC);
  68. #endif
  69. #ifdef sns_counter_CH5
  70.     eeprom_write_dword_crc(EEDATA32.Count[5], 0, WITHOUT_CRC);
  71. #endif
  72. #ifdef sns_counter_CH6
  73.     eeprom_write_dword_crc(EEDATA32.Count[6], 0, WITHOUT_CRC);
  74. #endif
  75. #ifdef sns_counter_CH7
  76.     eeprom_write_dword_crc(EEDATA32.Count[7], 0, WITHOUT_CRC);
  77. #endif
  78.     EEDATA_UPDATE_CRC;
  79.     return 0;
  80. #else
  81.     return 2;
  82. #endif
  83. }
  84.  
  85. void sns_counter_send_counter(uint8_t index)
  86. {
  87.     StdCan_Msg_t txMsg;
  88.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  89.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  90.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_COUNTER;
  91.     txMsg.Header.ModuleId = sns_counter_ID;
  92.     txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_COUNTER;
  93.     txMsg.Length = 5;
  94.     txMsg.Data[0] = index;
  95.     txMsg.Data[4] = (uint8_t)Count[index] & 0xff;
  96.     txMsg.Data[3] = (uint8_t)(Count[index] >> 8) & 0xff;
  97.     txMsg.Data[2] = (uint8_t)(Count[index] >> 16) & 0xff;
  98.     txMsg.Data[1] = (uint8_t)(Count[index] >> 24) & 0xff;
  99.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  100. }
  101.  
  102. /*
  103.  
  104. Callback function that is called from pin-change driver on AVR IO
  105. id gives which pin that changed, status is the new state of the changed pin
  106.  
  107. */
  108. void sns_counter_pcint_callback(uint8_t id, uint8_t status)
  109. {
  110. #ifdef sns_counter_CH0
  111.     if (id == sns_counter_PCINT_CH0) {
  112.         if (status == IO_LOW) {
  113. #if sns_counter_CH0_DEBOUNCE_TIME_MS
  114.             if (Timer_GetTicks() - PreviousTimerValue[0] >= sns_counter_CH0_DEBOUNCE_TIME_MS)
  115.             {
  116.                 PreviousTimerValue[0] = Timer_GetTicks();
  117. #endif
  118.                 Count[0]++;
  119.                 sns_counter_send_counter(0);
  120. #if defined sns_counter_USEEEPROM && defined sns_counter_CH0_EEPROM_FREQ
  121.                 if (Count[0] % sns_counter_CH0_EEPROM_FREQ == 0)
  122.                     StoreInEEPROM = 1;
  123. #endif
  124. #if sns_counter_CH0_DEBOUNCE_TIME_MS
  125.             }
  126. #endif
  127.         }
  128.     }
  129. #endif
  130. #ifdef sns_counter_CH1
  131.     if (id == sns_counter_PCINT_CH1) {
  132.         if (status == IO_LOW) {
  133. #if sns_counter_CH1_DEBOUNCE_TIME_MS
  134.             if (Timer_GetTicks() - PreviousTimerValue[1] >= sns_counter_CH1_DEBOUNCE_TIME_MS)
  135.             {
  136.                 PreviousTimerValue[1] = Timer_GetTicks();
  137. #endif
  138.                 Count[1]++;
  139.                 sns_counter_send_counter(1);
  140. #if defined sns_counter_USEEEPROM && defined sns_counter_CH1_EEPROM_FREQ
  141.                 if (Count[1] % sns_counter_CH1_EEPROM_FREQ == 0)
  142.                     StoreInEEPROM = 1;
  143. #endif
  144. #if sns_counter_CH1_DEBOUNCE_TIME_MS
  145.             }
  146. #endif
  147.         }
  148.     }
  149. #endif
  150. #ifdef sns_counter_CH2
  151.     if (id == sns_counter_PCINT_CH2) {
  152.         if (status == IO_LOW) {
  153. #if sns_counter_CH2_DEBOUNCE_TIME_MS
  154.             if (Timer_GetTicks() - PreviousTimerValue[2] >= sns_counter_CH2_DEBOUNCE_TIME_MS)
  155.             {
  156.                 PreviousTimerValue[2] = Timer_GetTicks();
  157. #endif
  158.                 Count[2]++;
  159.                 sns_counter_send_counter(2);
  160. #if defined sns_counter_USEEEPROM && defined sns_counter_CH2_EEPROM_FREQ
  161.                 if (Count[2] % sns_counter_CH2_EEPROM_FREQ == 0)
  162.                     StoreInEEPROM = 1;
  163. #endif
  164. #if sns_counter_CH2_DEBOUNCE_TIME_MS
  165.             }
  166. #endif
  167.         }
  168.     }
  169. #endif
  170. #ifdef sns_counter_CH3
  171.     if (id == sns_counter_PCINT_CH3) {
  172.         if (status == IO_LOW) {
  173. #if sns_counter_CH3_DEBOUNCE_TIME_MS
  174.             if (Timer_GetTicks() - PreviousTimerValue[3] >= sns_counter_CH3_DEBOUNCE_TIME_MS)
  175.             {
  176.                 PreviousTimerValue[3] = Timer_GetTicks();
  177. #endif
  178.                 Count[3]++;
  179.                 sns_counter_send_counter(3);
  180. #if defined sns_counter_USEEEPROM && defined sns_counter_CH3_EEPROM_FREQ
  181.                 if (Count[3] % sns_counter_CH3_EEPROM_FREQ == 0)
  182.                     StoreInEEPROM = 1;
  183. #endif
  184. #if sns_counter_CH3_DEBOUNCE_TIME_MS
  185.             }
  186. #endif
  187.         }
  188.     }
  189. #endif
  190. #ifdef sns_counter_CH4
  191.     if (id == sns_counter_PCINT_CH4) {
  192.         if (status == IO_LOW) {
  193. #if sns_counter_CH4_DEBOUNCE_TIME_MS
  194.             if (Timer_GetTicks() - PreviousTimerValue[4] >= sns_counter_CH4_DEBOUNCE_TIME_MS)
  195.             {
  196.                 PreviousTimerValue[4] = Timer_GetTicks();
  197. #endif
  198.                 Count[4]++;
  199.                 sns_counter_send_counter(4);
  200. #if defined sns_counter_USEEEPROM && defined sns_counter_CH4_EEPROM_FREQ
  201.                 if (Count[4] % sns_counter_CH4_EEPROM_FREQ == 0)
  202.                     StoreInEEPROM = 1;
  203. #endif
  204. #if sns_counter_CH5_DEBOUNCE_TIME_MS
  205.             }
  206. #endif
  207.         }
  208.     }
  209. #endif
  210. #ifdef sns_counter_CH5
  211.     if (id == sns_counter_PCINT_CH5) {
  212.         if (status == IO_LOW) {
  213. #if sns_counter_CH5_DEBOUNCE_TIME_MS
  214.             if (Timer_GetTicks() - PreviousTimerValue[5] >= sns_counter_CH5_DEBOUNCE_TIME_MS)
  215.             {
  216.                 PreviousTimerValue[5] = Timer_GetTicks();
  217. #endif
  218.                 Count[5]++;
  219.                 sns_counter_send_counter(5);
  220. #if defined sns_counter_USEEEPROM && defined sns_counter_CH5_EEPROM_FREQ
  221.                 if (Count[5] % sns_counter_CH5_EEPROM_FREQ == 0)
  222.                     StoreInEEPROM = 1;
  223. #endif
  224. #if sns_counter_CH5_DEBOUNCE_TIME_MS
  225.             }
  226. #endif
  227.         }
  228.     }
  229. #endif
  230. #ifdef sns_counter_CH6
  231.     if (id == sns_counter_PCINT_CH6) {
  232.         if (status == IO_LOW) {
  233. #if sns_counter_CH6_DEBOUNCE_TIME_MS
  234.             if (Timer_GetTicks() - PreviousTimerValue[6] >= sns_counter_CH6_DEBOUNCE_TIME_MS)
  235.             {
  236.                 PreviousTimerValue[6] = Timer_GetTicks();
  237. #endif
  238.                 Count[6]++;
  239.                 sns_counter_send_counter(6);
  240. #if defined sns_counter_USEEEPROM && defined sns_counter_CH6_EEPROM_FREQ
  241.                 if (Count[6] % sns_counter_CH6_EEPROM_FREQ == 0)
  242.                     StoreInEEPROM = 1;
  243. #endif
  244. #if sns_counter_CH6_DEBOUNCE_TIME_MS
  245.             }
  246. #endif
  247.         }
  248.     }
  249. #endif
  250. #ifdef sns_counter_CH7
  251.     if (id == sns_counter_PCINT_CH7) {
  252.         if (status == IO_LOW) {
  253. #if sns_counter_CH7_DEBOUNCE_TIME_MS
  254.             if (Timer_GetTicks() - PreviousTimerValue[7] >= sns_counter_CH7_DEBOUNCE_TIME_MS)
  255.             {
  256.                 PreviousTimerValue[7] = Timer_GetTicks();
  257. #endif
  258.                 Count[7]++;
  259.                 sns_counter_send_counter(7);
  260. #if defined sns_counter_USEEEPROM && defined sns_counter_CH7_EEPROM_FREQ
  261.                 if (Count[7] % sns_counter_CH7_EEPROM_FREQ == 0)
  262.                     StoreInEEPROM = 1;
  263. #endif
  264. #if sns_counter_CH7_DEBOUNCE_TIME_MS
  265.             }
  266. #endif
  267.         }
  268.     }
  269. #endif
  270. }
  271.  
  272. void sns_counter_Init(void)
  273. {
  274. #if sns_counter_USEEEPROM==1
  275.     if (EEDATA_OK)
  276.     {
  277.         //Use stored data to set initial values for the module
  278.         sns_counter_ReportInterval = eeprom_read_byte(EEDATA.reportInterval);
  279. #ifdef sns_counter_CH0
  280.         Count[0] = eeprom_read_dword(EEDATA32.Count[0]);
  281. #endif
  282. #ifdef sns_counter_CH1
  283.         Count[1] = eeprom_read_dword(EEDATA32.Count[1]);
  284. #endif
  285. #ifdef sns_counter_CH2
  286.         Count[2] = eeprom_read_dword(EEDATA32.Count[2]);
  287. #endif
  288. #ifdef sns_counter_CH3
  289.         Count[3] = eeprom_read_dword(EEDATA32.Count[3]);
  290. #endif
  291. #ifdef sns_counter_CH4
  292.         Count[4] = eeprom_read_dword(EEDATA32.Count[4]);
  293. #endif
  294. #ifdef sns_counter_CH5
  295.         Count[5] = eeprom_read_dword(EEDATA32.Count[5]);
  296. #endif
  297. #ifdef sns_counter_CH6
  298.         Count[6] = eeprom_read_dword(EEDATA32.Count[6]);
  299. #endif
  300. #ifdef sns_counter_CH7
  301.         Count[7] = eeprom_read_dword(EEDATA32.Count[7]);
  302. #endif
  303.     } else
  304.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  305.         sns_counter_save_data();
  306.     }
  307. #endif
  308.     //Initialize hardware etc here
  309. #ifdef sns_counter_CH0
  310.     #if (sns_counter_CH0_pullup == 1)
  311.         gpio_set_pullup(sns_counter_CH0);
  312.     #else
  313.         gpio_clr_pullup(sns_counter_CH0);
  314.     #endif
  315.         gpio_set_in(sns_counter_CH0);
  316.         Pcint_SetCallbackPin(sns_counter_PCINT_CH0, sns_counter_CH0 , &sns_counter_pcint_callback);
  317. #endif
  318. #ifdef sns_counter_CH1
  319.     #if (sns_counter_CH1_pullup == 1)
  320.         gpio_set_pullup(sns_counter_CH1);
  321.     #else
  322.         gpio_clr_pullup(sns_counter_CH1);
  323.     #endif
  324.         gpio_set_in(sns_counter_CH1);
  325.         Pcint_SetCallbackPin(sns_counter_PCINT_CH1, sns_counter_CH1 , &sns_counter_pcint_callback);
  326. #endif
  327. #ifdef sns_counter_CH2
  328.     #if (sns_counter_CH2_pullup == 1)
  329.         gpio_set_pullup(sns_counter_CH2);
  330.     #else
  331.         gpio_clr_pullup(sns_counter_CH2);
  332.     #endif
  333.         gpio_set_in(sns_counter_CH2);
  334.         Pcint_SetCallbackPin(sns_counter_PCINT_CH2, sns_counter_CH2 , &sns_counter_pcint_callback);
  335. #endif
  336. #ifdef sns_counter_CH3
  337.     #if (sns_counter_CH3_pullup == 1)
  338.         gpio_set_pullup(sns_counter_CH3);
  339.     #else
  340.         gpio_clr_pullup(sns_counter_CH3);
  341.     #endif
  342.         gpio_set_in(sns_counter_CH3);
  343.         Pcint_SetCallbackPin(sns_counter_PCINT_CH3, sns_counter_CH3 , &sns_counter_pcint_callback);
  344. #endif
  345. #ifdef sns_counter_CH4
  346.     #if (sns_counter_CH4_pullup == 1)
  347.         gpio_set_pullup(sns_counter_CH4);
  348.     #else
  349.         gpio_clr_pullup(sns_counter_CH4);
  350.     #endif
  351.         gpio_set_in(sns_counter_CH4);
  352.         Pcint_SetCallbackPin(sns_counter_PCINT_CH4, sns_counter_CH4 , &sns_counter_pcint_callback);
  353. #endif
  354. #ifdef sns_counter_CH5
  355.     #if (sns_counter_CH5_pullup == 1)
  356.         gpio_set_pullup(sns_counter_CH5);
  357.     #else
  358.         gpio_clr_pullup(sns_counter_CH5);
  359.     #endif
  360.         gpio_set_in(sns_counter_CH5);
  361.         Pcint_SetCallbackPin(sns_counter_PCINT_CH5, sns_counter_CH5 , &sns_counter_pcint_callback);
  362. #endif
  363. #ifdef sns_counter_CH6
  364.     #if (sns_counter_CH6_pullup == 1)
  365.         gpio_set_pullup(sns_counter_CH6);
  366.     #else
  367.         gpio_clr_pullup(sns_counter_CH6);
  368.     #endif
  369.         gpio_set_in(sns_counter_CH6);
  370.         Pcint_SetCallbackPin(sns_counter_PCINT_CH6, sns_counter_CH6 , &sns_counter_pcint_callback);
  371. #endif
  372. #ifdef sns_counter_CH7
  373.     #if (sns_counter_CH7_pullup == 1)
  374.         gpio_set_pullup(sns_counter_CH7);
  375.     #else
  376.         gpio_clr_pullup(sns_counter_CH7);
  377.     #endif
  378.         gpio_set_in(sns_counter_CH7);
  379.         Pcint_SetCallbackPin(sns_counter_PCINT_CH7, sns_counter_CH7 , &sns_counter_pcint_callback);
  380. #endif
  381.  
  382. #ifdef sns_counter_SEND_TIMER
  383.     Timer_SetTimeout(sns_counter_SEND_TIMER, sns_counter_ReportInterval*1000 , TimerTypeFreeRunning, 0);
  384. #endif
  385. }
  386.  
  387. void sns_counter_Process(void)
  388. {
  389. #if sns_counter_USEEEPROM==1
  390.     if (StoreInEEPROM == 1)
  391.     {
  392.         StoreInEEPROM = 0;
  393.         eeprom_write_dword_crc(EEDATA32.Count[0], (uint32_t)(Count[0]), WITH_CRC);
  394.     }
  395. #endif
  396. #ifdef sns_counter_SEND_TIMER
  397.     if (Timer_Expired(sns_counter_SEND_TIMER)) {
  398.     #ifdef sns_counter_CH0
  399.         sns_counter_send_counter(0);
  400.     #endif
  401.     #ifdef sns_counter_CH1
  402.         sns_counter_send_counter(1);
  403.     #endif
  404.     #ifdef sns_counter_CH2
  405.         sns_counter_send_counter(2);
  406.     #endif
  407.     #ifdef sns_counter_CH3
  408.         sns_counter_send_counter(3);
  409.     #endif
  410.     #ifdef sns_counter_CH4
  411.         sns_counter_send_counter(4);
  412.     #endif
  413.     #ifdef sns_counter_CH5
  414.         sns_counter_send_counter(5);
  415.     #endif
  416.     #ifdef sns_counter_CH6
  417.         sns_counter_send_counter(6);
  418.     #endif
  419.     #ifdef sns_counter_CH7
  420.         sns_counter_send_counter(7);
  421.     #endif
  422.     }
  423. #endif
  424. }
  425.  
  426. void sns_counter_HandleMessage(StdCan_Msg_t *rxMsg)
  427. {
  428.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  429.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  430.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_SNS_COUNTER &&
  431.         rxMsg->Header.ModuleId == sns_counter_ID)
  432.     {
  433.         StdCan_Msg_t txMsg;
  434.  
  435.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  436.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  437.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_COUNTER;
  438.         txMsg.Header.ModuleId = sns_counter_ID;
  439.  
  440.         switch (rxMsg->Header.Command)
  441.         {
  442.         case CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL:
  443.             if (rxMsg->Length > 0)
  444.             {
  445.                 sns_counter_ReportInterval = rxMsg->Data[0];
  446.                 Timer_SetTimeout(sns_counter_SEND_TIMER, sns_counter_ReportInterval*1000 , TimerTypeFreeRunning, 0);
  447.             }
  448.             txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL;
  449.             txMsg.Length = 1;
  450.             txMsg.Data[0] = sns_counter_ReportInterval;
  451.             StdCan_Put(&txMsg);
  452.             break;
  453.         case CAN_MODULE_CMD_COUNTER_SETCOUNTER:
  454.             if (rxMsg->Length != 5)
  455.                 break;
  456.             if (
  457. #ifdef sns_counter_CH0
  458.                 (rxMsg->Data[0] != 0) &&
  459. #endif
  460. #ifdef sns_counter_CH1
  461.                 (rxMsg->Data[0] != 1) &&
  462. #endif
  463. #ifdef sns_counter_CH2
  464.                 (rxMsg->Data[0] != 2) &&
  465. #endif
  466. #ifdef sns_counter_CH3
  467.                 (rxMsg->Data[0] != 3) &&
  468. #endif
  469. #ifdef sns_counter_CH4
  470.                 (rxMsg->Data[0] != 4) &&
  471. #endif
  472. #ifdef sns_counter_CH5
  473.                 (rxMsg->Data[0] != 5) &&
  474. #endif
  475. #ifdef sns_counter_CH6
  476.                 (rxMsg->Data[0] != 6) &&
  477. #endif
  478. #ifdef sns_counter_CH7
  479.                 (rxMsg->Data[0] != 7) &&
  480. #endif
  481.                 1)
  482.                 break;
  483.             Count[rxMsg->Data[0]] = rxMsg->Data[4];
  484.             Count[rxMsg->Data[0]] += ((uint32_t)rxMsg->Data[3])<<8;
  485.             Count[rxMsg->Data[0]] += ((uint32_t)rxMsg->Data[2])<<16;
  486.             Count[rxMsg->Data[0]] += ((uint32_t)rxMsg->Data[1])<<24;
  487.             txMsg.Header.Command = CAN_MODULE_CMD_COUNTER_SETCOUNTER;
  488.             txMsg.Length = 5;
  489.             txMsg.Data[0] = rxMsg->Data[0]; // CH
  490.             txMsg.Data[4] = (uint8_t)Count[rxMsg->Data[0]] & 0xff;
  491.             txMsg.Data[3] = (uint8_t)(Count[rxMsg->Data[0]] >> 8) & 0xff;
  492.             txMsg.Data[2] = (uint8_t)(Count[rxMsg->Data[0]] >> 16) & 0xff;
  493.             txMsg.Data[1] = (uint8_t)(Count[rxMsg->Data[0]] >> 24) & 0xff;
  494.             StdCan_Put(&txMsg);
  495.             break;
  496.         }
  497.     }
  498. }
  499.  
  500. void sns_counter_List(uint8_t ModuleSequenceNumber)
  501. {
  502.     StdCan_Msg_t txMsg;
  503.  
  504.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  505.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  506.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_COUNTER;
  507.     txMsg.Header.ModuleId = sns_counter_ID;
  508.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  509.     txMsg.Length = 6;
  510.  
  511.     uint32_t HwId=BIOS_GetHwId();
  512.     txMsg.Data[0] = HwId&0xff;
  513.     txMsg.Data[1] = (HwId>>8)&0xff;
  514.     txMsg.Data[2] = (HwId>>16)&0xff;
  515.     txMsg.Data[3] = (HwId>>24)&0xff;
  516.  
  517.     txMsg.Data[4] = NUMBER_OF_MODULES;
  518.     txMsg.Data[5] = ModuleSequenceNumber;
  519.  
  520.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  521. }
  522.