Subversion Repositories HomeAutomation

Rev

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