Rev 1842 | Rev 1846 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 1842 | Rev 1843 | ||
|---|---|---|---|
| Line 99... | Line 99... | ||
| 99 | #endif |
99 | #endif |
| 100 | 100 | ||
| 101 | #define sns_irTransceive_BaseFrq (4145146UL) |
101 | #define sns_irTransceive_BaseFrq (4145146UL) |
| 102 | 102 | ||
| 103 | #ifndef sns_irTransceive_PRONTO_SUPPORT |
103 | #ifndef sns_irTransceive_PRONTO_SUPPORT |
| 104 | #define sns_irTransceive_PRONTO_SUPPORT |
104 | #define sns_irTransceive_PRONTO_SUPPORT 1 |
| 105 | #endif |
105 | #endif |
| 106 | 106 | ||
| 107 | /* |
107 | /* |
| 108 | * PRONTO HEX Routines |
108 | * PRONTO HEX Routines |
| 109 | */ |
109 | */ |
| Line 262... | Line 262... | ||
| 262 | 262 | ||
| 263 | 263 | ||
| 264 | static int decodeProntoData(int channel, uint8_t data) |
264 | static int decodeProntoData(int channel, uint8_t data) |
| 265 | { |
265 | { |
| 266 | static uint8_t waitingForLSB = FALSE; |
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 | 267 | ||
| 273 | if (irTxChannel[channel].txlen >= MAX_NR_TIMES) { |
268 | if (irTxChannel[channel].txlen >= MAX_NR_TIMES) { |
| 274 | // max length exceeded |
269 | // max length exceeded |
| 275 | return -1; |
270 | return -1; |
| 276 | } |
271 | } |
| Line 279... | Line 274... | ||
| 279 | waitingForLSB = FALSE; |
274 | waitingForLSB = FALSE; |
| 280 | if (data == 0) { |
275 | if (data == 0) { |
| 281 | // cannot start with 0x00 |
276 | // cannot start with 0x00 |
| 282 | return -2; |
277 | return -2; |
| 283 | } |
278 | } |
| 284 | } |
279 | } |
| 285 | 280 | ||
| 286 | // 0x00 means that previously received time is MSB of 16bit value, and that next byte will be LSB |
281 | // 0x00 means that previously received time is MSB of 16bit value, and that next byte will be LSB |
| 287 | if (data == 0 && !waitingForLSB) { |
282 | if (data == 0 && !waitingForLSB) { |
| 288 | // convert previous time to MSB of the 16bit value. next received byte will become LSB |
283 | // convert previous time to MSB of the 16bit value. next received byte will become LSB |
| 289 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] <<= 8; |
284 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] <<= 8; |
| Line 301... | Line 296... | ||
| 301 | waitingForLSB = FALSE; |
296 | waitingForLSB = FALSE; |
| 302 | } |
297 | } |
| 303 | 298 | ||
| 304 | // non-zero value! simply new 8bit value |
299 | // non-zero value! simply new 8bit value |
| 305 | else { |
300 | else { |
| - | 301 | // check if we're already done |
|
| - | 302 | if (irTxChannel[activeChannel].txlen >= (((uint16_t)irTxChannel[activeChannel].onceSeqLen + (uint16_t)irTxChannel[activeChannel].repSeqLen))) { |
|
| - | 303 | // too much data received, not necessarily a problem in case frames are padded |
|
| - | 304 | return 2; |
|
| - | 305 | } |
|
| - | 306 | ||
| 306 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen] = data; |
307 | irTxChannel[channel].txbuf[irTxChannel[channel].txlen] = data; |
| 307 | 308 | ||
| 308 | irTxChannel[channel].txlen++; |
309 | irTxChannel[channel].txlen++; |
| 309 | } |
310 | } |
| 310 | 311 | ||
| Line 389... | Line 390... | ||
| 389 | Pca95xx_set_out(sns_irTransceive_TX0_PWRl); |
390 | Pca95xx_set_out(sns_irTransceive_TX0_PWRl); |
| 390 | Pca95xx_set_out(sns_irTransceive_TX0_PWRh); |
391 | Pca95xx_set_out(sns_irTransceive_TX0_PWRh); |
| 391 | if (power&0x1) |
392 | if (power&0x1) |
| 392 | { |
393 | { |
| 393 | Pca95xx_set_in(sns_irTransceive_TX0_PWRl); |
394 | Pca95xx_set_in(sns_irTransceive_TX0_PWRl); |
| 394 | } |
395 | } |
| 395 | if (power&0x2) |
396 | if (power&0x2) |
| 396 | { |
397 | { |
| 397 | Pca95xx_set_in(sns_irTransceive_TX0_PWRh); |
398 | Pca95xx_set_in(sns_irTransceive_TX0_PWRh); |
| 398 | } |
399 | } |
| 399 | #endif |
400 | #endif |
| 400 | break; |
401 | break; |
| 401 | case 1: |
402 | case 1: |
| 402 | #if IR_RX_ENABLE==1 |
403 | #if IR_RX_ENABLE==1 |
| 403 | gpio_set_pin(sns_irTransceive_VCC_EN1_PIN); |
404 | gpio_set_pin(sns_irTransceive_VCC_EN1_PIN); |
| 404 | IrTransceiver_DeInitRxChannel(channel, sns_irTransceive_RX1_PCINT, sns_irTransceive_RX1_PIN); |
405 | IrTransceiver_DeInitRxChannel(channel, sns_irTransceive_RX1_PCINT, sns_irTransceive_RX1_PIN); |
| Line 589... | Line 590... | ||
| 589 | 590 | ||
| 590 | /* Let protocol driver parse and then send on CAN */ |
591 | /* Let protocol driver parse and then send on CAN */ |
| 591 | uint8_t res2 = parseProtocol(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen, &irRxChannel[channel].proto); |
592 | uint8_t res2 = parseProtocol(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen, &irRxChannel[channel].proto); |
| 592 | if (res2 == IR_OK && irRxChannel[channel].proto.protocol != IR_PROTO_UNKNOWN) { |
593 | if (res2 == IR_OK && irRxChannel[channel].proto.protocol != IR_PROTO_UNKNOWN) { |
| 593 | irTxMsg.Data[0] = 0xf&CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_PRESSED; |
594 | irTxMsg.Data[0] = 0xf&CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_PRESSED; |
| 594 | irTxMsg.Data[0] |= channel<<4; |
595 | irTxMsg.Data[0] |= channel<<4; |
| 595 | irTxMsg.Data[1] = irRxChannel[channel].proto.protocol; |
596 | irTxMsg.Data[1] = irRxChannel[channel].proto.protocol; |
| 596 | irTxMsg.Data[2] = (irRxChannel[channel].proto.data>>24)&0xff; |
597 | irTxMsg.Data[2] = (irRxChannel[channel].proto.data>>24)&0xff; |
| 597 | irTxMsg.Data[3] = (irRxChannel[channel].proto.data>>16)&0xff; |
598 | irTxMsg.Data[3] = (irRxChannel[channel].proto.data>>16)&0xff; |
| 598 | irTxMsg.Data[4] = (irRxChannel[channel].proto.data>>8)&0xff; |
599 | irTxMsg.Data[4] = (irRxChannel[channel].proto.data>>8)&0xff; |
| 599 | irTxMsg.Data[5] = irRxChannel[channel].proto.data&0xff; |
600 | irTxMsg.Data[5] = irRxChannel[channel].proto.data&0xff; |
| 600 | 601 | ||
| 601 | StdCan_Put(&irTxMsg); |
602 | StdCan_Put(&irTxMsg); |
| 602 | } |
603 | } |
| 603 | else if (irRxChannel[channel].proto.protocol == IR_PROTO_UNKNOWN) |
604 | else if (irRxChannel[channel].proto.protocol == IR_PROTO_UNKNOWN) |
| 604 | { |
605 | { |
| 605 | #if (sns_irTransceive_SEND_DEBUG==1) |
606 | #if (sns_irTransceive_SEND_DEBUG==1) |
| 606 | send_debug(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen); |
607 | send_debug(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen); |
| Line 620... | Line 621... | ||
| 620 | 621 | ||
| 621 | case sns_irTransceive_STATE_START_PAUSE: |
622 | case sns_irTransceive_STATE_START_PAUSE: |
| 622 | /* set a timer so we can send release button event when no new IR is arriving */ |
623 | /* set a timer so we can send release button event when no new IR is arriving */ |
| 623 | Timer_SetTimeout(irRxChannel[channel].timerNum, irRxChannel[channel].proto.timeout, TimerTypeOneShot, 0); |
624 | Timer_SetTimeout(irRxChannel[channel].timerNum, irRxChannel[channel].proto.timeout, TimerTypeOneShot, 0); |
| 624 | irRxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
625 | irRxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
| 625 | break; |
626 | break; |
| 626 | 627 | ||
| 627 | case sns_irTransceive_STATE_PAUSING: |
628 | case sns_irTransceive_STATE_PAUSING: |
| 628 | /* reset timer if new IR arrived */ |
629 | /* reset timer if new IR arrived */ |
| 629 | if (irRxChannel[channel].newData == TRUE || IrTransceiver_GetStoreEnableRx(channel) == TRUE) { |
630 | if (irRxChannel[channel].newData == TRUE || IrTransceiver_GetStoreEnableRx(channel) == TRUE) { |
| 630 | cli(); |
631 | cli(); |
| Line 653... | Line 654... | ||
| 653 | } |
654 | } |
| 654 | irRxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
655 | irRxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| 655 | break; |
656 | break; |
| 656 | 657 | ||
| 657 | default: |
658 | default: |
| 658 | break; |
659 | break; |
| 659 | } |
660 | } |
| 660 | #endif |
661 | #endif |
| 661 | 662 | ||
| 662 | #if IR_TX_ENABLE==1 |
663 | #if IR_TX_ENABLE==1 |
| 663 | switch (irTxChannel[channel].state) |
664 | switch (irTxChannel[channel].state) |
| 664 | { |
665 | { |
| 665 | case sns_irTransceive_STATE_IDLE: |
666 | case sns_irTransceive_STATE_IDLE: |
| 666 | /* transmission is started when a command is received on can */ |
667 | /* transmission is started when a command is received on can */ |
| 667 | break; |
668 | break; |
| 668 | 669 | ||
| 669 | case sns_irTransceive_STATE_START_TRANSMIT: |
670 | case sns_irTransceive_STATE_START_TRANSMIT: |
| 670 | { |
671 | { |
| 671 | if (expandProtocol(irTxChannel[channel].txbuf, &irTxChannel[channel].txlen, &irTxChannel[channel].proto) == IR_OK) |
672 | if (expandProtocol(irTxChannel[channel].txbuf, &irTxChannel[channel].txlen, &irTxChannel[channel].proto) == IR_OK) { |
| 672 | { |
- | |
| 673 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen); |
673 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen); |
| 674 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
674 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
| 675 | } |
675 | } |
| 676 | else |
676 | else { |
| 677 | { |
- | |
| 678 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
677 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| 679 | } |
678 | } |
| 680 | break; |
679 | break; |
| 681 | } |
680 | } |
| - | 681 | ||
| 682 | case sns_irTransceive_STATE_START_TRANSMIT_PRONTO: |
682 | case sns_irTransceive_STATE_START_TRANSMIT_PRONTO: |
| 683 | { |
683 | { |
| 684 | /* Start IR transmission. */ |
684 | /* Start IR transmission. */ |
| 685 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].onceSeqLen - 1); |
685 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].onceSeqLen - 1); |
| 686 | 686 | ||
| 687 | /* Enter transmitting state. */ |
687 | /* Enter transmitting state. */ |
| 688 | irTxChannel[channel].sendingPronto = TRUE; |
688 | irTxChannel[channel].sendingPronto = TRUE; |
| 689 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
689 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
| 690 | break; |
690 | break; |
| 691 | } |
691 | } |
| - | 692 | ||
| 692 | case sns_irTransceive_STATE_PRONTO_REPEAT: |
693 | case sns_irTransceive_STATE_PRONTO_REPEAT: |
| 693 | { |
694 | { |
| 694 | /* Check if done. */ |
695 | /* Check if done. */ |
| 695 | if (irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats && irTxChannel[channel].proto.repeats != 0xFF) |
696 | if (irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats && irTxChannel[channel].proto.repeats != 0xFF) { |
| 696 | { |
- | |
| 697 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
697 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
| 698 | break; |
698 | break; |
| 699 | } |
699 | } |
| 700 | 700 | ||
| 701 | if (irTxChannel[channel].repeatCount < 255) { |
701 | if (irTxChannel[channel].repeatCount < 255) { |
| Line 714... | Line 714... | ||
| 714 | // don't transmit last passive. last passive handled by timer |
714 | // don't transmit last passive. last passive handled by timer |
| 715 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen - 1); |
715 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen - 1); |
| 716 | } |
716 | } |
| 717 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
717 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
| 718 | } |
718 | } |
| - | 719 | ||
| 719 | case sns_irTransceive_STATE_TRANSMITTING: |
720 | case sns_irTransceive_STATE_TRANSMITTING: |
| 720 | { |
721 | { |
| 721 | if (irTxChannel[channel].sendComplete == TRUE) |
722 | if (irTxChannel[channel].sendComplete == TRUE) |
| 722 | { |
723 | { |
| 723 | cli(); |
724 | cli(); |
| 724 | irTxChannel[channel].sendComplete = FALSE; |
725 | irTxChannel[channel].sendComplete = FALSE; |
| 725 | sei(); |
726 | sei(); |
| 726 | 727 | ||
| 727 | if (irTxChannel[channel].sendingPronto) |
728 | if (irTxChannel[channel].sendingPronto) |
| 728 | { |
729 | { |
| 729 | if(irTxChannel[channel].repeatCount == 0 || irTxChannel[channel].repSeqLen == 0) |
730 | if(irTxChannel[channel].repeatCount == 0 || irTxChannel[channel].repSeqLen == 0) |
| 730 | { |
731 | { |
| 731 | // use last passive time as timeout |
732 | // use last passive time as timeout |
| 732 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].onceSeqLen - 1] / 1000; |
733 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].onceSeqLen - 1] / 1000; |
| 733 | Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0); |
734 | Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0); |
| 734 | } |
735 | } |
| 735 | else |
736 | else |
| 736 | { |
737 | { |
| 737 | // use last passive time as timeout |
738 | // use last passive time as timeout |
| 738 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] / 1000; |
739 | uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] / 1000; |
| 739 | Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0); |
740 | Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0); |
| 740 | } |
741 | } |
| 741 | irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
742 | irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
| 742 | } |
743 | } |
| 743 | else |
744 | else |
| 744 | { |
745 | { |
| 745 | irTxChannel[channel].state = sns_irTransceive_STATE_START_PAUSE; |
746 | irTxChannel[channel].state = sns_irTransceive_STATE_START_PAUSE; |
| 746 | } |
747 | } |
| 747 | } |
748 | } |
| 748 | break; |
749 | break; |
| 749 | } |
750 | } |
| - | 751 | ||
| 750 | case sns_irTransceive_STATE_START_PAUSE: |
752 | case sns_irTransceive_STATE_START_PAUSE: |
| 751 | { |
753 | { |
| 752 | if (irTxChannel[channel].repeatCount < irTxChannel[channel].proto.repeats) |
754 | if (irTxChannel[channel].repeatCount < irTxChannel[channel].proto.repeats) |
| 753 | { |
755 | { |
| 754 | irTxChannel[channel].repeatCount++; |
756 | irTxChannel[channel].repeatCount++; |
| 755 | } |
757 | } |
| 756 | 758 | ||
| 757 | Timer_SetTimeout(irTxChannel[channel].timerNum, irTxChannel[channel].proto.timeout, TimerTypeOneShot, 0); |
759 | Timer_SetTimeout(irTxChannel[channel].timerNum, irTxChannel[channel].proto.timeout, TimerTypeOneShot, 0); |
| 758 | 760 | ||
| 759 | if (irTxChannel[channel].proto.framecnt != 255) |
761 | if (irTxChannel[channel].proto.framecnt != 255) |
| 760 | { |
762 | { |
| 761 | irTxChannel[channel].proto.framecnt++; |
763 | irTxChannel[channel].proto.framecnt++; |
| 762 | } |
764 | } |
| 763 | 765 | ||
| 764 | irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
766 | irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING; |
| 765 | break; |
767 | break; |
| 766 | } |
768 | } |
| - | 769 | ||
| 767 | case sns_irTransceive_STATE_PAUSING: |
770 | case sns_irTransceive_STATE_PAUSING: |
| 768 | { |
771 | { |
| 769 | if (irTxChannel[channel].sendingPronto) |
772 | if (irTxChannel[channel].sendingPronto) |
| 770 | { |
773 | { |
| 771 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
774 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
| 772 | { |
775 | { |
| 773 | irTxChannel[channel].state = sns_irTransceive_STATE_PRONTO_REPEAT; |
776 | irTxChannel[channel].state = sns_irTransceive_STATE_PRONTO_REPEAT; |
| 774 | } |
777 | } |
| 775 | break; |
778 | break; |
| 776 | } |
779 | } |
| 777 | 780 | ||
| 778 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
781 | if (Timer_Expired(irTxChannel[channel].timerNum)) |
| 779 | { |
782 | { |
| Line 786... | Line 789... | ||
| 786 | //TODO maybe send message on can for status? to confirm stopped sending, ready for new command |
789 | //TODO maybe send message on can for status? to confirm stopped sending, ready for new command |
| 787 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
790 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
| 788 | } |
791 | } |
| 789 | break; |
792 | break; |
| 790 | } |
793 | } |
| - | 794 | ||
| 791 | case sns_irTransceive_STATE_START_IDLE: |
795 | case sns_irTransceive_STATE_START_IDLE: |
| 792 | irTxChannel[channel].stopSend = FALSE; |
796 | irTxChannel[channel].stopSend = FALSE; |
| 793 | irTxChannel[channel].repeatCount = 0; |
797 | irTxChannel[channel].repeatCount = 0; |
| 794 | irTxChannel[channel].proto.framecnt = 0; |
798 | irTxChannel[channel].proto.framecnt = 0; |
| 795 | irTxChannel[channel].sendingPronto = FALSE; |
799 | irTxChannel[channel].sendingPronto = FALSE; |
| Line 936... | Line 940... | ||
| 936 | break; |
940 | break; |
| 937 | } |
941 | } |
| 938 | 942 | ||
| 939 | // decode pronto data |
943 | // decode pronto data |
| 940 | for (uint8_t i = 0; i < rxMsg->Length; i++) { |
944 | for (uint8_t i = 0; i < rxMsg->Length; i++) { |
| - | 945 | int res; |
|
| 941 | if (decodeProntoData(activeChannel |
946 | if ((res=decodeProntoData(activeChannel, rxMsg->Data[i])) != 1) { |
| 942 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
947 | irTxChannel[channel].state = sns_irTransceive_STATE_START_IDLE; |
| 943 | printf(" |
948 | printf("DE:%02d:%02d", res, i); |
| 944 | return; |
949 | return; |
| 945 | } |
950 | } |
| 946 | } |
951 | } |
| 947 | 952 | ||
| 948 | irTxChannel[activeChannel].expectedSeqNr++; |
953 | irTxChannel[activeChannel].expectedSeqNr++; |