Subversion Repositories HomeAutomation

Rev

Rev 1910 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1.  
  2. #include "sns_inputAnalog.h"
  3.  
  4. struct {
  5.     uint8_t             Status;         //Used for digital input, high or low
  6.     uint16_t            PeriodCnt;      //Counter for periodicity
  7.     uint16_t            LastSentAdVal;  //Remember the last sent AD value
  8. } sns_inputAnalog_Sensor[sns_inputAnalog_NUM_SUPPORTED];
  9.  
  10.  
  11. #define HIGH        1
  12. #define LOW         2
  13. #define NOCHANGE    0
  14.  
  15. #if sns_inputAnalog_USEEEPROM==1
  16. #include "sns_inputAnalog_eeprom.h"
  17.  
  18. struct eeprom_sns_inputAnalog EEMEM eeprom_sns_inputAnalog =
  19. {
  20.     {
  21.         {
  22.         /* Define initialization values on the EEPROM variables here, this will generate a *.eep file
  23.         that can be used to store this values to the node, can in future be done with a EEPROM module
  24.         and the make-scrips. Write the values in the exact same order as the struct is defined in the *.h file.  */
  25.         1*sns_inputAnalog0Factor/(2^sns_inputAnalog0Scale), //Config, low level threshold voltage, (1 volt)
  26.         2*sns_inputAnalog0Factor/(2^sns_inputAnalog0Scale), //Config, high level threshold voltage, (2 volts)
  27.         4800,   //Config, periodicity
  28.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE,   //Config, if sensor is of type periodic or digital input
  29.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_DISABLE,            //Config, if the pullup should be enabled
  30.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_DISABLE,         //Config, if the reference to GND should be enabled
  31.         },
  32. #if sns_inputAnalog_NUM_SUPPORTED>=2
  33.         {
  34.         1*sns_inputAnalog1Factor/(2^sns_inputAnalog1Scale), //Config, low level threshold voltage, (1 volt)
  35.         2*sns_inputAnalog1Factor/(2^sns_inputAnalog1Scale), //Config, high level threshold voltage, (2 volts)
  36.         4900,  
  37.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE,   //Config, if sensor is of type periodic or digital input
  38.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_DISABLE,            //Config, if the pullup should be enabled
  39.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_DISABLE,         //Config, if the reference to GND should be enabled
  40.         },
  41. #endif
  42. #if sns_inputAnalog_NUM_SUPPORTED>=3
  43.         {
  44.         1*sns_inputAnalog2Factor/(2^sns_inputAnalog2Scale), //Config, low level threshold voltage
  45.         2*sns_inputAnalog2Factor/(2^sns_inputAnalog2Scale), //Config, high level threshold voltage, (2 volts)
  46.         5100,
  47.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE,   //Config, if sensor is of type periodic or digital input
  48.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_DISABLE,            //Config, if the pullup should be enabled
  49.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_DISABLE,         //Config, if the reference to GND should be enabled
  50.         },
  51. #endif
  52. #if sns_inputAnalog_NUM_SUPPORTED>=4
  53.         {
  54.         1*sns_inputAnalog3Factor/(2^sns_inputAnalog3Scale), //Config, low level threshold voltage
  55.         2*sns_inputAnalog3Factor/(2^sns_inputAnalog3Scale), //Config, high level threshold voltage, (2 volts)
  56.         5200,
  57.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE,   //Config, if sensor is of type periodic or digital input
  58.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_DISABLE,            //Config, if the pullup should be enabled
  59.         CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_DISABLE,         //Config, if the reference to GND should be enabled
  60.         }
  61. #endif
  62.     },
  63.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  64. };
  65. #endif
  66.  
  67. /* Will set up pullup enable outputs according config */
  68. void setPullups(void)
  69. {
  70.     if (sns_inputAnalog_Config[0].PullupEnable==CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_ENABLE)
  71.     {
  72. #if sns_inputAnalog0PullupPCA95xx==0
  73.         gpio_set_pin(sns_inputAnalog0Pullup);
  74.         gpio_set_out(sns_inputAnalog0Pullup);
  75. #else
  76.         Pca95xx_set_pin(sns_inputAnalog0Pullup);
  77.         Pca95xx_set_out(sns_inputAnalog0Pullup);
  78. #endif
  79.     }
  80.     else
  81.     {
  82. #if sns_inputAnalog0PullupPCA95xx==0
  83.         gpio_clr_pin(sns_inputAnalog0Pullup);
  84.         gpio_set_out(sns_inputAnalog0Pullup);
  85. #else
  86.         Pca95xx_clr_pin(sns_inputAnalog0Pullup);
  87.         Pca95xx_set_out(sns_inputAnalog0Pullup);
  88. #endif
  89.     }
  90.    
  91. #if sns_inputAnalog_NUM_SUPPORTED>=2
  92.     if (sns_inputAnalog_Config[1].PullupEnable==CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_ENABLE)
  93.     {
  94. #if sns_inputAnalog1PullupPCA95xx==0
  95.         gpio_set_pin(sns_inputAnalog1Pullup);
  96.         gpio_set_out(sns_inputAnalog1Pullup);
  97. #else
  98.         Pca95xx_set_pin(sns_inputAnalog1Pullup);
  99.         Pca95xx_set_out(sns_inputAnalog1Pullup);
  100. #endif
  101.     }
  102.     else
  103.     {
  104. #if sns_inputAnalog1PullupPCA95xx==0
  105.         gpio_clr_pin(sns_inputAnalog1Pullup);
  106.         gpio_set_out(sns_inputAnalog1Pullup);
  107. #else
  108.         Pca95xx_clr_pin(sns_inputAnalog1Pullup);
  109.         Pca95xx_set_out(sns_inputAnalog1Pullup);
  110. #endif
  111.     }
  112. #endif
  113.  
  114. #if sns_inputAnalog_NUM_SUPPORTED>=3
  115.     if (sns_inputAnalog_Config[2].PullupEnable==CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_ENABLE)
  116.     {
  117. #if sns_inputAnalog2PullupPCA95xx==0
  118.         gpio_set_pin(sns_inputAnalog2Pullup);
  119.         gpio_set_out(sns_inputAnalog2Pullup);
  120. #else
  121.         Pca95xx_set_pin(sns_inputAnalog2Pullup);
  122.         Pca95xx_set_out(sns_inputAnalog2Pullup);
  123. #endif
  124.     }
  125.     else
  126.     {
  127. #if sns_inputAnalog2PullupPCA95xx==0
  128.         gpio_clr_pin(sns_inputAnalog2Pullup);
  129.         gpio_set_out(sns_inputAnalog2Pullup);
  130. #else
  131.         Pca95xx_clr_pin(sns_inputAnalog2Pullup);
  132.         Pca95xx_set_out(sns_inputAnalog2Pullup);
  133. #endif
  134.     }
  135. #endif
  136.  
  137. #if sns_inputAnalog_NUM_SUPPORTED>=4
  138.     if (sns_inputAnalog_Config[3].PullupEnable==CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_ENABLE)
  139.     {
  140. #if sns_inputAnalog3PullupPCA95xx==0
  141.         gpio_set_pin(sns_inputAnalog3Pullup);
  142.         gpio_set_out(sns_inputAnalog3Pullup);
  143. #else
  144.         Pca95xx_set_pin(sns_inputAnalog3Pullup);
  145.         Pca95xx_set_out(sns_inputAnalog3Pullup);
  146. #endif
  147.     }
  148.     else
  149.     {
  150. #if sns_inputAnalog3PullupPCA95xx==0
  151.         gpio_clr_pin(sns_inputAnalog3Pullup);
  152.         gpio_set_out(sns_inputAnalog3Pullup);
  153. #else
  154.         Pca95xx_clr_pin(sns_inputAnalog3Pullup);
  155.         Pca95xx_set_out(sns_inputAnalog3Pullup);
  156. #endif
  157.     }
  158. #endif
  159. }
  160.  
  161. /* Will set up reference enable outputs according config */
  162. void setReferences(void)
  163. {
  164.     if (sns_inputAnalog_Config[0].RefEnable==CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_ENABLE)
  165.     {
  166. #if sns_inputAnalog0RefPCA95xx==0
  167.         gpio_set_pin(sns_inputAnalog0Ref);
  168.         gpio_set_out(sns_inputAnalog0Ref);
  169. #else
  170.         Pca95xx_set_pin(sns_inputAnalog0Ref);
  171.         Pca95xx_set_out(sns_inputAnalog0Ref);
  172. #endif
  173.     }
  174.     else
  175.     {
  176. #if sns_inputAnalog0RefPCA95xx==0
  177.         gpio_clr_pin(sns_inputAnalog0Ref);
  178.         gpio_set_out(sns_inputAnalog0Ref);
  179. #else
  180.         Pca95xx_clr_pin(sns_inputAnalog0Ref);
  181.         Pca95xx_set_out(sns_inputAnalog0Ref);
  182. #endif
  183.     }
  184.    
  185. #if sns_inputAnalog_NUM_SUPPORTED>=2
  186.     if (sns_inputAnalog_Config[1].RefEnable==CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_ENABLE)
  187.     {
  188. #if sns_inputAnalog1RefPCA95xx==0
  189.         gpio_set_pin(sns_inputAnalog1Ref);
  190.         gpio_set_out(sns_inputAnalog1Ref);
  191. #else
  192.         Pca95xx_set_pin(sns_inputAnalog1Ref);
  193.         Pca95xx_set_out(sns_inputAnalog1Ref);
  194. #endif
  195.     }
  196.     else
  197.     {
  198. #if sns_inputAnalog1RefPCA95xx==0
  199.         gpio_clr_pin(sns_inputAnalog1Ref);
  200.         gpio_set_out(sns_inputAnalog1Ref);
  201. #else
  202.         Pca95xx_clr_pin(sns_inputAnalog1Ref);
  203.         Pca95xx_set_out(sns_inputAnalog1Ref);
  204. #endif
  205.     }
  206. #endif
  207.  
  208. #if sns_inputAnalog_NUM_SUPPORTED>=3
  209.     if (sns_inputAnalog_Config[2].RefEnable==CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_ENABLE)
  210.     {
  211. #if sns_inputAnalog2RefPCA95xx==0
  212.         gpio_set_pin(sns_inputAnalog2Ref);
  213.         gpio_set_out(sns_inputAnalog2Ref);
  214. #else
  215.         Pca95xx_set_pin(sns_inputAnalog2Ref);
  216.         Pca95xx_set_out(sns_inputAnalog2Ref);
  217. #endif
  218.     }
  219.     else
  220.     {
  221. #if sns_inputAnalog2RefPCA95xx==0
  222.         gpio_clr_pin(sns_inputAnalog2Ref);
  223.         gpio_set_out(sns_inputAnalog2Ref);
  224. #else
  225.         Pca95xx_clr_pin(sns_inputAnalog2Ref);
  226.         Pca95xx_set_out(sns_inputAnalog2Ref);
  227. #endif
  228.     }
  229. #endif
  230.  
  231. #if sns_inputAnalog_NUM_SUPPORTED>=4
  232.     if (sns_inputAnalog_Config[3].RefEnable==CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_ENABLE)
  233.     {
  234. #if sns_inputAnalog3RefPCA95xx==0
  235.         gpio_set_pin(sns_inputAnalog3Ref);
  236.         gpio_set_out(sns_inputAnalog3Ref);
  237. #else
  238.         Pca95xx_set_pin(sns_inputAnalog3Ref);
  239.         Pca95xx_set_out(sns_inputAnalog3Ref);
  240. #endif
  241.     }
  242.     else
  243.     {
  244. #if sns_inputAnalog3RefPCA95xx==0
  245.         gpio_clr_pin(sns_inputAnalog3Ref);
  246.         gpio_set_out(sns_inputAnalog3Ref);
  247. #else
  248.         Pca95xx_clr_pin(sns_inputAnalog3Ref);
  249.         Pca95xx_set_out(sns_inputAnalog3Ref);
  250. #endif
  251.     }
  252. #endif 
  253. }
  254.  
  255. void sns_inputAnalog_Init(void)
  256. {
  257. #if sns_inputAnalog_USEEEPROM==1
  258.     if (EEDATA_OK)
  259.     {
  260.         /* Use stored data to set initial values for the module */
  261.         for (uint8_t i=0; i<sns_inputAnalog_NUM_SUPPORTED; i++)
  262.         {
  263.             //eeprom_write_block( &sns_inputAnalog_Config[i], &eeprom_sns_inputAnalog, sizeof(sns_inputAnalog_Config)*i );
  264.             eeprom_read_block( &sns_inputAnalog_Config[i], &eeprom_sns_inputAnalog+sizeof(sns_inputAnalog_Config)*i, sizeof(sns_inputAnalog_Config) );
  265.         }
  266.     }
  267.     else
  268.     {
  269.         /* The CRC of the EEPROM is not correct, store default values and update CRC */
  270.         for (uint8_t i=0; i<sns_inputAnalog_NUM_SUPPORTED; i++)
  271.         {
  272.             sns_inputAnalog_Config[i].LowTh=50;         //Config, low level threshold voltage
  273.             sns_inputAnalog_Config[i].HighTh=100;       //Config, high level threshold voltage
  274.             sns_inputAnalog_Config[i].Periodicity=5000+i*100;   //Config, periodicity
  275.             sns_inputAnalog_Config[i].Type=CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE;    //Config, if sensor is of type periodic or digital input
  276.             sns_inputAnalog_Config[i].PullupEnable=CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_DISABLE;     //Config, if the pullup should be enabled
  277.             sns_inputAnalog_Config[i].RefEnable=CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_DISABLE;     //Config, if the reference to GND should be enabled
  278.            
  279. #if ((__AVR_LIBC_MAJOR__ == 1  && __AVR_LIBC_MINOR__ == 6 && __AVR_LIBC_REVISION__ >= 7)||(__AVR_LIBC_MAJOR__ == 1  && __AVR_LIBC_MINOR__ > 6)||__AVR_LIBC_MAJOR__ > 1)
  280.             eeprom_update_block( &sns_inputAnalog_Config[i], &eeprom_sns_inputAnalog+sizeof(sns_inputAnalog_Config)*i, sizeof(sns_inputAnalog_Config) );
  281. #else
  282.             eeprom_write_block( &sns_inputAnalog_Config[i], &eeprom_sns_inputAnalog+sizeof(sns_inputAnalog_Config)*i, sizeof(sns_inputAnalog_Config) );
  283.             #warning Using old version of AVRlibc, does not support eeprom_update-functions
  284. #endif
  285.         }
  286.         EEDATA_UPDATE_CRC;
  287.     }
  288. #endif  
  289.  
  290. #if sns_inputAnalog_ENABLE_PCA95xx==1
  291.     Pca95xx_Init(0);
  292. #endif
  293.     /* Initiate ADC */
  294.     ADC_Init();
  295.     /* Start timer for reading inputs */
  296.     Timer_SetTimeout(sns_inputAnalog_TIMER, sns_inputAnalog_POLL_PERIOD_MS , TimerTypeFreeRunning, 0);
  297.     /* Set pullups according config */
  298.     setPullups();
  299.     /* Set gnd references according config */
  300.     setReferences();
  301. }
  302.  
  303. void sns_inputAnalog_Process(void)
  304. {
  305.     /* When the timer has overflowed the AD channels shall be read */
  306.     if (Timer_Expired(sns_inputAnalog_TIMER))
  307.     {
  308.         StdCan_Msg_t txMsg;
  309.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  310.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  311.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_INPUTANALOG;
  312.         txMsg.Header.ModuleId = sns_inputAnalog_ID;
  313.  
  314.         uint16_t AdValue=0;
  315.         /* For each channel */
  316.         for (uint8_t i=0; i<sns_inputAnalog_NUM_SUPPORTED; i++)
  317.         {
  318.             /* Do reading of AD channel */
  319.             switch (i)
  320.             {
  321.                 case 0:
  322.                     AdValue = ADC_Get(sns_inputAnalog0AD);
  323.                     break;
  324.                 case 1:
  325.                     AdValue = ADC_Get(sns_inputAnalog1AD);
  326.                     break;
  327.                 case 2:
  328.                     AdValue = ADC_Get(sns_inputAnalog2AD);
  329.                     break;
  330.                 case 3:
  331.                     AdValue = ADC_Get(sns_inputAnalog3AD);
  332.                     break;
  333.             }
  334.            
  335.             /* If this channel is configured as periodic transmission of voltage */
  336.             if (sns_inputAnalog_Config[i].Type == CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE)
  337.             {
  338.                 /* Count periodicity */
  339.                 sns_inputAnalog_Sensor[i].PeriodCnt += sns_inputAnalog_POLL_PERIOD_MS;
  340.                 /* If periodicity overflowed or AD value changed more than threshold since last sent value */
  341.                 if (sns_inputAnalog_Sensor[i].PeriodCnt >= sns_inputAnalog_Config[i].Periodicity ||
  342.                     MAX(AdValue,sns_inputAnalog_Sensor[i].LastSentAdVal)-MIN(AdValue,sns_inputAnalog_Sensor[i].LastSentAdVal) > sns_inputAnalog_Config[i].LowTh)
  343.                 //if (sns_inputAnalog_Sensor[i].PeriodCnt >= sns_inputAnalog_Config[i].Periodicity ||
  344.                 //  abs(AdValue-sns_inputAnalog_Sensor[i].LastSentAdVal) > sns_inputAnalog_Config[i].LowTh)
  345.                 {
  346.                     /* Reset periodicity counter */
  347.                     sns_inputAnalog_Sensor[i].PeriodCnt = 0;
  348.                     /* Store value as last sent */
  349.                     sns_inputAnalog_Sensor[i].LastSentAdVal = AdValue;
  350.                    
  351.                     /* send sensor value on CAN with command CAN_MODULE_CMD_PHYSICAL_VOLTAGE */
  352.                     txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_VOLTAGE;
  353.                     txMsg.Length = 3;
  354.                     /* The channel should be transmitted in byte 0 */
  355.                     txMsg.Data[0] = i;
  356.                    
  357.                     uint8_t analogScale = 10;
  358.                     /* Select parameters for AD conversion */
  359.                     switch (i)
  360.                     {
  361.                         case 0:
  362.                             analogScale = sns_inputAnalog0Scale;
  363.                             AdValue = AdValue * sns_inputAnalog0Factor;
  364.                             break;
  365.                         case 1:
  366.                             analogScale = sns_inputAnalog1Scale;
  367.                             AdValue = AdValue * sns_inputAnalog1Factor;
  368.                             break;
  369.                         case 2:
  370.                             analogScale = sns_inputAnalog2Scale;
  371.                             AdValue = AdValue * sns_inputAnalog2Factor;
  372.                             break;
  373.                         case 3:
  374.                             analogScale = sns_inputAnalog3Scale;
  375.                             AdValue = AdValue * sns_inputAnalog3Factor;
  376.                             break;
  377.                     }
  378.                     txMsg.Data[1] = (AdValue>>(analogScale-6+8))&0xff;
  379.                     txMsg.Data[2] = (AdValue>>(analogScale-6))&0xff;
  380.                    
  381.                     /* Send value on CAN */
  382.                     while (StdCan_Put(&txMsg) != StdCan_Ret_OK) {}
  383.                 }
  384.             }
  385.             /* If this channel is configured as digital input */
  386.             else if (sns_inputAnalog_Config[i].Type == CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_DIGITALINPUT)
  387.             {
  388.                 txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PINSTATUS;
  389.                 txMsg.Length = 2;
  390.                 /* The channel should be transmitted in byte 0 */
  391.                 txMsg.Data[0] = i;
  392.                 /* If status was low but voltage is above high theshold */
  393.                 if (sns_inputAnalog_Sensor[i].Status != HIGH && AdValue > sns_inputAnalog_Config[i].HighTh)
  394.                 {
  395.                     /* Consider status to be high */
  396.                     sns_inputAnalog_Sensor[i].Status = HIGH;
  397.                     txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_PINSTATUS_STATUS_HIGH;
  398.                    
  399.                     /* send status on CAN with command CAN_MODULE_CMD_PHYSICAL_PINSTATUS */
  400.                     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  401.                 }
  402.                 /* If status was high but voltage is below low theshold */
  403.                 else if (sns_inputAnalog_Sensor[i].Status != LOW && AdValue < sns_inputAnalog_Config[i].LowTh)
  404.                 {
  405.                     /* Consider status to be low */
  406.                     sns_inputAnalog_Sensor[i].Status = LOW;
  407.                     txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_PINSTATUS_STATUS_LOW;
  408.                    
  409.                     /* send status on CAN with command CAN_MODULE_CMD_PHYSICAL_PINSTATUS */
  410.                     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  411.                 }
  412.             }
  413.         }
  414.     }
  415. }
  416.  
  417. void sns_inputAnalog_HandleMessage(StdCan_Msg_t *rxMsg)
  418. {
  419.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  420.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  421.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_SNS_INPUTANALOG &&
  422.         rxMsg->Header.ModuleId == sns_inputAnalog_ID)
  423.     {
  424.         uint8_t index=0;
  425.         switch (rxMsg->Header.Command)
  426.         {
  427.         case CAN_MODULE_CMD_INPUTANALOG_ANALOGCONFIG:
  428.             /* Find sensor id from incoming data */
  429.             index=(rxMsg->Data[0]>>4)&0x0f;
  430.             /* Check if sensor id is in range */
  431.             if (index < sns_inputAnalog_NUM_SUPPORTED)
  432.             {
  433.                 /* Save all config values */
  434.                 sns_inputAnalog_Config[index].Type=(rxMsg->Data[0]>>2)&0x03;
  435.                 sns_inputAnalog_Config[index].PullupEnable=(rxMsg->Data[0]>>1)&0x01;
  436.                 sns_inputAnalog_Config[index].RefEnable=(rxMsg->Data[0]>>0)&0x01;
  437.                 sns_inputAnalog_Config[index].LowTh=(rxMsg->Data[2])|(rxMsg->Data[1]<<8);
  438.                 sns_inputAnalog_Config[index].HighTh=(rxMsg->Data[4])|(rxMsg->Data[3]<<8);
  439.                 sns_inputAnalog_Config[index].Periodicity=(rxMsg->Data[6])|(rxMsg->Data[5]<<8);
  440.                
  441.                 /* Convert voltage to AD value (0-1023) acording static config parameters */
  442.                 switch (index)
  443.                 {
  444.                     case 0:
  445.                         sns_inputAnalog_Config[index].LowTh = sns_inputAnalog_Config[index].LowTh<<(sns_inputAnalog0Scale-6);
  446.                         sns_inputAnalog_Config[index].LowTh = sns_inputAnalog_Config[index].LowTh / sns_inputAnalog0Factor;
  447.                         sns_inputAnalog_Config[index].HighTh = sns_inputAnalog_Config[index].HighTh<<(sns_inputAnalog0Scale-6);
  448.                         sns_inputAnalog_Config[index].HighTh = sns_inputAnalog_Config[index].HighTh / sns_inputAnalog0Factor;
  449.                         break;
  450.                     case 1:
  451.                         sns_inputAnalog_Config[index].LowTh = sns_inputAnalog_Config[index].LowTh<<(sns_inputAnalog1Scale-6);
  452.                         sns_inputAnalog_Config[index].LowTh = sns_inputAnalog_Config[index].LowTh / sns_inputAnalog1Factor;
  453.                         sns_inputAnalog_Config[index].HighTh = sns_inputAnalog_Config[index].HighTh<<(sns_inputAnalog1Scale-6);
  454.                         sns_inputAnalog_Config[index].HighTh = sns_inputAnalog_Config[index].HighTh / sns_inputAnalog1Factor;
  455.                         break;
  456.                     case 2:
  457.                         sns_inputAnalog_Config[index].LowTh = sns_inputAnalog_Config[index].LowTh<<(sns_inputAnalog2Scale-6);
  458.                         sns_inputAnalog_Config[index].LowTh = sns_inputAnalog_Config[index].LowTh / sns_inputAnalog2Factor;
  459.                         sns_inputAnalog_Config[index].HighTh = sns_inputAnalog_Config[index].HighTh<<(sns_inputAnalog2Scale-6);
  460.                         sns_inputAnalog_Config[index].HighTh = sns_inputAnalog_Config[index].HighTh / sns_inputAnalog2Factor;
  461.                         break;
  462.                     case 3:
  463.                         sns_inputAnalog_Config[index].LowTh = sns_inputAnalog_Config[index].LowTh<<(sns_inputAnalog3Scale-6);
  464.                         sns_inputAnalog_Config[index].LowTh = sns_inputAnalog_Config[index].LowTh / sns_inputAnalog3Factor;
  465.                         sns_inputAnalog_Config[index].HighTh = sns_inputAnalog_Config[index].HighTh<<(sns_inputAnalog3Scale-6);
  466.                         sns_inputAnalog_Config[index].HighTh = sns_inputAnalog_Config[index].HighTh / sns_inputAnalog3Factor;
  467.                         break;
  468.                 }
  469.                
  470. #if sns_inputAnalog_USEEEPROM==1
  471.                 /* Store config to eeprom */
  472. #if ((__AVR_LIBC_MAJOR__ == 1  && __AVR_LIBC_MINOR__ == 6 && __AVR_LIBC_REVISION__ >= 7)||(__AVR_LIBC_MAJOR__ == 1  && __AVR_LIBC_MINOR__ > 6)||__AVR_LIBC_MAJOR__ > 1)
  473.                 eeprom_update_block( &sns_inputAnalog_Config[index], &eeprom_sns_inputAnalog+sizeof(sns_inputAnalog_Config)*index, sizeof(sns_inputAnalog_Config) );
  474. #else
  475.                 eeprom_write_block( &sns_inputAnalog_Config[index], &eeprom_sns_inputAnalog+sizeof(sns_inputAnalog_Config)*index, sizeof(sns_inputAnalog_Config) );
  476.                 #warning Using old version of AVRlibc, does not support eeprom_update-functions
  477. #endif
  478.                 EEDATA_UPDATE_CRC;
  479. #endif
  480.             }
  481.             break;
  482.         }
  483.         /* Set pullups according config */
  484.         setPullups();
  485.         /* Set gnd references according config */
  486.         setReferences();
  487.     }
  488. }
  489.  
  490. void sns_inputAnalog_List(uint8_t ModuleSequenceNumber)
  491. {
  492.     StdCan_Msg_t txMsg;
  493.    
  494.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  495.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  496.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_INPUTANALOG;
  497.     txMsg.Header.ModuleId = sns_inputAnalog_ID;
  498.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  499.     txMsg.Length = 6;
  500.  
  501.     uint32_t HwId=BIOS_GetHwId();
  502.     txMsg.Data[0] = HwId&0xff;
  503.     txMsg.Data[1] = (HwId>>8)&0xff;
  504.     txMsg.Data[2] = (HwId>>16)&0xff;
  505.     txMsg.Data[3] = (HwId>>24)&0xff;
  506.    
  507.     txMsg.Data[4] = NUMBER_OF_MODULES;
  508.     txMsg.Data[5] = ModuleSequenceNumber;
  509.    
  510.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  511. }
  512.