Subversion Repositories HomeAutomation

Rev

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

  1. /**
  2.  * CAN test program.
  3.  *
  4.  * @target  AVR
  5.  * @date    2006-10-29
  6.  * @author  Jimmy Myhrman
  7.  *  
  8.  */
  9.  
  10. /*-----------------------------------------------------------------------------
  11.  * Includes
  12.  *---------------------------------------------------------------------------*/
  13. /* system files */
  14. #include <avr/io.h>
  15. #include <avr/interrupt.h>
  16. #include <avr/wdt.h>
  17. #include <stdio.h>
  18. /* lib files */
  19. #include <can.h>
  20. #include <serial.h>
  21. #include <uart.h>
  22. #include <timebase.h>
  23.  
  24.  
  25. /*-----------------------------------------------------------------------------
  26.  * Defines
  27.  *---------------------------------------------------------------------------*/
  28. #define UART_START_BYTE 253
  29. #define UART_END_BYTE 250
  30.  
  31.  
  32. /*-----------------------------------------------------------------------------
  33.  * Functions
  34.  *---------------------------------------------------------------------------*/
  35. /**
  36.  * Parses an incoming UART byte by maintaining a state machine. The UART
  37.  * bytes will build up a CAN message according to the protocol described here:
  38.  *
  39.  * http://www.arune.se/projekt/doku.php?id=homeautomation:pc-mjukvara
  40.  *
  41.  * @param c
  42.  *      The received UART byte.
  43.  */
  44. void UartParseByte(uint8_t c) {
  45.     static Can_Message_t cm;
  46.     static uint8_t waitingMessage = 0;
  47.     static uint32_t startTime = 0;
  48.     static int8_t count = 0;
  49.    
  50.     /* 50ms timeout */
  51.     if (waitingMessage && Timebase_PassedTimeMillis(startTime) > 50) {
  52.         waitingMessage = 0;
  53.     }
  54.    
  55.     if (waitingMessage) {
  56.         /* save start time */
  57.         startTime = Timebase_CurrentTime();
  58.         /* UART END */
  59.         if (count >= 15) {
  60.             if (c == UART_END_BYTE) {
  61.                 PORTC ^= (1<<PC0);
  62.                 Can_Send(&cm);
  63.             }
  64.             waitingMessage = 0;
  65.             return;
  66.         }
  67.         /* data */
  68.         else if (count >= 7) {
  69.             cm.Data.bytes[count-7] = c;
  70.             count++;
  71.             return;
  72.         }
  73.         /* data length */
  74.         else if (count >= 6) {
  75.             cm.DataLength = c;
  76.             count++;
  77.             return;
  78.         }
  79.         /* remote request flag */
  80.         else if (count >= 5) {
  81.             cm.RemoteFlag = c;
  82.             count++;
  83.             return;
  84.         }
  85.         /* extended */
  86.         else if (count >= 4) {
  87.             cm.ExtendedFlag = c;
  88.             count++;
  89.             return;
  90.         }
  91.         /* ident */
  92.         else if (count >= 0) {
  93.             cm.Id += ((uint32_t)c << (count*8));
  94.             count++;
  95.             return;
  96.         }
  97.     }
  98.    
  99.     if (c == UART_START_BYTE && !waitingMessage) {
  100.         waitingMessage = 1;
  101.         startTime = Timebase_CurrentTime();
  102.         count = 0;
  103.         cm.Id = 0;
  104.         return;
  105.     }
  106. }
  107.  
  108.  
  109. /*-----------------------------------------------------------------------------
  110.  * Main Program
  111.  *---------------------------------------------------------------------------*/
  112. int main(void) {
  113.     Timebase_Init();
  114.     Serial_Init();
  115.     Can_Init();
  116.    
  117.     DDRC = 1<<PC1 | 1<<PC0;
  118.     PORTC = (1<<PC1) | (1<<PC0);
  119.    
  120.     sei();
  121.    
  122.     Can_Message_t rxMsg;
  123.     uint16_t rxByte;
  124.     uint8_t i = 0;
  125.    
  126.     /* main loop */
  127.     while (1) {
  128.         /* service the CAN routines */
  129.         Can_Service();
  130.        
  131.         /* any new CAN messages received? */
  132.         if (Can_Receive(&rxMsg) == CAN_OK) {
  133.             PORTC ^= (1<<PC1);
  134.             /* send message to CanWatcher */
  135.             uart_putc(UART_START_BYTE);
  136.             uart_putc((uint8_t)rxMsg.Id);
  137.             uart_putc((uint8_t)(rxMsg.Id>>8));
  138.             uart_putc((uint8_t)(rxMsg.Id>>16));
  139.             uart_putc((uint8_t)(rxMsg.Id>>24));
  140.             uart_putc(rxMsg.ExtendedFlag);
  141.             uart_putc(rxMsg.RemoteFlag);
  142.             uart_putc(rxMsg.DataLength);
  143.             for (i=0; i<8; i++) {
  144.                 uart_putc(rxMsg.Data.bytes[i]);
  145.             }
  146.             uart_putc(UART_END_BYTE);
  147.         }
  148.        
  149.         /* any UART bytes received? */
  150.         rxByte = uart_getc();
  151.         while (rxByte != UART_NO_DATA) {
  152.             /* parse byte! */
  153.             UartParseByte((uint8_t)(rxByte & 0x00FF));
  154.             /* receive next */
  155.             rxByte = uart_getc();
  156.         }
  157.     }
  158.    
  159.     return 0;
  160. }
  161.