Rev 1850 | Rev 1856 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 1850 | Rev 1854 | ||
|---|---|---|---|
| Line 41... | Line 41... | ||
| 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; |
| 44 | uint8_t stopSend; |
44 | uint8_t stopSend; |
| 45 | uint8_t sendComplete; |
45 | uint8_t sendComplete; |
| 46 |
|
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 | uint8_t expectedSeqNr; |
| 51 | } irTxChannel[IR_SUPPORTED_NUM_CHANNELS]; |
51 | } irTxChannel[IR_SUPPORTED_NUM_CHANNELS]; |
| Line 110... | Line 110... | ||
| 110 | #if sns_irTransceive_PRONTO_SUPPORT==1 |
110 | #if sns_irTransceive_PRONTO_SUPPORT==1 |
| 111 | volatile uint32_t sns_irTransceive_LastPronto=0; |
111 | volatile uint32_t sns_irTransceive_LastPronto=0; |
| 112 | static uint8_t activeChannel = 0; |
112 | static uint8_t activeChannel = 0; |
| 113 | #define sns_irTransceive_MAXTIMING (16*1000) |
113 | #define sns_irTransceive_MAXTIMING (16*1000) |
| 114 | 114 | ||
| - | 115 | typedef enum { |
|
| - | 116 | PRONTO_RESPONSE_OK = 0, |
|
| - | 117 | PRONTO_RESPONSE_STOPPED = 1, |
|
| - | 118 | PRONTO_RESPONSE_WAITING = 2, |
|
| - | 119 | PRONTO_RESPONSE_TRANSMITTING = 4, |
|
| - | 120 | ||
| - | 121 | PRONTO_RESPONSE_ALREADY_STOPPED = 241, |
|
| - | 122 | PRONTO_RESPONSE_ABORTED = 243, |
|
| - | 123 | PRONTO_RESPONSE_ERROR = 255, |
|
| - | 124 | } prontoResponse_t; |
|
| - | 125 | ||
| - | 126 | static void pronto_sendResponse(uint8_t channel, prontoResponse_t responseValue) |
|
| - | 127 | { |
|
| - | 128 | StdCan_Msg_t msg; |
|
| - | 129 | StdCan_Set_class(msg.Header, CAN_MODULE_CLASS_SNS); |
|
| - | 130 | StdCan_Set_direction(msg.Header, DIRECTIONFLAG_FROM_OWNER); |
|
| - | 131 | msg.Header.ModuleType = CAN_MODULE_TYPE_SNS_IRTRANSCEIVE; |
|
| - | 132 | msg.Header.ModuleId = sns_irTransceive_ID; |
|
| - | 133 | /* Send response command */ |
|
| - | 134 | msg.Length = 3; |
|
| - | 135 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTORESPONSE; |
|
| - | 136 | msg.Data[0] = ((channel<<4)|0xf); |
|
| - | 137 | msg.Data[1] = 0xF0; |
|
| - | 138 | msg.Data[2] = (uint8_t)responseValue; |
|
| - | 139 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
|
| - | 140 | _delay_ms(1); |
|
| - | 141 | } |
|
| - | 142 | ||
| 115 | static void |
143 | static void pronto_sendData(uint16_t *buffer, uint8_t len, uint8_t channel, uint16_t modfreq) |
| 116 | { |
144 | { |
| 117 | uint32_t currentTime = Timer_GetTicks(); |
145 | uint32_t currentTime = Timer_GetTicks(); |
| 118 | 146 | ||
| 119 | StdCan_Msg_t msg; |
147 | StdCan_Msg_t msg; |
| 120 | 148 | ||
| Line 124... | Line 152... | ||
| 124 | msg.Header.ModuleId = sns_irTransceive_ID; |
152 | msg.Header.ModuleId = sns_irTransceive_ID; |
| 125 | 153 | ||
| 126 | /* Send timing command */ |
154 | /* Send timing command */ |
| 127 | msg.Length = 5; |
155 | msg.Length = 5; |
| 128 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOTIMING; |
156 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOTIMING; |
| 129 | 157 | ||
| 130 | if ((currentTime < sns_irTransceive_LastPronto+sns_irTransceive_MAXTIMING) && (sns_irTransceive_LastPronto != 0)) |
158 | if ((currentTime < sns_irTransceive_LastPronto+sns_irTransceive_MAXTIMING) && (sns_irTransceive_LastPronto != 0)) |
| 131 | { |
159 | { |
| 132 | /* Calculate elapsed time since last pronto packet */ |
160 | /* Calculate elapsed time since last pronto packet */ |
| 133 | uint32_t elapsedTime = ((currentTime - sns_irTransceive_LastPronto) * 1000) & 0x00FFFFFFUL; |
161 | uint32_t elapsedTime = ((currentTime - sns_irTransceive_LastPronto) * 1000) & 0x00FFFFFFUL; /* 24bit value */ |
| 134 | 162 | ||
| 135 | /* Remove length of the last received sequence */ |
163 | /* Remove length of the last received sequence */ |
| 136 | uint32_t sequenceLength = IR_MAX_PULSE_WIDTH; |
164 | uint32_t sequenceLength = IR_MAX_PULSE_WIDTH; /* timeout value not included in buffer */ |
| 137 | for (uint8_t i = 0; i < len; i++) { |
165 | for (uint8_t i = 0; i < len; i++) { |
| 138 | sequenceLength += (uint32_t)buffer[i]; |
166 | sequenceLength += (uint32_t)buffer[i]; |
| 139 | } |
167 | } |
| 140 | if (sequenceLength <= elapsedTime) { |
168 | if (sequenceLength <= elapsedTime) { |
| 141 | elapsedTime -= sequenceLength; |
169 | elapsedTime -= sequenceLength; |
| Line 149... | Line 177... | ||
| 149 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
177 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
| 150 | _delay_ms(1); |
178 | _delay_ms(1); |
| 151 | } |
179 | } |
| 152 | sns_irTransceive_LastPronto = currentTime; |
180 | sns_irTransceive_LastPronto = currentTime; |
| 153 | 181 | ||
| 154 |
|
182 | /* Calculate frequency divider */ |
| 155 | uint16_t divider = (uint16_t)(sns_irTransceive_BaseFrq / (1000*(uint32_t)modfreq)); |
183 | uint16_t divider = (uint16_t)(sns_irTransceive_BaseFrq / (1000*(uint32_t)modfreq)); |
| 156 | 184 | ||
| 157 | /* Send pronto start */ |
185 | /* Send pronto start */ |
| 158 | msg.Length = 8; |
186 | msg.Length = 8; |
| 159 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART; |
187 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART; |
| Line 164... | Line 192... | ||
| 164 | msg.Data[3] = (divider & 0x00FF) >> 0; |
192 | msg.Data[3] = (divider & 0x00FF) >> 0; |
| 165 | msg.Data[4] = 0x00; /* Once seq length, first byte always 0 */ |
193 | msg.Data[4] = 0x00; /* Once seq length, first byte always 0 */ |
| 166 | msg.Data[5] = (len + 1) / 2; |
194 | msg.Data[5] = (len + 1) / 2; |
| 167 | msg.Data[6] = 0x00; /* Repeat seq length, always 0 for ir receive */ |
195 | msg.Data[6] = 0x00; /* Repeat seq length, always 0 for ir receive */ |
| 168 | msg.Data[7] = 0x00; |
196 | msg.Data[7] = 0x00; |
| 169 | 197 | ||
| 170 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
198 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
| 171 | _delay_ms(1); |
199 | _delay_ms(1); |
| 172 | 200 | ||
| 173 | /* Send pronto data */ |
201 | /* Send pronto data */ |
| 174 | //uint16_t divider = ((1000000ULL*modfreq)/sns_irTransceive_BaseFrq); |
202 | //uint16_t divider = ((1000000ULL*modfreq)/sns_irTransceive_BaseFrq); |
| 175 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1; |
203 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1; |
| 176 | uint8_t seqNr = 0; |
204 | uint8_t seqNr = 0; |
| 177 | /* Counter for buffer */ |
205 | /* Counter for buffer */ |
| Line 181... | Line 209... | ||
| 181 | /* Remember byte if data does not fit 8 bit */ |
209 | /* Remember byte if data does not fit 8 bit */ |
| 182 | uint8_t mem = 0; |
210 | uint8_t mem = 0; |
| 183 | while (i < len) |
211 | while (i < len) |
| 184 | { |
212 | { |
| 185 | if (mem > 0) |
213 | if (mem > 0) |
| 186 | { |
214 | { |
| 187 | /* If byte was memorized then buffer it */ |
215 | /* If byte was memorized then buffer it */ |
| 188 | msg.Data[j] = mem; |
216 | msg.Data[j] = mem; |
| 189 | /* Clear memory */ |
217 | /* Clear memory */ |
| 190 | mem = 0; |
218 | mem = 0; |
| 191 | } |
219 | } |
| 192 | else |
220 | else |
| 193 | { |
221 | { |
| 194 |
|
222 | /* Convert µs to pronto hex modulation pulses */ |
| 195 | uint16_t data = (uint16_t)(((uint32_t)buffer[i] * (uint32_t)modfreq) / 1000); |
223 | uint16_t data = (uint16_t)(((uint32_t)buffer[i] * (uint32_t)modfreq) / 1000); |
| 196 | 224 | ||
| 197 |
|
225 | /* Protocol compression */ |
| 198 | if (data >= 256) |
226 | if (data >= 256) |
| 199 | { |
227 | { |
| 200 | /* If data does not fit into 8 bit, then split, memorize low byte */ |
228 | /* If data does not fit into 8 bit, then split, memorize low byte */ |
| 201 | mem = data&0xff; |
229 | mem = data&0xff; |
| 202 | /* Buffer high byte */ |
230 | /* Buffer high byte */ |
| Line 219... | Line 247... | ||
| 219 | { |
247 | { |
| 220 | msg.Data[j] = data&0xff; |
248 | msg.Data[j] = data&0xff; |
| 221 | } |
249 | } |
| 222 | 250 | ||
| 223 | i++; |
251 | i++; |
| 224 | } |
252 | } |
| 225 | 253 | ||
| 226 | j++; |
254 | j++; |
| 227 | if (j==8) |
255 | if (j==8) |
| 228 | { |
256 | { |
| 229 | /* If send buffer is full, send frame */ |
257 | /* If send buffer is full, send frame */ |
| 230 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
258 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
| 231 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
259 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
| 232 | _delay_ms(1); |
260 | _delay_ms(1); |
| 233 | j=0; |
261 | j=0; |
| 234 | seqNr = (seqNr + 1) % 16; |
262 | seqNr = (seqNr + 1) % 16; |
| 235 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr; |
263 | msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr; |
| 236 | } |
264 | } |
| 237 | } |
265 | } |
| 238 | 266 | ||
| 239 | /* End with max pulse TODO fix uglyness */ |
267 | /* End with max pulse TODO fix uglyness */ |
| 240 | msg.Data[j] = ((IR_MAX_PULSE_WIDTH/((1000000ULL*109)/sns_irTransceive_BaseFrq))>>8) & 0xFF; |
268 | msg.Data[j] = ((IR_MAX_PULSE_WIDTH/((1000000ULL*109)/sns_irTransceive_BaseFrq))>>8) & 0xFF; |
| 241 | j++; |
269 | j++; |
| 242 | if (j==8) |
270 | if (j==8) |
| 243 | { |
271 | { |
| 244 | /* If send buffer is full, send frame */ |
272 | /* If send buffer is full, send frame */ |
| 245 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
273 | /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */ |
| 246 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
274 | while (StdCan_Put(&msg) != StdCan_Ret_OK) {} |
| 247 | _delay_ms(1); |
275 | _delay_ms(1); |
| Line 278... | Line 306... | ||
| 278 | { |
306 | { |
| 279 | static uint8_t waitingForLSB = FALSE; |
307 | static uint8_t waitingForLSB = FALSE; |
| 280 | static uint8_t previousValueWas16bit = FALSE; |
308 | static uint8_t previousValueWas16bit = FALSE; |
| 281 | 309 | ||
| 282 | if (irTxChannel[channel].txlen >= MAX_NR_TIMES) { |
310 | if (irTxChannel[channel].txlen >= MAX_NR_TIMES) { |
| 283 |
|
311 | /* Max length exceeded */ |
| 284 | return -1; |
312 | return -1; |
| 285 | } |
313 | } |
| 286 | 314 | ||
| 287 | if (irTxChannel[channel].txlen == 0) { |
315 | if (irTxChannel[channel].txlen == 0) { |
| 288 | waitingForLSB = FALSE; |
316 | waitingForLSB = FALSE; |
| 289 | if (data == 0) { |
317 | if (data == 0) { |
| 290 |
|
318 | /* Cannot start with 0x00 */ |
| 291 | return -2; |
319 | return -2; |
| 292 | } |
320 | } |
| 293 | } |
321 | } |
| 294 | 322 | ||
| 295 |
|
323 | /* 0x00 means that previously received time is MSB of 16bit value, and that next byte will be LSB */ |
| 296 | if (data == 0 && !waitingForLSB && previousValueWas16bit==FALSE) { |
324 | if (data == 0 && !waitingForLSB && previousValueWas16bit==FALSE) { |
| 297 |
|
325 | /* Convert previous time to MSB of the 16bit value. next received byte will become LSB */ |
| 298 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] <<= 8; |
326 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] <<= 8; |
| 299 | 327 | ||
| 300 |
|
328 | /* Flag that next received byte is LSB rather than a new timing value */ |
| 301 | waitingForLSB = TRUE; |
329 | waitingForLSB = TRUE; |
| 302 | } |
330 | } |
| 303 | 331 | ||
| 304 |
|
332 | /* Non-zero value! is this part of a 16bit-value? use the data as LSB for previously received time */ |
| 305 | else if (waitingForLSB) { |
333 | else if (waitingForLSB) { |
| 306 |
|
334 | /* Let this byte be LSB of previous 16bit value */ |
| 307 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] |= data; |
335 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] |= data; |
| 308 | 336 | ||
| 309 |
|
337 | /* We've now completed reception of the 16bit value */ |
| 310 | waitingForLSB = FALSE; |
338 | waitingForLSB = FALSE; |
| 311 | 339 | ||
| 312 | previousValueWas16bit = TRUE; |
340 | previousValueWas16bit = TRUE; |
| 313 | } |
341 | } |
| 314 | 342 | ||
| 315 |
|
343 | /* Non-zero value! simply new 8bit value */ |
| 316 | else { |
344 | else { |
| 317 |
|
345 | /* Check if we're already done */ |
| 318 | if (irTxChannel[channel].txlen >= (((uint16_t)irTxChannel[channel].onceSeqLen + (uint16_t)irTxChannel[channel].repSeqLen))) { |
346 | if (irTxChannel[channel].txlen >= (((uint16_t)irTxChannel[channel].onceSeqLen + (uint16_t)irTxChannel[channel].repSeqLen))) { |
| 319 |
|
347 | /* Too much data received, not necessarily a problem in case frames are padded */ |
| 320 | return 2; |
348 | return 2; |
| 321 | } |
349 | } |
| 322 | 350 | ||
| 323 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen] = data; |
351 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen] = data; |
| 324 | 352 | ||
| Line 330... | Line 358... | ||
| 330 | return 1; |
358 | return 1; |
| 331 | } |
359 | } |
| 332 | 360 | ||
| 333 | #endif |
361 | #endif |
| 334 | 362 | ||
| 335 | 363 | ||
| 336 | #if IR_RX_ENABLE==1 |
364 | #if IR_RX_ENABLE==1 |
| 337 | void sns_irTransceive_RX_done_callback(uint8_t channel, uint16_t *buffer, uint8_t len) |
365 | void sns_irTransceive_RX_done_callback(uint8_t channel, uint16_t *buffer, uint8_t len) |
| 338 | { |
366 | { |
| 339 | if (channel < IR_SUPPORTED_NUM_CHANNELS) |
367 | if (channel < IR_SUPPORTED_NUM_CHANNELS) |
| 340 | { |
368 | { |
| 341 | irRxChannel[channel].newData = TRUE; |
369 | irRxChannel[channel].newData = TRUE; |
| 342 | irRxChannel[channel].rxlen = len; |
370 | irRxChannel[channel].rxlen = len; |
| 343 | } |
371 | } |
| 344 | } |
372 | } |
| 345 | #endif |
373 | #endif |
| 346 | 374 | ||
| 347 | 375 | ||
| 348 | #if IR_TX_ENABLE==1 |
376 | #if IR_TX_ENABLE==1 |
| 349 | void sns_irTransceive_TX_done_callback(uint8_t channel) |
377 | void sns_irTransceive_TX_done_callback(uint8_t channel) |
| 350 | { |
378 | { |
| 351 | if (channel < IR_SUPPORTED_NUM_CHANNELS) |
379 | if (channel < IR_SUPPORTED_NUM_CHANNELS) |
| 352 | { |
380 | { |
| 353 | irTxChannel[channel].sendComplete = TRUE; |
381 | irTxChannel[channel].sendComplete = TRUE; |
| 354 | } |
382 | } |
| 355 | } |
383 | } |
| 356 | #endif |
384 | #endif |
| 357 | 385 | ||
| 358 | 386 | ||
| 359 | static void sns_irTransceive_setConfig(uint8_t channel, uint8_t config, uint8_t power, uint16_t modfreq) |
387 | static void sns_irTransceive_setConfig(uint8_t channel, uint8_t config, uint8_t power, uint16_t modfreq) |
| 360 | { |
388 | { |
| 361 | if (channel < IR_SUPPORTED_NUM_CHANNELS && config <= CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE && power < 4) |
389 | if (channel < IR_SUPPORTED_NUM_CHANNELS && config <= CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE && power < 4) |
| 362 | { |
390 | { |
| 363 | #if IR_RX_ENABLE==1 |
391 | #if IR_RX_ENABLE==1 |
| 364 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE) |
392 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE) |
| 365 | { |
393 | { |
| 366 | #if IR_TX_ENABLE==1 |
394 | #if IR_TX_ENABLE==1 |
| 367 | irTxChannel[channel].state = sns_irTransceive_STATE_DISABLED; |
395 | irTxChannel[channel].state = sns_irTransceive_STATE_DISABLED; |
| Line 382... | Line 410... | ||
| 382 | gpio_clr_pin(sns_irTransceive_VCC_EN2_PIN); |
410 | gpio_clr_pin(sns_irTransceive_VCC_EN2_PIN); |
| 383 | IrTransceiver_InitRxChannel(channel, irRxChannel[channel].rxbuf, sns_irTransceive_RX_done_callback, sns_irTransceive_RX2_PCINT, sns_irTransceive_RX2_PIN); |
411 | IrTransceiver_InitRxChannel(channel, irRxChannel[channel].rxbuf, sns_irTransceive_RX_done_callback, sns_irTransceive_RX2_PCINT, sns_irTransceive_RX2_PIN); |
| 384 | break; |
412 | break; |
| 385 | } |
413 | } |
| 386 | irRxChannel[channel].state = sns_irTransceive_STATE_RECEIVING; |
414 | irRxChannel[channel].state = sns_irTransceive_STATE_RECEIVING; |
| 387 | } |
415 | } |
| 388 | #endif |
416 | #endif |
| 389 | 417 | ||
| 390 | #if IR_TX_ENABLE==1 |
418 | #if IR_TX_ENABLE==1 |
| 391 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_TRANSMIT) |
419 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_TRANSMIT) |
| 392 | { |
420 | { |
| 393 | #if IR_RX_ENABLE==1 |
421 | #if IR_RX_ENABLE==1 |
| 394 | irRxChannel[channel].state = sns_irTransceive_STATE_DISABLED; |
422 | irRxChannel[channel].state = sns_irTransceive_STATE_DISABLED; |
| 395 | #endif |
423 | #endif |
| 396 | irTxChannel[channel].modfreq = modfreq; |
424 | irTxChannel[channel].modfreq = modfreq; |
| 397 | irTxChannel[channel].txbuf = buf[channel]; |
425 | irTxChannel[channel].txbuf = buf[channel]; |
| 398 | switch (channel) |
426 | switch (channel) |
| 399 | { |
427 | { |
| 400 | case 0: |
428 | case 0: |
| 401 | #if IR_RX_ENABLE==1 |
429 | #if IR_RX_ENABLE==1 |
| 402 | gpio_set_pin(sns_irTransceive_VCC_EN0_PIN); |
430 | gpio_set_pin(sns_irTransceive_VCC_EN0_PIN); |
| 403 | IrTransceiver_DeInitRxChannel(channel, sns_irTransceive_RX0_PCINT, sns_irTransceive_RX0_PIN); |
431 | IrTransceiver_DeInitRxChannel(channel, sns_irTransceive_RX0_PCINT, sns_irTransceive_RX0_PIN); |
| 404 | #endif |
432 | #endif |
| 405 | IrTransceiver_InitTxChannel(channel, sns_irTransceive_TX_done_callback, sns_irTransceive_TX0_PIN); |
433 | IrTransceiver_InitTxChannel(channel, sns_irTransceive_TX_done_callback, sns_irTransceive_TX0_PIN); |
| 406 | 434 | ||
| 407 | #if sns_irTransceive_ENABLE_PCA95xx==1 |
435 | #if sns_irTransceive_ENABLE_PCA95xx==1 |
| 408 | Pca95xx_set_out(sns_irTransceive_TX0_PWRl); |
436 | Pca95xx_set_out(sns_irTransceive_TX0_PWRl); |
| 409 | Pca95xx_set_out(sns_irTransceive_TX0_PWRh); |
437 | Pca95xx_set_out(sns_irTransceive_TX0_PWRh); |
| 410 | if (power&0x1) |
438 | if (power&0x1) |
| 411 | { |
439 | { |
| 412 | Pca95xx_set_in(sns_irTransceive_TX0_PWRl); |
440 | Pca95xx_set_in(sns_irTransceive_TX0_PWRl); |
| 413 | } |
441 | } |
| 414 | if (power&0x2) |
442 | if (power&0x2) |
| 415 | { |
443 | { |
| 416 | Pca95xx_set_in(sns_irTransceive_TX0_PWRh); |
444 | Pca95xx_set_in(sns_irTransceive_TX0_PWRh); |
| 417 | } |
445 | } |
| 418 | #endif |
446 | #endif |
| 419 | break; |
447 | break; |
| 420 | case 1: |
448 | case 1: |
| Line 448... | Line 476... | ||
| 448 | Pca95xx_set_out(sns_irTransceive_TX2_PWRl); |
476 | Pca95xx_set_out(sns_irTransceive_TX2_PWRl); |
| 449 | Pca95xx_set_out(sns_irTransceive_TX2_PWRh); |
477 | Pca95xx_set_out(sns_irTransceive_TX2_PWRh); |
| 450 | if (power&0x1) |
478 | if (power&0x1) |
| 451 | { |
479 | { |
| 452 | Pca95xx_set_in(sns_irTransceive_TX2_PWRl); |
480 | Pca95xx_set_in(sns_irTransceive_TX2_PWRl); |
| 453 | } |
481 | } |
| 454 | if (power&0x2) |
482 | if (power&0x2) |
| 455 | { |
483 | { |
| 456 | Pca95xx_set_in(sns_irTransceive_TX2_PWRh); |
484 | Pca95xx_set_in(sns_irTransceive_TX2_PWRh); |
| 457 | } |
485 | } |
| 458 | #endif |
486 | #endif |
| 459 | break; |
487 | break; |
| 460 | } |
488 | } |
| Line 497... | Line 525... | ||
| 497 | irTxChannel[i].proto.protocol=0; |
525 | irTxChannel[i].proto.protocol=0; |
| 498 | #endif |
526 | #endif |
| 499 | } |
527 | } |
| 500 | 528 | ||
| 501 | #if IR_RX_ENABLE==1 |
529 | #if IR_RX_ENABLE==1 |
| 502 | // TODO: hardcoded to 3 channels?? /jm |
- | |
| 503 | irRxChannel[0].timerNum=sns_irTransceive_RX0_REPEATE_TIMER; |
530 | if (IR_SUPPORTED_NUM_CHANNELS>=1) irRxChannel[0].timerNum=sns_irTransceive_RX0_REPEATE_TIMER; |
| 504 | irRxChannel[1].timerNum=sns_irTransceive_RX1_REPEATE_TIMER; |
531 | if (IR_SUPPORTED_NUM_CHANNELS>=2) irRxChannel[1].timerNum=sns_irTransceive_RX1_REPEATE_TIMER; |
| 505 | irRxChannel[2].timerNum=sns_irTransceive_RX2_REPEATE_TIMER; |
532 | if (IR_SUPPORTED_NUM_CHANNELS>=3) irRxChannel[2].timerNum=sns_irTransceive_RX2_REPEATE_TIMER; |
| 506 | #endif |
533 | #endif |
| 507 | 534 | ||
| 508 | #if IR_TX_ENABLE==1 |
535 | #if IR_TX_ENABLE==1 |
| 509 | // TODO: hardcoded to 3 channels?? /jm |
- | |
| 510 | irTxChannel[0].timerNum=sns_irTransceive_TX0_REPEATE_TIMER; |
536 | if (IR_SUPPORTED_NUM_CHANNELS>=1) irTxChannel[0].timerNum=sns_irTransceive_TX0_REPEATE_TIMER; |
| 511 | irTxChannel[1].timerNum=sns_irTransceive_TX1_REPEATE_TIMER; |
537 | if (IR_SUPPORTED_NUM_CHANNELS>=2) irTxChannel[1].timerNum=sns_irTransceive_TX1_REPEATE_TIMER; |
| 512 | irTxChannel[2].timerNum=sns_irTransceive_TX2_REPEATE_TIMER; |
538 | if (IR_SUPPORTED_NUM_CHANNELS>=3) irTxChannel[2].timerNum=sns_irTransceive_TX2_REPEATE_TIMER; |
| 513 | #endif |
539 | #endif |
| 514 | 540 | ||
| 515 | IrTransceiver_Init(); |
541 | IrTransceiver_Init(); |
| 516 | /* Configure all TX VCC pins as outputs and disable them */ |
542 | /* Configure all TX VCC pins as outputs and disable them */ |
| 517 | gpio_set_out(sns_irTransceive_VCC_EN0_PIN); |
543 | gpio_set_out(sns_irTransceive_VCC_EN0_PIN); |
| Line 598... | Line 624... | ||
| 598 | irRxChannel[channel].state = sns_irTransceive_STATE_RECEIVING; |
624 | irRxChannel[channel].state = sns_irTransceive_STATE_RECEIVING; |
| 599 | break; |
625 | break; |
| 600 | 626 | ||
| 601 | case sns_irTransceive_STATE_RECEIVING: |
627 | case sns_irTransceive_STATE_RECEIVING: |
| 602 | if (irRxChannel[channel].newData == TRUE) { |
628 | if (irRxChannel[channel].newData == TRUE) { |
| 603 |
|
629 | /* TODO: move this line to the RX callback */ |
| 604 | IrTransceiver_DisableRx(channel); |
630 | IrTransceiver_DisableRx(channel); |
| 605 | cli(); |
631 | cli(); |
| 606 | irRxChannel[channel].newData = FALSE; |
632 | irRxChannel[channel].newData = FALSE; |
| 607 | sei(); |
633 | sei(); |
| 608 | 634 | ||
| Line 623... | Line 649... | ||
| 623 | { |
649 | { |
| 624 | #if (sns_irTransceive_SEND_DEBUG==1) |
650 | #if (sns_irTransceive_SEND_DEBUG==1) |
| 625 | send_debug(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen); |
651 | send_debug(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen); |
| 626 | irRxChannel[channel].proto.timeout=300; |
652 | irRxChannel[channel].proto.timeout=300; |
| 627 | #elif sns_irTransceive_PRONTO_SUPPORT==1 |
653 | #elif sns_irTransceive_PRONTO_SUPPORT==1 |
| 628 |
|
654 | pronto_sendData(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen, channel, irRxChannel[channel].modfreq); |
| 629 | irRxChannel[channel].proto.timeout=1; |
655 | irRxChannel[channel].proto.timeout=1; |
| 630 | #endif |
656 | #endif |
| 631 | } |
657 | } |
| 632 | 658 | ||
| 633 | /* Enable the receiver again */ |
659 | /* Enable the receiver again */ |
| Line 669... | Line 695... | ||
| 669 | irTxMsg.Data[5] = irRxChannel[channel].proto.data&0xff; |
695 | irTxMsg.Data[5] = irRxChannel[channel].proto.data&0xff; |
| 670 | 696 | ||
| 671 | StdCan_Put(&irTxMsg); |
697 | StdCan_Put(&irTxMsg); |
| 672 | } |
698 | } |
| 673 | irRxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
699 | irRxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| 674 | break; |
700 | break; |
| 675 | 701 | ||
| 676 | default: |
702 | default: |
| 677 | break; |
703 | break; |
| 678 | } |
704 | } |
| 679 | #endif |
705 | #endif |
| 680 | 706 | ||
| 681 | #if IR_TX_ENABLE==1 |
707 | #if IR_TX_ENABLE==1 |
| 682 | switch (irTxChannel[channel].state) |
708 | switch (irTxChannel[channel].state) |
| 683 | { |
709 | { |
| 684 | case sns_irTransceive_STATE_IDLE: |
710 | case sns_irTransceive_STATE_IDLE: |
| 685 | /* transmission is started when a command is received on can */ |
711 | /* transmission is started when a command is received on can */ |
| Line 687... | Line 713... | ||
| 687 | 713 | ||
| 688 | case sns_irTransceive_STATE_START_TRANSMIT: |
714 | case sns_irTransceive_STATE_START_TRANSMIT: |
| 689 | { |
715 | { |
| 690 | if (expandProtocol(irTxChannel[channel].txbuf, &irTxChannel[channel].txlen, &irTxChannel[channel].proto) == IR_OK) { |
716 | if (expandProtocol(irTxChannel[channel].txbuf, &irTxChannel[channel].txlen, &irTxChannel[channel].proto) == IR_OK) { |
| 691 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen); |
717 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen); |
| 692 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
718 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
| 693 | } |
719 | } |
| 694 | else { |
720 | else { |
| 695 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
721 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| 696 | } |
722 | } |
| 697 | break; |
723 | break; |
| 698 | } |
724 | } |
| 699 | 725 | ||
| 700 | case sns_irTransceive_STATE_START_TRANSMIT_PRONTO: |
726 | case sns_irTransceive_STATE_START_TRANSMIT_PRONTO: |
| 701 | { |
727 | { |
| 702 | /* Start IR transmission. */ |
728 | /* Start IR transmission. */ |
| 703 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].onceSeqLen - 1); |
729 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].onceSeqLen - 1); |
| 704 | 730 | ||
| 705 | /* Enter transmitting state. */ |
731 | /* Enter transmitting state. */ |
| 706 | irTxChannel[channel].sendingPronto = TRUE; |
732 | irTxChannel[channel].sendingPronto = TRUE; |
| 707 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
733 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
| 708 | break; |
734 | break; |
| 709 | } |
735 | } |
| 710 | 736 | ||
| 711 | case sns_irTransceive_STATE_PRONTO_REPEAT: |
737 | case sns_irTransceive_STATE_PRONTO_REPEAT: |
| 712 | { |
738 | { |
| 713 | /* Check if done. */ |
739 | /* Check if done. */ |
| 714 | if ((irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats && irTxChannel[channel].proto.repeats != 0xFF) || irTxChannel[channel].stopSend) { |
740 | if ((irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats && irTxChannel[channel].proto.repeats != 0xFF) || irTxChannel[channel].stopSend) { |
| 715 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
741 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
| 716 | break; |
742 | break; |
| 717 | } |
743 | } |
| 718 | 744 | ||
| 719 | if (irTxChannel[channel].repeatCount < 255) { |
745 | if (irTxChannel[channel].repeatCount < 255) { |
| 720 | irTxChannel[channel].repeatCount++; |
746 | irTxChannel[channel].repeatCount++; |
| 721 | } |
747 | } |
| 722 | 748 | ||
| 723 |
|
749 | /* Repeat sequence exists? */ |
| 724 | if (irTxChannel[channel].repSeqLen != 0) { |
750 | if (irTxChannel[channel].repSeqLen != 0) { |
| 725 |
|
751 | /* Use repeat seq */ |
| 726 | uint16_t offset = ((uint16_t)irTxChannel[channel].onceSeqLen); |
752 | uint16_t offset = ((uint16_t)irTxChannel[channel].onceSeqLen); |
| 727 |
|
753 | /* Don't transmit last passive. last passive handled by timer */ |
| 728 | IrTransceiver_Transmit(channel, &irTxChannel[channel].txbuf[offset], 0, ((uint16_t)irTxChannel[channel].repSeqLen) - 1); |
754 | IrTransceiver_Transmit(channel, &irTxChannel[channel].txbuf[offset], 0, ((uint16_t)irTxChannel[channel].repSeqLen) - 1); |
| 729 | } |
755 | } |
| 730 | else { |
756 | else { |
| 731 |
|
757 | /* Use once seq */ |
| 732 |
|
758 | /* Don't transmit last passive. last passive handled by timer */ |
| 733 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen - 1); |
759 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen - 1); |
| 734 | } |
760 | } |
| 735 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
761 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
| 736 | } |
762 | } |
| 737 | 763 | ||
| 738 | case sns_irTransceive_STATE_TRANSMITTING: |
764 | case sns_irTransceive_STATE_TRANSMITTING: |
| 739 | { |
765 | { |
| 740 | if (irTxChannel[channel].sendComplete == TRUE) |
766 | if (irTxChannel[channel].sendComplete == TRUE) |
| 741 | { |
767 | { |
| 742 | cli(); |
768 | cli(); |
| 743 | irTxChannel[channel].sendComplete = FALSE; |
769 | irTxChannel[channel].sendComplete = FALSE; |
| 744 | sei(); |
770 | sei(); |
| 745 | 771 | ||
| 746 | if (irTxChannel[channel].sendingPronto) |
772 | if (irTxChannel[channel].sendingPronto) |
| 747 | { |
773 | { |
| 748 |
|
774 | /* First repeat, or no repeat sequence defined => use last passive time in once seq */ |
| 749 | if(irTxChannel[channel].repeatCount == 0 || irTxChannel[channel].repSeqLen == 0) |
775 | if(irTxChannel[channel].repeatCount == 0 || irTxChannel[channel].repSeqLen == 0) |
| 750 | { |
776 | { |
| 751 |
|
777 | /* Use last passive time as timeout */ |
| 752 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].onceSeqLen - 1] / 1000; |
778 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].onceSeqLen - 1] / 1000; |
| 753 | Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0); |
779 | Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0); |
| 754 | } |
780 | } |
| 755 |
|
781 | /* Second, or later repeat => use last passive time in repeat seq */ |
| 756 | else |
782 | else |
| 757 | { |
783 | { |
| 758 |
|
784 | /* Use last passive time as timeout */ |
| 759 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] / 1000; |
785 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] / 1000; |
| 760 | Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0); |
786 | Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0); |
| 761 | } |
787 | } |
| 762 | irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
788 | irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
| 763 | } |
789 | } |
| 764 | else |
790 | else |
| 765 | { |
791 | { |
| 766 | irTxChannel[channel].state = sns_irTransceive_STATE_START_PAUSE; |
792 | irTxChannel[channel].state = sns_irTransceive_STATE_START_PAUSE; |
| 767 | } |
793 | } |
| 768 | } |
794 | } |
| 769 | break; |
795 | break; |
| 770 | } |
796 | } |
| 771 | 797 | ||
| 772 | case sns_irTransceive_STATE_START_PAUSE: |
798 | case sns_irTransceive_STATE_START_PAUSE: |
| 773 | { |
799 | { |
| 774 | if (irTxChannel[channel].repeatCount < irTxChannel[channel].proto.repeats) |
800 | if (irTxChannel[channel].repeatCount < irTxChannel[channel].proto.repeats) |
| 775 | { |
801 | { |
| Line 779... | Line 805... | ||
| 779 | Timer_SetTimeout(irTxChannel[channel].timerNum, irTxChannel[channel].proto.timeout, TimerTypeOneShot, 0); |
805 | Timer_SetTimeout(irTxChannel[channel].timerNum, irTxChannel[channel].proto.timeout, TimerTypeOneShot, 0); |
| 780 | 806 | ||
| 781 | if (irTxChannel[channel].proto.framecnt != 255) |
807 | if (irTxChannel[channel].proto.framecnt != 255) |
| 782 | { |
808 | { |
| 783 | irTxChannel[channel].proto.framecnt++; |
809 | irTxChannel[channel].proto.framecnt++; |
| 784 | } |
810 | } |
| 785 | 811 | ||
| 786 | irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
812 | irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
| 787 | break; |
813 | break; |
| 788 | } |
814 | } |
| 789 | 815 | ||
| 790 | case sns_irTransceive_STATE_PAUSING: |
816 | case sns_irTransceive_STATE_PAUSING: |
| 791 | { |
817 | { |
| 792 | if (irTxChannel[channel].sendingPronto) |
818 | if (irTxChannel[channel].sendingPronto) |
| 793 | { |
819 | { |
| 794 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
820 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
| 795 | { |
821 | { |
| 796 | irTxChannel[channel].state = sns_irTransceive_STATE_PRONTO_REPEAT; |
822 | irTxChannel[channel].state = sns_irTransceive_STATE_PRONTO_REPEAT; |
| 797 | } |
823 | } |
| 798 | break; |
824 | break; |
| 799 | } |
825 | } |
| 800 | 826 | ||
| 801 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
827 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
| 802 | { |
828 | { |
| 803 | irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT; |
829 | irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT; |
| 804 | } |
830 | } |
| 805 | 831 | ||
| 806 | /* |
832 | /* Transmission is stopped when such command is recevied on can */ |
| 807 | if (irTxChannel[channel].stopSend == TRUE && irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats) |
833 | if (irTxChannel[channel].stopSend == TRUE && irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats) |
| 808 | { |
834 | { |
| 809 |
|
835 | /* TODO: maybe send message on can for status? to confirm stopped sending, ready for new command */ |
| 810 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
836 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
| 811 | } |
837 | } |
| 812 | break; |
838 | break; |
| 813 | } |
839 | } |
| 814 | 840 | ||
| 815 | case sns_irTransceive_STATE_START_IDLE: |
841 | case sns_irTransceive_STATE_START_IDLE: |
| 816 | irTxChannel[channel].stopSend = FALSE; |
842 | irTxChannel[channel].stopSend = FALSE; |
| 817 | irTxChannel[channel].repeatCount = 0; |
843 | irTxChannel[channel].repeatCount = 0; |
| 818 | irTxChannel[channel].proto.framecnt = 0; |
844 | irTxChannel[channel].proto.framecnt = 0; |
| 819 | irTxChannel[channel].sendingPronto = FALSE; |
845 | irTxChannel[channel].sendingPronto = FALSE; |
| 820 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
846 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| 821 | break; |
847 | break; |
| 822 | 848 | ||
| 823 | default: |
849 | default: |
| 824 | break; |
850 | break; |
| 825 | } |
851 | } |
| 826 | #endif |
852 | #endif |
| 827 | 853 | ||
| 828 | } |
854 | } |
| 829 | } |
855 | } |
| Line 835... | Line 861... | ||
| 835 | /* Sanity check. */ |
861 | /* Sanity check. */ |
| 836 | if (StdCan_Ret_class(rxMsg->Header) != CAN_MODULE_CLASS_SNS || |
862 | if (StdCan_Ret_class(rxMsg->Header) != CAN_MODULE_CLASS_SNS || |
| 837 | StdCan_Ret_direction(rxMsg->Header) != DIRECTIONFLAG_TO_OWNER || |
863 | StdCan_Ret_direction(rxMsg->Header) != DIRECTIONFLAG_TO_OWNER || |
| 838 | rxMsg->Header.ModuleType != CAN_MODULE_TYPE_SNS_IRTRANSCEIVE || |
864 | rxMsg->Header.ModuleType != CAN_MODULE_TYPE_SNS_IRTRANSCEIVE || |
| 839 | rxMsg->Header.ModuleId != sns_irTransceive_ID) return; |
865 | rxMsg->Header.ModuleId != sns_irTransceive_ID) return; |
| 840 | - | ||
| 841 | /* Get IR channel. */ |
- | |
| 842 | uint8_t channel = rxMsg->Data[0] >> 4; |
- | |
| 843 | 866 | ||
| 844 | switch (rxMsg->Header.Command) |
867 | switch (rxMsg->Header.Command) |
| 845 | { |
868 | { |
| 846 | #if IR_TX_ENABLE==1 |
869 | #if IR_TX_ENABLE==1 |
| 847 | case CAN_MODULE_CMD_PHYSICAL_IR: |
870 | case CAN_MODULE_CMD_PHYSICAL_IR: |
| 848 | { |
871 | { |
| - | 872 | /* Get IR channel. */ |
|
| - | 873 | uint8_t channel = rxMsg->Data[0] >> 4; |
|
| - | 874 | ||
| - | 875 | /* Sanity check. */ |
|
| - | 876 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) { |
|
| - | 877 | /* Invalid channel */ |
|
| - | 878 | break; |
|
| - | 879 | } |
|
| - | 880 | ||
| 849 | if ((0xf&rxMsg->Data[0]) == CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_PRESSED |
881 | if ((0xf&rxMsg->Data[0]) == CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_PRESSED) |
| 850 | { |
882 | { |
| 851 | if (irTxChannel[channel].state == sns_irTransceive_STATE_IDLE) |
883 | if (irTxChannel[channel].state == sns_irTransceive_STATE_IDLE) |
| 852 | { |
884 | { |
| 853 | irTxChannel[channel].proto.protocol = rxMsg->Data[1]; |
885 | irTxChannel[channel].proto.protocol = rxMsg->Data[1]; |
| 854 | 886 | ||
| 855 | irTxChannel[channel].proto.data = rxMsg->Data[2]; |
887 | irTxChannel[channel].proto.data = rxMsg->Data[2]; |
| Line 861... | Line 893... | ||
| 861 | irTxChannel[channel].proto.data |= rxMsg->Data[5]; |
893 | irTxChannel[channel].proto.data |= rxMsg->Data[5]; |
| 862 | 894 | ||
| 863 | irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT; |
895 | irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT; |
| 864 | } |
896 | } |
| 865 | } |
897 | } |
| 866 | else if ((0xf&rxMsg->Data[0]) == CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_RELEASED |
898 | else if ((0xf&rxMsg->Data[0]) == CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_RELEASED) |
| 867 | { |
899 | { |
| 868 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) |
900 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) |
| 869 | { |
901 | { |
| 870 | irTxChannel[channel].stopSend = TRUE; |
902 | irTxChannel[channel].stopSend = TRUE; |
| 871 | } |
903 | } |
| 872 | } |
904 | } |
| 873 | break; |
905 | break; |
| 874 | } |
906 | } |
| 875 | 907 | ||
| 876 | #if sns_irTransceive_PRONTO_SUPPORT==1 |
908 | #if sns_irTransceive_PRONTO_SUPPORT==1 |
| 877 | /* TODO: add struct which stores pronto info: |
- | |
| 878 | channel, pronto receive state, buffer length of once burst pairs, buffer length of repeat burst pairs */ |
- | |
| 879 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART: |
909 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART: |
| 880 | { |
910 | { |
| - | 911 | /* Get IR channel. */ |
|
| - | 912 | uint8_t channel = rxMsg->Data[0] >> 4; |
|
| - | 913 | ||
| 881 | /* Sanity check. */ |
914 | /* Sanity check. */ |
| 882 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) |
915 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) { |
| - | 916 | /* Invalid channel */ |
|
| - | 917 | pronto_sendResponse(channel, PRONTO_RESPONSE_ERROR); |
|
| - | 918 | break; |
|
| - | 919 | } |
|
| 883 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) |
920 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) { |
| - | 921 | /* We're already transmitting on this channel */ |
|
| - | 922 | pronto_sendResponse(channel, PRONTO_RESPONSE_ABORTED); |
|
| - | 923 | break; |
|
| - | 924 | } |
|
| 884 | 925 | ||
| 885 | /* Check if format is supported. */ |
926 | /* Check if format is supported. */ |
| 886 | if ((((uint16_t)(rxMsg->Data[0] & 0x0F) << 8) | (uint16_t)(rxMsg->Data[1])) != 0) |
927 | if ((((uint16_t)(rxMsg->Data[0] & 0x0F) << 8) | (uint16_t)(rxMsg->Data[1])) != 0) { |
| - | 928 | /* Invalid pronto format */ |
|
| - | 929 | pronto_sendResponse(channel, PRONTO_RESPONSE_ERROR); |
|
| - | 930 | break; |
|
| - | 931 | } |
|
| 887 | 932 | ||
| 888 | /* Extract received data. */ |
933 | /* Extract received data. */ |
| 889 | 934 | ||
| 890 | uint32_t divider = (rxMsg->Data[2] << 8) | (rxMsg->Data[3] << 0); |
935 | uint32_t divider = (rxMsg->Data[2] << 8) | (rxMsg->Data[3] << 0); |
| 891 | if (divider == 0) { |
936 | if (divider == 0) { |
| 892 |
|
937 | /* Invalid wFrqDiv value */ |
| - | 938 | pronto_sendResponse(channel, PRONTO_RESPONSE_ERROR); |
|
| 893 | break; |
939 | break; |
| 894 | } |
940 | } |
| 895 | uint32_t freqkHz = (sns_irTransceive_BaseFrq / (divider*1000)); |
941 | uint32_t freqkHz = (sns_irTransceive_BaseFrq / (divider*1000)); |
| 896 | if (freqkHz == 0) { |
942 | if (freqkHz == 0) { |
| 897 |
|
943 | /* Invalid wFrqDiv value */ |
| - | 944 | pronto_sendResponse(channel, PRONTO_RESPONSE_ERROR); |
|
| 898 | break; |
945 | break; |
| 899 | } |
946 | } |
| 900 | irTxChannel[channel].proto.modfreq = freqkHz; |
947 | irTxChannel[channel].proto.modfreq = freqkHz; |
| 901 | //printf("FRQ%05u", irTxChannel[channel].proto.modfreq); |
- | |
| 902 | 948 | ||
| 903 |
|
949 | /* TODO: reconfigure with new modfreq, if no other channels sending pronto */ |
| 904 | 950 | ||
| 905 | //irTxChannel[channel].proto.modfreq = (((F_CPU/2000)/IR_NEC_F_MOD) -1); |
- | |
| 906 |
|
951 | /* Convert lenghts to bytes */ |
| 907 | irTxChannel[channel].onceSeqLen = 2*((((uint16_t)rxMsg->Data[4]) << 8) | (((uint16_t)rxMsg->Data[5]) << 0)); |
952 | irTxChannel[channel].onceSeqLen = 2*((((uint16_t)rxMsg->Data[4]) << 8) | (((uint16_t)rxMsg->Data[5]) << 0)); |
| 908 | irTxChannel[channel].repSeqLen = 2*((((uint16_t)rxMsg->Data[6]) << 8) | (((uint16_t)rxMsg->Data[7]) << 0)); |
953 | irTxChannel[channel].repSeqLen = 2*((((uint16_t)rxMsg->Data[6]) << 8) | (((uint16_t)rxMsg->Data[7]) << 0)); |
| 909 | - | ||
| 910 | //printf("ONCE%04u", irTxChannel[channel].onceSeqLen); |
- | |
| 911 | //printf("REQL%04u", irTxChannel[channel].repSeqLen); |
- | |
| 912 | 954 | ||
| 913 | /* Enter prepering pronto state and clear transmit buffer. */ |
955 | /* Enter prepering pronto state and clear transmit buffer. */ |
| 914 | irTxChannel[channel].state = sns_irTransceive_STATE_PREPARING_PRONTO; |
956 | irTxChannel[channel].state = sns_irTransceive_STATE_PREPARING_PRONTO; |
| 915 | irTxChannel[channel].txlen = 0; |
957 | irTxChannel[channel].txlen = 0; |
| 916 | irTxChannel[channel].expectedSeqNr = 0; |
958 | irTxChannel[channel].expectedSeqNr = 0; |
| 917 | activeChannel = channel; |
959 | activeChannel = channel; |
| 918 | 960 | ||
| 919 | /* |
961 | /* We're now waiting for pronto data */ |
| - | 962 | pronto_sendResponse(channel, PRONTO_RESPONSE_WAITING); |
|
| 920 | break; |
963 | break; |
| 921 | } |
964 | } |
| 922 | 965 | ||
| 923 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTOP: |
966 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTOP: |
| - | 967 | { |
|
| - | 968 | /* Get IR channel. */ |
|
| - | 969 | uint8_t channel = rxMsg->Data[0] >> 4; |
|
| - | 970 | ||
| 924 | /* Sanity check. */ |
971 | /* Sanity check. */ |
| 925 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) |
972 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) { |
| - | 973 | /* Invalid channel */ |
|
| - | 974 | pronto_sendResponse(channel, PRONTO_RESPONSE_ERROR); |
|
| - | 975 | break; |
|
| - | 976 | } |
|
| 926 | 977 | ||
| 927 | irTxChannel[channel].stopSend = TRUE; |
978 | irTxChannel[channel].stopSend = TRUE; |
| 928 | 979 | ||
| - | 980 | /* Pronto transmission was stopped */ |
|
| - | 981 | pronto_sendResponse(channel, PRONTO_RESPONSE_STOPPED); |
|
| - | 982 | break; |
|
| - | 983 | } |
|
| - | 984 | ||
| - | 985 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOCONTINUE: |
|
| - | 986 | { |
|
| - | 987 | /* Get IR channel. */ |
|
| - | 988 | uint8_t channel = rxMsg->Data[0] >> 4; |
|
| - | 989 | ||
| - | 990 | /* Sanity check. */ |
|
| - | 991 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) { |
|
| - | 992 | /* Invalid channel */ |
|
| - | 993 | pronto_sendResponse(channel, PRONTO_RESPONSE_ERROR); |
|
| - | 994 | break; |
|
| - | 995 | } |
|
| - | 996 | ||
| - | 997 | /* State check. We must already be in some transmit state */ |
|
| 929 | /* TODO: |
998 | /* TODO: better way to check this? /jm */ |
| - | 999 | if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_START_TRANSMIT_PRONTO && |
|
| - | 1000 | irTxChannel[activeChannel].state != sns_irTransceive_STATE_TRANSMITTING && |
|
| - | 1001 | irTxChannel[activeChannel].state != sns_irTransceive_STATE_PRONTO_REPEAT && |
|
| - | 1002 | irTxChannel[activeChannel].state != sns_irTransceive_STATE_PAUSING && |
|
| - | 1003 | irTxChannel[activeChannel].state != sns_irTransceive_STATE_START_PAUSE) |
|
| - | 1004 | { |
|
| - | 1005 | /* Too late to continue! Not in TX state anymore */ |
|
| - | 1006 | pronto_sendResponse(activeChannel, PRONTO_RESPONSE_ALREADY_STOPPED); |
|
| 930 | break; |
1007 | break; |
| 931 | 1008 | } |
|
| 932 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOCONTINUE: |
- | |
| 933 | /* Sanity check. */ |
- | |
| 934 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) break; |
- | |
| 935 | 1009 | ||
| 936 | /* Reset repeat counter, i.e. request additional repeats. */ |
1010 | /* Reset repeat counter, i.e. request additional repeats. */ |
| 937 | irTxChannel[channel].repeatCount = 0; |
1011 | irTxChannel[channel].repeatCount = 0; |
| 938 | 1012 | ||
| 939 | /* |
1013 | /* The repeat period was extended. Still transmitting */ |
| - | 1014 | pronto_sendResponse(channel, PRONTO_RESPONSE_TRANSMITTING); |
|
| 940 | break; |
1015 | break; |
| - | 1016 | } |
|
| 941 | 1017 | ||
| 942 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1: /* Fall through */ |
1018 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1: /* Fall through */ |
| 943 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA2: /* Fall through */ |
1019 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA2: /* Fall through */ |
| 944 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA3: /* Fall through */ |
1020 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA3: /* Fall through */ |
| 945 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA4: /* Fall through */ |
1021 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA4: /* Fall through */ |
| 946 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA5: /* Fall through */ |
1022 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA5: /* Fall through */ |
| Line 954... | Line 1030... | ||
| 954 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA13: /* Fall through */ |
1030 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA13: /* Fall through */ |
| 955 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA14: /* Fall through */ |
1031 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA14: /* Fall through */ |
| 956 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA15: /* Fall through */ |
1032 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA15: /* Fall through */ |
| 957 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA16: |
1033 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA16: |
| 958 | { |
1034 | { |
| 959 | // unexpected CAN msg, out of order |
- | |
| 960 | if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) { |
1035 | if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) { |
| - | 1036 | /* Invalid state. CAN msg probably out of order */ |
|
| - | 1037 | pronto_sendResponse(activeChannel, PRONTO_RESPONSE_ERROR); |
|
| 961 | break; |
1038 | break; |
| 962 | } |
1039 | } |
| 963 | 1040 | ||
| 964 | // unexpected CAN msg, out of order |
- | |
| 965 | if ((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1) != (irTxChannel[activeChannel].expectedSeqNr % 16)) { |
1041 | if ((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1) != (irTxChannel[activeChannel].expectedSeqNr % 16)) { |
| - | 1042 | /* Unexpected CAN msg, out of order */ |
|
| 966 |
|
1043 | pronto_sendResponse(activeChannel, PRONTO_RESPONSE_ERROR); |
| 967 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_IDLE; |
1044 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_IDLE; |
| 968 | break; |
1045 | break; |
| 969 | } |
1046 | } |
| 970 | 1047 | ||
| 971 |
|
1048 | /* Decode pronto data */ |
| 972 | for (uint8_t i = 0; i < rxMsg->Length; i++) { |
1049 | for (uint8_t i = 0; i < rxMsg->Length; i++) { |
| 973 | if (decodeProntoData(activeChannel, rxMsg->Data[i]) != 1) { |
1050 | if (decodeProntoData(activeChannel, rxMsg->Data[i]) != 1) { |
| - | 1051 | /* Decode error */ |
|
| - | 1052 | pronto_sendResponse(activeChannel, PRONTO_RESPONSE_ERROR); |
|
| 974 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_IDLE; |
1053 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_IDLE; |
| 975 | printf("DECERROR"); |
- | |
| 976 | return; |
1054 | return; |
| 977 | } |
1055 | } |
| 978 | } |
1056 | } |
| 979 | 1057 | ||
| 980 | irTxChannel[activeChannel].expectedSeqNr++; |
1058 | irTxChannel[activeChannel].expectedSeqNr++; |
| - | 1059 | ||
| - | 1060 | /* We're still waiting for more pronto data, or for pronto end */ |
|
| - | 1061 | pronto_sendResponse(activeChannel, PRONTO_RESPONSE_WAITING); |
|
| 981 | break; |
1062 | break; |
| 982 | } |
1063 | } |
| 983 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1: /* Fall through */ |
1064 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1: /* Fall through */ |
| 984 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND2: /* Fall through */ |
1065 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND2: /* Fall through */ |
| 985 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND3: /* Fall through */ |
1066 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND3: /* Fall through */ |
| Line 996... | Line 1077... | ||
| 996 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND14: /* Fall through */ |
1077 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND14: /* Fall through */ |
| 997 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND15: /* Fall through */ |
1078 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND15: /* Fall through */ |
| 998 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND16: /* Fall through */ |
1079 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND16: /* Fall through */ |
| 999 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND17: |
1080 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND17: |
| 1000 | { |
1081 | { |
| 1001 | // unexpected CAN msg, out of order |
- | |
| 1002 | if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) { |
1082 | if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) { |
| - | 1083 | /* Invalid state. CAN msg probably out of order */ |
|
| - | 1084 | pronto_sendResponse(activeChannel, PRONTO_RESPONSE_ERROR); |
|
| 1003 | break; |
1085 | break; |
| 1004 | } |
1086 | } |
| 1005 | 1087 | ||
| 1006 | // unexpected CAN msg, out of order |
- | |
| 1007 | if (((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1) % 16) != (irTxChannel[activeChannel].expectedSeqNr % 16)) { |
1088 | if (((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1) % 16) != (irTxChannel[activeChannel].expectedSeqNr % 16)) { |
| - | 1089 | /* Unexpected CAN msg, out of order */ |
|
| 1008 |
|
1090 | pronto_sendResponse(activeChannel, PRONTO_RESPONSE_ERROR); |
| 1009 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_IDLE; |
1091 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_IDLE; |
| 1010 | break; |
1092 | break; |
| 1011 | } |
1093 | } |
| 1012 | 1094 | ||
| 1013 |
|
1095 | /* Decode remaining pronto data (if any). -1 because last byte is repeat count */ |
| 1014 | for (uint16_t i = 0; i < rxMsg->Length - 1; i++) { |
1096 | for (uint16_t i = 0; i < rxMsg->Length - 1; i++) { |
| 1015 | if (decodeProntoData(activeChannel, rxMsg->Data[i]) < 0) { |
1097 | if (decodeProntoData(activeChannel, rxMsg->Data[i]) < 0) { |
| 1016 |
|
1098 | /* Decode error */ |
| - | 1099 | pronto_sendResponse(activeChannel, PRONTO_RESPONSE_ERROR); |
|
| 1017 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_IDLE; |
1100 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_IDLE; |
| 1018 | return; |
1101 | return; |
| 1019 | } |
1102 | } |
| 1020 | } |
1103 | } |
| 1021 | 1104 | ||
| 1022 |
|
1105 | /* Sanity check */ |
| 1023 | if (irTxChannel[activeChannel].txlen != (((uint16_t)irTxChannel[activeChannel].onceSeqLen + (uint16_t)irTxChannel[activeChannel].repSeqLen))) |
1106 | if (irTxChannel[activeChannel].txlen != (((uint16_t)irTxChannel[activeChannel].onceSeqLen + (uint16_t)irTxChannel[activeChannel].repSeqLen))) { |
| 1024 | { |
- | |
| - | 1107 | /* Length doesn't match the expected length */ |
|
| - | 1108 | pronto_sendResponse(activeChannel, PRONTO_RESPONSE_ERROR); |
|
| 1025 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE; |
1109 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE; |
| 1026 | break; |
1110 | break; |
| 1027 | } |
1111 | } |
| 1028 | 1112 | ||
| 1029 |
|
1113 | /* Last byte determines nr of repeats. 0xFF means INF, 0 means no repeats */ |
| 1030 | irTxChannel[activeChannel].proto.repeats = rxMsg->Data[rxMsg->Length - 1]; |
1114 | irTxChannel[activeChannel].proto.repeats = rxMsg->Data[rxMsg->Length - 1]; |
| 1031 | irTxChannel[activeChannel].proto.timeout = 1; |
1115 | 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 */ |
| 1032 | 1116 | ||
| 1033 |
|
1117 | /* Convert pronto data to µs */ |
| 1034 |
|
1118 | /* TODO: calculate actual value instead of 27 */ |
| 1035 | for (uint16_t i = 0; i < irTxChannel[activeChannel].txlen; i++) { |
1119 | for (uint16_t i = 0; i < irTxChannel[activeChannel].txlen; i++) { |
| 1036 | uint32_t newVal = ((uint32_t)irTxChannel[activeChannel].txbuf[i]) * 27UL; |
1120 | uint32_t newVal = ((uint32_t)irTxChannel[activeChannel].txbuf[i]) * 27UL; |
| 1037 | if (newVal > 0xFFFFUL) { |
1121 | if (newVal > 0xFFFFUL) { |
| 1038 | newVal = 0xFFFFUL; |
1122 | newVal = 0xFFFFUL; |
| 1039 | } |
1123 | } |
| 1040 | irTxChannel[activeChannel].txbuf[i] = (uint16_t)newVal; |
1124 | irTxChannel[activeChannel].txbuf[i] = (uint16_t)newVal; |
| 1041 | } |
1125 | } |
| 1042 | 1126 | ||
| 1043 |
|
1127 | /* Send IR data */ |
| 1044 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_TRANSMIT_PRONTO; |
1128 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_TRANSMIT_PRONTO; |
| 1045 | 1129 | ||
| 1046 | /* |
1130 | /* We're now transmitting the pronto data */ |
| - | 1131 | pronto_sendResponse(activeChannel, PRONTO_RESPONSE_TRANSMITTING); |
|
| 1047 | break; |
1132 | break; |
| 1048 | } |
1133 | } |
| 1049 | 1134 | ||
| 1050 | /* TODO: In IR state machine add sending a response frame when ir stops sending, also implement pronto repeat */ |
1135 | /* TODO: In IR state machine add sending a response frame when ir stops sending, also implement pronto repeat */ |
| 1051 | #endif |
1136 | #endif |
| 1052 | #endif |
1137 | #endif |
| 1053 | 1138 | ||
| 1054 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRCONFIG: |
1139 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRCONFIG: |
| - | 1140 | { |
|
| - | 1141 | /* Get IR channel. */ |
|
| - | 1142 | uint8_t channel = rxMsg->Data[0] >> 4; |
|
| - | 1143 | ||
| - | 1144 | /* Sanity check. */ |
|
| - | 1145 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) { |
|
| - | 1146 | /* Invalid channel */ |
|
| - | 1147 | break; |
|
| - | 1148 | } |
|
| - | 1149 | ||
| 1055 | uint8_t config = rxMsg->Data[0] & 0x0f; |
1150 | uint8_t config = rxMsg->Data[0] & 0x0f; |
| 1056 | uint8_t power = rxMsg->Data[1]>>6; |
1151 | uint8_t power = rxMsg->Data[1]>>6; |
| 1057 | uint32_t divider = ((uint16_t)rxMsg->Data[2] << 8) | ((uint16_t)rxMsg->Data[3] << 0); |
1152 | uint32_t divider = ((uint16_t)rxMsg->Data[2] << 8) | ((uint16_t)rxMsg->Data[3] << 0); |
| 1058 | if (divider == 0) { |
1153 | if (divider == 0) { |
| 1059 |
|
1154 | /* Invalid modfreq */ |
| 1060 | break; |
1155 | break; |
| 1061 | } |
1156 | } |
| 1062 | uint32_t modfreq = (sns_irTransceive_BaseFrq / (divider*1000)); |
1157 | uint32_t modfreq = (sns_irTransceive_BaseFrq / (divider*1000)); |
| 1063 | if (modfreq == 0) { |
1158 | if (modfreq == 0) { |
| 1064 |
|
1159 | /* Invalid modfreq */ |
| 1065 | break; |
1160 | break; |
| 1066 | } |
1161 | } |
| 1067 | sns_irTransceive_setConfig(channel, config, power, modfreq); |
1162 | sns_irTransceive_setConfig(channel, config, power, modfreq); |
| 1068 | 1163 | ||
| 1069 | #ifdef sns_irTransceive_USEEEPROM |
1164 | #ifdef sns_irTransceive_USEEEPROM |