Subversion Repositories HomeAutomation

Rev

Rev 941 | 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. #include <drivers/can/can.h>
  10. #include <drivers/can/mcp2515/mcp2515.h>
  11.  
  12. #define APP_TYPE    CAN_APPTYPES_CANGW
  13. #define APP_VERSION 0x0001
  14.  
  15. // A simple message "queue", with space for one message only.
  16. // These are declared volatile to tell the compiler not to optimize away accesses.
  17. volatile Can_Message_t rxMsg; // Message storage
  18. volatile uint8_t rxMsgFull;   // Synchronization flag
  19. volatile Can_Message_t extRxMsg;
  20. volatile uint8_t extRxMsgFull;   // Synchronization flag
  21.  
  22. volatile Can_Message_t txMsg; // Message storage
  23. volatile Can_Message_t extTxMsg;
  24.  
  25.  
  26. // external CAN message reception callback
  27. // This function runs with interrupts disabled, keep it as short as possible.
  28. void Can_Process_USART(Can_Message_t* msg) {
  29.     if (!extRxMsgFull) {
  30.         memcpy((void*)&extRxMsg, msg, sizeof(extRxMsg));
  31.         extRxMsgFull = 1;
  32.     }  
  33. }
  34.  
  35. // CAN message reception callback.
  36. // This function runs with interrupts disabled, keep it as short as possible.
  37. void can_receive(Can_Message_t *msg) {
  38.     if (!rxMsgFull) {
  39.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  40.         rxMsgFull = 1;
  41.     }
  42. }
  43.  
  44. int main(void)
  45. {
  46.     // Enable interrupts as early as possible
  47.     sei();
  48.    
  49.     Timer_Init();
  50.     Serial_Init();
  51.     uint8_t returnval = Can_Init();
  52.     if (returnval != CAN_OK) {
  53.     }
  54.    
  55.     Can_Message_t txMsg;
  56.     txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
  57.     txMsg.DataLength = 4;
  58.     txMsg.RemoteFlag = 0;
  59.     txMsg.ExtendedFlag = 1;
  60.     txMsg.Data.words[0] = APP_TYPE;
  61.     txMsg.Data.words[1] = APP_VERSION;
  62.    
  63.     // Set up callback for CAN reception, this is optional if only sending is required.
  64.     BIOS_CanCallback = &can_receive;
  65.     // Send CAN_NMT_APP_START
  66.     BIOS_CanSend(&txMsg);
  67.    
  68.     while (1) {
  69.        
  70.         if (extRxMsgFull) {
  71.             txMsg.Id = extRxMsg.Id;
  72.             txMsg.DataLength = extRxMsg.DataLength;
  73.             txMsg.RemoteFlag = extRxMsg.RemoteFlag;
  74.             txMsg.ExtendedFlag = extRxMsg.ExtendedFlag;
  75.             for (uint8_t i = 0; i < txMsg.DataLength; i++) {
  76.                 txMsg.Data.bytes[i] = extRxMsg.Data.bytes[i];
  77.             }
  78.             BIOS_CanSend(&txMsg);
  79.  
  80.             extRxMsgFull = 0; //  
  81.         }
  82.         if (rxMsgFull) {
  83.             extTxMsg.Id = rxMsg.Id;
  84.             extTxMsg.DataLength = rxMsg.DataLength;
  85.             extTxMsg.RemoteFlag = rxMsg.RemoteFlag;
  86.             extTxMsg.ExtendedFlag = rxMsg.ExtendedFlag;
  87.             for (uint8_t i = 0; i < extTxMsg.DataLength; i++) {
  88.                 extTxMsg.Data.bytes[i] = rxMsg.Data.bytes[i];
  89.             }
  90.             Can_Send(&extTxMsg);
  91.  
  92.             rxMsgFull = 0; //  
  93.         }
  94.     }
  95.    
  96.     return 0;
  97. }
  98.  
  99.