CAN.cpp
Go to the documentation of this file.
1 /*
2 MIT LICENSE
3 
4 Copyright 2014-2019 Inertial Sense, Inc. - http://inertialsense.com
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
7 
8 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9 
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT, IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 */
12 
13 /* module_inst */
14 
15 #include "asf.h"
16 #include "CAN.h"
17 #include "globals.h"
18 
19 #define MCAN_TEST_SEND_ID_STD 0x125
20 #define MCAN_TEST_SEND_ID_EXT 0x100000A5
21 #define MCAN_TEST_RECV_ID_STD 0x126
22 #define MCAN_TEST_RECV_ID_EXT 0x100000A6
23 
24 static struct mcan_module mcan_instance;
25 
26 void CAN_init(void)
27 {
29  /* Initialize the module. */
30  struct mcan_config config_mcan;
31  mcan_get_config_defaults(&config_mcan);
32  config_mcan.rx_fifo_0_overwrite = true;
33  mcan_init(&mcan_instance, MCAN1, &config_mcan);
36 
38 }
39 
40 bool mcan_send_message(uint32_t id_value, uint8_t *data, uint32_t data_length)
41 {
42  uint32_t status = mcan_tx_get_fifo_queue_status(&mcan_instance);
43 
44  //check if fifo is full
45  if(status & MCAN_TXFQS_TFQF) {
46  return false;
47  }
48 
49  //Prevent sending more data than buffer size
50  if(data_length > CONF_MCAN_ELEMENT_DATA_SIZE)
51  data_length = CONF_MCAN_ELEMENT_DATA_SIZE;
52 
53  //get the put index where we put the next packet
54  uint32_t put_index = (status & MCAN_TXFQS_TFQPI_Msk) >> MCAN_TXFQS_TFQPI_Pos;
55 
56  struct mcan_tx_element tx_element;
58 
59  if(id_value >= 0x800)
61  else
62  tx_element.T0.reg |= MCAN_TX_ELEMENT_T0_STANDARD_ID(id_value);
63 
64  tx_element.T1.bit.DLC = data_length;
65 
66  for (uint32_t i = 0; i < data_length; i++) {
67  tx_element.data[i] = data[i];
68  }
69 
70  mcan_set_tx_buffer_element(&mcan_instance, &tx_element, put_index);
71  mcan_tx_transfer_request(&mcan_instance, (1 << put_index));
72 
73  return true;
74 }
75 
76 /* Returns data length received or zero for no messages available.
77 */
78 uint8_t mcan_receive_message(uint32_t *id_value, uint8_t *data)
79 {
80  uint32_t fifo_status;
81 
82  //Check standard message fifo
83  fifo_status = mcan_rx_get_fifo_status(&mcan_instance, 0);
84  if (fifo_status & MCAN_RXF0S_F0FL_Msk)
85  {
86  struct mcan_rx_element_fifo_0 rx_element_buffer;
87  uint32_t rx_fifo_index = (fifo_status >> MCAN_RXF0S_F0GI_Pos ) & 0x3fu;
88 
89  mcan_get_rx_fifo_0_element(&mcan_instance, &rx_element_buffer, rx_fifo_index);
90  mcan_rx_fifo_acknowledge(&mcan_instance, 0, rx_fifo_index);
91 
92  //Read out data
93  *id_value = rx_element_buffer.R0.bit.ID >> 18;
94  for(int i=0; i<rx_element_buffer.R1.bit.DLC; i++)
95  data[i] = rx_element_buffer.data[i];
96 
97  return rx_element_buffer.R1.bit.DLC;
98  }
99 
100  //check extended message fifo
101  fifo_status = mcan_rx_get_fifo_status(&mcan_instance, 1);
102  if (fifo_status & MCAN_RXF1S_F1FL_Msk)
103  {
104  struct mcan_rx_element_fifo_1 rx_element_buffer;
105  uint32_t rx_fifo_index = (fifo_status >> MCAN_RXF1S_F1GI_Pos ) & 0x3fu;
106 
107  mcan_get_rx_fifo_1_element(&mcan_instance, &rx_element_buffer, rx_fifo_index);
108  mcan_rx_fifo_acknowledge(&mcan_instance, 1, rx_fifo_index);
109 
110  //Read out data
111  *id_value = rx_element_buffer.R0.bit.ID;
112  for(int i=0; i<rx_element_buffer.R1.bit.DLC; i++)
113  data[i] = rx_element_buffer.data[i];
114 
115  return rx_element_buffer.R1.bit.DLC;
116  }
117 
118  //No data ready
119  return 0;
120 }
121 
122 /* Adds ID filter
123  * returns index of added ID or -1 for errror
124  */
125 int mcan_set_rx_filter(uint32_t id_value)
126 {
127  static int standard_filter_count = 0;
128  static int extended_filter_count = 0;
129 
130  if(id_value >= 0x800)
131  { //extended id
132  struct mcan_extended_message_filter_element et_filter;
133 
134  if(extended_filter_count >= CONF_MCAN1_RX_EXTENDED_ID_FILTER_NUM)
135  return -1;
136 
138  et_filter.F0.bit.EFID1 = id_value;
139 
140  mcan_set_rx_extended_filter(&mcan_instance, &et_filter, extended_filter_count);
141 
142  return extended_filter_count++;
143  }
144  else
145  { //standard id
146  struct mcan_standard_message_filter_element sd_filter;
147 
148  if(standard_filter_count >= CONF_MCAN1_RX_STANDARD_ID_FILTER_NUM)
149  return -1;
150 
152  sd_filter.S0.bit.SFID1 = id_value;
153 
154  mcan_set_rx_standard_filter(&mcan_instance, &sd_filter, standard_filter_count);
155 
156  return standard_filter_count++;
157  }
158 }
159 
160 /* Master device for CAN test
161  * This unit sends a message out the CAN bus then receives the return message and checks that it is valid.
162  */
164 {
165  uint8_t msg_cnt = 0;
166 
167  uint32_t success_count = 0;
168  uint32_t failure_count = 0;
169 
170  //Setup receive
173 
174  while(1)
175  {
176  uint8_t can_tx_message[CONF_MCAN_ELEMENT_DATA_SIZE];
177  uint8_t can_rx_message[CONF_MCAN_ELEMENT_DATA_SIZE];
178  uint8_t len;
179 
180  //Create message
181  msg_cnt++;
182  len = 2 + rand() % 7;
183 
184  for(int i=0; i<len; i++)
185  can_tx_message[i] = rand();
186 
187  //Send message
188  if(msg_cnt % 2 == 0)
189  mcan_send_message(MCAN_TEST_SEND_ID_STD, can_tx_message, len);
190  else
191  mcan_send_message(MCAN_TEST_SEND_ID_EXT, can_tx_message, len);
192 
193  //Wait for and Get response
194  uint32_t id, timeout = 100;
195  while((len = mcan_receive_message(&id, can_rx_message)) == 0 && --timeout > 0)
196  vTaskDelay(1);
197 
198  //Check return message
199  int i;
200  for(i=0; i<len; i++)
201  if((uint8_t)(can_tx_message[i] + 1) != can_rx_message[i])
202  break;
203 
204  if(i == len)
205  success_count++;
206  else
207  failure_count++;
208  //TODO: Do something with test result
209  }
210 }
211 
212 /* Slave device for CAN test
213  * This unit listens for a CAN message and returns a response.
214  */
215 void mcan_test_slave(void)
216 {
217  //Setup receive
220 
221  while(1)
222  {
223  uint8_t can_tx_message[CONF_MCAN_ELEMENT_DATA_SIZE];
224  uint8_t can_rx_message[CONF_MCAN_ELEMENT_DATA_SIZE];
225  uint32_t id;
226  uint8_t len;
227 
228  if((len = mcan_receive_message(&id, can_rx_message)) > 0)
229  {
230  //Change data and send back
231  for(int i=0; i<len; i++)
232  can_tx_message[i] = can_rx_message[i] + 1;
233 
234  if(id == MCAN_TEST_SEND_ID_STD)
235  mcan_send_message(MCAN_TEST_RECV_ID_STD, can_tx_message, len);
236  else
237  mcan_send_message(MCAN_TEST_RECV_ID_EXT, can_tx_message, len);
238  }
239  }
240 }
MCAN receive element structure for FIFO 0.
#define MCAN_RXF1S_F1FL_Msk
(MCAN_RXF1S) Receive FIFO 1 Fill Level
MCAN transfer element structure.
struct MCAN_RX_ELEMENT_R0_Type::@3 bit
int mcan_set_rx_filter(uint32_t id_value)
Definition: CAN.cpp:125
void CAN_init(void)
Definition: CAN.cpp:26
#define CONF_MCAN1_RX_EXTENDED_ID_FILTER_NUM
Definition: conf_mcan.h:74
MCAN extended message ID filter element structure.
#define MCAN1
(MCAN1 ) Base Address
Definition: same70j20.h:509
__IO MCAN_EXTENDED_MESSAGE_FILTER_ELEMENT_F0_Type F0
#define MCAN_TX_ELEMENT_T0_EXTENDED_ID(value)
MCAN receive element structure for FIFO 1.
void mcan_test_slave(void)
Definition: CAN.cpp:215
static void mcan_rx_fifo_acknowledge(struct mcan_module *const module_inst, bool fifo_number, uint32_t index)
Set Rx acknowledge.
struct MCAN_STANDARD_MESSAGE_FILTER_ELEMENT_S0_Type::@9 bit
__IO MCAN_RX_ELEMENT_R1_Type R1
void mcan_stop(struct mcan_module *const module_inst)
stop mcan module when bus off occurs
Definition: mcan.c:381
#define MCAN_TX_ELEMENT_T0_XTD
static struct mcan_module mcan_instance
Definition: CAN.cpp:24
static void mcan_get_config_defaults(struct mcan_config *const config)
Initializes an MCAN configuration structure to defaults.
void mcan_start(struct mcan_module *const module_inst)
start can module after initialization.
Definition: mcan.c:368
#define CONF_MCAN_ELEMENT_DATA_SIZE
Definition: conf_mcan.h:77
#define MCAN_TEST_SEND_ID_STD
Definition: CAN.cpp:19
static void mcan_get_extended_message_filter_element_default(struct mcan_extended_message_filter_element *et_filter)
Get the extended message filter default value.
#define CONF_MCAN1_RX_STANDARD_ID_FILTER_NUM
Definition: conf_mcan.h:72
MCAN configuration structure.
#define MCAN_TEST_RECV_ID_EXT
Definition: CAN.cpp:22
__IO MCAN_TX_ELEMENT_T0_Type T0
uint8_t data[CONF_MCAN_ELEMENT_DATA_SIZE]
uint8_t data[CONF_MCAN_ELEMENT_DATA_SIZE]
bool mcan_send_message(uint32_t id_value, uint8_t *data, uint32_t data_length)
Definition: CAN.cpp:40
static void mcan_get_standard_message_filter_element_default(struct mcan_standard_message_filter_element *sd_filter)
Get the standard message filter default value.
enum status_code mcan_set_rx_extended_filter(struct mcan_module *const module_inst, struct mcan_extended_message_filter_element *et_filter, uint32_t index)
set extended receive CAN ID.
Definition: mcan.c:574
#define MCAN_TXFQS_TFQF
(MCAN_TXFQS) Tx FIFO/Queue Full
static uint32_t mcan_tx_get_fifo_queue_status(struct mcan_module *const module_inst)
Get Tx FIFO/Queue status.
#define MCAN_TX_ELEMENT_T0_STANDARD_ID(value)
struct MCAN_RX_ELEMENT_R1_Type::@4 bit
static void mcan_get_tx_buffer_element_defaults(struct mcan_tx_element *tx_element)
Get the default transfer buffer element.
__IO MCAN_TX_ELEMENT_T1_Type T1
static uint32_t mcan_rx_get_fifo_status(struct mcan_module *const module_inst, bool fifo_number)
Get Rx FIFO status.
USBInterfaceDescriptor data
enum status_code mcan_get_rx_fifo_0_element(struct mcan_module *const module_inst, struct mcan_rx_element_fifo_0 *rx_element, uint32_t index)
get FIFO rx buffer element .
Definition: mcan.c:622
evb_flash_cfg_t * g_flashCfg
Definition: globals.c:22
static enum status_code mcan_tx_transfer_request(struct mcan_module *const module_inst, uint32_t trig_mask)
Tx buffer add transfer request.
enum status_code mcan_get_rx_fifo_1_element(struct mcan_module *const module_inst, struct mcan_rx_element_fifo_1 *rx_element, uint32_t index)
get FIFO rx buffer element .
Definition: mcan.c:645
void mcan_set_baudrate(Mcan *hw, uint32_t baudrate)
Set MCAN baudrate.
Definition: mcan.c:311
uint8_t mcan_receive_message(uint32_t *id_value, uint8_t *data)
Definition: CAN.cpp:78
__IO MCAN_RX_ELEMENT_R1_Type R1
struct MCAN_TX_ELEMENT_T1_Type::@6 bit
void vTaskDelay(const TickType_t xTicksToDelay) PRIVILEGED_FUNCTION
__IO MCAN_RX_ELEMENT_R0_Type R0
MCAN standard message ID filter element structure.
Autogenerated API include file for the Atmel Software Framework (ASF)
__IO MCAN_STANDARD_MESSAGE_FILTER_ELEMENT_S0_Type S0
struct MCAN_EXTENDED_MESSAGE_FILTER_ELEMENT_F0_Type::@10 bit
#define MCAN_RXF0S_F0FL_Msk
(MCAN_RXF0S) Receive FIFO 0 Fill Level
enum status_code mcan_set_tx_buffer_element(struct mcan_module *const module_inst, struct mcan_tx_element *tx_element, uint32_t index)
set dedicated transmit buffer element .
Definition: mcan.c:668
__IO MCAN_RX_ELEMENT_R0_Type R0
void mcan_init(struct mcan_module *const module_inst, Mcan *hw, struct mcan_config *config)
initialize can module.
Definition: mcan.c:270
uint32_t can_receive_address
Definition: data_sets.h:3178
#define MCAN_TEST_RECV_ID_STD
Definition: CAN.cpp:21
#define MCAN_TXFQS_TFQPI_Msk
(MCAN_TXFQS) Tx FIFO/Queue Put Index
MCAN software device instance structure.
#define MCAN_TEST_SEND_ID_EXT
Definition: CAN.cpp:20
enum status_code mcan_set_rx_standard_filter(struct mcan_module *const module_inst, struct mcan_standard_message_filter_element *sd_filter, uint32_t index)
set standard receive CAN ID.
Definition: mcan.c:551
void mcan_test_master(void)
Definition: CAN.cpp:163
uint32_t CANbaud_kbps
Definition: data_sets.h:3175
uint8_t data[CONF_MCAN_ELEMENT_DATA_SIZE]


inertial_sense_ros
Author(s):
autogenerated on Sun Feb 28 2021 03:17:08