Subversion Repositories HomeAutomation

Rev

Rev 2291 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. #include <inttypes.h>
  2. //#include <stdio.h>
  3. #include <avr/io.h>
  4. #include <avr/interrupt.h>
  5. #include <drivers/can/avr_internal/avr_internal.h>
  6.  
  7. /* Hack to fix lack of PBx, PCx defines in /usr/lib/avr/include/avr/portpins.h */
  8. /* http://savannah.nongnu.org/bugs/?25930 http://www.mail-archive.com/avr-libc-dev@nongnu.org/msg03306.html */
  9. #include <drivers/mcu/portpins.h>
  10.  
  11. #include <vectors.h>
  12. #include <drivers/can/avr_internal/can_lib.h>
  13.  
  14. #define DATA_BUFFER_SIZE 8 // Up to 8 bytes Max
  15.  
  16. static Can_Message_t msgbuf;
  17. static uint8_t receive_buffer[DATA_BUFFER_SIZE]; // buffer to hold payload from Sensor Nodes
  18. static st_cmd_t receive_msg; // Response Mob
  19.  
  20. Can_Return_t Can_Receive(Can_Message_t *msg);
  21.  
  22. Can_Return_t Can_ActivateRxMOb(void)
  23. {
  24.     receive_msg.pt_data = &receive_buffer[0]; // Point Response MOb to first element of buffer
  25.     receive_msg.status = 0; // clear status
  26.     for(uint8_t i=0; i<DATA_BUFFER_SIZE; i++) {receive_buffer[i] = 0;} // clear message object data buffer
  27.     //response_msg.id.ext = 0;
  28.     receive_msg.ctrl.ide = 1; // This message object accepts extended (2.0A) CAN frames
  29.     receive_msg.ctrl.rtr = 0; // this message object is not requesting a remote node to transmit data back
  30.     //response_msg.dlc = DATA_BUFFER_SIZE; // Number of bytes (8 max) of data to expect
  31.     receive_msg.cmd = CMD_RX_DATA; // assign this as a "Receive Standard (2.0A) CAN frame" message object
  32.  
  33.     while(can_cmd(&receive_msg) != CAN_CMD_ACCEPTED); // Wait for MOb to configure (Must re-configure MOb for every transaction)
  34.  
  35.     return CAN_OK;
  36. }
  37.  
  38. // /usr/lib/avr/include/avr/iom64c1.h
  39. ISR(CAN_INT_vect) {
  40.     // Get first available message from controller and pass it to
  41.     // application handler. If both RX buffers contain messages
  42.     // we will get another interrupt as soon as this one returns.
  43.     if (Can_Receive(&msgbuf) == CAN_OK) {
  44.         // Callbacks are run with global interrupts disabled but
  45.         // with controller flag cleared so another msg can be
  46.         // received while this one is processed.
  47.         Can_Process(&msgbuf);
  48.        
  49.     }
  50.     //???
  51.     Can_ActivateRxMOb();
  52.     /* Clear interrupt flag */
  53.     CANGIT |= (1<<BXOK);
  54. }
  55.  
  56.  
  57. Can_Return_t Can_EnableRxInterrupt(void) {
  58.     CANGIE |= (1<<ENIT|1<<ENRX);
  59.    
  60.     return CAN_OK;
  61. }
  62.  
  63.  
  64. /*-----------------------------------------------------------------------------
  65.  * Public Functions
  66.  *---------------------------------------------------------------------------*/
  67.  
  68. /**
  69.  * Initializes the CAN interface. Edit can_cfg.h to choose bitrate.
  70.  *
  71.  * @return
  72.  *      CAN_OK if initialization was successful.
  73.  *      CAN_INIT_FAIL_SET_BITRATE if bitrate could not be set correctly.
  74.  *      CAN_INIT_FAIL_SET_MODE if the controller could not be set to normal operation mode.
  75.  *      CAN_INIT_FAIL in case of general error.
  76.  */
  77. Can_Return_t Can_Init(void) {
  78.     can_init(0);
  79.     Can_ActivateRxMOb();
  80.     Can_EnableRxInterrupt();
  81.    
  82.     return CAN_OK;
  83. }
  84.  
  85.  
  86.  
  87. /**
  88.  * Sends a CAN message immediately with the controller hardware. If the CAN
  89.  * controller is busy, the function will return CAN_FAIL.
  90.  *
  91.  * @param msg
  92.  *      Pointer to the CAN message storage buffer.
  93.  *
  94.  * @return
  95.  *      CAN_OK if the message was successfully sent to the controller.
  96.  *      CAN_FAIL if the controller is busy.
  97.  */
  98. Can_Return_t Can_Send(Can_Message_t *msg) {
  99.     uint8_t tx_remote_buffer[DATA_BUFFER_SIZE];
  100.     st_cmd_t tx_remote_msg; //
  101.     tx_remote_msg.pt_data = &tx_remote_buffer[0]; // Point Remote Tx MOb to first element of buffer
  102.     tx_remote_msg.status = 0; // clear status
  103.  
  104.     // Configure Remote Tx MOb
  105.     for(uint8_t i=0; i<DATA_BUFFER_SIZE; i++) {tx_remote_buffer[i]=msg->Data.bytes[i];} // set data
  106.     tx_remote_msg.id.ext = msg->Id; //
  107.     tx_remote_msg.ctrl.ide = msg->ExtendedFlag; // This message object sends extended (2.0A) CAN frames
  108.     tx_remote_msg.ctrl.rtr = msg->RemoteFlag; //
  109.     tx_remote_msg.dlc = msg->DataLength; // Number of data bytes (8 max)
  110.     tx_remote_msg.cmd = CMD_TX_DATA; //
  111.  
  112.     while(can_cmd(&tx_remote_msg) != CAN_CMD_ACCEPTED); // Wait for MOb to configure (Must re-configure MOb for every transaction) and send request
  113.  
  114.     while(can_get_status(&tx_remote_msg) == CAN_STATUS_NOT_COMPLETED); // Wait for Tx to complete
  115.  
  116.     return CAN_OK;
  117. }
  118.  
  119.  
  120. /**
  121.  * Receives a CAN message from the CAN controller hardware.
  122.  *
  123.  * @param msg
  124.  *      Pointer to the message storage buffer into which the message should be copied.
  125.  *
  126.  * @return
  127.  *      CAN_OK if a received message was successfully copied into the buffer.
  128.  *      CAN_NO_MSG_AVAILABLE if there is no message available in the controller.
  129.  */
  130. Can_Return_t Can_Receive(Can_Message_t *msg) {
  131.     if (can_get_status(&receive_msg) == CAN_STATUS_COMPLETED) {
  132.         msg->Id = receive_msg.id.ext;
  133.         msg->DataLength = receive_msg.dlc;
  134.         msg->RemoteFlag = receive_msg.ctrl.rtr;
  135.         for(uint8_t i=0; i<DATA_BUFFER_SIZE; i++) {msg->Data.bytes[i]=receive_buffer[i];} // set data
  136.        
  137.         return CAN_OK;
  138.     }
  139.  
  140.     return CAN_NO_MSG_AVAILABLE;
  141. }
  142.