11#if DETWS_ENABLE_NMEA2000
15uint8_t n2k_fastpacket_num_frames(uint16_t total_len)
17 if (total_len <= N2K_FP_F0_DATA)
19 return (uint8_t)(1u + (total_len - N2K_FP_F0_DATA + (N2K_FP_FN_DATA - 1)) / N2K_FP_FN_DATA);
22bool n2k_fastpacket_build_frame(
CanFrame *out, uint8_t seq, uint8_t frame_idx, uint8_t priority, uint32_t pgn,
23 uint8_t sa, uint8_t da,
const uint8_t *data, uint16_t total_len)
25 if (!out || !data || seq > 7 || total_len == 0 || total_len > DETWS_N2K_FP_MAX)
27 if (frame_idx >= n2k_fastpacket_num_frames(total_len))
30 if (!j1939_encode_id(&
id, priority, pgn, sa, da))
36 memset(out->
data, 0xFF,
sizeof(out->
data));
38 out->
data[0] = (uint8_t)((seq << N2K_FP_SEQ_SHIFT) | (frame_idx & N2K_FP_FRAME_MASK));
41 out->
data[1] = (uint8_t)total_len;
42 uint8_t n = total_len < N2K_FP_F0_DATA ? (uint8_t)total_len : (uint8_t)N2K_FP_F0_DATA;
43 memcpy(out->
data + 2, data, n);
47 uint16_t off = (uint16_t)(N2K_FP_F0_DATA + (frame_idx - 1) * N2K_FP_FN_DATA);
48 uint16_t remaining = (uint16_t)(total_len - off);
49 uint8_t n = remaining < N2K_FP_FN_DATA ? (uint8_t)remaining : (uint8_t)N2K_FP_FN_DATA;
50 memcpy(out->
data + 1, data + off, n);
55void n2k_fastpacket_reset(N2kFastPacketRx *rx)
58 memset(rx, 0,
sizeof(*rx));
61N2kFpResult n2k_fastpacket_feed(N2kFastPacketRx *rx,
const CanFrame *f)
64 return N2kFpResult::N2K_FP_IGNORED;
66 if (!j1939_decode_id(f->
id, &
id))
67 return N2kFpResult::N2K_FP_IGNORED;
70 uint8_t seq = (uint8_t)(f->
data[0] >> N2K_FP_SEQ_SHIFT);
71 uint8_t frame_idx = (uint8_t)(f->
data[0] & N2K_FP_FRAME_MASK);
75 uint16_t total = f->
data[1];
76 if (total == 0 || total > DETWS_N2K_FP_MAX)
77 return N2kFpResult::N2K_FP_ERR;
78 n2k_fastpacket_reset(rx);
83 rx->total_len = total;
84 uint8_t n = total < N2K_FP_F0_DATA ? (uint8_t)total : (uint8_t)N2K_FP_F0_DATA;
85 memcpy(rx->buf, f->
data + 2, n);
88 if (rx->received >= total)
91 return N2kFpResult::N2K_FP_COMPLETE;
93 return N2kFpResult::N2K_FP_STARTED;
97 if (!rx->active || seq != rx->seq ||
id.sa != rx->sa ||
id.pgn != rx->pgn)
98 return N2kFpResult::N2K_FP_IGNORED;
99 if (frame_idx != rx->next_frame)
101 n2k_fastpacket_reset(rx);
102 return N2kFpResult::N2K_FP_ERR;
104 uint16_t remaining = (uint16_t)(rx->total_len - rx->received);
105 uint8_t n = remaining < N2K_FP_FN_DATA ? (uint8_t)remaining : (uint8_t)N2K_FP_FN_DATA;
106 memcpy(rx->buf + rx->received, f->
data + 1, n);
107 rx->received = (uint16_t)(rx->received + n);
109 if (rx->received >= rx->total_len)
112 return N2kFpResult::N2K_FP_COMPLETE;
114 return N2kFpResult::N2K_FP_PROGRESS;
117bool n2k_build_single(
CanFrame *out, uint8_t priority, uint32_t pgn, uint8_t sa, uint8_t da,
const uint8_t *data,
120 return j1939_build_message(out, priority, pgn, sa, da, data, len);
#define DET_CAN_MAX_DLC
classic CAN carries at most 8 data octets.
NMEA 2000 codec (DETWS_ENABLE_NMEA2000) - the marine instrumentation network, built on J1939 over CAN...
uint8_t data[DET_CAN_MAX_DLC]