Subversion Repositories HomeAutomation

Rev

Rev 543 | 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.  
  10. #define APP_TYPE    CAN_APPTYPES_IRTRANSMITTER
  11. #define APP_VERSION 0x0001
  12.  
  13. #define STATE_IDLE              0
  14. #define STATE_START_TRANSMIT    1
  15. #define STATE_TRANSMITTING      2
  16. #define STATE_START_PAUSE       3
  17. #define STATE_PAUSING           4
  18. #define STATE_STOP              5
  19.  
  20. // A simple message "queue", with space for one message only.
  21. // These are declared volatile to tell the compiler not to optimize away accesses.
  22. volatile Can_Message_t rxMsg; // Message storage
  23. volatile uint8_t rxMsgFull;   // Synchronization flag
  24.  
  25. // CAN message reception callback.
  26. // This function runs with interrupts disabled, keep it as short as possible.
  27. void can_receive(Can_Message_t *msg) {
  28.     if (!rxMsgFull) {
  29.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  30.         rxMsgFull = 1;
  31.     }
  32. }
  33.  
  34. int main(void)
  35. {
  36.     // Enable interrupts as early as possible
  37.     sei();
  38.    
  39.     Timebase_Init();
  40.     IrTransceiver_Init();
  41.    
  42.     Can_Message_t txMsg;
  43.     txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
  44.     txMsg.DataLength = 4;
  45.     txMsg.RemoteFlag = 0;
  46.     txMsg.ExtendedFlag = 1;
  47.     txMsg.Data.words[0] = APP_TYPE;
  48.     txMsg.Data.words[1] = APP_VERSION;
  49.    
  50.     // Set up callback for CAN reception, this is optional if only sending is required.
  51.     BIOS_CanCallback = &can_receive;
  52.     // Send CAN_NMT_APP_START
  53.     BIOS_CanSend(&txMsg);
  54.  
  55.     uint32_t time = Timebase_CurrentTime();
  56.     uint32_t timePauseStarted = 0;
  57.    
  58.     uint8_t state=STATE_IDLE;
  59.     uint8_t repeatcnt=0;
  60.     uint8_t stop=0;
  61.     uint8_t protocol=0; uint32_t ir_data=0; uint16_t timeout=0; uint8_t repeats=0;
  62.    
  63.     while (1) {
  64.         time = Timebase_CurrentTime();
  65.         if (state == STATE_IDLE) {
  66.         } else if (state == STATE_START_TRANSMIT) {
  67.             if (IrTransceiver_Transmit(protocol, ir_data, &timeout, &repeats) == IR_OK) {
  68.                 state = STATE_TRANSMITTING;
  69.             } else {
  70.                 state = STATE_IDLE;
  71.             }
  72.         } else if (state == STATE_TRANSMITTING) {
  73.             //polla om den är klar, om klar gå till STATE_START_PAUSE
  74.             if (IrTransceiver_Transmit_Poll() != IR_NOT_FINISHED) {
  75.                 state = STATE_START_PAUSE;
  76.             }
  77.         } else if (state == STATE_START_PAUSE) {
  78.             if (repeatcnt<repeats) {
  79.                 repeatcnt++;
  80.             }
  81.             timePauseStarted = Timebase_CurrentTime();
  82.             state = STATE_PAUSING;
  83.         } else if (state == STATE_PAUSING) {
  84.             //när timeout har gått (timebase) så gå till STATE_START_TRANSMIT
  85.             if (time - timePauseStarted >= timeout) {
  86.                 state = STATE_START_TRANSMIT;
  87.             }
  88.             if (stop == 1 && repeatcnt >= repeats) {
  89.                 state = STATE_STOP;
  90.             }
  91.  
  92.         } else if (state == STATE_STOP) {
  93.             stop = 0;
  94.             timeout = 0;
  95.             repeatcnt = 0;
  96.             state = STATE_IDLE;
  97.         }
  98.  
  99.        
  100.         if (rxMsgFull) {
  101.             if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT) {
  102.                 uint16_t acttype =(uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
  103.                 uint8_t actid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
  104.                
  105.                 if (rxMsg.DataLength==6) {
  106.                     if (acttype == ACT_TYPE_IR) {
  107.                         if (state == STATE_IDLE && rxMsg.Data.bytes[0] == IR_BUTTON_DOWN) {
  108.                             protocol = rxMsg.Data.bytes[1];
  109.                             ir_data = rxMsg.Data.bytes[5];
  110.                             ir_data |= (rxMsg.Data.bytes[4]<<8);
  111.                             ir_data |= ((uint32_t)rxMsg.Data.bytes[3]<<16);
  112.                             ir_data |= ((uint32_t)rxMsg.Data.bytes[2]<<24);
  113.  
  114.                             state = STATE_START_TRANSMIT;
  115.                         } else if (state != STATE_IDLE && rxMsg.Data.bytes[0] == IR_BUTTON_UP) {
  116.                             stop = 1;
  117.                         }
  118.                     }
  119.                 }
  120.             }
  121.            
  122.             // Flush the received message
  123.             rxMsgFull = 0; //  
  124.         }
  125.     }
  126.    
  127.     return 0;
  128. }
  129.