CAN Asynchronous Driver

In Control Area Network (CAN) asynchronous driver, a callback function can be registered in the driver by the application and triggered when CAN message transfer done or error happen.

Summary of the API's Functional Features

The API provides functions to:
  • Initialize and deinitialize the driver and associated hardware

  • Enable or disable CAN instance

  • CAN message transfer: transmission, reception

  • Callback on message transmitted, recepted, error

  • Callback on error warning, error active, error passive, bus off, data overrun

  • Set CAN mode: normal, monitoring

Summary of Configuration Options

Below is a list of the main CAN parameters that can be configured in START. Many of these parameters are used by the can_async_init function when initializing the driver and underlying hardware.
  • CAN TX and RX signal pin

  • Data bit timing and prescaler configuration

  • Normal bit timing and prescaler configuration

  • TX FIFO configuration

  • RX FIFO configuration

  • Filter configuration

Driver Implementation Description

The driver is focus on the MAC layer and try to offer the APIs which can be used by upper application layer.

Example of Usage

The following shows a simple example of using the CAN. The CAN must have been initialized by can_async_init. This initialization will configure the operation of the CAN, such as input pins, single-shot, or continuous measurement mode, etc.

The example registers callback functions for CAN message send and receive.

          void CAN_0_tx_callback(struct can_async_descriptor *const descr)
          {
              (void)descr;
          }
          void CAN_0_rx_callback(struct can_async_descriptor *const descr)
          {
              struct can_message msg;
              uint8_t            data[64];
              msg.data = data;
              can_async_read(descr, &msg);
              return;
          }
          /**
           * Example of using CAN_0 to Encrypt/Decrypt data.
           */
          void CAN_0_example(void)
          {
              struct can_message msg;
              struct can_filter  filter;
              uint8_t            send_data[4];
              send_data[0] = 0x00;
              send_data[1] = 0x01;
              send_data[2] = 0x02;
              send_data[3] = 0x03;
              msg.id   = 0x45A;
              msg.type = CAN_TYPE_DATA;
              msg.data = send_data;
              msg.len  = 4;
              msg.fmt  = CAN_FMT_STDID;
              can_async_register_callback(&CAN_0, CAN_ASYNC_TX_CB, (FUNC_PTR)CAN_0_tx_callback);
              can_async_enable(&CAN_0);
              /**
                * CAN_0_tx_callback callback should be invoked after call
                * can_async_write, and remote device should receive message with ID=0x45A
                */
              can_async_write(&CAN_0, &msg);
              msg.id  = 0x100000A5;
              msg.fmt = CAN_FMT_EXTID;
              /**
               * remote device should receive message with ID=0x100000A5
                */
              can_async_write(&CAN_0, &msg);
              /**
                * CAN_0_rx_callback callback should be invoked after call
                * can_async_set_filter and remote device send CAN Message with the same
                * content as the filter.
                */
              can_async_register_callback(&CAN_0, CAN_ASYNC_RX_CB, (FUNC_PTR)CAN_0_rx_callback);
              filter.id   = 0x469;
              filter.mask = 0;
              can_async_set_filter(&CAN_0, 0, CAN_FMT_STDID, &filter);
              filter.id   = 0x10000096;
              filter.mask = 0;
              can_async_set_filter(&CAN_0, 1, CAN_FMT_EXTID, &filter);
          }
        

Dependencies

  • The CAN peripheral and its related I/O lines and clocks

  • The NVIC must be configured so that CAN interrupt requests are periodically serviced