Subversion Repositories HomeAutomation

Rev

Rev 603 | Rev 614 | Go to most recent revision | Blame | Compare with Previous | 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.  
  22. #define IR_ID_DATA  0
  23. #define IR_ID_RAW   1
  24. #define IR_ID_DEBUG 10
  25.  
  26. // A simple message "queue", with space for one message only.
  27. // These are declared volatile to tell the compiler not to optimize away accesses.
  28. volatile Can_Message_t rxMsg; // Message storage
  29. volatile uint8_t rxMsgFull;   // Synchronization flag
  30.  
  31. // CAN message reception callback.
  32. // This function runs with interrupts disabled, keep it as short as possible.
  33. void can_receive(Can_Message_t *msg) {
  34.     if (!rxMsgFull) {
  35.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  36.         rxMsgFull = 1;
  37.     }
  38. }
  39.  
  40. int main(void)
  41. {
  42.     // Enable interrupts as early as possible
  43.     sei();
  44.    
  45.     Timebase_Init();
  46.     IrTransceiver_Init();
  47.    
  48.     Can_Message_t txMsg;
  49.     txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
  50.     txMsg.DataLength = 4;
  51.     txMsg.RemoteFlag = 0;
  52.     txMsg.ExtendedFlag = 1;
  53.     txMsg.Data.words[0] = APP_TYPE;
  54.     txMsg.Data.words[1] = APP_VERSION;
  55.    
  56.     // Set up callback for CAN reception, this is optional if only sending is required.
  57.     BIOS_CanCallback = &can_receive;
  58.     // Send CAN_NMT_APP_START
  59.     BIOS_CanSend(&txMsg);
  60.    
  61.     uint32_t time = Timebase_CurrentTime();
  62.     uint32_t timePauseStarted = 0;
  63.    
  64.     uint8_t state = STATE_IDLE;
  65.    
  66.     Ir_Protocol_Data_t proto;
  67.     proto.timeout=0; proto.data=0; proto.repeats=0; proto.protocol=0;
  68.     uint8_t len=0;
  69.     uint16_t rxbuffer[MAX_NR_TIMES];
  70.    
  71.     while (1) {
  72.         if (state == STATE_IDLE) {
  73.             IrTransceiver_Receive_Start(rxbuffer);
  74.             state = STATE_START_RECEIVE;
  75.         } else if (state == STATE_START_RECEIVE) {
  76.             state = STATE_RECEIVING;
  77.         } else if (state == STATE_RECEIVING) {
  78.             len = IrTransceiver_Receive_Poll();
  79.             if (len > 0) {
  80.                 //låt protocols parsa och skicka på can
  81.                 if (parseProtocol(rxbuffer, len, &proto) == IR_OK) {
  82.                     if (proto.protocol != IR_PROTO_UNKNOWN) {
  83.                         txMsg.Data.bytes[0] = IR_BUTTON_DOWN;
  84.                         txMsg.Data.bytes[1] = proto.protocol;
  85.                         txMsg.Data.bytes[2] = (proto.data>>24)&0xff;
  86.                         txMsg.Data.bytes[3] = (proto.data>>16)&0xff;
  87.                         txMsg.Data.bytes[4] = (proto.data>>8)&0xff;
  88.                         txMsg.Data.bytes[5] = proto.data&0xff;
  89.                         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));
  90.                         txMsg.DataLength = 6;
  91.                         BIOS_CanSend(&txMsg);
  92.                     }
  93.                 }
  94.                
  95.                 state = STATE_START_PAUSE;
  96.             }
  97.         } else if (state == STATE_START_PAUSE) {
  98.             timePauseStarted = Timebase_CurrentTime();
  99.             state = STATE_PAUSING;
  100.         } else if (state == STATE_PAUSING) {
  101.             //resetta timebase-var om ir finns, detta bör göras snyggare
  102.             for (uint8_t i=0; i<10; i++) {
  103.                 if (IrTransceiver_Receive_Pause_Poll() == 0) {
  104.                     break;
  105.                 }
  106.                 if (i==9) {
  107.                     timePauseStarted = Timebase_CurrentTime();
  108.                 }
  109.             }
  110.            
  111.             time = Timebase_CurrentTime();
  112.             if (time - timePauseStarted >= proto.timeout) {
  113.                 if (proto.protocol != IR_PROTO_UNKNOWN) {
  114.                     //skicka på can
  115.                     txMsg.Data.bytes[0] = IR_BUTTON_UP;
  116.                     BIOS_CanSend(&txMsg);
  117.                 }
  118.                 state = STATE_IDLE;
  119.             }
  120.         }
  121.        
  122.        
  123.         if (rxMsgFull) {
  124.             /* No message reception functionality implemented */
  125.             /* Flush the received message */
  126.             rxMsgFull = 0; //  
  127.         }
  128.     }
  129.     return 0;
  130. }
  131.