Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed

  1. #include <inttypes.h>
  2. #include <avr/interrupt.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <config.h> // All configuration parameters
  6. #include <bios.h>   // BIOS interface declarations, including CAN structure and ID defines.
  7. #include <drivers/timer/timebase.h>
  8. #include <drivers/ir/transceiver/irtransceiver.h>
  9. #include <drivers/ir/protocols.h>
  10.  
  11. //Transmitter
  12. #define APP_TYPE_TRANSMIT    CAN_APPTYPES_IRTRANSMITTER
  13. #define APP_VERSION_TRANSMIT 0x0002
  14.  
  15. #define STATE_IDLE_TRANSMIT             0
  16. #define STATE_START_TRANSMIT    1
  17. #define STATE_TRANSMITTING      2
  18. #define STATE_START_PAUSE_TRANSMIT      3
  19. #define STATE_PAUSING_TRANSMIT          4
  20. #define STATE_STOP_TRANSMIT             5
  21.  
  22.  
  23. //Receiver
  24. #define APP_TYPE_RECEIVE    CAN_APPTYPES_IRRECEIVER
  25. #define APP_VERSION_RECEIVE 0x0004
  26.  
  27. #define STATE_IDLE_RECEIVE          0
  28. #define STATE_IR_REPEAT_RECEIVE     1
  29. #define STATE_START_RECEIVE 2
  30. #define STATE_RECEIVING     3
  31. #define STATE_START_PAUSE_RECEIVE   4
  32. #define STATE_PAUSING_RECEIVE       5
  33. #define STATE_START_IDLE_RECEIVE    6
  34.  
  35. #define IR_ID_DATA  0
  36. #define IR_ID_RAW   1
  37. #define IR_ID_DEBUG 10
  38.  
  39.  
  40. // A simple message "queue", with space for one message only.
  41. // These are declared volatile to tell the compiler not to optimize away accesses.
  42. volatile Can_Message_t rxMsg; // Message storage
  43. volatile uint8_t rxMsgFull;   // Synchronization flag
  44.  
  45. // CAN message reception callback.
  46. // This function runs with interrupts disabled, keep it as short as possible.
  47. void can_receive(Can_Message_t *msg) {
  48.     if (!rxMsgFull) {
  49.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  50.         rxMsgFull = 1;
  51.     }
  52. }
  53.  
  54. #if (SEND_DEBUG)
  55. void send_debug(uint16_t *buffer, uint8_t len) {
  56.     Can_Message_t txMsg;
  57.    
  58.     /* the protocol is unknown so the raw ir-data is sent, makes it easier to develop a new protocol */
  59.     txMsg.DataLength = 8;
  60.     txMsg.Id = ((CAN_SNS << CAN_SHIFT_CLASS) | (SNS_TYPE_IR << CAN_SHIFT_SNS_TYPE) | (IR_ID_RAW<<CAN_SHIFT_SNS_ID) | (NODE_ID << CAN_SHIFT_SNS_SID));
  61.     for (uint8_t i = 0; i < len>>2; i++) {
  62.         uint8_t index = i<<2;
  63.         txMsg.Data.bytes[0] = (buffer[index]>>8)&0xff;
  64.         txMsg.Data.bytes[1] = (buffer[index]>>0)&0xff;
  65.         txMsg.Data.bytes[2] = (buffer[index+1]>>8)&0xff;
  66.         txMsg.Data.bytes[3] = (buffer[index+1]>>0)&0xff;
  67.         txMsg.Data.bytes[4] = (buffer[index+2]>>8)&0xff;
  68.         txMsg.Data.bytes[5] = (buffer[index+2]>>0)&0xff;
  69.         txMsg.Data.bytes[6] = (buffer[index+3]>>8)&0xff;
  70.         txMsg.Data.bytes[7] = (buffer[index+3]>>0)&0xff;
  71.        
  72.         /* buffers will be filled when sending more than 2-3 messages, so retry until sent */
  73.         //while (BIOS_CanSend(&txMsg) != CAN_OK) {}
  74.         BIOS_CanSend(&txMsg);
  75.        
  76.         uint16_t dummycnt = 1;
  77.         while (dummycnt > 0) {
  78.             dummycnt++;
  79.             asm("nop");
  80.             asm("nop");
  81.         }
  82.     }
  83.    
  84.     uint8_t lastpacketcnt = len&0x03;
  85.     if (lastpacketcnt > 0) {
  86.         txMsg.DataLength = lastpacketcnt<<1;
  87.         for (uint8_t i = 0; i < lastpacketcnt; i++) {
  88.             txMsg.Data.bytes[i<<1] = (buffer[(len&0xfc)|i]>>8)&0xff;
  89.             txMsg.Data.bytes[(i<<1)+1] = (buffer[(len&0xfc)|i]>>0)&0xff;
  90.         }
  91.         /* buffers will be filled when sending more than 2-3 messages, so retry until sent */
  92.         //while (BIOS_CanSend(&txMsg) != CAN_OK) {}
  93.         BIOS_CanSend(&txMsg);
  94.     }
  95.  
  96. }
  97. #endif
  98.  
  99. int main(void)
  100. {
  101.     // Enable interrupts as early as possible
  102.     sei();
  103.    
  104.     Timebase_Init();
  105.     IrTransceiver_Init();
  106.    
  107.     Can_Message_t txMsg_receive;
  108.     txMsg_receive.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) |
  109.         (NODE_ID << CAN_SHIFT_NMT_SID);
  110.     txMsg_receive.DataLength = 4;
  111.     txMsg_receive.RemoteFlag = 0;
  112.     txMsg_receive.ExtendedFlag = 1;
  113.     txMsg_receive.Data.words[0] = APP_TYPE_RECEIVE;
  114.     txMsg_receive.Data.words[1] = APP_VERSION_RECEIVE;
  115.  
  116.     // We will pretend to be two applications
  117.     Can_Message_t txMsg_transmit;
  118.     txMsg_transmit.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) |
  119.         (NODE_ID << CAN_SHIFT_NMT_SID);
  120.     txMsg_transmit.DataLength = 4;
  121.     txMsg_transmit.RemoteFlag = 0;
  122.     txMsg_transmit.ExtendedFlag = 1;
  123.     txMsg_transmit.Data.words[0] = APP_TYPE_TRANSMIT;
  124.     txMsg_transmit.Data.words[1] = APP_VERSION_TRANSMIT;
  125.    
  126.     // Set up callback for CAN reception, this is optional if only sending is required.
  127.     BIOS_CanCallback = &can_receive;
  128.     // Send CAN_NMT_APP_START for the receiver part, this is first since
  129.     // we don't send commands to it
  130.     BIOS_CanSend(&txMsg_receive);
  131.    
  132.     // Send CAN_NMT_APP_START for the transmitter part aswell
  133.     BIOS_CanSend(&txMsg_transmit);
  134.    
  135.     uint32_t time = Timebase_CurrentTime();
  136.     uint32_t timePauseStarted_transmit = 0;
  137.     uint32_t timePauseStarted_receive = 0;
  138.    
  139.     // Transmitter
  140.     uint8_t state_transmit=STATE_IDLE_TRANSMIT;
  141.     uint8_t repeatcnt_transmit=0;
  142.     uint8_t stop_transmit=0;
  143.  
  144.     Ir_Protocol_Data_t proto_transmit;
  145.     proto_transmit.timeout=0;
  146.     proto_transmit.data=0;
  147.     proto_transmit.repeats=0;
  148.     proto_transmit.protocol=0;
  149.     proto_transmit.framecnt = 0;
  150.    
  151.     uint8_t len_transmit=0;
  152.    
  153.     uint16_t txbuffer[MAX_NR_TIMES];
  154.    
  155.     //Receiver
  156.     uint8_t state_receive = STATE_IDLE_RECEIVE;
  157.    
  158.     Ir_Protocol_Data_t proto_receive;
  159.     proto_receive.timeout=0;
  160.     proto_receive.data=0;
  161.     proto_receive.repeats=0;
  162.     proto_receive.protocol=0;
  163.    
  164.     uint8_t len_receive=0;
  165.  
  166.     uint16_t rxbuffer[MAX_NR_TIMES];
  167.    
  168.     while (1) {
  169.  
  170.     //Transmitter
  171.         if (state_transmit == STATE_IDLE_TRANSMIT) {
  172.         }
  173.         else if (state_transmit == STATE_START_TRANSMIT) {
  174.             if (expandProtocol(txbuffer, &len_transmit, &proto_transmit) == IR_OK) {
  175.                 if (IrTransceiver_Transmit(txbuffer,
  176.                     len_transmit, proto_transmit.modfreq) == IR_OK) {
  177.                     state_transmit = STATE_TRANSMITTING;
  178.                 } else {
  179.                     state_transmit = STATE_IDLE_TRANSMIT;
  180.                 }
  181.             } else {
  182.                 state_transmit = STATE_IDLE_TRANSMIT;
  183.             }
  184.         } else if (state_transmit == STATE_TRANSMITTING) {
  185.             //polla om den är klar, om klar gå till STATE_START_PAUSE
  186.             if (IrTransceiver_Transmit_Poll() != IR_NOT_FINISHED) {
  187.                 state_transmit = STATE_START_PAUSE_TRANSMIT;
  188.             }
  189.         } else if (state_transmit == STATE_START_PAUSE_TRANSMIT) {
  190.             if (repeatcnt_transmit<proto_transmit.repeats) {
  191.                 repeatcnt_transmit++;
  192.             }
  193.             timePauseStarted_transmit = Timebase_CurrentTime();
  194.             if (proto_transmit.framecnt != 255) {
  195.                 proto_transmit.framecnt++;
  196.             }
  197.             state_transmit = STATE_PAUSING_TRANSMIT;
  198.         } else if (state_transmit == STATE_PAUSING_TRANSMIT) {
  199.             //när timeout har gått (timebase) så gå till STATE_START_TRANSMIT
  200.             time = Timebase_CurrentTime();
  201.             if (time - timePauseStarted_transmit >= proto_transmit.timeout) {
  202.                 state_transmit = STATE_START_TRANSMIT;
  203.             }
  204.             if (stop_transmit == 1 && repeatcnt_transmit >= proto_transmit.repeats) {
  205.                 state_transmit = STATE_STOP_TRANSMIT;
  206.             }
  207.         } else if (state_transmit == STATE_STOP_TRANSMIT) {
  208.             stop_transmit = 0;
  209.             proto_transmit.timeout = 0;
  210.             proto_transmit.framecnt = 0;
  211.             repeatcnt_transmit = 0;
  212.             state_transmit = STATE_IDLE_TRANSMIT;
  213.         }
  214.        
  215.         if (rxMsgFull) {
  216.             if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT) {
  217.                 uint16_t acttype =(uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
  218.                 uint8_t actid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
  219.                
  220.                 if (rxMsg.DataLength==6) {
  221.                     if (acttype == ACT_TYPE_IR) {
  222.                         if (state_transmit == STATE_IDLE_TRANSMIT && rxMsg.Data.bytes[0] == IR_BUTTON_DOWN) {
  223.                             proto_transmit.protocol = rxMsg.Data.bytes[1];
  224.                             proto_transmit.data = rxMsg.Data.bytes[5];
  225.                             proto_transmit.data |= (rxMsg.Data.bytes[4]<<8);
  226.                             proto_transmit.data |= ((uint32_t)rxMsg.Data.bytes[3]<<16);
  227.                             proto_transmit.data |= ((uint32_t)rxMsg.Data.bytes[2]<<24);
  228.  
  229.                             state_transmit = STATE_START_TRANSMIT;
  230.                         } else if (state_transmit != STATE_IDLE_TRANSMIT && rxMsg.Data.bytes[0] == IR_BUTTON_UP) {
  231.                             stop_transmit = 1;
  232.                         }
  233.                     }
  234.                 }
  235.             }
  236.        
  237.             // Flush the received message
  238.             rxMsgFull = 0; //  
  239.         }
  240.        
  241.         //Receiver         
  242.         if (state_receive == STATE_IDLE_RECEIVE) {
  243.             IrTransceiver_Receive_Start(rxbuffer);
  244.             state_receive = STATE_START_RECEIVE;
  245.         } else if (state_receive == STATE_START_RECEIVE) {
  246.             state_receive = STATE_RECEIVING;
  247.         } else if (state_receive == STATE_RECEIVING) {
  248.             uint8_t res = IrTransceiver_Receive_Poll(&len_receive);
  249.             if ((res == IR_OK) && (len_receive > 0)) {
  250.                 //låt protocols parsa och skicka på can
  251.                 uint8_t res2 = parseProtocol(rxbuffer, len_receive, &proto_receive);
  252.                 if (res2 == IR_OK && proto_receive.protocol != IR_PROTO_UNKNOWN) {
  253.                     txMsg_receive.Data.bytes[0] = IR_BUTTON_DOWN;
  254.                     txMsg_receive.Data.bytes[1] = proto_receive.protocol;
  255.                     txMsg_receive.Data.bytes[2] = (proto_receive.data>>24)&0xff;
  256.                     txMsg_receive.Data.bytes[3] = (proto_receive.data>>16)&0xff;
  257.                     txMsg_receive.Data.bytes[4] = (proto_receive.data>>8)&0xff;
  258.                     txMsg_receive.Data.bytes[5] = proto_receive.data&0xff;
  259.                     txMsg_receive.Id = ((CAN_SNS << CAN_SHIFT_CLASS) | (SNS_TYPE_IR << CAN_SHIFT_SNS_TYPE) | (IR_ID_DATA<<CAN_SHIFT_SNS_ID) | (NODE_ID << CAN_SHIFT_SNS_SID));
  260.                     txMsg_receive.DataLength = 6;
  261.                     BIOS_CanSend(&txMsg_receive);
  262.                 } else if (proto_receive.protocol == IR_PROTO_UNKNOWN) {
  263. #if (SEND_DEBUG)
  264.                     send_debug(rxbuffer, len_receiver);
  265.                     proto_receiver.timeout=300;
  266. #endif
  267.                 }
  268.                 state_receive = STATE_START_PAUSE_RECEIVE;
  269.             }
  270.         } else if (state_receive == STATE_START_PAUSE_RECEIVE) {
  271.             IrTransceiver_Receive_Start(rxbuffer);
  272.             timePauseStarted_receive = Timebase_CurrentTime();
  273.             state_receive = STATE_PAUSING_RECEIVE;
  274.         } else if (state_receive == STATE_PAUSING_RECEIVE) {
  275.             //resetta timebase-var om ir finns
  276.             uint8_t res = IrTransceiver_Receive_Poll(&len_receive);
  277.             if (res == IR_NOT_FINISHED || res == IR_OK) {
  278.                 timePauseStarted_receive = Timebase_CurrentTime();
  279.             }
  280.             if (res == IR_OK) {
  281.                 /* start a new reception */
  282.                 IrTransceiver_Receive_Start(rxbuffer);
  283.             }
  284.            
  285.             time = Timebase_CurrentTime();
  286.             if (time - timePauseStarted_receive >= proto_receive.timeout) {
  287.                 state_receive = STATE_START_IDLE_RECEIVE;
  288.             }
  289.         } else if (state_receive == STATE_START_IDLE_RECEIVE) {
  290.             if (proto_receive.protocol != IR_PROTO_UNKNOWN) {
  291.                 //skicka på can
  292.                 txMsg_receive.Data.bytes[0] = IR_BUTTON_UP;
  293.                 BIOS_CanSend(&txMsg_receive);
  294.             }
  295.             state_receive = STATE_IDLE_RECEIVE;
  296.         }
  297.        
  298.     //  if (rxMsgFull) {
  299.             /* No message reception functionality implemented */
  300.             /* Flush the received message */
  301.     //      rxMsgFull = 0; //  
  302.     //  }
  303.     }
  304.    
  305.     return 0;
  306. }
  307.  
  308.