11#if DETWS_ENABLE_DEVICENET
15bool devicenet_encode_id(uint32_t *
id, DeviceNetGroup group, uint8_t msg_id, uint8_t mac_id)
17 if (!
id || mac_id > DEVICENET_MAC_MASK)
21 case DeviceNetGroup::DEVICENET_GROUP_1:
24 *
id = DEVICENET_G1_BASE | ((uint32_t)msg_id << 6) | mac_id;
26 case DeviceNetGroup::DEVICENET_GROUP_2:
29 *
id = DEVICENET_G2_BASE | ((uint32_t)mac_id << 3) | msg_id;
31 case DeviceNetGroup::DEVICENET_GROUP_3:
34 *
id = DEVICENET_G3_BASE | ((uint32_t)msg_id << 6) | mac_id;
36 case DeviceNetGroup::DEVICENET_GROUP_4:
39 *
id = DEVICENET_G4_BASE | msg_id;
46bool devicenet_decode_id(uint32_t can_id, DeviceNetId *out)
51 if (
id < DEVICENET_G2_BASE)
53 out->group = DeviceNetGroup::DEVICENET_GROUP_1;
54 out->msg_id = (uint8_t)((
id >> 6) & 0x0Fu);
55 out->mac_id = (uint8_t)(
id & DEVICENET_MAC_MASK);
58 if (
id < DEVICENET_G3_BASE)
60 out->group = DeviceNetGroup::DEVICENET_GROUP_2;
61 out->mac_id = (uint8_t)((
id >> 3) & DEVICENET_MAC_MASK);
62 out->msg_id = (uint8_t)(
id & 0x07u);
65 if (
id < DEVICENET_G4_BASE)
67 out->group = DeviceNetGroup::DEVICENET_GROUP_3;
68 out->msg_id = (uint8_t)((
id >> 6) & 0x07u);
69 out->mac_id = (uint8_t)(
id & DEVICENET_MAC_MASK);
74 out->group = DeviceNetGroup::DEVICENET_GROUP_4;
75 out->msg_id = (uint8_t)(
id & 0x3Fu);
82uint8_t devicenet_msg_header(
bool frag,
bool xid, uint8_t mac_id)
84 return (uint8_t)((frag ? DEVICENET_HDR_FRAG : 0u) | (xid ? DEVICENET_HDR_XID : 0u) | (mac_id & DEVICENET_MAC_MASK));
87uint8_t devicenet_frag_octet(uint8_t type, uint8_t count)
89 return (uint8_t)((type & DEVICENET_FRAG_TYPE_MASK) | (count & DEVICENET_FRAG_COUNT_MASK));
92bool devicenet_build_explicit(
CanFrame *out, DeviceNetGroup group, uint8_t msg_id, uint8_t mac_id,
const uint8_t *body,
95 if (!out || body_len > 7 || (body_len && !body))
98 if (!devicenet_encode_id(&
id, group, msg_id, mac_id))
103 out->
dlc = (uint8_t)(1 + body_len);
104 memset(out->
data, 0,
sizeof(out->
data));
105 out->
data[0] = devicenet_msg_header(
false,
false, mac_id);
107 memcpy(out->
data + 1, body, body_len);
111void devicenet_frag_reset(DeviceNetFragRx *rx)
114 memset(rx, 0,
sizeof(*rx));
118static bool frag_append(DeviceNetFragRx *rx,
const uint8_t *p, uint8_t n)
120 if ((uint32_t)rx->len + n > DETWS_DEVICENET_MSG_MAX)
122 memcpy(rx->buf + rx->len, p, n);
123 rx->len = (uint16_t)(rx->len + n);
127DeviceNetFragResult devicenet_frag_feed(DeviceNetFragRx *rx,
const uint8_t *body, uint8_t body_len)
129 if (!rx || !body || body_len < 1)
130 return DeviceNetFragResult::DEVICENET_FRAG_IGNORED;
132 if (!(body[0] & DEVICENET_HDR_FRAG))
134 devicenet_frag_reset(rx);
135 if (body_len > 1 && !frag_append(rx, body + 1, (uint8_t)(body_len - 1)))
136 return DeviceNetFragResult::DEVICENET_FRAG_ERR;
138 return DeviceNetFragResult::DEVICENET_FRAG_COMPLETE;
141 return DeviceNetFragResult::DEVICENET_FRAG_ERR;
142 uint8_t type = body[1] & DEVICENET_FRAG_TYPE_MASK;
143 uint8_t count = body[1] & DEVICENET_FRAG_COUNT_MASK;
144 const uint8_t *data = body + 2;
145 uint8_t data_len = (uint8_t)(body_len - 2);
149 case DEVICENET_FRAG_FIRST:
150 devicenet_frag_reset(rx);
152 rx->next_count = (uint8_t)((count + 1u) & DEVICENET_FRAG_COUNT_MASK);
153 if (data_len && !frag_append(rx, data, data_len))
154 return DeviceNetFragResult::DEVICENET_FRAG_ERR;
157 return DeviceNetFragResult::DEVICENET_FRAG_STARTED;
158 case DEVICENET_FRAG_MIDDLE:
159 if (!rx->active || count != rx->next_count)
161 devicenet_frag_reset(rx);
162 return DeviceNetFragResult::DEVICENET_FRAG_ERR;
164 if (data_len && !frag_append(rx, data, data_len))
166 devicenet_frag_reset(rx);
167 return DeviceNetFragResult::DEVICENET_FRAG_ERR;
169 rx->next_count = (uint8_t)((count + 1u) & DEVICENET_FRAG_COUNT_MASK);
170 return DeviceNetFragResult::DEVICENET_FRAG_PROGRESS;
171 case DEVICENET_FRAG_LAST:
172 if (!rx->active || count != rx->next_count)
174 devicenet_frag_reset(rx);
175 return DeviceNetFragResult::DEVICENET_FRAG_ERR;
177 if (data_len && !frag_append(rx, data, data_len))
179 devicenet_frag_reset(rx);
180 return DeviceNetFragResult::DEVICENET_FRAG_ERR;
183 return DeviceNetFragResult::DEVICENET_FRAG_COMPLETE;
185 return DeviceNetFragResult::DEVICENET_FRAG_IGNORED;
#define DET_CAN_STD_ID_MASK
11-bit standard identifier.
DeviceNet link-adaptation codec (DETWS_ENABLE_DEVICENET) - the CAN-specific layer of "CIP over CAN".
uint8_t data[DET_CAN_MAX_DLC]