Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "sns_power.h"
  3.  
  4. static uint32_t volatile PreviusTimerValue, lastMeasurment;
  5.  
  6. #ifdef sns_power_10000_PULSES_PER_KWH
  7.   static uint8_t volatile tmpCounter=0;
  8. #endif
  9. static uint8_t volatile StoreInEEPROM = 0;
  10. static uint8_t sns_power_ReportInterval = (uint8_t)sns_power_SEND_PERIOD;
  11. static uint16_t volatile MeasurmentBuffer[32]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  12. static uint8_t volatile MeasurmentBufferPointer=0;
  13. static uint32_t volatile EnergyCounter=0;
  14. #if sns_power_SEND_1_MIN_AVG == 1
  15.   static uint16_t volatile avgCounter = 0;
  16. #endif
  17.  
  18. #ifdef POWER_SNS_PIN_ch2
  19.   static uint32_t volatile PreviusTimerValue_ch2, lastMeasurment_ch2;
  20.  
  21.   #ifdef sns_power_10000_PULSES_PER_KWH
  22.     static uint8_t volatile tmpCounter_ch2=0;
  23.   #endif
  24.   static uint16_t volatile MeasurmentBuffer_ch2[32]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  25.   static uint8_t volatile MeasurmentBufferPointer_ch2=0;
  26.   static uint32_t volatile EnergyCounter_ch2=0;
  27.   #if sns_power_SEND_1_MIN_AVG == 1
  28.     static uint16_t volatile avgCounter_ch2 = 0;
  29.   #endif
  30. #endif
  31. #if sns_power_USEEEPROM==1
  32.   #include "sns_power_eeprom.h"
  33.   struct eeprom_sns_power EEMEM eeprom_sns_power =
  34.   {
  35.       {
  36.           ///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.
  37.           (uint8_t)sns_power_SEND_PERIOD,   // reportInterval
  38.           0,    // EnergyCounterUpper
  39.           0,    // EnergyCounterLower
  40.           #ifdef POWER_SNS_PIN_ch2
  41.             0,  // EnergyCounterUpper_ch2
  42.             0,  // EnergyCounterLower_ch2
  43.           #endif
  44.       },
  45.       0 // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  46.   };
  47. #endif
  48.  
  49. #if sns_power_SEND_1_MIN_AVG == 1
  50.   void sns_power_timer_callback(uint8_t timer)
  51.   {
  52.       StdCan_Msg_t txMsg;
  53.       StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  54.       StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  55.       txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_POWER;
  56.       txMsg.Header.ModuleId = sns_power_ID;
  57.       txMsg.Header.Command = CAN_MODULE_CMD_POWER_AVGPOWER;
  58.       txMsg.Length = 2;
  59.       cli();
  60.       txMsg.Data[0] = (uint8_t)((avgCounter>>8) & 0xff);
  61.       txMsg.Data[1] = (uint8_t)(avgCounter & 0xff);
  62.       avgCounter = 0;
  63.       sei();
  64.       while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  65.  
  66.       #ifdef POWER_SNS_PIN_ch2
  67.         txMsg.Length = 2;
  68.         txMsg.Header.ModuleId = sns_power_ID_ch2;
  69.         cli();
  70.         txMsg.Data[0] = (uint8_t)((avgCounter_ch2>>8) & 0xff);
  71.         txMsg.Data[1] = (uint8_t)(avgCounter_ch2 & 0xff);
  72.         avgCounter = 0;
  73.         sei();
  74.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  75.  
  76.       #endif
  77.   }
  78. #endif
  79.  
  80. void sns_power_pcint_callback(uint8_t id, uint8_t status)
  81. {
  82.     if (status == 0)
  83.     {
  84.         if (Timer_GetTicks() - PreviusTimerValue >= 16)
  85.         {
  86.             MeasurmentBufferPointer++;
  87.             if (MeasurmentBufferPointer >= 32) MeasurmentBufferPointer = 0;
  88.             lastMeasurment =  Timer_GetTicks() - PreviusTimerValue;
  89.             MeasurmentBuffer[MeasurmentBufferPointer] = (uint16_t) (lastMeasurment & 0x0000FFFF);
  90.             PreviusTimerValue = Timer_GetTicks();
  91.             #if sns_power_100_PULSES_PER_KWH == 1
  92.                 EnergyCounter+=10;
  93.                 if (EnergyCounter % 1024 == 0)
  94.                     StoreInEEPROM = 1; 
  95.             #endif
  96.             #if sns_power_1000_PULSES_PER_KWH == 1
  97.                 EnergyCounter++;
  98.                 if (EnergyCounter % 1024 == 0)
  99.                     StoreInEEPROM = 1; 
  100.             #endif
  101.             #if sns_power_10000_PULSES_PER_KWH == 1
  102.                 tmpCounter++;
  103.                 #if sns_power_SEND_1_MIN_AVG == 1
  104.                 avgCounter++;
  105.                 #endif
  106.                 if(tmpCounter >= 10) {
  107.                     EnergyCounter++;
  108.                     if (EnergyCounter % 1024 == 0)
  109.                         StoreInEEPROM = 1;
  110.                     tmpCounter = 0;
  111.                 }
  112.             #endif
  113.  
  114. #ifdef sns_power_LED_PIN
  115.             gpio_toggle_pin(sns_power_LED_PIN); // toggle pin
  116. #endif
  117.         }
  118.     }
  119. }
  120.  
  121. #ifdef POWER_SNS_PIN_ch2
  122. void sns_power_pcint_callback_ch2(uint8_t id, uint8_t status)
  123. {
  124.     if (status == 0)
  125.     {
  126.         if (Timer_GetTicks() - PreviusTimerValue_ch2 >= 16)
  127.         {
  128.             MeasurmentBufferPointer_ch2++;
  129.             if (MeasurmentBufferPointer_ch2 >= 32) MeasurmentBufferPointer_ch2 = 0;
  130.             lastMeasurment_ch2 =  Timer_GetTicks() - PreviusTimerValue_ch2;
  131.             MeasurmentBuffer_ch2[MeasurmentBufferPointer_ch2] = (uint16_t) (lastMeasurment_ch2 & 0x0000FFFF);
  132.             PreviusTimerValue_ch2 = Timer_GetTicks();
  133.             #if sns_power_100_PULSES_PER_KWH == 1
  134.                 EnergyCounter_ch2+=10;
  135.             #endif
  136.             #if sns_power_1000_PULSES_PER_KWH == 1
  137.                 EnergyCounter_ch2++;
  138.             #endif
  139.             #if sns_power_10000_PULSES_PER_KWH == 1
  140.                 tmpCounter_ch2++;
  141.                 #if sns_power_SEND_1_MIN_AVG == 1
  142.                 avgCounter_ch2++;
  143.                 #endif
  144.                 if(tmpCounter_ch2 >= 10) {
  145.                     EnergyCounter_ch2++;
  146.                     tmpCounter_ch2 = 0;
  147.                 }
  148.             #endif
  149. #ifdef sns_power_LED_PIN
  150.             gpio_toggle_pin(sns_power_LED_PIN); // toggle pin
  151. #endif
  152.         }
  153.     }
  154. }
  155. #endif
  156.  
  157. void sns_power_Init(void)
  158. {
  159. #if sns_power_USEEEPROM==1
  160.     if (EEDATA_OK)
  161.     {
  162.       ///TODO: Use stored data to set initial values for the module
  163.       sns_power_ReportInterval = eeprom_read_byte(EEDATA.reportInterval);
  164.       EnergyCounter = eeprom_read_word(EEDATA16.EnergyCounterLower);
  165.       EnergyCounter += (((uint32_t)(eeprom_read_word(EEDATA16.EnergyCounterUpper)))<<16);
  166.         #ifdef POWER_SNS_PIN_ch2
  167.           EnergyCounter_ch2 = eeprom_read_word(EEDATA16.EnergyCounterLower_ch2);
  168.           EnergyCounter_ch2 += (((uint32_t)(eeprom_read_word(EEDATA16.EnergyCounterUpper_ch2)))<<16);
  169.         #endif
  170.     } else
  171.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  172.       eeprom_write_byte_crc(EEDATA.reportInterval, sns_power_SEND_PERIOD, WITHOUT_CRC);
  173.       eeprom_write_word_crc(EEDATA16.EnergyCounterUpper, 0, WITHOUT_CRC);
  174.       eeprom_write_word_crc(EEDATA16.EnergyCounterLower, 0, WITHOUT_CRC);
  175.       #ifdef POWER_SNS_PIN_ch2
  176.         eeprom_write_word_crc(EEDATA16.EnergyCounterUpper_ch2, 0, WITHOUT_CRC);
  177.         eeprom_write_word_crc(EEDATA16.EnergyCounterLower_ch2, 0, WITHOUT_CRC);
  178.       #endif
  179.       EEDATA_UPDATE_CRC;
  180.       sns_power_ReportInterval = eeprom_read_byte(EEDATA.reportInterval);
  181.     }
  182. #endif  
  183.     ///Initialize hardware etc
  184.     gpio_set_in(POWER_SNS_PIN); // Set to input
  185. #if sns_power_PIN_PULLUP==1
  186.     gpio_set_pullup(POWER_SNS_PIN); // Enable pull-up
  187. #endif
  188.  
  189.     Pcint_SetCallbackPin(sns_power_PCINT, POWER_SNS_PIN, &sns_power_pcint_callback);
  190.  
  191.     MeasurmentBufferPointer = 0;
  192. #ifdef POWER_SNS_PIN_ch2
  193.     gpio_set_in(POWER_SNS_PIN_ch2); // Set to input
  194. #if sns_power_PIN_PULLUP_ch2==1
  195.     gpio_set_pullup(POWER_SNS_PIN_ch2); // Enable pull-up
  196. #endif
  197.    
  198.     Pcint_SetCallbackPin(sns_power_PCINT_ch2, POWER_SNS_PIN_ch2, &sns_power_pcint_callback_ch2);
  199.  
  200.     MeasurmentBufferPointer_ch2 = 0;
  201. #endif
  202.     Timer_SetTimeout(sns_power_SEND_TIMER, sns_power_ReportInterval*1000 , TimerTypeFreeRunning, 0);
  203. #if sns_power_SEND_1_MIN_AVG == 1
  204.     Timer_SetTimeout(sns_power_SEND_TIMER_1_MIN_AVG, 60000-10 , TimerTypeFreeRunning, &sns_power_timer_callback);
  205. #endif
  206.  
  207. #ifdef sns_power_LED_PIN
  208.     gpio_set_out(sns_power_LED_PIN);    // Set to output
  209.     gpio_clr_pin(sns_power_LED_PIN);    // clear pin
  210. #endif
  211. }
  212.  
  213. void sns_power_Process(void)
  214. {
  215.     if (StoreInEEPROM == 1)
  216.     {
  217.         StoreInEEPROM = 0;
  218.        
  219.         eeprom_write_word_crc(EEDATA16.EnergyCounterUpper, (uint16_t)((EnergyCounter>>16) & 0xffff), WITHOUT_CRC);
  220.         eeprom_write_word_crc(EEDATA16.EnergyCounterLower, (uint16_t)(EnergyCounter & 0xffff), WITH_CRC);
  221.     #ifdef POWER_SNS_PIN_ch2
  222.         eeprom_write_word_crc(EEDATA16.EnergyCounterUpper_ch2, (uint16_t)((EnergyCounter_ch2>>16) & 0xffff), WITHOUT_CRC);
  223.         eeprom_write_word_crc(EEDATA16.EnergyCounterLower_ch2, (uint16_t)(EnergyCounter_ch2 & 0xffff), WITH_CRC);
  224.     #endif
  225.     }
  226.     StdCan_Msg_t txMsg;
  227.     if (Timer_Expired(sns_power_SEND_TIMER)) {
  228.         //4 times average
  229.         /*uint32_t Avg4 = MeasurmentBuffer[MeasurmentBufferPointer] + MeasurmentBuffer[MeasurmentBufferPointer-1] + MeasurmentBuffer[MeasurmentBufferPointer-2] + MeasurmentBuffer[MeasurmentBufferPointer-3];
  230.         Avg4 = (360000/(Avg4/4));
  231.         */
  232.         //32 times average
  233.         uint32_t Avg32 = 0;
  234.         for (uint8_t i = 0; i<32;i++) {
  235.              Avg32 += MeasurmentBuffer[i];
  236.         }
  237.         Avg32 /= 32;
  238.         #if sns_power_100_PULSES_PER_KWH == 1
  239.             Avg32 = (36000000UL/Avg32);
  240.         #endif
  241.         #if sns_power_1000_PULSES_PER_KWH == 1
  242.             Avg32 = (3600000/Avg32);
  243.         #endif
  244.         #if sns_power_10000_PULSES_PER_KWH == 1
  245.             Avg32 = (360000/Avg32);
  246.         #endif
  247.  
  248.            
  249.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  250.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  251.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_POWER;
  252.         txMsg.Header.ModuleId = sns_power_ID;
  253.         txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_ELECTRICPOWER;
  254.         txMsg.Length = 8;
  255.         #if sns_power_100_PULSES_PER_KWH == 1
  256.             uint32_t tmp = 36000000UL/MeasurmentBuffer[MeasurmentBufferPointer];
  257.         #endif
  258.         #if sns_power_1000_PULSES_PER_KWH == 1
  259.             uint32_t tmp = 3600000/MeasurmentBuffer[MeasurmentBufferPointer];
  260.         #endif
  261.         #if sns_power_10000_PULSES_PER_KWH == 1
  262.             uint32_t tmp = 360000/MeasurmentBuffer[MeasurmentBufferPointer];
  263.         #endif
  264.         txMsg.Data[0] = (uint8_t)((tmp>>8) & 0xff);
  265.         txMsg.Data[1] = (uint8_t)(tmp & 0xff);
  266.         txMsg.Data[5] = (uint8_t)EnergyCounter & 0xff;
  267.         txMsg.Data[4] = (uint8_t)(EnergyCounter >> 8) & 0xff;
  268.         txMsg.Data[3] = (uint8_t)(EnergyCounter >> 16) & 0xff;
  269.         txMsg.Data[2] = (uint8_t)(EnergyCounter >> 24) & 0xff;
  270.         txMsg.Data[6] = (uint8_t)((Avg32>>8) & 0xff);
  271.         txMsg.Data[7] = (uint8_t)(Avg32 & 0xff);
  272.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  273.        
  274.     #ifdef POWER_SNS_PIN_ch2
  275.         uint32_t Avg32_ch2 = 0;
  276.         for (uint8_t i = 0; i<32;i++) {
  277.              Avg32_ch2 += MeasurmentBuffer_ch2[i];
  278.         }
  279.         Avg32_ch2 /= 32;
  280.         #if sns_power_100_PULSES_PER_KWH == 1
  281.             Avg32_ch2 = (36000000UL/Avg32_ch2);
  282.         #endif
  283.         #if sns_power_1000_PULSES_PER_KWH == 1
  284.             Avg32_ch2 = (3600000/Avg32_ch2);
  285.         #endif
  286.         #if sns_power_10000_PULSES_PER_KWH == 1
  287.             Avg32_ch2 = (360000/Avg32_ch2);
  288.         #endif
  289.            
  290.         txMsg.Header.ModuleId = sns_power_ID_ch2;
  291.         #if sns_power_100_PULSES_PER_KWH == 1
  292.             tmp = 36000000UL/MeasurmentBuffer_ch2[MeasurmentBufferPointer_ch2];
  293.         #endif
  294.         #if sns_power_1000_PULSES_PER_KWH == 1
  295.             tmp = 3600000/MeasurmentBuffer_ch2[MeasurmentBufferPointer_ch2];
  296.         #endif
  297.         #if sns_power_10000_PULSES_PER_KWH == 1
  298.             tmp = 360000/MeasurmentBuffer_ch2[MeasurmentBufferPointer_ch2];
  299.         #endif
  300.         txMsg.Data[0] = (uint8_t)((tmp>>8) & 0xff);
  301.         txMsg.Data[1] = (uint8_t)(tmp & 0xff);
  302.         txMsg.Data[5] = (uint8_t)EnergyCounter_ch2 & 0xff;
  303.         txMsg.Data[4] = (uint8_t)(EnergyCounter_ch2 >> 8) & 0xff;
  304.         txMsg.Data[3] = (uint8_t)(EnergyCounter_ch2 >> 16) & 0xff;
  305.         txMsg.Data[2] = (uint8_t)(EnergyCounter_ch2 >> 24) & 0xff;
  306.         txMsg.Data[6] = (uint8_t)((Avg32_ch2>>8) & 0xff);
  307.         txMsg.Data[7] = (uint8_t)(Avg32_ch2 & 0xff);
  308.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  309.        
  310.     #endif
  311.        
  312.        
  313.     }
  314. }
  315.  
  316. void sns_power_HandleMessage(StdCan_Msg_t *rxMsg)
  317. {
  318.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  319.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  320.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_SNS_POWER &&
  321.         rxMsg->Header.ModuleId == sns_power_ID)
  322.     {
  323. StdCan_Msg_t txMsg;
  324.         switch (rxMsg->Header.Command)
  325.         {
  326.         case CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL:
  327.             if (rxMsg->Length > 0)
  328.             {
  329.                 sns_power_ReportInterval = rxMsg->Data[0];
  330.                 Timer_SetTimeout(sns_power_SEND_TIMER, sns_power_ReportInterval*1000 , TimerTypeFreeRunning, 0);
  331.             }
  332.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  333.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  334.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_POWER;
  335.             txMsg.Header.ModuleId = sns_power_ID;
  336.             txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL;
  337.             txMsg.Length = 1;
  338.             txMsg.Data[0] = sns_power_ReportInterval;
  339.             StdCan_Put(&txMsg);
  340.             break;
  341.         case CAN_MODULE_CMD_POWER_SETENERGY:
  342.             if (rxMsg->Length == 4)
  343.             {
  344.                 EnergyCounter = rxMsg->Data[3];
  345.                 EnergyCounter += ((uint32_t)rxMsg->Data[2])<<8;
  346.                 EnergyCounter += ((uint32_t)rxMsg->Data[1])<<16;
  347.                 EnergyCounter += ((uint32_t)rxMsg->Data[0])<<24;
  348.             }
  349.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  350.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  351.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_POWER;
  352.             txMsg.Header.ModuleId = sns_power_ID;
  353.             txMsg.Header.Command = CAN_MODULE_CMD_POWER_SETENERGY;
  354.             txMsg.Length = 1;
  355.             txMsg.Data[3] = (uint8_t)EnergyCounter & 0xff;
  356.             txMsg.Data[2] = (uint8_t)(EnergyCounter >> 8) & 0xff;
  357.             txMsg.Data[1] = (uint8_t)(EnergyCounter >> 16) & 0xff;
  358.             txMsg.Data[0] = (uint8_t)(EnergyCounter >> 24) & 0xff;
  359.             StdCan_Put(&txMsg);
  360.            
  361.             break;
  362.         }
  363.     }
  364.    
  365. #ifdef POWER_SNS_PIN_ch2   
  366.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  367.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  368.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_SNS_POWER &&
  369.         rxMsg->Header.ModuleId == sns_power_ID_ch2)
  370.     {
  371.         StdCan_Msg_t txMsg;
  372.         switch (rxMsg->Header.Command)
  373.         {
  374.         case CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL:
  375.             if (rxMsg->Length > 0)
  376.             {
  377.                 sns_power_ReportInterval = rxMsg->Data[0];
  378.                 Timer_SetTimeout(sns_power_SEND_TIMER, sns_power_ReportInterval*1000 , TimerTypeFreeRunning, 0);
  379.             }
  380.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  381.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  382.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_POWER;
  383.             txMsg.Header.ModuleId = sns_power_ID_ch2;
  384.             txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL;
  385.             txMsg.Length = 1;
  386.             txMsg.Data[0] = sns_power_ReportInterval;
  387.             StdCan_Put(&txMsg);
  388.             break;
  389.         case CAN_MODULE_CMD_POWER_SETENERGY:
  390.             if (rxMsg->Length == 4)
  391.             {
  392.                 EnergyCounter_ch2 = rxMsg->Data[3];
  393.                 EnergyCounter_ch2 += ((uint32_t)rxMsg->Data[2])<<8;
  394.                 EnergyCounter_ch2 += ((uint32_t)rxMsg->Data[1])<<16;
  395.                 EnergyCounter_ch2 += ((uint32_t)rxMsg->Data[0])<<24;
  396.             }
  397.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  398.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  399.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_POWER;
  400.             txMsg.Header.ModuleId = sns_power_ID_ch2;
  401.             txMsg.Header.Command = CAN_MODULE_CMD_POWER_SETENERGY;
  402.             txMsg.Length = 1;
  403.             txMsg.Data[3] = (uint8_t)EnergyCounter_ch2 & 0xff;
  404.             txMsg.Data[2] = (uint8_t)(EnergyCounter_ch2 >> 8) & 0xff;
  405.             txMsg.Data[1] = (uint8_t)(EnergyCounter_ch2 >> 16) & 0xff;
  406.             txMsg.Data[0] = (uint8_t)(EnergyCounter_ch2 >> 24) & 0xff;
  407.             StdCan_Put(&txMsg);
  408.            
  409.             break;
  410.         }
  411.     }
  412. #endif
  413.    
  414. }
  415.  
  416. void sns_power_List(uint8_t ModuleSequenceNumber)
  417. {
  418.     StdCan_Msg_t txMsg;
  419.    
  420.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  421.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  422.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_POWER;
  423.     txMsg.Header.ModuleId = sns_power_ID;
  424.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  425.     txMsg.Length = 6;
  426.  
  427.     uint32_t HwId=BIOS_GetHwId();
  428.     txMsg.Data[0] = HwId&0xff;
  429.     txMsg.Data[1] = (HwId>>8)&0xff;
  430.     txMsg.Data[2] = (HwId>>16)&0xff;
  431.     txMsg.Data[3] = (HwId>>24)&0xff;
  432.    
  433.     txMsg.Data[4] = NUMBER_OF_MODULES;
  434.     txMsg.Data[5] = ModuleSequenceNumber;
  435.    
  436.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  437.    
  438.    
  439. #ifdef POWER_SNS_PIN_ch2   
  440.     txMsg.Header.ModuleId = sns_power_ID_ch2;
  441.     txMsg.Data[5] = ModuleSequenceNumber;
  442.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  443. #endif
  444. }
  445.