Subversion Repositories HomeAutomation

Rev

Rev 614 | 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.  
  8. #include <drivers/timer/timebase.h>
  9. #include <drivers/ir/transceiver/irtransceiver.h>
  10. #include <drivers/ir/protocols.h>
  11.  
  12. #define APP_TYPE    CAN_APPTYPES_IRRECEIVER
  13. #define APP_VERSION 0x0004
  14.  
  15. #define STATE_IDLE          0
  16. #define STATE_IR_REPEAT     1
  17. #define STATE_START_RECEIVE 2
  18. #define STATE_RECEIVING     3
  19. #define STATE_START_PAUSE   4
  20. #define STATE_PAUSING       5
  21. #define STATE_START_IDLE    6
  22.  
  23. #define IR_ID_DATA  0
  24. #define IR_ID_RAW   1
  25. #define IR_ID_DEBUG 10
  26.  
  27. // A simple message "queue", with space for one message only.
  28. // These are declared volatile to tell the compiler not to optimize away accesses.
  29. volatile Can_Message_t rxMsg; // Message storage
  30. volatile uint8_t rxMsgFull;   // Synchronization flag
  31.  
  32. // CAN message reception callback.
  33. // This function runs with interrupts disabled, keep it as short as possible.
  34. void can_receive(Can_Message_t *msg) {
  35.     if (!rxMsgFull) {
  36.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  37.         rxMsgFull = 1;
  38.     }
  39. }
  40.  
  41. #if (SEND_DEBUG)
  42. void send_debug(uint16_t *buffer, uint8_t len) {
  43.     Can_Message_t txMsg;
  44.    
  45.     /* the protocol is unknown so the raw ir-data is sent, makes it easier to develop a new protocol */
  46.     txMsg.DataLength = 8;
  47.     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));
  48.     for (uint8_t i = 0; i < len>>2; i++) {
  49.         uint8_t index = i<<2;
  50.         txMsg.Data.bytes[0] = (buffer[index]>>8)&0xff;
  51.         txMsg.Data.bytes[1] = (buffer[index]>>0)&0xff;
  52.         txMsg.Data.bytes[2] = (buffer[index+1]>>8)&0xff;
  53.         txMsg.Data.bytes[3] = (buffer[index+1]>>0)&0xff;
  54.         txMsg.Data.bytes[4] = (buffer[index+2]>>8)&0xff;
  55.         txMsg.Data.bytes[5] = (buffer[index+2]>>0)&0xff;
  56.         txMsg.Data.bytes[6] = (buffer[index+3]>>8)&0xff;
  57.         txMsg.Data.bytes[7] = (buffer[index+3]>>0)&0xff;
  58.        
  59.         /* buffers will be filled when sending more than 2-3 messages, so retry until sent */
  60.         //while (BIOS_CanSend(&txMsg) != CAN_OK) {}
  61.         BIOS_CanSend(&txMsg);
  62.        
  63.         uint16_t dummycnt = 1;
  64.         while (dummycnt > 0) {
  65.             dummycnt++;
  66.             asm("nop");
  67.             asm("nop");
  68.         }
  69.     }
  70.    
  71.     uint8_t lastpacketcnt = len&0x03;
  72.     if (lastpacketcnt > 0) {
  73.         txMsg.DataLength = lastpacketcnt<<1;
  74.         for (uint8_t i = 0; i < lastpacketcnt; i++) {
  75.             txMsg.Data.bytes[i<<1] = (buffer[(len&0xfc)|i]>>8)&0xff;
  76.             txMsg.Data.bytes[(i<<1)+1] = (buffer[(len&0xfc)|i]>>0)&0xff;
  77.         }
  78.         /* buffers will be filled when sending more than 2-3 messages, so retry until sent */
  79.         //while (BIOS_CanSend(&txMsg) != CAN_OK) {}
  80.         BIOS_CanSend(&txMsg);
  81.     }
  82.  
  83. }
  84. #endif
  85.  
  86. int main(void)
  87. {
  88.     // Enable interrupts as early as possible
  89.     sei();
  90.    
  91.     Timebase_Init();
  92.     IrTransceiver_Init();
  93.    
  94.     Can_Message_t txMsg;
  95.     txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
  96.     txMsg.DataLength = 4;
  97.     txMsg.RemoteFlag = 0;
  98.     txMsg.ExtendedFlag = 1;
  99.     txMsg.Data.words[0] = APP_TYPE;
  100.     txMsg.Data.words[1] = APP_VERSION;
  101.    
  102.     // Set up callback for CAN reception, this is optional if only sending is required.
  103.     BIOS_CanCallback = &can_receive;
  104.     // Send CAN_NMT_APP_START
  105.     BIOS_CanSend(&txMsg);
  106.    
  107.     uint32_t time = Timebase_CurrentTime();
  108.     uint32_t timePauseStarted = 0;
  109.    
  110.     uint8_t state = STATE_IDLE;
  111.    
  112.     Ir_Protocol_Data_t proto;
  113.     proto.timeout=0; proto.data=0; proto.repeats=0; proto.protocol=0;
  114.     uint8_t len=0;
  115.     uint16_t rxbuffer[MAX_NR_TIMES];
  116.    
  117.     while (1) {
  118.         if (state == STATE_IDLE) {
  119.             IrTransceiver_Receive_Start(rxbuffer);
  120.             state = STATE_START_RECEIVE;
  121.         } else if (state == STATE_START_RECEIVE) {
  122.             state = STATE_RECEIVING;
  123.         } else if (state == STATE_RECEIVING) {
  124.             uint8_t res = IrTransceiver_Receive_Poll(&len);
  125.             if ((res == IR_OK) && (len > 0)) {
  126.                 //låt protocols parsa och skicka på can
  127.                 uint8_t res2 = parseProtocol(rxbuffer, len, &proto);
  128.                 if (res2 == IR_OK && proto.protocol != IR_PROTO_UNKNOWN) {
  129.                     txMsg.Data.bytes[0] = IR_BUTTON_DOWN;
  130.                     txMsg.Data.bytes[1] = proto.protocol;
  131.                     txMsg.Data.bytes[2] = (proto.data>>24)&0xff;
  132.                     txMsg.Data.bytes[3] = (proto.data>>16)&0xff;
  133.                     txMsg.Data.bytes[4] = (proto.data>>8)&0xff;
  134.                     txMsg.Data.bytes[5] = proto.data&0xff;
  135.                     txMsg.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));
  136.                     txMsg.DataLength = 6;
  137.                     BIOS_CanSend(&txMsg);
  138.                 } else if (proto.protocol == IR_PROTO_UNKNOWN) {
  139. #if (SEND_DEBUG)
  140.                         send_debug(rxbuffer, len);
  141.                         proto.timeout=300;
  142. #endif
  143.                    
  144.                 }
  145.                
  146.                 state = STATE_START_PAUSE;
  147.             }
  148.         } else if (state == STATE_START_PAUSE) {
  149.             IrTransceiver_Receive_Start(rxbuffer);
  150.             timePauseStarted = Timebase_CurrentTime();
  151.             state = STATE_PAUSING;
  152.         } else if (state == STATE_PAUSING) {
  153.             //resetta timebase-var om ir finns
  154.             uint8_t res = IrTransceiver_Receive_Poll(&len);
  155.             if (res == IR_NOT_FINISHED || res == IR_OK) {
  156.                 timePauseStarted = Timebase_CurrentTime();
  157.             }
  158.             if (res == IR_OK) {
  159.                 /* start a new reception */
  160.                 IrTransceiver_Receive_Start(rxbuffer);
  161.             }
  162.            
  163.             time = Timebase_CurrentTime();
  164.             if (time - timePauseStarted >= proto.timeout) {
  165.                 state = STATE_START_IDLE;
  166.             }
  167.         } else if (state == STATE_START_IDLE) {
  168.             if (proto.protocol != IR_PROTO_UNKNOWN) {
  169.                 //skicka på can
  170.                 txMsg.Data.bytes[0] = IR_BUTTON_UP;
  171.                 BIOS_CanSend(&txMsg);
  172.             }
  173.             state = STATE_IDLE;
  174.         }
  175.        
  176.        
  177.        
  178.         if (rxMsgFull) {
  179.             /* No message reception functionality implemented */
  180.             /* Flush the received message */
  181.             rxMsgFull = 0; //  
  182.         }
  183.     }
  184.     return 0;
  185. }
  186.