Skip to content

Commit c28ccaa

Browse files
author
JTrantow
committed
Issue #3849 Fix up ifdelay calculations and ENOMSG handling.
1 parent 75386d8 commit c28ccaa

1 file changed

Lines changed: 11 additions & 10 deletions

File tree

src/hal/drivers/mesa-hostmot2/hm2_modbus.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -374,23 +374,27 @@ static void setup_icdelay(hm2_modbus_inst_t *inst, unsigned baudrate, unsigned p
374374
inst->hal->icdelay = inst->maxicharbits;
375375
}
376376

377+
#define HARDWARE_MAX_DELAY (1020) //!< Maximum ifdelay in number of bits limited by hardware.
378+
#define HARDWARE_BAUD_LIMIT ((HARDWARE_MAX_DELAY*100000-99999)/175) //!< Baud that limits out the hardware ifdelay.
377379
//
378-
// Calculate the inter-frame delay time:
380+
// Calculate the inter-frame delay time in units of numbers of bits.
381+
// Returns:
382+
// - HARDWARE_MAX_DELAY bits if baud > HARDWARE_BAUD_LIMIT
379383
// - 3.5 chars if baudrate <= 19200
380-
// - 1750 microseconds if baudrate > 19200
384+
// - 1750 microseconds worth of bits when baudrate > 19200 and <= HARDWARE_BAUD_LIMIT
381385
//
382386
static unsigned calc_ifdelay(hm2_modbus_inst_t *inst, unsigned baudrate, unsigned parity, unsigned stopbits)
383387
{
384-
if(baudrate > 582000) {
388+
if(baudrate > HARDWARE_BAUD_LIMIT) {
385389
MSG_WARN("%s: warning: Baudrate > 582000 will make inter-frame timer overflow. Setting to maximum.\n", inst->name);
386-
return 1020;
390+
return HARDWARE_MAX_DELAY;
387391
}
388392

389393
// calculation works for baudrates less than ~24 Mbit/s
390-
if(baudrate <= 19200)
394+
if(baudrate > 19200)
391395
return (175u * baudrate + 99999u) / 100000u;
392396
unsigned bits = 1 + 8 + (parity ? 1 : 0) + (stopbits > 1 ? 2 : 1);
393-
return (bits * 35 + 9) / 10; // Bit-times * 3.5 rounded up
397+
return (bits * 35 + 9) / 10; // Ceil of bits in 3.5 characters.
394398
}
395399

396400
//
@@ -1049,13 +1053,10 @@ static void process(void *arg, long period)
10491053
break;
10501054
}
10511055
if(inst->maxicharbits && HM2_PKTUART_RCR_ICHARBITS_VAL(frsize) > inst->maxicharbits) {
1052-
MSG_WARN("%s: warning: reply to command %u had too long inter-character delay (%u > %u), dropping\n",
1056+
MSG_WARN("%s: warning: reply to command %u had too long inter-character delay (%u > %u), trying to interpret\n",
10531057
inst->name, inst->cmdidx,
10541058
HM2_PKTUART_RCR_ICHARBITS_VAL(frsize), inst->maxicharbits);
10551059
set_error(inst, ENOMSG);
1056-
force_resend(inst);
1057-
queue_reset(inst);
1058-
break;
10591060
}
10601061
inst->rxdata[0] = 0; // This will fail the parse packet if the read did not resolve
10611062
r = hm2_pktuart_queue_read_data(inst->uart, inst->rxdata, HM2_PKTUART_RCR_NBYTES_VAL(frsize));

0 commit comments

Comments
 (0)