24static const DncEiaPair DNC_EIA_MAP[] = {
73 {
'%', (uint8_t)DncEiaCode::DNC_EIA_EOR},
76static const size_t DNC_EIA_MAP_LEN =
sizeof(DNC_EIA_MAP) /
sizeof(DNC_EIA_MAP[0]);
78uint8_t dnc_iso_to_eia(
char c)
80 for (
size_t i = 0; i < DNC_EIA_MAP_LEN; i++)
81 if (DNC_EIA_MAP[i].ascii == c)
82 return DNC_EIA_MAP[i].eia;
86char dnc_eia_to_iso(uint8_t b)
88 for (
size_t i = 0; i < DNC_EIA_MAP_LEN; i++)
89 if (DNC_EIA_MAP[i].eia == b)
90 return DNC_EIA_MAP[i].ascii;
94uint8_t dnc_iso_add_parity(uint8_t ascii7)
96 uint8_t v = ascii7 & 0x7F;
102 x &= (uint8_t)(x - 1);
104 return (uint8_t)(v | (p ? 0x80 : 0x00));
107void dnc_flow_init(DncFlow *f)
112bool dnc_flow_feed(DncFlow *f, uint8_t rx)
114 if (rx == (uint8_t)DncFlowByte::DNC_XOFF)
119 if (rx == (uint8_t)DncFlowByte::DNC_XON)
128static size_t dnc_put_eob(
const DncCfg *cfg, uint8_t *out,
size_t cap,
size_t n)
130 if (cfg->code == DncCode::DNC_CODE_EIA)
134 out[n++] = (uint8_t)DncEiaCode::DNC_EIA_EOB;
139 uint8_t cr = cfg->even_parity ? dnc_iso_add_parity(0x0D) : 0x0D;
144 uint8_t lf = cfg->even_parity ? dnc_iso_add_parity(0x0A) : 0x0A;
151size_t dnc_encode_block(
const DncCfg *cfg,
const char *line,
size_t line_len, uint8_t *out,
size_t out_cap)
154 for (
size_t i = 0; i < line_len; i++)
157 if (cfg->code == DncCode::DNC_CODE_EIA)
159 uint8_t e = dnc_iso_to_eia(line[i]);
166 b = (uint8_t)line[i] & 0x7F;
167 if (cfg->even_parity)
168 b = dnc_iso_add_parity(b);
174 return dnc_put_eob(cfg, out, out_cap, n);
177size_t dnc_encode_marker(
const DncCfg *cfg, uint8_t *out,
size_t out_cap)
180 if (cfg->code == DncCode::DNC_CODE_EIA)
184 out[n++] = (uint8_t)DncEiaCode::DNC_EIA_EOR;
188 uint8_t pct = cfg->even_parity ? dnc_iso_add_parity(0x25) : 0x25;
193 return dnc_put_eob(cfg, out, out_cap, n);
196size_t dnc_encode_leader(
const DncCfg *cfg, uint8_t *out,
size_t out_cap)
198 uint16_t n = cfg->leader_len;
199 if ((
size_t)n > out_cap)
201 for (uint16_t i = 0; i < n; i++)
206void dnc_decode_init(DncDecoder *d, DncCode code)
211 d->in_program =
false;
212 d->line_ready =
false;
216DncEvent dnc_decode_feed(DncDecoder *d, uint8_t wire)
221 d->line_ready =
false;
230 bool is_marker =
false;
233 if (d->code == DncCode::DNC_CODE_EIA)
235 if (wire == (uint8_t)DncEiaCode::DNC_EIA_EOB)
237 else if (wire == (uint8_t)DncEiaCode::DNC_EIA_EOR)
240 ascii = (uint8_t)dnc_eia_to_iso(wire);
244 uint8_t v = wire & 0x7F;
249 else if (v ==
'\r' || v == 0x00 || v == (uint8_t)DncEiaCode::DNC_EIA_DEL)
262 d->in_program =
true;
263 return DncEvent::DNC_EV_PROG_START;
265 d->in_program =
false;
266 return DncEvent::DNC_EV_PROG_END;
276 return DncEvent::DNC_EV_OVERFLOW;
279 return DncEvent::DNC_EV_NONE;
281 d->line_ready =
true;
282 return DncEvent::DNC_EV_LINE;
286 return DncEvent::DNC_EV_NONE;
289 return DncEvent::DNC_EV_NONE;
293 return DncEvent::DNC_EV_NONE;
295 d->line[d->len++] = (char)ascii;
296 return DncEvent::DNC_EV_NONE;
#define DETWS_DNC_LINE_MAX
Largest G-code block (one line) the DNC decoder reassembles (DETWS_ENABLE_DNC).
CNC RS-232 DNC (Distributed Numerical Control) drip-feed codec (DETWS_ENABLE_DNC).