Subversion Repositories HomeAutomation

Rev

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

  1. #include "bios_funs.h"
  2. #include "avr_cfg.h"
  3. #include <inttypes.h>
  4. #include <avr/io.h>
  5. #include <avr/interrupt.h>
  6. #include <avr/wdt.h>
  7. #include <avr/pgmspace.h>
  8. #include <stdio.h>
  9. #include "flash.h"
  10. #include "vectors.h" // Must be included after sfr_defs.h but before any ISR()
  11. #include "can.h"
  12.  
  13. //---------------------------------------------------------------------------
  14. // Globals
  15.  
  16. volatile long gMilliSecTick;
  17.  
  18. //---------------------------------------------------------------------------
  19. // Function definitions for the exported interface
  20.  
  21. void reset(void) {
  22.     //Just loop and let the watchdog reset
  23.     cli();
  24.     while(1);
  25. };
  26.  
  27. void bios_putchar(char c) {
  28.     UART_PUTCHAR(c);
  29. };
  30.  
  31. char bios_getchar(void) {
  32.     char c;
  33.     UART_GETCHAR(c)
  34.     return c;
  35. };
  36.  
  37. long timebase_get(void) {
  38.     uint8_t sreg;
  39.     long res;
  40.    
  41.     //Disable interrupts while reading tick count
  42.     sreg=SREG;
  43.     cli();
  44.    
  45.     res = gMilliSecTick;
  46.    
  47.     SREG=sreg;
  48.    
  49.     return res;
  50. }
  51.  
  52. //---------------------------------------------------------------------------
  53. // Function definitions for the private functions
  54.  
  55. static int console_getchar(FILE *stream) {
  56.     return bios_getchar();
  57. }
  58.  
  59. static int console_putchar(char c, FILE *stream) {
  60.     bios_putchar(c);
  61.     return 0;
  62. }
  63.  
  64. static FILE bios_stdio = FDEV_SETUP_STREAM(console_putchar, console_getchar,
  65.                                          _FDEV_SETUP_RW);
  66.    
  67.  
  68. //---------------------------------------------------------------------------
  69. // Interrupt Service Routines
  70. // Read app_vectors.h!
  71.  
  72. ISR(TIMEBASE_VECTOR) {
  73.     TIMEBASE_COUNTER -= TIMEBASE_RELOAD;
  74.     gMilliSecTick++;
  75.     wdt_reset();
  76. }
  77.  
  78. int main() {
  79.     void (*app_reset)(void) = 0;
  80.    
  81.     // Setup USART for debug channel
  82.     UART_INIT();
  83.     stdout = &bios_stdio;
  84.     stdin = &bios_stdio;
  85.    
  86.     // Initialize a suitable hardware timer to create a 1KHz interrupt.
  87.     TIMEBASE_INIT();
  88.    
  89.     // Enable watchdog timer to protect against an application locking the
  90.     // node by leaving interrupts disabled.
  91.     wdt_enable(WDTO_500MS);
  92.    
  93.     // Move interrupt vectors to start of bootloader section and enable interrupts
  94.     IVSEL_REG = _BV(IVCE);
  95.     IVSEL_REG = _BV(IVSEL);
  96.     sei();
  97.    
  98.     printf("AVR BIOS\n");
  99.    
  100.     if (pgm_read_word(0) != 0xffff) {
  101.         printf("Starting application.\n");
  102.         app_reset();
  103.     }
  104.    
  105.     printf("No application found.\n");
  106.    
  107.     printf("\n------------------------------------------------------------\n");
  108.     printf(  "   CAN Test: Periodic Transmission\n");
  109.     printf(  "------------------------------------------------------------\n");
  110.    
  111.     printf("CanInit...");
  112.     if (Can_Init() != CAN_OK) {
  113.         printf("FAILED!\n");
  114.     }
  115.     else {
  116.         printf("OK!\n");
  117.     }
  118.    
  119.     uint32_t timeStamp = 0;
  120.    
  121.     Can_Message_t txMsg;
  122.     Can_Message_t rxMsg;
  123.     //The databytes are just what happens to be in the memory. They are never set.
  124.     txMsg.RemoteFlag = 0;
  125.     txMsg.ExtendedFlag = 1;
  126. #define NODENUMBER 2
  127. #if NODENUMBER == 1
  128.     txMsg.Id = 16;
  129.     txMsg.DataLength = 2;
  130. #elif NODENUMBER == 2
  131.     txMsg.Id = 32;
  132.     txMsg.DataLength = 5;
  133. #else
  134. # error NODENUMBER not set!
  135. #endif
  136.    
  137.     uint8_t i;
  138.     /* main loop */
  139.     while (1) {
  140.         /* service the CAN routines */
  141.         Can_Service();
  142.        
  143.         /* send CAN message and check for CAN errors once every second */
  144.         if ((timebase_get() - timeStamp) >= 1000) {
  145.             timeStamp = timebase_get();
  146.             /* send txMsg */
  147.             txMsg.Id++;
  148.             Can_Send(&txMsg);
  149.         }
  150.        
  151.         /* check if any messages have been received */
  152.         while (Can_Receive(&rxMsg) == CAN_OK) {
  153.             printf("BIOS Received: ID=%lx, DLC=%u, EXT=%u, RTR=%u, ", rxMsg.Id, (uint16_t)(rxMsg.DataLength), (uint16_t)(rxMsg.ExtendedFlag), (uint16_t)(rxMsg.RemoteFlag));
  154.             printf("data={ ");
  155.             for (i=0; i<rxMsg.DataLength; i++) {
  156.                 printf("%x ", rxMsg.Data.bytes[i]);
  157.             }
  158.             printf("}\n");
  159.            
  160.             if (rxMsg.Id % 20 == 19) reset();
  161.         }
  162.     }
  163.  
  164.     return 0;
  165. }
  166.