Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "sns_inputAnalog.h"
  3.  
  4. struct {
  5.     uint16_t            LowTh;          //Config, low level threshold voltage
  6.     uint16_t            HighTh;         //Config, high level threshold voltage
  7.     uint16_t            Periodicity;    //Config, periodicity
  8.     uint8_t             Type;           //Config, if sensor is of type periodic or digital input
  9.     uint8_t             PullupEnable;   //Config, if the pullup should be enabled
  10.     uint8_t             RefEnable;      //Config, if the reference to GND should be enabled
  11. } sns_inputAnalog_Config[sns_inputAnalog_NUM_SUPPORTED];
  12.  
  13. struct {
  14.     uint8_t             Status;         //Used for digital input, high or low
  15.     uint16_t            PeriodCnt;      //Counter for periodicity
  16. } sns_inputAnalog_Sensor[sns_inputAnalog_NUM_SUPPORTED];
  17.  
  18. #define HIGH        1
  19. #define LOW         2
  20. #define NOCHANGE    0
  21.  
  22. #ifdef sns_inputAnalog_USEEEPROM
  23. #include "sns_inputAnalog_eeprom.h"
  24.  
  25. struct eeprom_sns_inputAnalog EEMEM eeprom_sns_inputAnalog =
  26. {
  27.     {
  28.         ///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.
  29.         0xAB,   // x
  30.         0x1234  // y
  31.     },
  32.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  33. };
  34. #endif
  35.  
  36. void sns_inputAnalog_Init(void)
  37. {
  38. #ifdef sns_inputAnalog_USEEEPROM
  39.     if (EEDATA_OK)
  40.     {
  41.       ///TODO: Use stored data to set initial values for the module
  42.       blablaX = eeprom_read_byte(EEDATA.x);
  43.       blablaY = eeprom_read_word(EEDATA.y);
  44.     } else
  45.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  46.       eeprom_write_byte_crc(EEDATA.x, 0xAB, WITHOUT_CRC);
  47.       eeprom_write_word_crc(EEDATA.y, 0x1234, WITHOUT_CRC);
  48.       EEDATA_UPDATE_CRC;
  49.     }
  50. #endif  
  51.  
  52.     ADC_Init();
  53.     Timer_SetTimeout(sns_inputAnalog_TIMER, sns_inputAnalog_POLL_PERIOD_MS , TimerTypeFreeRunning, 0);
  54. }
  55.  
  56. void sns_inputAnalog_Process(void)
  57. {
  58.     /* When the timer has overflowed the AD channels shall be read */
  59.     if (Timer_Expired(sns_inputAnalog_TIMER))
  60.     {
  61.         StdCan_Msg_t txMsg;
  62.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  63.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  64.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_INPUTANALOG;
  65.         txMsg.Header.ModuleId = sns_inputAnalog_ID;
  66.  
  67.         uint16_t AdValue;
  68.         /* For each channel */
  69.         for (uint8_t i=0; i<sns_inputAnalog_NUM_SUPPORTED; i++)
  70.         {
  71.             uint8_t analogScale = 10;
  72.             /* Select some parameters and do reading of AD channel */
  73.             switch (i)
  74.             {
  75.                 case 0:
  76.                     analogScale = sns_inputAnalog0Scale;
  77.                     AdValue = ADC_Get(sns_inputAnalog0AD);
  78.                     break;
  79.                 case 1:
  80.                     analogScale = sns_inputAnalog1Scale;
  81.                     AdValue = ADC_Get(sns_inputAnalog1AD);
  82.                     break;
  83.                 case 2:
  84.                     analogScale = sns_inputAnalog2Scale;
  85.                     AdValue = ADC_Get(sns_inputAnalog2AD);
  86.                     break;
  87.                 case 3:
  88.                     analogScale = sns_inputAnalog3Scale;
  89.                     AdValue = ADC_Get(sns_inputAnalog3AD);
  90.                     break;
  91.             }
  92.            
  93.             /* If this channel is configured as periodic transmission of voltage */
  94.             if (sns_inputAnalog_Config[i].Type == CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE)
  95.             {
  96.                 /* Count periodicity */
  97.                 sns_inputAnalog_Sensor[i].PeriodCnt += sns_inputAnalog_POLL_PERIOD_MS;
  98.                 /* If periodicity overflowed */
  99.                 if (sns_inputAnalog_Sensor[i].PeriodCnt >= sns_inputAnalog_Config[i].Periodicity)
  100.                 {
  101.                     sns_inputAnalog_Sensor[i].PeriodCnt = 0;
  102.                    
  103.                     /* send sensor value on CAN with command CAN_MODULE_CMD_PHYSICAL_VOLTAGE */
  104.                     txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_VOLTAGE;
  105.                     txMsg.Length = 3;
  106.                     /* The channel should be transmitted in byte 0 */
  107.                     txMsg.Data[0] = i;
  108.                     /* Select parameter */
  109.                     switch (i)
  110.                     {
  111.                         case 0:
  112.                             AdValue = AdValue * sns_inputAnalog0Factor;
  113.                             break;
  114.                         case 1:
  115.                             AdValue = AdValue * sns_inputAnalog1Factor;
  116.                             break;
  117.                         case 2:
  118.                             AdValue = AdValue * sns_inputAnalog2Factor;
  119.                             break;
  120.                         case 3:
  121.                             AdValue = AdValue * sns_inputAnalog3Factor;
  122.                             break;
  123.                     }
  124.                     txMsg.Data[1] = (AdValue>>(analogScale-6+8))&0xff;
  125.                     txMsg.Data[2] = (AdValue>>(analogScale-6))&0xff;
  126.                    
  127.                     while (StdCan_Put(&txMsg) != StdCan_Ret_OK) {}
  128.                 }
  129.             }
  130.             /* If this channel is configured as digital input */
  131.             else if (sns_inputAnalog_Config[i].Type == CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_DIGITALINPUT)
  132.             {
  133.                 txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PINSTATUS;
  134.                 txMsg.Length = 2;
  135.                 /* The channel should be transmitted in byte 0 */
  136.                 txMsg.Data[0] = i;
  137.                 /* If status was low but voltage is above high theshold */
  138.                 if (sns_inputAnalog_Sensor[i].Status == LOW && AdValue > sns_inputAnalog_Config[i].HighTh)
  139.                 {
  140.                     /* Consider status to be high */
  141.                     sns_inputAnalog_Sensor[i].Status = HIGH;
  142.                     txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_PINSTATUS_STATUS_HIGH;
  143.                    
  144.                     /* send status on CAN with command CAN_MODULE_CMD_PHYSICAL_PINSTATUS */
  145.                     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  146.                 }
  147.                 /* If status was high but voltage is below low theshold */
  148.                 else if (sns_inputAnalog_Sensor[i].Status == HIGH && AdValue < sns_inputAnalog_Config[i].LowTh)
  149.                 {
  150.                     /* Consider status to be low */
  151.                     sns_inputAnalog_Sensor[i].Status = LOW;
  152.                     txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_PINSTATUS_STATUS_LOW;
  153.                    
  154.                     /* send status on CAN with command CAN_MODULE_CMD_PHYSICAL_PINSTATUS */
  155.                     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  156.                 }
  157.             }
  158.         }
  159.  
  160.     }
  161. }
  162.  
  163. void sns_inputAnalog_HandleMessage(StdCan_Msg_t *rxMsg)
  164. {
  165. /*  if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  166.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  167.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_SNS_INPUTANALOG &&
  168.         rxMsg->Header.ModuleId == sns_inputAnalog_ID)
  169.     {
  170.         switch (rxMsg->Header.Command)
  171.         {
  172.         case CAN_CMD_MODULE_DUMMY:
  173.         ///TODO: Do something dummy
  174.         break;
  175.         }
  176.     }*/
  177. }
  178.  
  179. void sns_inputAnalog_List(uint8_t ModuleSequenceNumber)
  180. {
  181.     StdCan_Msg_t txMsg;
  182.    
  183.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  184.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  185.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_INPUTANALOG;
  186.     txMsg.Header.ModuleId = sns_inputAnalog_ID;
  187.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  188.     txMsg.Length = 6;
  189.  
  190.     txMsg.Data[0] = NODE_HW_ID_BYTE0;
  191.     txMsg.Data[1] = NODE_HW_ID_BYTE1;
  192.     txMsg.Data[2] = NODE_HW_ID_BYTE2;
  193.     txMsg.Data[3] = NODE_HW_ID_BYTE3;
  194.    
  195.     txMsg.Data[4] = NUMBER_OF_MODULES;
  196.     txMsg.Data[5] = ModuleSequenceNumber;
  197.    
  198.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  199. }
  200.