Rev 1864 | Rev 1871 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 1864 | Rev 1865 | ||
|---|---|---|---|
| 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 | uint16_t modfreq; |
- | |
| 27 | uint16_t *rxbuf; |
26 | uint16_t *rxbuf; |
| 28 | uint8_t rxlen; |
27 | uint8_t rxlen; |
| 29 | uint8_t timerNum; |
28 | uint8_t timerNum; |
| 30 | Ir_Protocol_Data_t proto; |
29 | Ir_Protocol_Data_t proto; |
| 31 | uint8_t newData; |
30 | uint8_t newData; |
| Line 33... | Line 32... | ||
| 33 | #endif |
32 | #endif |
| 34 | 33 | ||
| 35 | #if IR_TX_ENABLE==1 |
34 | #if IR_TX_ENABLE==1 |
| 36 | struct { |
35 | struct { |
| 37 | uint8_t state; |
36 | uint8_t state; |
| 38 | uint16_t modfreq; |
- | |
| 39 | uint16_t *txbuf; |
37 | uint16_t *txbuf; |
| 40 | uint8_t txlen; |
38 | uint8_t txlen; |
| 41 | uint8_t timerNum; |
39 | uint8_t timerNum; |
| 42 | uint8_t repeatCount; |
40 | uint8_t repeatCount; |
| 43 | Ir_Protocol_Data_t proto; |
41 | Ir_Protocol_Data_t proto; |
| Line 381... | Line 379... | ||
| 381 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE) |
379 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_RECEIVE) |
| 382 | { |
380 | { |
| 383 | #if IR_TX_ENABLE==1 |
381 | #if IR_TX_ENABLE==1 |
| 384 | irTxChannel[channel].state = sns_irTransceive_STATE_DISABLED; |
382 | irTxChannel[channel].state = sns_irTransceive_STATE_DISABLED; |
| 385 | #endif |
383 | #endif |
| 386 | irRxChannel[channel].modfreq = modfreq; |
384 | irRxChannel[channel].proto.modfreq = modfreq; |
| 387 | irRxChannel[channel].rxbuf = buf[channel]; |
385 | irRxChannel[channel].rxbuf = buf[channel]; |
| 388 | switch (channel) |
386 | switch (channel) |
| 389 | { |
387 | { |
| 390 | case 0: |
388 | case 0: |
| 391 | gpio_clr_pin(sns_irTransceive_VCC_EN0_PIN); |
389 | gpio_clr_pin(sns_irTransceive_VCC_EN0_PIN); |
| Line 408... | Line 406... | ||
| 408 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_TRANSMIT) |
406 | if (config == CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_TRANSMIT) |
| 409 | { |
407 | { |
| 410 | #if IR_RX_ENABLE==1 |
408 | #if IR_RX_ENABLE==1 |
| 411 | irRxChannel[channel].state = sns_irTransceive_STATE_DISABLED; |
409 | irRxChannel[channel].state = sns_irTransceive_STATE_DISABLED; |
| 412 | #endif |
410 | #endif |
| 413 | irTxChannel[channel].modfreq = modfreq; |
- | |
| 414 | irTxChannel[channel].txbuf = buf[channel]; |
411 | irTxChannel[channel].txbuf = buf[channel]; |
| 415 | switch (channel) |
412 | switch (channel) |
| 416 | { |
413 | { |
| 417 | case 0: |
414 | case 0: |
| 418 | #if IR_RX_ENABLE==1 |
415 | #if IR_RX_ENABLE==1 |
| Line 473... | Line 470... | ||
| 473 | Pca95xx_set_in(sns_irTransceive_TX2_PWRh); |
470 | Pca95xx_set_in(sns_irTransceive_TX2_PWRh); |
| 474 | } |
471 | } |
| 475 | #endif |
472 | #endif |
| 476 | break; |
473 | break; |
| 477 | } |
474 | } |
| 478 | irTxChannel[channel].state = |
475 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| 479 | } |
476 | } |
| 480 | #endif |
477 | #endif |
| 481 | } |
478 | } |
| 482 | } |
479 | } |
| 483 | 480 | ||
| Line 600... | Line 597... | ||
| 600 | 597 | ||
| 601 | #if IR_RX_ENABLE==1 |
598 | #if IR_RX_ENABLE==1 |
| 602 | switch (irRxChannel[channel].state) |
599 | switch (irRxChannel[channel].state) |
| 603 | { |
600 | { |
| 604 | case sns_irTransceive_STATE_IDLE: |
601 | case sns_irTransceive_STATE_IDLE: |
| - | 602 | { |
|
| - | 603 | if (irRxChannel[channel].proto.protocol != IR_PROTO_UNKNOWN) { |
|
| - | 604 | /* Send button release command on CAN */ |
|
| - | 605 | irTxMsg.Data[0] = 0xf&CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_RELEASED; |
|
| - | 606 | irTxMsg.Data[0] |= channel<<4; |
|
| - | 607 | irTxMsg.Data[1] = irRxChannel[channel].proto.protocol; |
|
| - | 608 | irTxMsg.Data[2] = (irRxChannel[channel].proto.data>>24)&0xff; |
|
| - | 609 | irTxMsg.Data[3] = (irRxChannel[channel].proto.data>>16)&0xff; |
|
| - | 610 | irTxMsg.Data[4] = (irRxChannel[channel].proto.data>>8)&0xff; |
|
| - | 611 | irTxMsg.Data[5] = irRxChannel[channel].proto.data&0xff; |
|
| - | 612 | ||
| - | 613 | StdCan_Put(&irTxMsg); |
|
| - | 614 | } |
|
| 605 | irRxChannel[channel].state = sns_irTransceive_STATE_START_RECEIVE; |
615 | irRxChannel[channel].state = sns_irTransceive_STATE_START_RECEIVE; |
| 606 | break; |
616 | break; |
| - | 617 | } |
|
| 607 | 618 | ||
| 608 | case sns_irTransceive_STATE_START_RECEIVE: |
619 | case sns_irTransceive_STATE_START_RECEIVE: |
| 609 | IrTransceiver_ResetRx(channel); |
620 | IrTransceiver_ResetRx(channel); |
| 610 | cli(); |
621 | cli(); |
| 611 | irRxChannel[channel].newData = FALSE; |
622 | irRxChannel[channel].newData = FALSE; |
| Line 638... | Line 649... | ||
| 638 | { |
649 | { |
| 639 | #if (sns_irTransceive_SEND_DEBUG==1) |
650 | #if (sns_irTransceive_SEND_DEBUG==1) |
| 640 | send_debug(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen); |
651 | send_debug(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen); |
| 641 | irRxChannel[channel].proto.timeout=300; |
652 | irRxChannel[channel].proto.timeout=300; |
| 642 | #elif sns_irTransceive_PRONTO_SUPPORT==1 |
653 | #elif sns_irTransceive_PRONTO_SUPPORT==1 |
| 643 | pronto_sendData(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen, channel, irRxChannel[channel].modfreq); |
654 | pronto_sendData(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen, channel, irRxChannel[channel].proto.modfreq); |
| 644 | irRxChannel[channel].proto.timeout=1; |
655 | irRxChannel[channel].proto.timeout=1; |
| 645 | #endif |
656 | #endif |
| 646 | } |
657 | } |
| 647 | 658 | ||
| 648 | /* Enable the receiver again */ |
659 | /* Enable the receiver again */ |
| Line 666... | Line 677... | ||
| 666 | sei(); |
677 | sei(); |
| 667 | Timer_SetTimeout(irRxChannel[channel].timerNum, irRxChannel[channel].proto.timeout, TimerTypeOneShot, 0); |
678 | Timer_SetTimeout(irRxChannel[channel].timerNum, irRxChannel[channel].proto.timeout, TimerTypeOneShot, 0); |
| 668 | } |
679 | } |
| 669 | 680 | ||
| 670 | if (Timer_Expired(irRxChannel[channel].timerNum)) { |
681 | if (Timer_Expired(irRxChannel[channel].timerNum)) { |
| 671 | irRxChannel[channel].state = |
682 | irRxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| 672 | } |
- | |
| 673 | break; |
- | |
| 674 | - | ||
| 675 | case sns_irTransceive_STATE_START_IDLE: |
- | |
| 676 | if (irRxChannel[channel].proto.protocol != IR_PROTO_UNKNOWN) { |
- | |
| 677 | /* Send button release command on CAN */ |
- | |
| 678 | irTxMsg.Data[0] = 0xf&CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_RELEASED; |
- | |
| 679 | irTxMsg.Data[0] |= channel<<4; |
- | |
| 680 | irTxMsg.Data[1] = irRxChannel[channel].proto.protocol; |
- | |
| 681 | irTxMsg.Data[2] = (irRxChannel[channel].proto.data>>24)&0xff; |
- | |
| 682 | irTxMsg.Data[3] = (irRxChannel[channel].proto.data>>16)&0xff; |
- | |
| 683 | irTxMsg.Data[4] = (irRxChannel[channel].proto.data>>8)&0xff; |
- | |
| 684 | irTxMsg.Data[5] = irRxChannel[channel].proto.data&0xff; |
- | |
| 685 | - | ||
| 686 | StdCan_Put(&irTxMsg); |
- | |
| 687 | } |
683 | } |
| 688 | irRxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
- | |
| 689 | break; |
684 | break; |
| 690 | 685 | ||
| 691 | default: |
686 | default: |
| 692 | break; |
687 | break; |
| 693 | } |
688 | } |
| 694 | #endif |
689 | #endif |
| 695 | 690 | ||
| 696 | #if IR_TX_ENABLE==1 |
691 | #if IR_TX_ENABLE==1 |
| 697 | switch (irTxChannel[channel].state) |
692 | switch (irTxChannel[channel].state) |
| 698 | { |
693 | { |
| 699 | case sns_irTransceive_STATE_IDLE: |
694 | case sns_irTransceive_STATE_IDLE: |
| - | 695 | { |
|
| 700 | /* transmission is started when a command is received on can */ |
696 | /* transmission is started when a command is received on can */ |
| - | 697 | irTxChannel[channel].stopSend = FALSE; |
|
| - | 698 | irTxChannel[channel].repeatCount = 0; |
|
| - | 699 | irTxChannel[channel].proto.framecnt = 0; |
|
| - | 700 | irTxChannel[channel].sendingPronto = FALSE; |
|
| 701 | break; |
701 | break; |
| - | 702 | } |
|
| 702 | 703 | ||
| 703 | case sns_irTransceive_STATE_START_TRANSMIT: |
704 | case sns_irTransceive_STATE_START_TRANSMIT: |
| 704 | { |
705 | { |
| - | 706 | /* Expand protocol. */ |
|
| 705 | if (expandProtocol(irTxChannel[channel].txbuf, &irTxChannel[channel].txlen, &irTxChannel[channel].proto) |
707 | if (expandProtocol(irTxChannel[channel].txbuf, &irTxChannel[channel].txlen, &irTxChannel[channel].proto) != IR_OK) { |
| 706 |
|
708 | /* Failed to expand protocol -> enter idle state. */ |
| 707 | irTxChannel[channel].state = |
709 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| - | 710 | break; |
|
| 708 | } |
711 | } |
| - | 712 | ||
| - | 713 | /* Start IR transmission. */ |
|
| - | 714 | /* TODO Send respone. Function call may fail when different modulation frequencies are used simultaneously. */ |
|
| - | 715 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen, irTxChannel[channel].proto.modfreq); |
|
| - | 716 | ||
| 709 |
|
717 | /* Enter transmitting state. */ |
| 710 |
|
718 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
| 711 | } |
- | |
| 712 | break; |
719 | break; |
| 713 | } |
720 | } |
| 714 | 721 | ||
| 715 | case sns_irTransceive_STATE_START_TRANSMIT_PRONTO: |
722 | case sns_irTransceive_STATE_START_TRANSMIT_PRONTO: |
| 716 | { |
723 | { |
| 717 | /* Start IR transmission. */ |
724 | /* Start IR transmission. */ |
| 718 | IrTransceiver_Transmit |
725 | if(IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].onceSeqLen - 1, irTxChannel[channel].proto.modfreq) < 0) { |
| - | 726 | /* Send error code. */ |
|
| - | 727 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ABORTED); |
|
| - | 728 | ||
| - | 729 | /* Enter idle state. */ |
|
| - | 730 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
|
| - | 731 | break; |
|
| - | 732 | } |
|
| 719 | 733 | ||
| 720 | /* Enter transmitting state. */ |
734 | /* Enter transmitting state. */ |
| 721 | irTxChannel[channel].sendingPronto = TRUE; |
735 | irTxChannel[channel].sendingPronto = TRUE; |
| 722 | irTxChannel[channel].stopSend = FALSE; |
- | |
| 723 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
736 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
| 724 | break; |
737 | break; |
| 725 | } |
738 | } |
| 726 | 739 | ||
| 727 | case sns_irTransceive_STATE_PRONTO_REPEAT: |
740 | case sns_irTransceive_STATE_PRONTO_REPEAT: |
| 728 | { |
741 | { |
| 729 | /* Check if done. */ |
742 | /* Check if done. */ |
| 730 | if ((irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats && irTxChannel[channel].proto.repeats != 0xFF) || irTxChannel[channel].stopSend) { |
743 | if ((irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats && irTxChannel[channel].proto.repeats != 0xFF) || irTxChannel[channel].stopSend) { |
| 731 | /* Pronto transmission was stopped/completed */ |
744 | /* Pronto transmission was stopped/completed */ |
| 732 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_STOPPED); |
745 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_STOPPED); |
| 733 | irTxChannel[channel].state = |
746 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| 734 | break; |
747 | break; |
| 735 | } |
748 | } |
| 736 | 749 | ||
| 737 | if (irTxChannel[channel].repeatCount < 255) { |
750 | if (irTxChannel[channel].repeatCount < 255) { |
| 738 | irTxChannel[channel].repeatCount++; |
751 | irTxChannel[channel].repeatCount++; |
| Line 741... | Line 754... | ||
| 741 | /* Repeat sequence exists? */ |
754 | /* Repeat sequence exists? */ |
| 742 | if (irTxChannel[channel].repSeqLen != 0) { |
755 | if (irTxChannel[channel].repSeqLen != 0) { |
| 743 | /* Use repeat seq */ |
756 | /* Use repeat seq */ |
| 744 | uint16_t offset = ((uint16_t)irTxChannel[channel].onceSeqLen); |
757 | uint16_t offset = ((uint16_t)irTxChannel[channel].onceSeqLen); |
| 745 | /* Don't transmit last passive. last passive handled by timer */ |
758 | /* Don't transmit last passive. last passive handled by timer */ |
| 746 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, offset, ((uint16_t)irTxChannel[channel].repSeqLen) - 1); |
759 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, offset, ((uint16_t)irTxChannel[channel].repSeqLen) - 1, irTxChannel[channel].proto.modfreq); |
| 747 | } |
760 | } |
| 748 | else { |
761 | else { |
| 749 | /* Use once seq */ |
762 | /* Use once seq */ |
| 750 | /* Don't transmit last passive. last passive handled by timer */ |
763 | /* Don't transmit last passive. last passive handled by timer */ |
| 751 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen - 1); |
764 | IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen - 1, irTxChannel[channel].proto.modfreq); |
| 752 | } |
765 | } |
| 753 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
766 | irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING; |
| 754 | } |
767 | } |
| 755 | 768 | ||
| 756 | case sns_irTransceive_STATE_TRANSMITTING: |
769 | case sns_irTransceive_STATE_TRANSMITTING: |
| Line 823... | Line 836... | ||
| 823 | 836 | ||
| 824 | /* Transmission is stopped when such command is recevied on can */ |
837 | /* Transmission is stopped when such command is recevied on can */ |
| 825 | if (irTxChannel[channel].stopSend == TRUE && irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats) |
838 | if (irTxChannel[channel].stopSend == TRUE && irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats) |
| 826 | { |
839 | { |
| 827 | /* Non-pronto transmission was stopped/completed */ |
840 | /* Non-pronto transmission was stopped/completed */ |
| 828 | /* TODO: Not sure we want this response when sending non-pronto data, but probably doesn't hurt? /jm */ |
- | |
| 829 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_STOPPED); |
841 | pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_STOPPED); |
| 830 | 842 | ||
| 831 | irTxChannel[channel].state = |
843 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
| 832 | } |
844 | } |
| 833 | break; |
845 | break; |
| 834 | } |
846 | } |
| 835 | - | ||
| 836 | case sns_irTransceive_STATE_START_IDLE: |
- | |
| 837 | irTxChannel[channel].stopSend = FALSE; |
- | |
| 838 | irTxChannel[channel].repeatCount = 0; |
- | |
| 839 | irTxChannel[channel].proto.framecnt = 0; |
- | |
| 840 | irTxChannel[channel].sendingPronto = FALSE; |
- | |
| 841 | irTxChannel[channel].state = sns_irTransceive_STATE_IDLE; |
- | |
| 842 | break; |
- | |
| 843 | - | ||
| 844 | default: |
847 | default: |
| 845 | break; |
848 | break; |
| 846 | } |
849 | } |
| 847 | #endif |
850 | #endif |
| 848 | 851 | ||
| - | 852 | } |
|
| 849 | } |
853 | } |
| 850 | } |
- | |
| 851 | 854 | ||
| 852 | 855 | ||
| 853 | /* Handle incoming CAN data */ |
856 | /* Handle incoming CAN data */ |
| 854 | void sns_irTransceive_HandleMessage(StdCan_Msg_t *rxMsg) |
857 | void sns_irTransceive_HandleMessage(StdCan_Msg_t *rxMsg) |
| 855 | { |
858 | { |
| 856 | /* Sanity check. */ |
859 | /* Sanity check. */ |
| 857 | if (StdCan_Ret_class(rxMsg->Header) != CAN_MODULE_CLASS_SNS || |
860 | if (StdCan_Ret_class(rxMsg->Header) != CAN_MODULE_CLASS_SNS || |
| 858 | StdCan_Ret_direction(rxMsg->Header) != DIRECTIONFLAG_TO_OWNER || |
861 | StdCan_Ret_direction(rxMsg->Header) != DIRECTIONFLAG_TO_OWNER || |
| 859 | rxMsg->Header.ModuleType != CAN_MODULE_TYPE_SNS_IRTRANSCEIVE || |
862 | rxMsg->Header.ModuleType != CAN_MODULE_TYPE_SNS_IRTRANSCEIVE || |
| 860 | rxMsg->Header.ModuleId != sns_irTransceive_ID) return; |
863 | rxMsg->Header.ModuleId != sns_irTransceive_ID) return; |
| 861 | 864 | ||
| 862 | switch (rxMsg->Header.Command) |
865 | switch (rxMsg->Header.Command) |
| 863 | { |
866 | { |
| 864 | #if IR_TX_ENABLE==1 |
867 | #if IR_TX_ENABLE==1 |
| 865 | case CAN_MODULE_CMD_PHYSICAL_IR: |
868 | case CAN_MODULE_CMD_PHYSICAL_IR: |
| 866 | { |
869 | { |
| 867 | /* Get IR channel. */ |
870 | /* Get IR channel. */ |
| 868 | uint8_t channel = rxMsg->Data[0] >> 4; |
871 | uint8_t channel = rxMsg->Data[0] >> 4; |
| - | 872 | ||
| - | 873 | /* Get button status. */ |
|
| - | 874 | uint8_t buttonStatus = rxMsg->Data[0] & 0x0F; |
|
| 869 | 875 | ||
| 870 | /* Sanity check. */ |
876 | /* Sanity check. */ |
| 871 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) { |
877 | if (channel >= IR_SUPPORTED_NUM_CHANNELS) { |
| 872 | /* Invalid channel */ |
878 | /* Invalid channel */ |
| - | 879 | break; |
|
| - | 880 | } |
|
| - | 881 | ||
| - | 882 | /* Check if channel is busy sending Pronto */ |
|
| - | 883 | if (irTxChannel[channel].sendingPronto) { |
|
| - | 884 | /* Channel busy */ |
|
| 873 | break; |
885 | break; |
| 874 | } |
886 | } |
| 875 | 887 | ||
| 876 | if ( |
888 | if (buttonStatus == CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_PRESSED) |
| 877 | { |
889 | { |
| 878 | if (irTxChannel[channel].state == sns_irTransceive_STATE_IDLE) |
890 | if (irTxChannel[channel].state == sns_irTransceive_STATE_IDLE) |
| 879 | { |
891 | { |
| 880 | irTxChannel[channel].proto.protocol = rxMsg->Data[1]; |
892 | irTxChannel[channel].proto.protocol = rxMsg->Data[1]; |
| 881 | - | ||
| 882 | irTxChannel[channel].proto.data = rxMsg->Data[2]; |
893 | irTxChannel[channel].proto.data = rxMsg->Data[2]; |
| 883 | irTxChannel[channel].proto.data = irTxChannel[channel].proto.data<<8; |
894 | irTxChannel[channel].proto.data = irTxChannel[channel].proto.data<<8; |
| 884 | irTxChannel[channel].proto.data |= rxMsg->Data[3]; |
895 | irTxChannel[channel].proto.data |= rxMsg->Data[3]; |
| 885 | irTxChannel[channel].proto.data = irTxChannel[channel].proto.data<<8; |
896 | irTxChannel[channel].proto.data = irTxChannel[channel].proto.data<<8; |
| 886 | irTxChannel[channel].proto.data |= rxMsg->Data[4]; |
897 | irTxChannel[channel].proto.data |= rxMsg->Data[4]; |
| Line 888... | Line 899... | ||
| 888 | irTxChannel[channel].proto.data |= rxMsg->Data[5]; |
899 | irTxChannel[channel].proto.data |= rxMsg->Data[5]; |
| 889 | 900 | ||
| 890 | irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT; |
901 | irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT; |
| 891 | } |
902 | } |
| 892 | } |
903 | } |
| 893 | else if ( |
904 | else if (buttonStatus == CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_RELEASED) |
| 894 | { |
905 | { |
| 895 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) |
906 | if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) |
| 896 | { |
907 | { |
| 897 | irTxChannel[channel].stopSend = TRUE; |
908 | irTxChannel[channel].stopSend = TRUE; |
| 898 | } |
909 | } |
| Line 1046... | Line 1057... | ||
| 1046 | } |
1057 | } |
| 1047 | 1058 | ||
| 1048 | if ((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1) != (irTxChannel[activeChannel].expectedSeqNr % 16)) { |
1059 | if ((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1) != (irTxChannel[activeChannel].expectedSeqNr % 16)) { |
| 1049 | /* Unexpected CAN msg, out of order */ |
1060 | /* Unexpected CAN msg, out of order */ |
| 1050 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1061 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1051 | irTxChannel[activeChannel].state = |
1062 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE; |
| 1052 | break; |
1063 | break; |
| 1053 | } |
1064 | } |
| 1054 | 1065 | ||
| 1055 | /* Decode pronto data */ |
1066 | /* Decode pronto data */ |
| 1056 | for (uint8_t i = 0; i < rxMsg->Length; i++) { |
1067 | for (uint8_t i = 0; i < rxMsg->Length; i++) { |
| 1057 | if (decodeProntoData(activeChannel, rxMsg->Data[i]) != 1) { |
1068 | if (decodeProntoData(activeChannel, rxMsg->Data[i]) != 1) { |
| 1058 | /* Decode error */ |
1069 | /* Decode error */ |
| 1059 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1070 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1060 | irTxChannel[activeChannel].state = |
1071 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE; |
| 1061 | return; |
1072 | return; |
| 1062 | } |
1073 | } |
| 1063 | } |
1074 | } |
| 1064 | 1075 | ||
| 1065 | irTxChannel[activeChannel].expectedSeqNr++; |
1076 | irTxChannel[activeChannel].expectedSeqNr++; |
| 1066 | 1077 | ||
| 1067 | /* We're still waiting for more pronto data, or for pronto end */ |
1078 | /* We're still waiting for more pronto data, or for pronto end */ |
| 1068 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_WAITING); |
1079 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_WAITING); |
| 1069 | break; |
1080 | break; |
| 1070 | } |
1081 | } |
| Line 1085... | Line 1096... | ||
| 1085 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND15: /* Fall through */ |
1096 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND15: /* Fall through */ |
| 1086 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND16: /* Fall through */ |
1097 | case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND16: /* Fall through */ |
| 1087 | { |
1098 | { |
| 1088 | if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) { |
1099 | if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) { |
| 1089 | /* Invalid state. CAN msg probably out of order */ |
1100 | /* Invalid state. CAN msg probably out of order */ |
| 1090 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1101 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1091 | break; |
1102 | break; |
| 1092 | } |
1103 | } |
| 1093 | 1104 | ||
| 1094 | if (((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1) % 16) != (irTxChannel[activeChannel].expectedSeqNr % 16)) { |
1105 | if (((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1) % 16) != (irTxChannel[activeChannel].expectedSeqNr % 16)) { |
| 1095 | /* Unexpected CAN msg, out of order */ |
1106 | /* Unexpected CAN msg, out of order */ |
| 1096 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1107 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1097 | irTxChannel[activeChannel].state = |
1108 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE; |
| 1098 | break; |
1109 | break; |
| 1099 | } |
1110 | } |
| 1100 | 1111 | ||
| 1101 | /* Decode remaining pronto data (if any). -1 because last byte is repeat count */ |
1112 | /* Decode remaining pronto data (if any). -1 because last byte is repeat count */ |
| 1102 | for (uint16_t i = 0; i < rxMsg->Length - 1; i++) { |
1113 | for (uint16_t i = 0; i < rxMsg->Length - 1; i++) { |
| 1103 | if (decodeProntoData(activeChannel, rxMsg->Data[i]) < 0) { |
1114 | if (decodeProntoData(activeChannel, rxMsg->Data[i]) < 0) { |
| 1104 | /* Decode error */ |
1115 | /* Decode error */ |
| 1105 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
1116 | pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR); |
| 1106 | irTxChannel[activeChannel].state = |
1117 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE; |
| 1107 | return; |
1118 | return; |
| 1108 | } |
1119 | } |
| 1109 | } |
1120 | } |
| 1110 | 1121 | ||
| 1111 | /* Sanity check */ |
1122 | /* Sanity check */ |
| Line 1119... | Line 1130... | ||
| 1119 | /* Last byte determines nr of repeats. 0xFF means INF, 0 means no repeats */ |
1130 | /* Last byte determines nr of repeats. 0xFF means INF, 0 means no repeats */ |
| 1120 | irTxChannel[activeChannel].proto.repeats = rxMsg->Data[rxMsg->Length - 1]; |
1131 | irTxChannel[activeChannel].proto.repeats = rxMsg->Data[rxMsg->Length - 1]; |
| 1121 | 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 */ |
1132 | 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 */ |
| 1122 | 1133 | ||
| 1123 | /* Convert pronto data to µs */ |
1134 | /* Convert pronto data to µs */ |
| 1124 |
|
1135 | uint32_t nsPerTick = 1000000UL / ((uint32_t)irTxChannel[activeChannel].proto.modfreq); |
| 1125 | for (uint16_t i = 0; i < irTxChannel[activeChannel].txlen; i++) { |
1136 | for (uint16_t i = 0; i < irTxChannel[activeChannel].txlen; i++) { |
| 1126 | uint32_t |
1137 | uint32_t us = (((uint32_t)irTxChannel[activeChannel].txbuf[i]) * nsPerTick) / 1000UL; |
| 1127 | if ( |
1138 | if (us > 0xFFFFUL) { |
| 1128 |
|
1139 | us = 0xFFFFUL; |
| 1129 | } |
1140 | } |
| 1130 | irTxChannel[activeChannel].txbuf[i] = (uint16_t) |
1141 | irTxChannel[activeChannel].txbuf[i] = (uint16_t)us; |
| 1131 | } |
1142 | } |
| 1132 | 1143 | ||
| 1133 | /* Send IR data */ |
1144 | /* Send IR data */ |
| 1134 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_TRANSMIT_PRONTO; |
1145 | irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_TRANSMIT_PRONTO; |
| 1135 | 1146 | ||