Rev 1835 | Rev 1838 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 1835 | Rev 1837 | ||
|---|---|---|---|
| Line 21... | Line 21... | ||
| 21 | #endif |
21 | #endif |
| 22 | 22 | ||
| 23 | #if IR_RX_ENABLE==1 |
23 | #if IR_RX_ENABLE==1 |
| 24 | struct { |
24 | struct { |
| 25 | uint8_t state; |
25 | uint8_t state; |
| 26 |
|
26 | uint16_t modfreq; |
| 27 | uint16_t *rxbuf; |
27 | uint16_t *rxbuf; |
| 28 | uint8_t rxlen; |
28 | uint8_t rxlen; |
| 29 | uint8_t timerNum; |
29 | uint8_t timerNum; |
| 30 | Ir_Protocol_Data_t proto; |
30 | Ir_Protocol_Data_t proto; |
| 31 | uint8_t newData; |
31 | uint8_t newData; |
| Line 33... | Line 33... | ||
| 33 | #endif |
33 | #endif |
| 34 | 34 | ||
| 35 | #if IR_TX_ENABLE==1 |
35 | #if IR_TX_ENABLE==1 |
| 36 | struct { |
36 | struct { |
| 37 | uint8_t state; |
37 | uint8_t state; |
| 38 |
|
38 | uint16_t modfreq; |
| 39 | uint16_t *txbuf; |
39 | uint16_t *txbuf; |
| 40 | uint8_t txlen; |
40 | uint8_t txlen; |
| 41 | uint8_t timerNum; |
41 | uint8_t timerNum; |
| 42 | uint8_t repeatCount; |
42 | uint8_t repeatCount; |
| 43 | Ir_Protocol_Data_t proto; |
43 | Ir_Protocol_Data_t proto; |
| Line 45... | Line 45... | ||
| 45 | uint8_t sendComplete; |
45 | uint8_t sendComplete; |
| 46 | // pronto params |
46 | // pronto params |
| 47 | uint8_t sendingPronto; |
47 | uint8_t sendingPronto; |
| 48 | uint8_t onceSeqLen; |
48 | uint8_t onceSeqLen; |
| 49 | uint8_t repSeqLen; |
49 | uint8_t repSeqLen; |
| - | 50 | uint8_t expectedSeqNr; |
|
| 50 | } irTxChannel[IR_SUPPORTED_NUM_CHANNELS]; |
51 | } irTxChannel[IR_SUPPORTED_NUM_CHANNELS]; |
| 51 | #endif |
52 | #endif |
| 52 | 53 | ||
| 53 | uint16_t buf[IR_SUPPORTED_NUM_CHANNELS][MAX_NR_TIMES]; |
54 | uint16_t buf[IR_SUPPORTED_NUM_CHANNELS][MAX_NR_TIMES]; |
| 54 | 55 | ||
| Line 95... | Line 96... | ||
| 95 | } |
96 | } |
| 96 | 97 | ||
| 97 | } |
98 | } |
| 98 | #endif |
99 | #endif |
| 99 | 100 | ||
| 100 | #define sns_irTransceive_BaseFrq ( |
101 | #define sns_irTransceive_BaseFrq (4145146UL) |
| 101 | 102 | ||
| 102 | #ifndef sns_irTransceive_PRONTO_SUPPORT |
103 | #ifndef sns_irTransceive_PRONTO_SUPPORT |
| 103 | #define sns_irTransceive_PRONTO_SUPPORT 0 |
104 | #define sns_irTransceive_PRONTO_SUPPORT 0 |
| 104 | #endif |
105 | #endif |
| 105 | 106 | ||
| - | 107 | /* |
|
| - | 108 | * PRONTO HEX Routines |
|
| - | 109 | */ |
|
| 106 | #if sns_irTransceive_PRONTO_SUPPORT==1 |
110 | #if sns_irTransceive_PRONTO_SUPPORT==1 |
| 107 | volatile uint32_t sns_irTransceive_LastPronto=0; |
111 | volatile uint32_t sns_irTransceive_LastPronto=0; |
| 108 | static uint8_t activeChannel = 0; |
112 | static uint8_t activeChannel = 0; |
| 109 | #define sns_irTransceive_MAXTIMING (16*1000) |
113 | #define sns_irTransceive_MAXTIMING (16*1000) |
| 110 | 114 | ||
| 111 | void send_pronto( |
115 | static void send_pronto(uint16_t *buffer, uint8_t len, uint8_t channel, uint16_t modfreq) { |
| 112 | StdCan_Msg_t msg; |
116 | StdCan_Msg_t msg; |
| 113 | 117 | ||
| 114 | StdCan_Set_class(msg.Header, CAN_MODULE_CLASS_SNS); |
118 | StdCan_Set_class(msg.Header, CAN_MODULE_CLASS_SNS); |
| 115 | StdCan_Set_direction(msg.Header, DIRECTIONFLAG_FROM_OWNER); |
119 | StdCan_Set_direction(msg.Header, DIRECTIONFLAG_FROM_OWNER); |
| 116 | msg.Header.ModuleType = CAN_MODULE_TYPE_SNS_IRTRANSCEIVE; |
120 | msg.Header.ModuleType = CAN_MODULE_TYPE_SNS_IRTRANSCEIVE; |
| 117 | msg.Header.ModuleId = sns_irTransceive_ID; |
121 | msg.Header.ModuleId = sns_irTransceive_ID; |
| - | 122 | ||
| - | 123 | printf("LEN:%04d", len); |
|
| 118 | 124 | ||
| 119 | /* Send timing command */ |
125 | /* Send timing command */ |
| 120 | msg.Length = 5; |
126 | msg.Length = 5; |
| 121 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOTIMING; |
127 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOTIMING; |
| 122 | uint32_t currentTime=Timer_GetTicks(); |
128 | uint32_t currentTime=Timer_GetTicks(); |
| Line 125... | Line 131... | ||
| 125 | msg.Data[0] = 0xff; |
131 | msg.Data[0] = 0xff; |
| 126 | msg.Data[1] = 0x10; |
132 | msg.Data[1] = 0x10; |
| 127 | msg.Data[2] = (((currentTime-sns_irTransceive_LastPronto)*1000)>>16)&0xff; |
133 | msg.Data[2] = (((currentTime-sns_irTransceive_LastPronto)*1000)>>16)&0xff; |
| 128 | msg.Data[3] = (((currentTime-sns_irTransceive_LastPronto)*1000)>>8)&0xff; |
134 | msg.Data[3] = (((currentTime-sns_irTransceive_LastPronto)*1000)>>8)&0xff; |
| 129 | msg.Data[4] = ((currentTime-sns_irTransceive_LastPronto)*1000)&0xff; |
135 | msg.Data[4] = ((currentTime-sns_irTransceive_LastPronto)*1000)&0xff; |
| 130 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
136 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
| 131 | _delay_ms(1); |
137 | _delay_ms(1); |
| 132 | } |
138 | } |
| 133 | sns_irTransceive_LastPronto=currentTime; |
139 | sns_irTransceive_LastPronto=currentTime; |
| - | 140 | ||
| - | 141 | // calculate frequency divider |
|
| - | 142 | uint16_t divider = (uint16_t)(sns_irTransceive_BaseFrq / (1000*(uint32_t)modfreq)); |
|
| 134 | 143 | ||
| 135 | /* Send pronto start */ |
144 | /* Send pronto start */ |
| 136 | msg.Length = 8; |
145 | msg.Length = 8; |
| 137 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART; |
146 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART; |
| 138 | 147 | ||
| 139 | msg.Data[0] = ((channel<<4)|0x0); /* Channel and Prontoformat |
148 | msg.Data[0] = ((channel<<4)|0x0); /* Channel and Prontoformat 0x0000 */ |
| 140 | msg.Data[1] = 0x00; |
149 | msg.Data[1] = 0x00; |
| 141 | msg.Data[2] = |
150 | msg.Data[2] = (divider & 0xFF00) >> 8; /* Freq divider */ |
| 142 | msg.Data[3] = |
151 | msg.Data[3] = (divider & 0x00FF) >> 0; |
| 143 | msg.Data[4] = 0x00; /* Once seq length, first byte always 0 */ |
152 | msg.Data[4] = 0x00; /* Once seq length, first byte always 0 */ |
| 144 | msg.Data[5] = len/2; |
153 | msg.Data[5] = (len + 1) / 2; |
| 145 | msg.Data[6] = 0x00; /* Repeat seq length, always 0 for ir receive */ |
154 | msg.Data[6] = 0x00; /* Repeat seq length, always 0 for ir receive */ |
| 146 | msg.Data[7] = 0x00; |
155 | msg.Data[7] = 0x00; |
| 147 | 156 | ||
| 148 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
157 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
| 149 | _delay_ms(1); |
158 | _delay_ms(1); |
| 150 | 159 | ||
| 151 | /* Send pronto data */ |
160 | /* Send pronto data */ |
| 152 |
|
161 | //uint16_t divider = ((1000000ULL*modfreq)/sns_irTransceive_BaseFrq); |
| 153 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1; |
162 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1; |
| - | 163 | uint8_t seqNr = 0; |
|
| 154 | /* Counter for buffer */ |
164 | /* Counter for buffer */ |
| 155 | uint8_t i = 0; |
165 | uint8_t i = 0; |
| 156 | /* Counter for filling can frame data */ |
166 | /* Counter for filling can frame data */ |
| 157 | uint8_t j = 0; |
167 | uint8_t j = 0; |
| 158 | /* Remember byte if data does not fit 8 bit */ |
168 | /* Remember byte if data does not fit 8 bit */ |
| Line 163... | Line 173... | ||
| 163 | { |
173 | { |
| 164 | /* If byte was memorized then buffer it */ |
174 | /* If byte was memorized then buffer it */ |
| 165 | msg.Data[j] = mem; |
175 | msg.Data[j] = mem; |
| 166 | /* Clear memory */ |
176 | /* Clear memory */ |
| 167 | mem = 0; |
177 | mem = 0; |
| 168 | } |
178 | } |
| 169 | else |
179 | else |
| 170 | { |
180 | { |
| - | 181 | // convert us to pronto hex modulation pulses |
|
| 171 | uint16_t data = |
182 | uint16_t data = (uint16_t)(((uint32_t)buffer[i] * (uint32_t)modfreq) / 1000); |
| - | 183 | ||
| - | 184 | // protocol compression |
|
| 172 | if (data >= 256) |
185 | if (data >= 256) |
| 173 | { |
186 | { |
| 174 | /* If data does not fit into 8 bit, then split, memorize low byte */ |
187 | /* If data does not fit into 8 bit, then split, memorize low byte */ |
| 175 | mem = data&0xff; |
188 | mem = data&0xff; |
| 176 | /* Buffer high byte */ |
189 | /* Buffer high byte */ |
| 177 | msg.Data[j] = (data>>8)&0xff; |
190 | msg.Data[j] = (data>>8)&0xff; |
| 178 | j++; |
191 | j++; |
| 179 | if (j==8) |
192 | if (j==8) |
| 180 | { |
193 | { |
| 181 | /* If send buffer is full, send frame */ |
194 | /* If send buffer is full, send frame */ |
| 182 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
195 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
| 183 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
196 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
| 184 | _delay_ms(1); |
197 | _delay_ms(1); |
| 185 | j=0; |
198 | j=0; |
| 186 |
|
199 | seqNr = (seqNr + 1) % 16; |
| - | 200 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr; |
|
| 187 | } |
201 | } |
| 188 | /* Set complementary burst pair to 0 to indicate 16bit transmission */ |
202 | /* Set complementary burst pair to 0 to indicate 16bit transmission */ |
| 189 | msg.Data[j] = 0; |
203 | msg.Data[j] = 0; |
| 190 | } |
204 | } |
| 191 | else |
205 | else |
| 192 | { |
206 | { |
| 193 | msg.Data[j] = data&0xff; |
207 | msg.Data[j] = data&0xff; |
| 194 | } |
208 | } |
| 195 | 209 | ||
| 196 | i++; |
210 | i++; |
| 197 | } |
211 | } |
| 198 | 212 | ||
| 199 | j++; |
213 | j++; |
| 200 | if (j==8) |
214 | if (j==8) |
| 201 | { |
215 | { |
| 202 | /* If send buffer is full, send frame */ |
216 | /* If send buffer is full, send frame */ |
| 203 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
217 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
| 204 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
218 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
| 205 | _delay_ms(1); |
219 | _delay_ms(1); |
| 206 | j=0; |
220 | j=0; |
| 207 |
|
221 | seqNr = (seqNr + 1) % 16; |
| - | 222 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr; |
|
| 208 | } |
223 | } |
| 209 | } |
224 | } |
| 210 | 225 | ||
| 211 | /* End with |
226 | /* End with max pulse TODO fix uglyness */ |
| 212 | msg.Data[j] = ((IR_MAX_PULSE_WIDTH/ |
227 | msg.Data[j] = ((IR_MAX_PULSE_WIDTH/((1000000ULL*109)/sns_irTransceive_BaseFrq))>>8) & 0xFF; |
| 213 | j++; |
228 | j++; |
| 214 | if (j==8) |
229 | if (j==8) |
| 215 | { |
230 | { |
| 216 | /* If send buffer is full, send frame */ |
231 | /* If send buffer is full, send frame */ |
| 217 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
232 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
| 218 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
233 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
| 219 | _delay_ms(1); |
234 | _delay_ms(1); |
| 220 | j=0; |
235 | j=0; |
| 221 |
|
236 | seqNr = (seqNr + 1) % 16; |
| - | 237 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr; |
|
| 222 | } |
238 | } |
| 223 | msg.Data[j] = 0; |
239 | msg.Data[j] = 0; |
| 224 | j++; |
240 | j++; |
| 225 | msg.Data[j] = (IR_MAX_PULSE_WIDTH/ |
241 | msg.Data[j] = (IR_MAX_PULSE_WIDTH/((1000000ULL*109)/sns_irTransceive_BaseFrq))&0xff; |
| 226 | j++; |
242 | j++; |
| 227 | if (j==8) |
243 | if (j==8) |
| 228 | { |
244 | { |
| 229 | /* If send buffer is full, send frame */ |
245 | /* If send buffer is full, send frame */ |
| 230 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
246 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
| 231 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
247 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
| 232 | _delay_ms(1); |
248 | _delay_ms(1); |
| 233 | j=0; |
249 | j=0; |
| 234 |
|
250 | seqNr = (seqNr + 1) % 16; |
| - | 251 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr; |
|
| 235 | } |
252 | } |
| 236 | 253 | ||
| 237 | /* Msg command kept from for loop, but increase 16 to send ProntoEnd */ |
254 | /* Msg command kept from for loop, but increase 16 to send ProntoEnd */ |
| 238 | msg.Header.Command |
255 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1 + seqNr; |
| 239 | msg.Length = j; |
256 | msg.Length = j; |
| 240 | /* data kept from loop, if any */ |
257 | /* data kept from loop, if any */ |
| 241 | /* buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
258 | /* buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
| 242 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
259 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
| 243 | _delay_ms(1); |
260 | _delay_ms(1); |
| 244 | } |
261 | } |
| - | 262 | ||
| - | 263 | ||
| - | 264 | static int decodeProntoData(int channel, uint8_t data) |
|
| - | 265 | { |
|
| - | 266 | static uint8_t waitingForLSB = FALSE; |
|
| - | 267 | ||
| - | 268 | // check if done |
|
| - | 269 | if (irTxChannel[activeChannel].txlen == (((uint16_t)irTxChannel[activeChannel].onceSeqLen + (uint16_t)irTxChannel[activeChannel].repSeqLen))) { |
|
| - | 270 | return 2; |
|
| - | 271 | } |
|
| - | 272 | ||
| - | 273 | if (irTxChannel[channel].txlen >= MAX_NR_TIMES) { |
|
| - | 274 | // max length exceeded |
|
| - | 275 | return -1; |
|
| - | 276 | } |
|
| - | 277 | ||
| - | 278 | if (irTxChannel[channel].txlen == 0) { |
|
| - | 279 | waitingForLSB = FALSE; |
|
| - | 280 | if (data == 0) { |
|
| - | 281 | // cannot start with 0x00 |
|
| - | 282 | return -2; |
|
| - | 283 | } |
|
| - | 284 | } |
|
| - | 285 | ||
| - | 286 | // 0x00 means that previously received time is MSB of 16bit value, and that next byte will be LSB |
|
| - | 287 | if (data == 0 && !waitingForLSB) { |
|
| - | 288 | // convert previous time to MSB of the 16bit value. next received byte will become LSB |
|
| - | 289 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] <<= 8; |
|
| - | 290 | ||
| - | 291 | // flag that next received byte is LSB rather than a new timing value |
|
| - | 292 | waitingForLSB = TRUE; |
|
| - | 293 | } |
|
| - | 294 | ||
| - | 295 | // non-zero value! is this part of a 16bit-value? use the data as LSB for previously received time |
|
| - | 296 | else if (waitingForLSB) { |
|
| - | 297 | // let this byte be LSB of previous 16bit value |
|
| - | 298 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] |= data; |
|
| - | 299 | ||
| - | 300 | // we've now completed reception of the 16bit value |
|
| - | 301 | waitingForLSB = FALSE; |
|
| - | 302 | } |
|
| - | 303 | ||
| - | 304 | // non-zero value! simply new 8bit value |
|
| - | 305 | else { |
|
| - | 306 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen] = data; |
|
| - | 307 | ||
| - | 308 | irTxChannel[channel].txlen++; |
|
| - | 309 | } |
|
| - | 310 | ||
| - | 311 | return 1; |
|
| - | 312 | } |
|
| - | 313 | ||
| 245 | #endif |
314 | #endif |
| 246 | 315 | ||
| 247 | 316 | ||
| 248 | #if IR_RX_ENABLE==1 |
317 | #if IR_RX_ENABLE==1 |
| 249 | void sns_irTransceive_RX_done_callback(uint8_t channel, uint16_t *buffer, uint8_t len) |
318 | void sns_irTransceive_RX_done_callback(uint8_t channel, uint16_t *buffer, uint8_t len) |
| 250 | { |
319 | { |
| 251 | if (channel < IR_SUPPORTED_NUM_CHANNELS) |
320 | if (channel < IR_SUPPORTED_NUM_CHANNELS) |
| 252 | { |
321 | { |
| 253 | irRxChannel[channel].newData = TRUE; |
322 | irRxChannel[channel].newData = TRUE; |
| 254 | irRxChannel[channel].rxlen = len; |
323 | irRxChannel[channel].rxlen = len; |
| 255 | } |
324 | } |
| 256 | } |
325 | } |
| 257 | #endif |
326 | #endif |
| 258 | 327 | ||
| 259 | 328 | ||
| 260 | #if IR_TX_ENABLE==1 |
329 | #if IR_TX_ENABLE==1 |
| 261 | void sns_irTransceive_TX_done_callback(uint8_t channel) |
330 | void sns_irTransceive_TX_done_callback(uint8_t channel) |
| 262 | { |
331 | { |
| 263 | if (channel < IR_SUPPORTED_NUM_CHANNELS) |
332 | if (channel < IR_SUPPORTED_NUM_CHANNELS) |
| 264 | { |
333 | { |
| 265 | irTxChannel[channel].sendComplete = TRUE; |
334 | irTxChannel[channel].sendComplete = TRUE; |
| 266 | } |
335 | } |
| 267 | } |
336 | } |
| 268 | #endif |
337 | #endif |
| 269 | 338 | ||
| 270 | 339 | ||
| 271 | void sns_irTransceive_setConfig( |
340 | static void sns_irTransceive_setConfig(uint8_t channel, uint8_t config, uint8_t power, uint16_t modfreq) |
| 272 | { |
341 | { |
| 273 | if (channel < IR_SUPPORTED_NUM_CHANNELS && config <= CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE && power < 4) |
342 | if (channel < IR_SUPPORTED_NUM_CHANNELS && config <= CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE && power < 4) |
| 274 | { |
343 | { |
| 275 | #if IR_RX_ENABLE==1 |
344 | #if IR_RX_ENABLE==1 |
| 276 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE) |
345 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE) |
| Line 283... | Line 352... | ||
| 283 | switch (channel) |
352 | switch (channel) |
| 284 | { |
353 | { |
| 285 | case 0: |
354 | case 0: |
| 286 | gpio_clr_pin(sns_irTransceive_VCC_EN0_PIN); |
355 | gpio_clr_pin(sns_irTransceive_VCC_EN0_PIN); |
| 287 | IrTransceiver_InitRxChannel(channel, irRxChannel[channel].rxbuf, sns_irTransceive_RX_done_callback, sns_irTransceive_RX0_PCINT, sns_irTransceive_RX0_PIN); |
356 | IrTransceiver_InitRxChannel(channel, irRxChannel[channel].rxbuf, sns_irTransceive_RX_done_callback, sns_irTransceive_RX0_PCINT, sns_irTransceive_RX0_PIN); |
| 288 | break; |
357 | break; |
| 289 | case 1: |
358 | case 1: |
| 290 | gpio_clr_pin(sns_irTransceive_VCC_EN1_PIN); |
359 | gpio_clr_pin(sns_irTransceive_VCC_EN1_PIN); |
| 291 | IrTransceiver_InitRxChannel(channel, irRxChannel[channel].rxbuf, sns_irTransceive_RX_done_callback, sns_irTransceive_RX1_PCINT, sns_irTransceive_RX1_PIN); |
360 | IrTransceiver_InitRxChannel(channel, irRxChannel[channel].rxbuf, sns_irTransceive_RX_done_callback, sns_irTransceive_RX1_PCINT, sns_irTransceive_RX1_PIN); |
| 292 | break; |
361 | break; |
| 293 | case 2: |
362 | case 2: |
| 294 | gpio_clr_pin(sns_irTransceive_VCC_EN2_PIN); |
363 | gpio_clr_pin(sns_irTransceive_VCC_EN2_PIN); |
| 295 | IrTransceiver_InitRxChannel(channel, irRxChannel[channel].rxbuf, sns_irTransceive_RX_done_callback, sns_irTransceive_RX2_PCINT, sns_irTransceive_RX2_PIN); |
364 | IrTransceiver_InitRxChannel(channel, irRxChannel[channel].rxbuf, sns_irTransceive_RX_done_callback, sns_irTransceive_RX2_PCINT, sns_irTransceive_RX2_PIN); |
| 296 | break; |
365 | break; |
| 297 | } |
366 | } |
| 298 | irRxChannel[channel].state = sns_irTransceive_STATE_RECEIVING; |
367 | irRxChannel[channel].state = sns_irTransceive_STATE_RECEIVING; |
| 299 | } |
368 | } |
| 300 | #endif |
369 | #endif |
| 301 | 370 | ||
| 302 | #if IR_TX_ENABLE==1 |
371 | #if IR_TX_ENABLE==1 |
| 303 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_TRANSMIT) |
372 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_TRANSMIT) |
| 304 | { |
373 | { |
| 305 | #if IR_RX_ENABLE==1 |
374 | #if IR_RX_ENABLE==1 |
| Line 313... | Line 382... | ||
| 313 | #if IR_RX_ENABLE==1 |
382 | #if IR_RX_ENABLE==1 |
| 314 | gpio_set_pin(sns_irTransceive_VCC_EN0_PIN); |
383 | gpio_set_pin(sns_irTransceive_VCC_EN0_PIN); |
| 315 | IrTransceiver_DeInitRxChannel(channel, sns_irTransceive_RX0_PCINT, sns_irTransceive_RX0_PIN); |
384 | IrTransceiver_DeInitRxChannel(channel, sns_irTransceive_RX0_PCINT, sns_irTransceive_RX0_PIN); |
| 316 | #endif |
385 | #endif |
| 317 | IrTransceiver_InitTxChannel(channel, sns_irTransceive_TX_done_callback, sns_irTransceive_TX0_PIN); |
386 | IrTransceiver_InitTxChannel(channel, sns_irTransceive_TX_done_callback, sns_irTransceive_TX0_PIN); |
| 318 | 387 | ||
| 319 | #if sns_irTransceive_ENABLE_PCA95xx==1 |
388 | #if sns_irTransceive_ENABLE_PCA95xx==1 |
| 320 | Pca95xx_set_out(sns_irTransceive_TX0_PWRl); |
389 | Pca95xx_set_out(sns_irTransceive_TX0_PWRl); |
| 321 | Pca95xx_set_out(sns_irTransceive_TX0_PWRh); |
390 | Pca95xx_set_out(sns_irTransceive_TX0_PWRh); |
| 322 | if (power&0x1) |
391 | if (power&0x1) |
| 323 | { |
392 | { |
| 324 | Pca95xx_set_in(sns_irTransceive_TX0_PWRl); |
393 | Pca95xx_set_in(sns_irTransceive_TX0_PWRl); |
| 325 | } |
394 | } |
| 326 | if (power&0x2) |
395 | if (power&0x2) |
| 327 | { |
396 | { |
| 328 | Pca95xx_set_in(sns_irTransceive_TX0_PWRh); |
397 | Pca95xx_set_in(sns_irTransceive_TX0_PWRh); |
| Line 340... | Line 409... | ||
| 340 | Pca95xx_set_out(sns_irTransceive_TX1_PWRl); |
409 | Pca95xx_set_out(sns_irTransceive_TX1_PWRl); |
| 341 | Pca95xx_set_out(sns_irTransceive_TX1_PWRh); |
410 | Pca95xx_set_out(sns_irTransceive_TX1_PWRh); |
| 342 | if (power&0x1) |
411 | if (power&0x1) |
| 343 | { |
412 | { |
| 344 | Pca95xx_set_in(sns_irTransceive_TX1_PWRl); |
413 | Pca95xx_set_in(sns_irTransceive_TX1_PWRl); |
| 345 | } |
414 | } |
| 346 | if (power&0x2) |
415 | if (power&0x2) |
| 347 | { |
416 | { |
| 348 | Pca95xx_set_in(sns_irTransceive_TX1_PWRh); |
417 | Pca95xx_set_in(sns_irTransceive_TX1_PWRh); |
| 349 | } |
418 | } |
| 350 | #endif |
419 | #endif |
| 351 | break; |
420 | break; |
| 352 | case 2: |
421 | case 2: |
| Line 413... | Line 482... | ||
| 413 | #if IR_RX_ENABLE==1 |
482 | #if IR_RX_ENABLE==1 |
| 414 | // TODO: hardcoded to 3 channels?? /jm |
483 | // TODO: hardcoded to 3 channels?? /jm |
| 415 | irRxChannel[0].timerNum=sns_irTransceive_RX0_REPEATE_TIMER; |
484 | irRxChannel[0].timerNum=sns_irTransceive_RX0_REPEATE_TIMER; |
| 416 | irRxChannel[1].timerNum=sns_irTransceive_RX1_REPEATE_TIMER; |
485 | irRxChannel[1].timerNum=sns_irTransceive_RX1_REPEATE_TIMER; |
| 417 | irRxChannel[2].timerNum=sns_irTransceive_RX2_REPEATE_TIMER; |
486 | irRxChannel[2].timerNum=sns_irTransceive_RX2_REPEATE_TIMER; |
| 418 | #endif |
487 | #endif |
| 419 | 488 | ||
| 420 | #if IR_TX_ENABLE==1 |
489 | #if IR_TX_ENABLE==1 |
| 421 | // TODO: hardcoded to 3 channels?? /jm |
490 | // TODO: hardcoded to 3 channels?? /jm |
| 422 | irTxChannel[0].timerNum=sns_irTransceive_TX0_REPEATE_TIMER; |
491 | irTxChannel[0].timerNum=sns_irTransceive_TX0_REPEATE_TIMER; |
| 423 | irTxChannel[1].timerNum=sns_irTransceive_TX1_REPEATE_TIMER; |
492 | irTxChannel[1].timerNum=sns_irTransceive_TX1_REPEATE_TIMER; |
| Line 467... | Line 536... | ||
| 467 | 536 | ||
| 468 | #ifdef sns_irTransceive_USEEEPROM |
537 | #ifdef sns_irTransceive_USEEEPROM |
| 469 | if (EEDATA_OK) |
538 | if (EEDATA_OK) |
| 470 | { |
539 | { |
| 471 | /* Use stored data to set initial values for the module */ |
540 | /* Use stored data to set initial values for the module */ |
| 472 | sns_irTransceive_setConfig(0, eeprom_read_byte(EEDATA.ch0_config), eeprom_read_byte(EEDATA.ch0_txpower), |
541 | sns_irTransceive_setConfig(0, eeprom_read_byte(EEDATA.ch0_config), eeprom_read_byte(EEDATA.ch0_txpower), eeprom_read_word(EEDATA.ch0_modfreq)); |
| 473 | sns_irTransceive_setConfig(1, eeprom_read_byte(EEDATA.ch1_config), eeprom_read_byte(EEDATA.ch1_txpower), |
542 | sns_irTransceive_setConfig(1, eeprom_read_byte(EEDATA.ch1_config), eeprom_read_byte(EEDATA.ch1_txpower), eeprom_read_word(EEDATA.ch1_modfreq)); |
| 474 | sns_irTransceive_setConfig(2, eeprom_read_byte(EEDATA.ch2_config), eeprom_read_byte(EEDATA.ch2_txpower), |
543 | sns_irTransceive_setConfig(2, eeprom_read_byte(EEDATA.ch2_config), eeprom_read_byte(EEDATA.ch2_txpower), eeprom_read_word(EEDATA.ch2_modfreq)); |
| 475 | } |
544 | } |
| 476 | else |
545 | else |
| 477 | { |
546 | { |
| 478 | /* The CRC of the EEPROM is not correct, store default values and update CRC */ |
547 | /* The CRC of the EEPROM is not correct, store default values and update CRC */ |
| 479 | eeprom_write_byte_crc(EEDATA.ch0_config, CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO, WITHOUT_CRC); |
548 | eeprom_write_byte_crc(EEDATA.ch0_config, CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO, WITHOUT_CRC); |
| 480 | eeprom_write_byte_crc(EEDATA.ch0_txpower, 0, WITHOUT_CRC); |
549 | eeprom_write_byte_crc(EEDATA.ch0_txpower, 0, WITHOUT_CRC); |
| 481 |
|
550 | eeprom_write_word_crc(EEDATA.ch0_modfreq, sns_irTransceive_BaseFrq/38000UL, WITHOUT_CRC); |
| 482 | eeprom_write_byte_crc(EEDATA.ch1_config, CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO, WITHOUT_CRC); |
551 | eeprom_write_byte_crc(EEDATA.ch1_config, CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO, WITHOUT_CRC); |
| 483 | eeprom_write_byte_crc(EEDATA.ch1_txpower, 0, WITHOUT_CRC); |
552 | eeprom_write_byte_crc(EEDATA.ch1_txpower, 0, WITHOUT_CRC); |
| 484 |
|
553 | eeprom_write_word_crc(EEDATA.ch1_modfreq, sns_irTransceive_BaseFrq/38000UL, WITHOUT_CRC); |
| 485 | eeprom_write_byte_crc(EEDATA.ch2_config, CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO, WITHOUT_CRC); |
554 | eeprom_write_byte_crc(EEDATA.ch2_config, CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO, WITHOUT_CRC); |
| 486 | eeprom_write_byte_crc(EEDATA.ch2_txpower, 0, WITHOUT_CRC); |
555 | eeprom_write_byte_crc(EEDATA.ch2_txpower, 0, WITHOUT_CRC); |
| 487 |
|
556 | eeprom_write_word_crc(EEDATA.ch2_modfreq, sns_irTransceive_BaseFrq/38000UL, WITHOUT_CRC); |
| 488 | EEDATA_UPDATE_CRC; |
557 | EEDATA_UPDATE_CRC; |
| 489 | } |
558 | } |
| 490 | #endif |
559 | #endif |
| 491 | } |
560 | } |
| 492 | 561 | ||
| Line 512... | Line 581... | ||
| 512 | 581 | ||
| 513 | case sns_irTransceive_STATE_RECEIVING: |
582 | case sns_irTransceive_STATE_RECEIVING: |
| 514 | if (irRxChannel[channel].newData == TRUE) { |
583 | if (irRxChannel[channel].newData == TRUE) { |
| 515 | //TODO: move this line to the RX callback |
584 | //TODO: move this line to the RX callback |
| 516 | IrTransceiver_DisableRx(channel); |
585 | IrTransceiver_DisableRx(channel); |
| 517 | cli(); |
586 | cli(); |
| 518 | irRxChannel[channel].newData = FALSE; |
587 | irRxChannel[channel].newData = FALSE; |
| 519 | sei(); |
588 | sei(); |
| 520 | 589 | ||
| 521 | /* Let protocol driver parse and then send on CAN */ |
590 | /* Let protocol driver parse and then send on CAN */ |
| 522 | uint8_t res2 = parseProtocol(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen, &irRxChannel[channel].proto); |
591 | uint8_t res2 = parseProtocol(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen, &irRxChannel[channel].proto); |
| 523 | if (res2 == IR_OK && irRxChannel[channel].proto.protocol != IR_PROTO_UNKNOWN) { |
592 | if (res2 == IR_OK && irRxChannel[channel].proto.protocol != IR_PROTO_UNKNOWN) { |
| Line 700... | Line 769... | ||
| 700 | if (irTxChannel[channel].sendingPronto) |
769 | if (irTxChannel[channel].sendingPronto) |
| 701 | { |
770 | { |
| 702 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
771 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
| 703 | { |
772 | { |
| 704 | irTxChannel[channel].state = sns_irTransceive_STATE_PRONTO_REPEAT; |
773 | irTxChannel[channel].state = sns_irTransceive_STATE_PRONTO_REPEAT; |
| 705 | } |
774 | } |
| 706 | break; |
775 | break; |
| 707 | } |
776 | } |
| 708 | 777 | ||
| 709 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
778 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
| 710 | { |
779 | { |
| 711 | irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT; |
780 | irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT; |
| 712 | } |
781 | } |
| 713 | 782 | ||
| 714 | /* transmission is stopped when such command is recevied on can */ |
783 | /* transmission is stopped when such command is recevied on can */ |
| 715 | if (irTxChannel[channel].stopSend == TRUE && irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats) |
784 | if (irTxChannel[channel].stopSend == TRUE && irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats) |
| 716 | { |
785 | { |
| 717 | //TODO maybe send message on can for status? to confirm stopped sending, ready for new command |
786 | //TODO maybe send message on can for status? to confirm stopped sending, ready for new command |
| 718 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
787 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
| 719 | } |
788 | } |
| 720 | break; |
789 | break; |
| 721 | } |
790 | } |
| 722 | case sns_irTransceive_STATE_START_IDLE: |
791 | case sns_irTransceive_STATE_START_IDLE: |
| 723 | irTxChannel[channel].stopSend = FALSE; |
792 | irTxChannel[channel].stopSend = FALSE; |
| 724 | irTxChannel[channel].repeatCount = 0; |
793 | irTxChannel[channel].repeatCount = 0; |
| 725 | irTxChannel[channel].proto.framecnt = 0; |
794 | irTxChannel[channel].proto.framecnt = 0; |
| 726 | irTxChannel[channel].sendingPronto = FALSE; |
795 | irTxChannel[channel].sendingPronto = FALSE; |
| 727 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
796 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| 728 | break; |
797 | break; |
| 729 | 798 | ||
| 730 | default: |
799 | default: |
| 731 | break; |
800 | break; |
| 732 | } |
801 | } |
| 733 | #endif |
802 | #endif |
| 734 | 803 | ||
| 735 | } |
804 | } |
| 736 | } |
805 | } |
| 737 | 806 | ||
| Line 774... | Line 843... | ||
| 774 | { |
843 | { |
| 775 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) |
844 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) |
| 776 | { |
845 | { |
| 777 | irTxChannel[channel].stopSend = TRUE; |
846 | irTxChannel[channel].stopSend = TRUE; |
| 778 | } |
847 | } |
| 779 | } |
848 | } |
| 780 | break; |
849 | break; |
| 781 | } |
850 | } |
| 782 | 851 | ||
| 783 | #if sns_irTransceive_PRONTO_SUPPORT==1 |
852 | #if sns_irTransceive_PRONTO_SUPPORT==1 |
| 784 | /* TODO: add struct which stores pronto info: |
853 | /* TODO: add struct which stores pronto info: |
| 785 | channel, pronto receive state, buffer length of once burst pairs, buffer length of repeat burst pairs */ |
854 | channel, pronto receive state, buffer length of once burst pairs, buffer length of repeat burst pairs */ |
| 786 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART: |
855 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART: |
| Line 788... | Line 857... | ||
| 788 | /* Sanity check. */ |
857 | /* Sanity check. */ |
| 789 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) break; |
858 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) break; |
| 790 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) break; |
859 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) break; |
| 791 | 860 | ||
| 792 | /* Check if format is supported. */ |
861 | /* Check if format is supported. */ |
| 793 | if ((uint16_t)(rxMsg->Data[ |
862 | if ((((uint16_t)(rxMsg->Data[0] & 0x0F) << 8) | (uint16_t)(rxMsg->Data[1])) != 0) break; |
| 794 | 863 | ||
| 795 | /* Extract received data. */ |
864 | /* Extract received data. */ |
| - | 865 | ||
| - | 866 | uint32_t divider = (rxMsg->Data[2] << 8) | (rxMsg->Data[3] << 0); |
|
| - | 867 | if (divider == 0) { |
|
| - | 868 | // invalid modfreq |
|
| - | 869 | break; |
|
| - | 870 | } |
|
| - | 871 | uint32_t freqkHz = (sns_irTransceive_BaseFrq / (divider*1000)); |
|
| - | 872 | if (freqkHz == 0) { |
|
| - | 873 | // invalid modfreq |
|
| - | 874 | break; |
|
| - | 875 | } |
|
| 796 |
|
876 | irTxChannel[channel].proto.modfreq = freqkHz; |
| - | 877 | //printf("FRQ%05u", irTxChannel[channel].proto.modfreq); |
|
| - | 878 | ||
| 797 |
|
879 | // TODO: reconfigure with new modfreq, if no other channels sending pronto |
| - | 880 | ||
| 798 | irTxChannel |
881 | //irTxChannel[channel].proto.modfreq = (((F_CPU/2000)/IR_NEC_F_MOD) -1); |
| 799 | // convert lenghts to bytes |
882 | // convert lenghts to bytes |
| 800 | irTxChannel[channel].onceSeqLen = 2*((((uint16_t)rxMsg->Data[4]) << 8) | (((uint16_t)rxMsg->Data[5]) << 0)); |
883 | irTxChannel[channel].onceSeqLen = 2*((((uint16_t)rxMsg->Data[4]) << 8) | (((uint16_t)rxMsg->Data[5]) << 0)); |
| 801 | irTxChannel[channel].repSeqLen = 2*((((uint16_t)rxMsg->Data[6]) << 8) | (((uint16_t)rxMsg->Data[7]) << 0)); |
884 | irTxChannel[channel].repSeqLen = 2*((((uint16_t)rxMsg->Data[6]) << 8) | (((uint16_t)rxMsg->Data[7]) << 0)); |
| - | 885 | ||
| - | 886 | //printf("ONCE%04u", irTxChannel[channel].onceSeqLen); |
|
| - | 887 | //printf("REQL%04u", irTxChannel[channel].repSeqLen); |
|
| 802 | 888 | ||
| 803 | /* Enter prepering pronto state and clear transmit buffer. */ |
889 | /* Enter prepering pronto state and clear transmit buffer. */ |
| 804 | irTxChannel[channel].state = sns_irTransceive_STATE_PREPARING_PRONTO; |
890 | irTxChannel[channel].state = sns_irTransceive_STATE_PREPARING_PRONTO; |
| 805 | irTxChannel[channel].txlen = 0; |
891 | irTxChannel[channel].txlen = 0; |
| - | 892 | irTxChannel[channel].expectedSeqNr = 0; |
|
| 806 | activeChannel = channel; |
893 | activeChannel = channel; |
| 807 | 894 | ||
| 808 | /* TODO: Send response frame */ |
895 | /* TODO: Send response frame */ |
| 809 | break; |
896 | break; |
| 810 | } |
897 | } |
| 811 | 898 | ||
| 812 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTOP: |
899 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTOP: |
| 813 | /* TODO: stop sending IR */ |
900 | /* TODO: stop sending IR */ |
| 814 | 901 | ||
| 815 | /* TODO: Send response frame */ |
902 | /* TODO: Send response frame */ |
| 816 | break; |
903 | break; |
| 817 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOCONTINUE: |
904 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOCONTINUE: |
| 818 | /* TODO: reset timeout to continue sending repeat sequences */ |
905 | /* TODO: reset timeout to continue sending repeat sequences */ |
| 819 | 906 | ||
| 820 | /* TODO: Send response frame */ |
907 | /* TODO: Send response frame */ |
| 821 | break; |
908 | break; |
| 822 | 909 | ||
| 823 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1: /* Fall through */ |
910 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1: /* Fall through */ |
| 824 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA2: /* Fall through */ |
911 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA2: /* Fall through */ |
| Line 834... | Line 921... | ||
| 834 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA12: /* Fall through */ |
921 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA12: /* Fall through */ |
| 835 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA13: /* Fall through */ |
922 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA13: /* Fall through */ |
| 836 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA14: /* Fall through */ |
923 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA14: /* Fall through */ |
| 837 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA15: /* Fall through */ |
924 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA15: /* Fall through */ |
| 838 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA16: |
925 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA16: |
| 839 | { |
926 | { |
| 840 | // unexpected CAN msg, out of order |
927 | // unexpected CAN msg, out of order |
| 841 | if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) |
928 | if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) { |
| - | 929 | break; |
|
| - | 930 | } |
|
| 842 | 931 | ||
| - | 932 | // unexpected CAN msg, out of order |
|
| 843 | if (( |
933 | if ((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1) != (irTxChannel[activeChannel].expectedSeqNr % 16)) { |
| 844 |
|
934 | printf("SEQERROR"); |
| 845 | irTxChannel[ |
935 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
| 846 | break; |
936 | break; |
| 847 | } |
937 | } |
| - | 938 | ||
| - | 939 | // decode pronto data |
|
| 848 | for (uint8_t i=0; i < rxMsg->Length; i++) { |
940 | for (uint8_t i = 0; i < rxMsg->Length; i++) { |
| 849 |
|
941 | if (decodeProntoData(activeChannel, rxMsg->Data[i]) != 1) { |
| 850 |
|
942 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
| - | 943 | printf("DECERROR"); |
|
| - | 944 | return; |
|
| - | 945 | } |
|
| 851 | } |
946 | } |
| - | 947 | ||
| - | 948 | irTxChannel[activeChannel].expectedSeqNr++; |
|
| 852 | break; |
949 | break; |
| 853 | } |
950 | } |
| 854 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1: /* Fall through */ |
951 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1: /* Fall through */ |
| 855 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND2: /* Fall through */ |
952 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND2: /* Fall through */ |
| 856 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND3: /* Fall through */ |
953 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND3: /* Fall through */ |
| Line 866... | Line 963... | ||
| 866 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND13: /* Fall through */ |
963 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND13: /* Fall through */ |
| 867 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND14: /* Fall through */ |
964 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND14: /* Fall through */ |
| 868 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND15: /* Fall through */ |
965 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND15: /* Fall through */ |
| 869 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND16: /* Fall through */ |
966 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND16: /* Fall through */ |
| 870 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND17: |
967 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND17: |
| 871 | { |
968 | { |
| 872 | // unexpected CAN msg, out of order |
969 | // unexpected CAN msg, out of order |
| 873 | if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) { |
970 | if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) { |
| 874 | //printf("StERR:%02d", irTxChannel[activeChannel].state); |
- | |
| 875 | break; |
971 | break; |
| 876 | } |
972 | } |
| - | 973 | ||
| - | 974 | // unexpected CAN msg, out of order |
|
| - | 975 | if (((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1) % 16) != (irTxChannel[activeChannel].expectedSeqNr % 16)) { |
|
| - | 976 | printf("SEQERROR"); |
|
| - | 977 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
|
| - | 978 | break; |
|
| - | 979 | } |
|
| 877 | 980 | ||
| - | 981 | // decode remaining pronto data (if any) |
|
| - | 982 | for (uint16_t i = 0; i < rxMsg->Length - 1; i++) { |
|
| 878 | if |
983 | if (decodeProntoData(activeChannel, rxMsg->Data[i]) < 0) { |
| 879 |
|
984 | printf("DECERROR"); |
| 880 | irTxChannel[ |
985 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
| 881 |
|
986 | return; |
| 882 | } |
987 | } |
| 883 | - | ||
| 884 | uint16_t nrBytesRemaining = (((uint16_t)irTxChannel[activeChannel].onceSeqLen + (uint16_t)irTxChannel[activeChannel].repSeqLen)) - irTxChannel[activeChannel].txlen; |
- | |
| 885 | //printf("TXLEN:%02d", irTxChannel[activeChannel].txlen); |
- | |
| 886 | //printf("BYTES:%02d", nrBytesRemaining); |
- | |
| 887 | // end packet does not always contain data, last byte is reserved |
- | |
| 888 | for (uint8_t i=0; i < nrBytesRemaining; i++) { |
- | |
| 889 | // TODO: (109 * 1) / (4.145146 MHz) = 27, fix formula with modfreq |
- | |
| 890 | irTxChannel[activeChannel].txbuf[irTxChannel[activeChannel].txlen++] = 27 * rxMsg->Data[i]; |
- | |
| 891 | } |
988 | } |
| 892 | 989 | ||
| 893 | // sanity check |
990 | // sanity check |
| 894 | if(irTxChannel[activeChannel].txlen != (((uint16_t)irTxChannel[activeChannel].onceSeqLen + (uint16_t)irTxChannel[activeChannel].repSeqLen))) |
991 | if (irTxChannel[activeChannel].txlen != (((uint16_t)irTxChannel[activeChannel].onceSeqLen + (uint16_t)irTxChannel[activeChannel].repSeqLen))) |
| 895 | { |
992 | { |
| 896 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE; |
993 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE; |
| 897 | break; |
994 | break; |
| 898 | } |
995 | } |
| 899 | 996 | ||
| 900 | // last byte |
997 | // last byte determines nr of repeats. 0xFF means INF, 0 means no repeats |
| 901 | irTxChannel[activeChannel].proto.repeats = rxMsg->Data[rxMsg->Length-1]; |
998 | irTxChannel[activeChannel].proto.repeats = rxMsg->Data[rxMsg->Length - 1]; |
| - | 999 | irTxChannel[activeChannel].proto.timeout = 1; // TODO: timer is buggy and doesn't support timeout 0, so we're forced to use 1ms extra between repeats |
|
| - | 1000 | ||
| - | 1001 | // convert pronto data to µs |
|
| - | 1002 | // TODO: calculate value |
|
| - | 1003 | for (uint16_t i=0; i < irTxChannel[activeChannel].txlen; i++) { |
|
| - | 1004 | uint32_t newVal = ((uint32_t)irTxChannel[activeChannel].txbuf[i]) * 27; |
|
| - | 1005 | if (newVal > 0xFFFF) { |
|
| - | 1006 | newVal = 0xFFFF; |
|
| - | 1007 | } |
|
| 902 | irTxChannel |
1008 | irTxChannel[activeChannel].txbuf[i] = (uint16_t)newVal; |
| - | 1009 | } |
|
| 903 | 1010 | ||
| 904 | // send |
1011 | // send |
| 905 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_TRANSMIT_PRONTO; |
1012 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_TRANSMIT_PRONTO; |
| 906 | 1013 | ||
| 907 | /* TODO: Send response frame */ |
1014 | /* TODO: Send response frame */ |
| Line 913... | Line 1020... | ||
| 913 | #endif |
1020 | #endif |
| 914 | 1021 | ||
| 915 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRCONFIG: { |
1022 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRCONFIG: { |
| 916 | uint8_t config = rxMsg->Data[0] & 0x0f; |
1023 | uint8_t config = rxMsg->Data[0] & 0x0f; |
| 917 | uint8_t power = rxMsg->Data[1]>>6; |
1024 | uint8_t power = rxMsg->Data[1]>>6; |
| - | 1025 | uint32_t divider = ((uint16_t)rxMsg->Data[2] << 8) | ((uint16_t)rxMsg->Data[3] << 0); |
|
| - | 1026 | if (divider == 0) { |
|
| - | 1027 | // invalid modfreq |
|
| - | 1028 | break; |
|
| - | 1029 | } |
|
| - | 1030 | uint32_t modfreq = (sns_irTransceive_BaseFrq / (divider*1000)); |
|
| 918 |
|
1031 | if (modfreq == 0) { |
| - | 1032 | // invalid modfreq |
|
| - | 1033 | break; |
|
| 919 | 1034 | } |
|
| 920 | sns_irTransceive_setConfig(channel, config, power, modfreq); |
1035 | sns_irTransceive_setConfig(channel, config, power, modfreq); |
| 921 | 1036 | ||
| 922 | #ifdef sns_irTransceive_USEEEPROM |
1037 | #ifdef sns_irTransceive_USEEEPROM |
| 923 | if (channel < IR_SUPPORTED_NUM_CHANNELS && config <= CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE && power < 4) |
1038 | if (channel < IR_SUPPORTED_NUM_CHANNELS && config <= CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE && power < 4) |
| 924 | { |
1039 | { |
| 925 | switch (channel) |
1040 | switch (channel) |
| 926 | { |
1041 | { |
| 927 | case 0: |
1042 | case 0: |
| 928 | eeprom_write_byte_crc(EEDATA.ch0_config, config, WITHOUT_CRC); |
1043 | eeprom_write_byte_crc(EEDATA.ch0_config, config, WITHOUT_CRC); |
| 929 | eeprom_write_byte_crc(EEDATA.ch0_txpower, power, WITHOUT_CRC); |
1044 | eeprom_write_byte_crc(EEDATA.ch0_txpower, power, WITHOUT_CRC); |
| 930 |
|
1045 | eeprom_write_word_crc(EEDATA.ch0_modfreq, modfreq, WITHOUT_CRC); |
| 931 | break; |
1046 | break; |
| 932 | case 1: |
1047 | case 1: |
| 933 | eeprom_write_byte_crc(EEDATA.ch1_config, config, WITHOUT_CRC); |
1048 | eeprom_write_byte_crc(EEDATA.ch1_config, config, WITHOUT_CRC); |
| 934 | eeprom_write_byte_crc(EEDATA.ch1_txpower, power, WITHOUT_CRC); |
1049 | eeprom_write_byte_crc(EEDATA.ch1_txpower, power, WITHOUT_CRC); |
| 935 |
|
1050 | eeprom_write_word_crc(EEDATA.ch1_modfreq, modfreq, WITHOUT_CRC); |
| 936 | break; |
1051 | break; |
| 937 | case 2: |
1052 | case 2: |
| 938 | eeprom_write_byte_crc(EEDATA.ch2_config, config, WITHOUT_CRC); |
1053 | eeprom_write_byte_crc(EEDATA.ch2_config, config, WITHOUT_CRC); |
| 939 | eeprom_write_byte_crc(EEDATA.ch2_txpower, power, WITHOUT_CRC); |
1054 | eeprom_write_byte_crc(EEDATA.ch2_txpower, power, WITHOUT_CRC); |
| 940 |
|
1055 | eeprom_write_word_crc(EEDATA.ch2_modfreq, modfreq, WITHOUT_CRC); |
| 941 | break; |
1056 | break; |
| 942 | default: |
1057 | default: |
| 943 | break; |
1058 | break; |
| 944 | } |
1059 | } |
| 945 | EEDATA_UPDATE_CRC; |
1060 | EEDATA_UPDATE_CRC; |