Dawn Framework 1.0
Universal data acquisition framework for embedded systems
can.cxx
1// dawn/src/porting/nuttx/can.cxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#include "dawn/porting/can.hxx"
7
8#include <cstring>
9#include <errno.h>
10#include <fcntl.h>
11#include <sys/ioctl.h>
12#include <unistd.h>
13
14#include "dawn/debug.hxx"
15#include "dawn/porting/config.hxx"
16
17//***************************************************************************
18// Public Functions
19//***************************************************************************
20
21/****************************************************************************
22 * Public Functions
23 ****************************************************************************/
24
25/****************************************************************************
26 * Name: can_open
27 *
28 * Description:
29 * Open CAN character device interface.
30 *
31 ****************************************************************************/
32
33int can_open(const char *path)
34{
35 return open(path, O_RDWR);
36}
37
38/****************************************************************************
39 * Name: can_close
40 *
41 * Description:
42 * Close CAN character device interface.
43 *
44 ****************************************************************************/
45
46void can_close(int fd)
47{
48 close(fd);
49}
50
51/****************************************************************************
52 * Name: can_init
53 *
54 * Description:
55 * Initialzie CAN character device interface.
56 *
57 ****************************************************************************/
58
59int can_init(int fd)
60{
61 return OK;
62}
63
64/****************************************************************************
65 * Name: can_read
66 *
67 * Description:
68 * Read CAN data (blocking).
69 *
70 ****************************************************************************/
71
72int can_read(int fd, FAR dawn::porting::canmsg_s *msg)
73{
74 struct can_msg_s frame;
75 ssize_t ret;
76
77 /* Read frame */
78
79 ret = read(fd, &frame, sizeof(struct can_msg_s));
80 if (ret < 0)
81 {
82 if (errno != EAGAIN)
83 {
84 DAWNERR("read failed %d\n", -errno);
85 }
86
87 return -errno;
88 }
89
90 /* Convert frame to common format */
91
92 msg->id = frame.cm_hdr.ch_id;
93 msg->len = can_dlc2bytes(frame.cm_hdr.ch_dlc);
94 msg->rtr = frame.cm_hdr.ch_rtr;
95 msg->error = 0;
96 msg->_res = 0;
97#ifdef CONFIG_CAN_EXTID
98 msg->extid = frame.cm_hdr.ch_extid;
99#else
100 msg->extid = 0;
101#endif
102#ifdef CONFIG_CAN_ERRORS
103 msg->error = frame.cm_hdr.ch_error;
104#endif
105
106 std::memcpy(msg->data, frame.cm_data, CAN_DATA_MAX);
107
108 return static_cast<int>(ret);
109}
110
111/****************************************************************************
112 * Name: can_send
113 *
114 * Description:
115 * Send CAN data.
116 *
117 ****************************************************************************/
118
119int can_send(int fd, FAR dawn::porting::canmsg_s *msg)
120{
121 struct can_msg_s frame;
122 ssize_t ret;
123
124 /* Convert from common format */
125
126 frame.cm_hdr.ch_id = msg->id;
127 frame.cm_hdr.ch_rtr = msg->rtr;
128 frame.cm_hdr.ch_dlc = can_bytes2dlc(msg->len);
129#ifdef CONFIG_CAN_ERRORS
130 frame.cm_hdr.ch_error = 0;
131#endif
132#ifdef CONFIG_CAN_EXTID
133 frame.cm_hdr.ch_extid = msg->extid;
134#endif
135 frame.cm_hdr.ch_tcf = 0;
136 std::memcpy(frame.cm_data, msg->data, CAN_DATA_MAX);
137
138 /* Send frame */
139
140 ret = write(fd, &frame, CAN_MSGLEN(msg->len));
141 if (ret < 0)
142 {
143 DAWNERR("write failed %d\n", -errno);
144 return -errno;
145 }
146
147 return static_cast<int>(ret);
148}
Common CAN message format for chardev and socketCAN.
Definition can.hxx:20