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 pc_dnc_iso_to_eia(
char c)
80 for (
size_t i = 0; i < DNC_EIA_MAP_LEN; i++)
82 if (DNC_EIA_MAP[i].ascii == c)
84 return DNC_EIA_MAP[i].eia;
90char pc_dnc_eia_to_iso(uint8_t b)
92 for (
size_t i = 0; i < DNC_EIA_MAP_LEN; i++)
94 if (DNC_EIA_MAP[i].eia == b)
96 return DNC_EIA_MAP[i].ascii;
102uint8_t pc_dnc_iso_add_parity(uint8_t ascii7)
104 uint8_t v = ascii7 & 0x7F;
110 x &= (uint8_t)(x - 1);
112 return (uint8_t)(v | (p ? 0x80 : 0x00));
115void pc_dnc_flow_init(DncFlow *f)
120bool pc_dnc_flow_feed(DncFlow *f, uint8_t rx)
122 if (rx == (uint8_t)DncFlowByte::DNC_XOFF)
127 if (rx == (uint8_t)DncFlowByte::DNC_XON)
136static size_t dnc_put_eob(
const DncCfg *cfg, uint8_t *out,
size_t cap,
size_t n)
138 if (cfg->code == DncCode::DNC_CODE_EIA)
144 out[n++] = (uint8_t)DncEiaCode::DNC_EIA_EOB;
149 uint8_t cr = cfg->even_parity ? pc_dnc_iso_add_parity(0x0D) : 0x0D;
156 uint8_t lf = cfg->even_parity ? pc_dnc_iso_add_parity(0x0A) : 0x0A;
165size_t pc_dnc_encode_block(
const DncCfg *cfg,
const char *line,
size_t line_len, uint8_t *out,
size_t out_cap)
168 for (
size_t i = 0; i < line_len; i++)
171 if (cfg->code == DncCode::DNC_CODE_EIA)
173 uint8_t e = pc_dnc_iso_to_eia(line[i]);
182 b = (uint8_t)line[i] & 0x7F;
183 if (cfg->even_parity)
185 b = pc_dnc_iso_add_parity(b);
194 return dnc_put_eob(cfg, out, out_cap, n);
197size_t pc_dnc_encode_marker(
const DncCfg *cfg, uint8_t *out,
size_t out_cap)
200 if (cfg->code == DncCode::DNC_CODE_EIA)
206 out[n++] = (uint8_t)DncEiaCode::DNC_EIA_EOR;
210 uint8_t pct = cfg->even_parity ? pc_dnc_iso_add_parity(0x25) : 0x25;
217 return dnc_put_eob(cfg, out, out_cap, n);
220size_t pc_dnc_encode_leader(
const DncCfg *cfg, uint8_t *out,
size_t out_cap)
222 uint16_t n = cfg->leader_len;
223 if ((
size_t)n > out_cap)
227 for (uint16_t i = 0; i < n; i++)
234void pc_dnc_decode_init(DncDecoder *d, DncCode code)
239 d->in_program =
false;
240 d->line_ready =
false;
244DncEvent pc_dnc_decode_feed(DncDecoder *d, uint8_t wire)
249 d->line_ready =
false;
258 bool is_marker =
false;
261 if (d->code == DncCode::DNC_CODE_EIA)
263 if (wire == (uint8_t)DncEiaCode::DNC_EIA_EOB)
267 else if (wire == (uint8_t)DncEiaCode::DNC_EIA_EOR)
273 ascii = (uint8_t)pc_dnc_eia_to_iso(wire);
278 uint8_t v = wire & 0x7F;
287 else if (v ==
'\r' || v == 0x00 || v == (uint8_t)DncEiaCode::DNC_EIA_DEL)
304 d->in_program =
true;
305 return DncEvent::DNC_EV_PROG_START;
307 d->in_program =
false;
308 return DncEvent::DNC_EV_PROG_END;
318 return DncEvent::DNC_EV_OVERFLOW;
322 return DncEvent::DNC_EV_NONE;
325 d->line_ready =
true;
326 return DncEvent::DNC_EV_LINE;
331 return DncEvent::DNC_EV_NONE;
336 return DncEvent::DNC_EV_NONE;
341 return DncEvent::DNC_EV_NONE;
343 d->line[d->len++] = (char)ascii;
344 return DncEvent::DNC_EV_NONE;
CNC RS-232 DNC (Distributed Numerical Control) drip-feed codec (PC_ENABLE_DNC).
#define PC_DNC_LINE_MAX
Largest G-code block (one line) the DNC decoder reassembles (PC_ENABLE_DNC).