Rev 1539 | Rev 1541 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 1539 | Rev 1540 | ||
|---|---|---|---|
| Line 1... | Line 1... | ||
| 1 | 1 | ||
| 2 | #include "sns_inputAnalog.h" |
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 |
|
3 | //TODO: Config over CAN, save to eeprom, pullups, references |
| 10 | uint8_t RefEnable; //Config, if the reference to GND should be enabled |
- | |
| 11 | } sns_inputAnalog_Config[sns_inputAnalog_NUM_SUPPORTED]; |
- | |
| 12 | 4 | ||
| 13 | struct { |
5 | struct { |
| 14 | uint8_t Status; //Used for digital input, high or low |
6 | uint8_t Status; //Used for digital input, high or low |
| 15 | uint16_t PeriodCnt; //Counter for periodicity |
7 | uint16_t PeriodCnt; //Counter for periodicity |
| - | 8 | uint16_t LastSentAdVal; //Remember the last sent AD value |
|
| 16 | } sns_inputAnalog_Sensor[sns_inputAnalog_NUM_SUPPORTED]; |
9 | } sns_inputAnalog_Sensor[sns_inputAnalog_NUM_SUPPORTED]; |
| - | 10 | ||
| 17 | 11 | ||
| 18 | #define HIGH 1 |
12 | #define HIGH 1 |
| 19 | #define LOW 2 |
13 | #define LOW 2 |
| 20 | #define NOCHANGE 0 |
14 | #define NOCHANGE 0 |
| 21 | 15 | ||
| Line 23... | Line 17... | ||
| 23 | #include "sns_inputAnalog_eeprom.h" |
17 | #include "sns_inputAnalog_eeprom.h" |
| 24 | 18 | ||
| 25 | struct eeprom_sns_inputAnalog EEMEM eeprom_sns_inputAnalog = |
19 | struct eeprom_sns_inputAnalog EEMEM eeprom_sns_inputAnalog = |
| 26 | { |
20 | { |
| 27 | { |
21 | { |
| - | 22 | { |
|
| - | 23 | /* Define initialization values on the EEPROM variables here, this will generate a *.eep file |
|
| - | 24 | that can be used to store this values to the node, can in future be done with a EEPROM module |
|
| 28 |
|
25 | and the make-scrips. Write the values in the exact same order as the struct is defined in the *.h file. */ |
| - | 26 | 1*sns_inputAnalog0Factor/(2^sns_inputAnalog0Scale), //Config, low level threshold voltage, (1 volt) |
|
| - | 27 | 2*sns_inputAnalog0Factor/(2^sns_inputAnalog0Scale), //Config, high level threshold voltage, (2 volts) |
|
| - | 28 | 4800, //Config, periodicity |
|
| - | 29 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE, //Config, if sensor is of type periodic or digital input |
|
| - | 30 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_DISABLE, //Config, if the pullup should be enabled |
|
| - | 31 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_DISABLE, //Config, if the reference to GND should be enabled |
|
| - | 32 | }, |
|
| - | 33 | #if sns_inputAnalog_NUM_SUPPORTED>=2 |
|
| - | 34 | { |
|
| - | 35 | 1*sns_inputAnalog1Factor/(2^sns_inputAnalog1Scale), //Config, low level threshold voltage, (1 volt) |
|
| - | 36 | 2*sns_inputAnalog1Factor/(2^sns_inputAnalog1Scale), //Config, high level threshold voltage, (2 volts) |
|
| 29 |
|
37 | 4900, |
| - | 38 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE, //Config, if sensor is of type periodic or digital input |
|
| - | 39 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_DISABLE, //Config, if the pullup should be enabled |
|
| - | 40 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_DISABLE, //Config, if the reference to GND should be enabled |
|
| - | 41 | }, |
|
| - | 42 | #endif |
|
| - | 43 | #if sns_inputAnalog_NUM_SUPPORTED>=3 |
|
| - | 44 | { |
|
| - | 45 | 1*sns_inputAnalog2Factor/(2^sns_inputAnalog2Scale), //Config, low level threshold voltage |
|
| - | 46 | 2*sns_inputAnalog2Factor/(2^sns_inputAnalog2Scale), //Config, high level threshold voltage, (2 volts) |
|
| - | 47 | 5100, |
|
| - | 48 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE, //Config, if sensor is of type periodic or digital input |
|
| - | 49 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_DISABLE, //Config, if the pullup should be enabled |
|
| - | 50 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_DISABLE, //Config, if the reference to GND should be enabled |
|
| - | 51 | }, |
|
| - | 52 | #endif |
|
| - | 53 | #if sns_inputAnalog_NUM_SUPPORTED>=4 |
|
| - | 54 | { |
|
| - | 55 | 1*sns_inputAnalog3Factor/(2^sns_inputAnalog3Scale), //Config, low level threshold voltage |
|
| - | 56 | 2*sns_inputAnalog3Factor/(2^sns_inputAnalog3Scale), //Config, high level threshold voltage, (2 volts) |
|
| 30 |
|
57 | 5200, |
| - | 58 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE, //Config, if sensor is of type periodic or digital input |
|
| - | 59 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_DISABLE, //Config, if the pullup should be enabled |
|
| - | 60 | CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_DISABLE, //Config, if the reference to GND should be enabled |
|
| - | 61 | } |
|
| - | 62 | #endif |
|
| 31 | }, |
63 | }, |
| 32 | 0 // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts |
64 | 0 // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts |
| 33 | }; |
65 | }; |
| 34 | #endif |
66 | #endif |
| 35 | 67 | ||
| 36 | void sns_inputAnalog_Init(void) |
68 | void sns_inputAnalog_Init(void) |
| 37 | { |
69 | { |
| 38 | #ifdef sns_inputAnalog_USEEEPROM |
70 | #ifdef sns_inputAnalog_USEEEPROM |
| 39 | if (EEDATA_OK) |
71 | if (EEDATA_OK) |
| 40 | { |
72 | { |
| 41 |
|
73 | /* Use stored data to set initial values for the module */ |
| 42 |
|
74 | for (uint8_t i=0; i<sns_inputAnalog_NUM_SUPPORTED; i++) |
| - | 75 | { |
|
| 43 |
|
76 | //eeprom_write_block( &sns_inputAnalog_Config[i], &eeprom_sns_inputAnalog, sizeof(sns_inputAnalog_Config)*i ); |
| - | 77 | eeprom_read_block( &sns_inputAnalog_Config[i], &eeprom_sns_inputAnalog+sizeof(sns_inputAnalog_Config)*i, sizeof(sns_inputAnalog_Config) ); |
|
| - | 78 | } |
|
| - | 79 | } |
|
| 44 |
|
80 | else |
| - | 81 | { |
|
| 45 |
|
82 | /* The CRC of the EEPROM is not correct, store default values and update CRC */ |
| 46 |
|
83 | for (uint8_t i=0; i<sns_inputAnalog_NUM_SUPPORTED; i++) |
| - | 84 | { |
|
| - | 85 | sns_inputAnalog_Config[i].LowTh=50; //Config, low level threshold voltage |
|
| - | 86 | sns_inputAnalog_Config[i].HighTh=100; //Config, high level threshold voltage |
|
| 47 |
|
87 | sns_inputAnalog_Config[i].Periodicity=5000; //Config, periodicity |
| - | 88 | sns_inputAnalog_Config[i].Type=CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE; //Config, if sensor is of type periodic or digital input |
|
| - | 89 | sns_inputAnalog_Config[i].PullupEnable=CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_PULLUP_DISABLE; //Config, if the pullup should be enabled |
|
| - | 90 | sns_inputAnalog_Config[i].RefEnable=CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_REFERENCE_DISABLE; //Config, if the reference to GND should be enabled |
|
| - | 91 | ||
| - | 92 | eeprom_update_block( &sns_inputAnalog_Config[i], &eeprom_sns_inputAnalog+sizeof(sns_inputAnalog_Config)*i, sizeof(sns_inputAnalog_Config) ); |
|
| - | 93 | } |
|
| 48 | EEDATA_UPDATE_CRC; |
94 | EEDATA_UPDATE_CRC; |
| 49 | } |
95 | } |
| 50 | #endif |
96 | #endif |
| 51 | 97 | ||
| 52 | ADC_Init(); |
98 | ADC_Init(); |
| 53 | Timer_SetTimeout(sns_inputAnalog_TIMER, sns_inputAnalog_POLL_PERIOD_MS , TimerTypeFreeRunning, 0); |
99 | Timer_SetTimeout(sns_inputAnalog_TIMER, sns_inputAnalog_POLL_PERIOD_MS , TimerTypeFreeRunning, 0); |
| 54 | } |
100 | } |
| 55 | 101 | ||
| 56 | void sns_inputAnalog_Process(void) |
102 | void sns_inputAnalog_Process(void) |
| 57 | { |
103 | { |
| 58 | /* When the timer has overflowed the AD channels shall be read */ |
104 | /* When the timer has overflowed the AD channels shall be read */ |
| 59 | if (Timer_Expired(sns_inputAnalog_TIMER)) |
105 | if (Timer_Expired(sns_inputAnalog_TIMER)) |
| 60 | { |
106 | { |
| 61 | StdCan_Msg_t txMsg; |
107 | StdCan_Msg_t txMsg; |
| 62 | StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS); |
108 | StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS); |
| 63 | StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER); |
109 | StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER); |
| 64 | txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_INPUTANALOG; |
110 | txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_INPUTANALOG; |
| 65 | txMsg.Header.ModuleId = sns_inputAnalog_ID; |
111 | txMsg.Header.ModuleId = sns_inputAnalog_ID; |
| 66 | 112 | ||
| 67 | uint16_t AdValue; |
113 | uint16_t AdValue=0; |
| 68 | /* For each channel */ |
114 | /* For each channel */ |
| 69 | for (uint8_t i=0; i<sns_inputAnalog_NUM_SUPPORTED; i++) |
115 | for (uint8_t i=0; i<sns_inputAnalog_NUM_SUPPORTED; i++) |
| 70 | { |
116 | { |
| 71 | uint8_t analogScale = 10; |
- | |
| 72 | /* |
117 | /* Do reading of AD channel */ |
| 73 | switch (i) |
118 | switch (i) |
| 74 | { |
119 | { |
| 75 | case 0: |
120 | case 0: |
| 76 | analogScale = sns_inputAnalog0Scale; |
- | |
| 77 | AdValue = ADC_Get(sns_inputAnalog0AD); |
121 | AdValue = ADC_Get(sns_inputAnalog0AD); |
| 78 | break; |
122 | break; |
| 79 | case 1: |
123 | case 1: |
| 80 | analogScale = sns_inputAnalog1Scale; |
- | |
| 81 | AdValue = ADC_Get(sns_inputAnalog1AD); |
124 | AdValue = ADC_Get(sns_inputAnalog1AD); |
| 82 | break; |
125 | break; |
| 83 | case 2: |
126 | case 2: |
| 84 | analogScale = sns_inputAnalog2Scale; |
- | |
| 85 | AdValue = ADC_Get(sns_inputAnalog2AD); |
127 | AdValue = ADC_Get(sns_inputAnalog2AD); |
| 86 | break; |
128 | break; |
| 87 | case 3: |
129 | case 3: |
| 88 | analogScale = sns_inputAnalog3Scale; |
- | |
| 89 | AdValue = ADC_Get(sns_inputAnalog3AD); |
130 | AdValue = ADC_Get(sns_inputAnalog3AD); |
| 90 | break; |
131 | break; |
| 91 | } |
132 | } |
| 92 | 133 | ||
| 93 | /* If this channel is configured as periodic transmission of voltage */ |
134 | /* If this channel is configured as periodic transmission of voltage */ |
| 94 | if (sns_inputAnalog_Config[i].Type == CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE) |
135 | if (sns_inputAnalog_Config[i].Type == CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_PERIODICMEASURE) |
| 95 | { |
136 | { |
| 96 | /* Count periodicity */ |
137 | /* Count periodicity */ |
| 97 | sns_inputAnalog_Sensor[i].PeriodCnt += sns_inputAnalog_POLL_PERIOD_MS; |
138 | sns_inputAnalog_Sensor[i].PeriodCnt += sns_inputAnalog_POLL_PERIOD_MS; |
| 98 | /* If periodicity overflowed */ |
139 | /* If periodicity overflowed or AD value changed more than threshold since last sent value */ |
| 99 | if (sns_inputAnalog_Sensor[i].PeriodCnt >= sns_inputAnalog_Config[i].Periodicity |
140 | if (sns_inputAnalog_Sensor[i].PeriodCnt >= sns_inputAnalog_Config[i].Periodicity || |
| - | 141 | MAX(AdValue,sns_inputAnalog_Sensor[i].LastSentAdVal)-MIN(AdValue,sns_inputAnalog_Sensor[i].LastSentAdVal) > sns_inputAnalog_Config[i].LowTh) |
|
| - | 142 | //if (sns_inputAnalog_Sensor[i].PeriodCnt >= sns_inputAnalog_Config[i].Periodicity || |
|
| - | 143 | // abs(AdValue-sns_inputAnalog_Sensor[i].LastSentAdVal) > sns_inputAnalog_Config[i].LowTh) |
|
| 100 | { |
144 | { |
| - | 145 | /* Reset periodicity counter */ |
|
| 101 | sns_inputAnalog_Sensor[i].PeriodCnt = 0; |
146 | sns_inputAnalog_Sensor[i].PeriodCnt = 0; |
| - | 147 | /* Store value as last sent */ |
|
| - | 148 | sns_inputAnalog_Sensor[i].LastSentAdVal = AdValue; |
|
| 102 | 149 | ||
| 103 | /* send sensor value on CAN with command CAN_MODULE_CMD_PHYSICAL_VOLTAGE */ |
150 | /* send sensor value on CAN with command CAN_MODULE_CMD_PHYSICAL_VOLTAGE */ |
| 104 | txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_VOLTAGE; |
151 | txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_VOLTAGE; |
| 105 | txMsg.Length = 3; |
152 | txMsg.Length = 3; |
| 106 | /* The channel should be transmitted in byte 0 */ |
153 | /* The channel should be transmitted in byte 0 */ |
| 107 | txMsg.Data[0] = i; |
154 | txMsg.Data[0] = i; |
| - | 155 | ||
| - | 156 | uint8_t analogScale = 10; |
|
| 108 | /* Select |
157 | /* Select parameters for AD conversion */ |
| 109 | switch (i) |
158 | switch (i) |
| 110 | { |
159 | { |
| 111 | case 0: |
160 | case 0: |
| - | 161 | analogScale = sns_inputAnalog0Scale; |
|
| 112 | AdValue = AdValue * sns_inputAnalog0Factor; |
162 | AdValue = AdValue * sns_inputAnalog0Factor; |
| 113 | break; |
163 | break; |
| 114 | case 1: |
164 | case 1: |
| - | 165 | analogScale = sns_inputAnalog1Scale; |
|
| 115 | AdValue = AdValue * sns_inputAnalog1Factor; |
166 | AdValue = AdValue * sns_inputAnalog1Factor; |
| 116 | break; |
167 | break; |
| 117 | case 2: |
168 | case 2: |
| - | 169 | analogScale = sns_inputAnalog2Scale; |
|
| 118 | AdValue = AdValue * sns_inputAnalog2Factor; |
170 | AdValue = AdValue * sns_inputAnalog2Factor; |
| 119 | break; |
171 | break; |
| 120 | case 3: |
172 | case 3: |
| - | 173 | analogScale = sns_inputAnalog3Scale; |
|
| 121 | AdValue = AdValue * sns_inputAnalog3Factor; |
174 | AdValue = AdValue * sns_inputAnalog3Factor; |
| 122 | break; |
175 | break; |
| 123 | } |
176 | } |
| 124 | txMsg.Data[1] = (AdValue>>(analogScale-6+8))&0xff; |
177 | txMsg.Data[1] = (AdValue>>(analogScale-6+8))&0xff; |
| 125 | txMsg.Data[2] = (AdValue>>(analogScale-6))&0xff; |
178 | txMsg.Data[2] = (AdValue>>(analogScale-6))&0xff; |
| 126 | 179 | ||
| - | 180 | /* Send value on CAN */ |
|
| 127 | while (StdCan_Put(&txMsg) != StdCan_Ret_OK) {} |
181 | while (StdCan_Put(&txMsg) != StdCan_Ret_OK) {} |
| 128 | } |
182 | } |
| 129 | } |
183 | } |
| 130 | /* If this channel is configured as digital input */ |
184 | /* If this channel is configured as digital input */ |
| 131 | else if (sns_inputAnalog_Config[i].Type == CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_DIGITALINPUT) |
185 | else if (sns_inputAnalog_Config[i].Type == CAN_MODULE_ENUM_INPUTANALOG_ANALOGCONFIG_SETTING_DIGITALINPUT) |