Subversion Repositories HomeAutomation

Rev

Rev 554 | 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. #include <drivers/uart/serial.h>
  8. #include <drivers/timer/timer.h>
  9.  
  10. #define APP_TYPE    0xf001
  11. #define APP_VERSION 0x0002
  12.  
  13. // A simple message "queue", with space for one message only.
  14. // These are declared volatile to tell the compiler not to optimize away accesses.
  15. volatile Can_Message_t rxMsg; // Message storage
  16. volatile uint8_t rxMsgFull;   // Synchronization flag
  17.  
  18. // CAN message reception callback.
  19. // This function runs with interrupts disabled, keep it as short as possible.
  20. void can_receive(Can_Message_t *msg) {
  21.     if (!rxMsgFull) {
  22.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  23.         rxMsgFull = 1;
  24.     }
  25. }
  26.  
  27. // Timer callback function used for some timer tests
  28. void timer_callback(uint8_t timer) {
  29.     Can_Message_t msg;
  30.    
  31.     msg.ExtendedFlag = 1;
  32.     msg.Id = (CAN_TST << CAN_SHIFT_CLASS) | NODE_ID;
  33.     msg.RemoteFlag = 0;
  34.     msg.DataLength = 1;
  35.     msg.Data.bytes[0] = timer;
  36.    
  37.     BIOS_CanSend(&msg);
  38. }
  39.  
  40. int main(void)
  41. {
  42.     // Enable interrupts as early as possible
  43.     sei();
  44.    
  45.     Timer_Init();
  46.     Serial_Init();
  47.    
  48.     unsigned long time;
  49.    
  50.     Can_Message_t txMsg;
  51.     txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
  52.     txMsg.DataLength = 4;
  53.     txMsg.RemoteFlag = 0;
  54.     txMsg.ExtendedFlag = 1;
  55.     txMsg.Data.words[0] = APP_TYPE;
  56.     txMsg.Data.words[1] = APP_VERSION;
  57.    
  58.     // Set up callback for CAN reception, this is optional if only sending is required.
  59.     BIOS_CanCallback = &can_receive;
  60.     // Send CAN_NMT_APP_START
  61.     BIOS_CanSend(&txMsg);
  62.    
  63.     printf("AVR Test Application\n");
  64.    
  65.     txMsg.Id = (CAN_TST << CAN_SHIFT_CLASS) | NODE_ID;
  66.     txMsg.Data.dwords[0] = 0x01020304;
  67.     txMsg.DataLength = 8;
  68.  
  69.     // Set up three timers (assume at least three has been defined)
  70.     // The timeout is specified in ticks, which is equal to ms if
  71.     // the tick frequency is set to 1000.
  72.     Timer_SetTimeout(0, 2000, TimerTypeFreeRunning, 0);
  73.     Timer_SetTimeout(1, 10768, TimerTypeOneShot, &timer_callback);
  74.     Timer_SetTimeout(2, 3141, TimerTypeFreeRunning, &timer_callback);
  75.    
  76.     while (1) {
  77.         if (Timer_Expired(0)) {
  78.             // Send a CAN message
  79.             time = Timer_GetTicks();
  80.             txMsg.Data.dwords[1] = time;
  81.             BIOS_CanSend(&txMsg);
  82.             printf("Two seconds passed, time is now %ld.\n", time);
  83.         }
  84.        
  85.         if (rxMsgFull) {
  86.             // Print the received message
  87.             printf("RX: ID=%08lx, DLC=%u, EXT=%u, RTR=%u, data={ ",
  88.                     rxMsg.Id,
  89.                     (uint16_t)rxMsg.DataLength,
  90.                     (uint16_t)rxMsg.ExtendedFlag,
  91.                     (uint16_t)rxMsg.RemoteFlag);
  92.             for (uint8_t i=0; i<rxMsg.DataLength; i++) {
  93.                 printf("%02x ", rxMsg.Data.bytes[i]);
  94.             }
  95.             printf("}\n");
  96.             rxMsgFull = 0; //  
  97.         }
  98.     }
  99.    
  100.     return 0;
  101. }
  102.