Subversion Repositories HomeAutomation

Rev

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