diff --git a/docs/src/man/man3/hm2_bspi_write_chan.3.adoc b/docs/src/man/man3/hm2_bspi_write_chan.3.adoc index 066f5327f3d..46152f86a4b 100644 --- a/docs/src/man/man3/hm2_bspi_write_chan.3.adoc +++ b/docs/src/man/man3/hm2_bspi_write_chan.3.adoc @@ -33,7 +33,7 @@ Not available in non-realtime components. == RETURN VALUE -Returns 0 on success and -1 on failure. +Returns a positive value on success and -1 on failure. == SEE ALSO diff --git a/src/hal/drivers/mesa-hostmot2/bspi.c b/src/hal/drivers/mesa-hostmot2/bspi.c index c48493c9c83..7d3d043af10 100644 --- a/src/hal/drivers/mesa-hostmot2/bspi.c +++ b/src/hal/drivers/mesa-hostmot2/bspi.c @@ -121,6 +121,10 @@ int hm2_tram_add_bspi_frame(char *name, int chan, rtapi_u32 **wbuff, rtapi_u32 * HM2_ERR_NO_LL("Can not find BSPI instance %s.\n", name); return -1; } + if (chan < 0 || chan > 15) { + HM2_ERR("BSPI %s: channel number %i is out of range\n", name, chan); + return -1; + } if (hm2->bspi.instance[i].conf_flag[chan] != true){ HM2_ERR("The selected write channel (%i) on bspi instance %s.\n" "Has not been configured.\n", chan, name); @@ -187,8 +191,9 @@ int hm2_bspi_clear_fifo(char * name) } rtapi_u32 zero = 0; r = hm2->llio->write(hm2->llio, hm2->bspi.instance[i].count_addr, &zero, sizeof(rtapi_u32)); - if (r < 0) { + if (!r) { HM2_ERR("BSPI: hm2->llio->write failure %s\n", name); + return -1; } return r; @@ -205,14 +210,19 @@ int hm2_bspi_write_chan(char* name, int chan, rtapi_u32 val) HM2_ERR_NO_LL("Can not find BSPI instance %s.\n", name); return -1; } + if (chan < 0 || chan > 15) { + HM2_ERR("BSPI %s: channel number %i is out of range\n", name, chan); + return -1; + } if (hm2->bspi.instance[i].conf_flag[chan] != true){ HM2_ERR("The selected write channel (%i) on bspi instance %s.\n" "Has not been configured.\n", chan, name); return -1; } r = hm2->llio->write(hm2->llio, hm2->bspi.instance[i].addr[chan], &buff, sizeof(rtapi_u32)); - if (r < 0) { + if (!r) { HM2_ERR("BSPI: hm2->llio->write failure %s\n", name); + return -1; } return r; @@ -247,6 +257,10 @@ int hm2_bspi_setup_chan(char *name, int chan, int cs, int bits, double mhz, "BSPI only supports 1-64 bits\n", name, chan, bits); return -1; } + if (mhz <= 0) { + HM2_ERR("BSPI %s: clock frequency must be greater than zero\n", name); + return -1; + } if (delay < 0 || delay > 1e6){ HM2_ERR("The requested frame delay on channel %i of %inS seems " "rather implausible for an SPI device. Exiting.\n", delay, chan); diff --git a/src/hal/drivers/mesa-hostmot2/inm.c b/src/hal/drivers/mesa-hostmot2/inm.c index 596b9e2ba02..ecb935cf634 100644 --- a/src/hal/drivers/mesa-hostmot2/inm.c +++ b/src/hal/drivers/mesa-hostmot2/inm.c @@ -423,7 +423,21 @@ void hm2_inm_force_write(hostmot2_t *hm2) { scanrate = 10000000; hal_set_ui32(inst->hal.param.scan_rate, scanrate/inst->scanwidth); } - divisor = (hm2->inm.clock_frequency / (4 * scanrate)) - 1; + if (scanrate <= 0) { + divisor = 1023; + // Round up so the normalized rate stays within the divisor limit. + hal_set_ui32(inst->hal.param.scan_rate, + (hm2->inm.clock_frequency - 1) + / (4 * (divisor + 1) * inst->scanwidth) + 1); + } else { + divisor = (hm2->inm.clock_frequency / (4 * scanrate)) - 1; + if (divisor > 1023) { + divisor = 1023; + hal_set_ui32(inst->hal.param.scan_rate, + (hm2->inm.clock_frequency - 1) + / (4 * (divisor + 1) * inst->scanwidth) + 1); + } + } rtapi_u32 fast_scans = hal_get_ui32(inst->hal.param.fast_scans); if (fast_scans > 63) { fast_scans = hal_set_ui32(inst->hal.param.fast_scans, 63); @@ -472,13 +486,24 @@ void hm2_inm_write(hostmot2_t *hm2) { hal_set_ui32(inst->hal.param.scan_rate, scanrate/inst->scanwidth); HM2_ERR("inm %d scanrate too high, resetting to %d \n", i, hal_get_ui32(inst->hal.param.scan_rate)); } - divisor = (hm2->inm.clock_frequency / (4 * scanrate)) - 1; // bound divisor so we dont splatter into other fields - if ((divisor > 1023 ) | (scanrate == 0 )) { + if (scanrate <= 0) { divisor = 1023; - hal_set_ui32(inst->hal.param.scan_rate, (hm2->inm.clock_frequency/4)/(divisor +1) - /inst->scanwidth); + // Round up so the normalized rate stays within the divisor limit. + hal_set_ui32(inst->hal.param.scan_rate, + (hm2->inm.clock_frequency - 1) + / (4 * (divisor + 1) * inst->scanwidth) + 1); HM2_ERR("inm %d scanrate too low, resetting to %d \n", i, hal_get_ui32(inst->hal.param.scan_rate)); + } else { + divisor = (hm2->inm.clock_frequency / (4 * scanrate)) - 1; + if (divisor > 1023) { + divisor = 1023; + hal_set_ui32(inst->hal.param.scan_rate, + (hm2->inm.clock_frequency - 1) + / (4 * (divisor + 1) * inst->scanwidth) + 1); + HM2_ERR("inm %d scanrate too low, resetting to %d \n", + i, hal_get_ui32(inst->hal.param.scan_rate)); + } } rtapi_u32 fast_scans = hal_get_ui32(inst->hal.param.fast_scans); if (fast_scans > 63) { diff --git a/src/hal/drivers/mesa-hostmot2/inmux.c b/src/hal/drivers/mesa-hostmot2/inmux.c index eee23922016..833bea8907e 100644 --- a/src/hal/drivers/mesa-hostmot2/inmux.c +++ b/src/hal/drivers/mesa-hostmot2/inmux.c @@ -348,7 +348,21 @@ void hm2_inmux_force_write(hostmot2_t *hm2) { muxrate = 5000000; hal_set_ui32(inst->hal.param.scan_rate, muxrate/inst->scanwidth); } - divisor = (hm2->inmux.clock_frequency / (4 * muxrate)) - 1; + if (muxrate <= 0) { + divisor = 1023; + // Round up so the normalized rate stays within the divisor limit. + hal_set_ui32(inst->hal.param.scan_rate, + (hm2->inmux.clock_frequency - 1) + / (4 * (divisor + 1) * inst->scanwidth) + 1); + } else { + divisor = (hm2->inmux.clock_frequency / (4 * muxrate)) - 1; + if (divisor > 1023) { + divisor = 1023; + hal_set_ui32(inst->hal.param.scan_rate, + (hm2->inmux.clock_frequency - 1) + / (4 * (divisor + 1) * inst->scanwidth) + 1); + } + } rtapi_u32 fast_scans = hal_get_ui32(inst->hal.param.fast_scans); if (fast_scans > 63) { fast_scans = hal_set_ui32(inst->hal.param.fast_scans, 63); @@ -394,13 +408,24 @@ void hm2_inmux_write(hostmot2_t *hm2) { hal_set_ui32(inst->hal.param.scan_rate, muxrate/inst->scanwidth); HM2_ERR("InMux %d scanrate too high, resetting to %d \n", i, hal_get_ui32(inst->hal.param.scan_rate)); } - divisor = (hm2->inmux.clock_frequency / (4 * muxrate)) - 1; // bound divisor so we dont splatter into other fields - if ((divisor > 1023 ) | (muxrate == 0 )) { + if (muxrate <= 0) { divisor = 1023; + // Round up so the normalized rate stays within the divisor limit. hal_set_ui32(inst->hal.param.scan_rate, - (hm2->inmux.clock_frequency/4) / (divisor +1) / inst->scanwidth); + (hm2->inmux.clock_frequency - 1) + / (4 * (divisor + 1) * inst->scanwidth) + 1); HM2_ERR("InMux %d scanrate too low, resetting to %d \n", i, hal_get_ui32(inst->hal.param.scan_rate)); + } else { + divisor = (hm2->inmux.clock_frequency / (4 * muxrate)) - 1; + if (divisor > 1023) { + divisor = 1023; + hal_set_ui32(inst->hal.param.scan_rate, + (hm2->inmux.clock_frequency - 1) + / (4 * (divisor + 1) * inst->scanwidth) + 1); + HM2_ERR("InMux %d scanrate too low, resetting to %d \n", + i, hal_get_ui32(inst->hal.param.scan_rate)); + } } rtapi_u32 fast_scans = hal_get_ui32(inst->hal.param.fast_scans); if (fast_scans > 63) { diff --git a/src/hal/drivers/mesa-hostmot2/pins.c b/src/hal/drivers/mesa-hostmot2/pins.c index 46a1e8a2ec9..e64ffc79e5d 100644 --- a/src/hal/drivers/mesa-hostmot2/pins.c +++ b/src/hal/drivers/mesa-hostmot2/pins.c @@ -769,7 +769,7 @@ int hm2_read_pin_descriptors(hostmot2_t *hm2) { if (pin->port_num >= hm2->llio->num_ioport_connectors) { HM2_ERR("hm2_read_pin_descriptors: Calculated port number (%d) is " - "invalid\n", pin->port_pin ); + "invalid\n", pin->port_num ); return -EINVAL; } @@ -894,7 +894,9 @@ void hm2_print_pin_usage(hostmot2_t *hm2) { char connector_pin_name[100]; - if (hm2->llio->io_connector_pin_names == NULL) { + if (hm2->llio->io_connector_pin_names == NULL + || (unsigned)i >= (hm2->llio->num_ioport_connectors + * hm2->llio->pins_per_connector)) { snprintf(connector_pin_name, sizeof(connector_pin_name), "%s-%02d", hm2->llio->ioport_connector_name[pin->port_num], pin->port_pin); } else { if (hm2->llio->io_connector_pin_names[i] == NULL) { diff --git a/src/hal/drivers/mesa-hostmot2/resolver.c b/src/hal/drivers/mesa-hostmot2/resolver.c index f8c3a064ac2..74df77a44e6 100644 --- a/src/hal/drivers/mesa-hostmot2/resolver.c +++ b/src/hal/drivers/mesa-hostmot2/resolver.c @@ -283,6 +283,12 @@ void hm2_resolver_process_tram_read(hostmot2_t *hm2, long period) { for (i = 0; i < hm2->resolver.num_resolvers; i ++) { res = &hm2->resolver.instance[i]; + rtapi_u32 index_div = hal_get_ui32(res->hal.param.index_div); + + if (index_div == 0) { + HM2_ERR("resolver.%02d.index-div == 0, bogus, setting to 1\n", i); + index_div = hal_set_ui32(res->hal.param.index_div, 1); + } scale = hal_get_real(res->hal.param.scale); @@ -326,7 +332,6 @@ void hm2_resolver_process_tram_read(hostmot2_t *hm2, long period) { if ((res->old_reg > hm2->resolver.position_reg[i]) && (res->old_reg - hm2->resolver.position_reg[i] > 0x80000000)){ res->index_cnts++; if (hal_get_bool(res->hal.pin.index_enable)){ - rtapi_u32 index_div = hal_get_ui32(res->hal.param.index_div); int r = (res->index_cnts % index_div); if ((index_div > 1 && r == 1) || (index_div == 1 && r == 0)){ @@ -337,7 +342,7 @@ void hm2_resolver_process_tram_read(hostmot2_t *hm2, long period) { } else if ((res->old_reg < hm2->resolver.position_reg[i]) && (hm2->resolver.position_reg[i] - res->old_reg > 0x80000000)){ res->index_cnts--; - if (hal_get_bool(res->hal.pin.index_enable) && (res->index_cnts % hal_get_ui32(res->hal.param.index_div) == 0)){ + if (hal_get_bool(res->hal.pin.index_enable) && (res->index_cnts % index_div == 0)){ res->offset = (res->accum - hm2->resolver.position_reg[i] + 0x100000000LL); hal_set_bool(res->hal.pin.index_enable, 0); } diff --git a/src/hal/drivers/mesa-hostmot2/spix_rpi3.c b/src/hal/drivers/mesa-hostmot2/spix_rpi3.c index 3e700048af6..22b4b7336b0 100644 --- a/src/hal/drivers/mesa-hostmot2/spix_rpi3.c +++ b/src/hal/drivers/mesa-hostmot2/spix_rpi3.c @@ -850,8 +850,8 @@ static const spix_port_t *rpi3_open(int port, const spix_args_t *args) if(!rpp->spiport) { rpp->clkdivw = spi0_clkdiv_calc(spiclk_base, args->clkw); rpp->clkdivr = spi0_clkdiv_calc(spiclk_base, args->clkr); - ccw = spiclk_base / rpp->clkdivw; - ccr = spiclk_base / rpp->clkdivr; + ccw = spiclk_base / (rpp->clkdivw ? rpp->clkdivw : 65536); + ccr = spiclk_base / (rpp->clkdivr ? rpp->clkdivr : 65536); } else { rpp->clkdivw = spi1_clkdiv_calc(spiclk_base, args->clkw); rpp->clkdivr = spi1_clkdiv_calc(spiclk_base, args->clkr); diff --git a/src/hal/drivers/mesa-hostmot2/tp_pwmgen.c b/src/hal/drivers/mesa-hostmot2/tp_pwmgen.c index fd5fa57530d..396d6fa2abb 100644 --- a/src/hal/drivers/mesa-hostmot2/tp_pwmgen.c +++ b/src/hal/drivers/mesa-hostmot2/tp_pwmgen.c @@ -443,9 +443,9 @@ void hm2_tp_pwmgen_prepare_tram_write(hostmot2_t *hm2) { if (scaled_Avalue > 1.0) scaled_Avalue = 1.0; else if (scaled_Avalue < -1.0) scaled_Avalue = -1.0; if (scaled_Bvalue > 1.0) scaled_Bvalue = 1.0; - else if (scaled_Avalue < -1.0) scaled_Avalue = -1.0; + else if (scaled_Bvalue < -1.0) scaled_Bvalue = -1.0; if (scaled_Cvalue > 1.0) scaled_Cvalue = 1.0; - else if (scaled_Avalue < -1.0) scaled_Avalue = -1.0; + else if (scaled_Cvalue < -1.0) scaled_Cvalue = -1.0; // duty_cycle goes from 0.0 to 1.0, and needs to be puffed out to 10 bits diff --git a/src/hal/drivers/mesa-hostmot2/uart.c b/src/hal/drivers/mesa-hostmot2/uart.c index 0ca9ed6a5a5..1e0758545ec 100644 --- a/src/hal/drivers/mesa-hostmot2/uart.c +++ b/src/hal/drivers/mesa-hostmot2/uart.c @@ -139,7 +139,7 @@ int hm2_uart_setup(char *name, int bitrate, rtapi_s32 tx_mode, rtapi_s32 rx_mode hostmot2_t *hm2; hm2_uart_instance_t *inst = NULL; rtapi_u32 buff; - int i,r; + int i; i = hm2_get_uart(&hm2, name); if (i < 0){ @@ -149,33 +149,40 @@ int hm2_uart_setup(char *name, int bitrate, rtapi_s32 tx_mode, rtapi_s32 rx_mode inst = &hm2->uart.instance[i]; buff = (rtapi_u32)((bitrate * 1048576.0)/inst->clock_freq); //20 bits in this version - r = 0; if (buff != inst->bitrate){ + rtapi_u32 zero = 0; + inst->bitrate = 0; // A partial change invalidates both directions' cached rate. + if (hm2->llio->write(hm2->llio, inst->rx_bitrate_addr, + &buff, sizeof(buff)) == 0) goto fail; + if (hm2->llio->write(hm2->llio, inst->tx_bitrate_addr, + &buff, sizeof(buff)) == 0) goto fail; + // Clear faults and FIFOs before caching the new configuration. + if (hm2->llio->write(hm2->llio, inst->rx_mode_addr, + &zero, sizeof(zero)) == 0) goto fail; + if (hm2->llio->write(hm2->llio, inst->rx_fifo_count_addr, + &zero, sizeof(zero)) == 0) goto fail; + if (hm2->llio->write(hm2->llio, inst->tx_fifo_count_addr, + &zero, sizeof(zero)) == 0) goto fail; inst->bitrate = buff; - r += hm2->llio->write(hm2->llio, inst->rx_bitrate_addr, &buff, sizeof(rtapi_u32)); - r += hm2->llio->write(hm2->llio, inst->tx_bitrate_addr, &buff, sizeof(rtapi_u32)); - buff = 0; - r += hm2->llio->write(hm2->llio, inst->rx_mode_addr, &buff, sizeof(rtapi_u32)); // clear faults - r += hm2->llio->write(hm2->llio, inst->rx_fifo_count_addr, &buff, sizeof(rtapi_u32)); // clear fifo - r += hm2->llio->write(hm2->llio, inst->tx_fifo_count_addr, &buff, sizeof(rtapi_u32)); // clear fifo } if (tx_mode >= 0) { buff = ((rtapi_u32)tx_mode) & 0x7f; - r += hm2->llio->write(hm2->llio, inst->tx_mode_addr, &buff, sizeof(rtapi_u32)); + if (hm2->llio->write(hm2->llio, inst->tx_mode_addr, + &buff, sizeof(buff)) == 0) goto fail; } if (rx_mode >= 0) { buff = ((rtapi_u32)rx_mode) & 0xff; - r += hm2->llio->write(hm2->llio, inst->rx_mode_addr, &buff, sizeof(rtapi_u32)); - } - - if (r < 0) { - HM2_ERR("UART: hm2->llio->write failure %s\n", name); - return -1; + if (hm2->llio->write(hm2->llio, inst->rx_mode_addr, + &buff, sizeof(buff)) == 0) goto fail; } return 0; + +fail: + HM2_ERR("UART: hm2->llio->write failure %s\n", name); + return -1; } @@ -189,17 +196,20 @@ int hm2_uart_send(char *name, unsigned char data[], int count) static int err_flag = 0; inst = hm2_get_uart(&hm2, name); - if (inst < 0 && !err_flag){ - HM2_ERR_NO_LL("Can not find UART instance %s.\n", name); + if (inst < 0){ + if (!err_flag) + HM2_ERR_NO_LL("Can not find UART instance %s.\n", name); err_flag = 1; return -1; } - if (hm2->uart.instance[inst].bitrate == 0 && !err_flag){ - HM2_ERR("The selected UART instance %s.\n" - "Has not been configured.\n", name); + if (hm2->uart.instance[inst].bitrate == 0){ + if (!err_flag) + HM2_ERR("The selected UART instance %s.\n" + "Has not been configured.\n", name); err_flag = 1; // don't fill dmesg with junk. return -1; } + if (count < 0) return -1; c = 0; err_flag = 0; @@ -207,12 +217,12 @@ int hm2_uart_send(char *name, unsigned char data[], int count) buff = (data[c] + (data[c+1] << 8) + (data[c+2] << 16) + - (data[c+3] << 24)); + ((rtapi_u32)data[c+3] << 24)); r = hm2->llio->write(hm2->llio, hm2->uart.instance[inst].tx4_addr, &buff, sizeof(rtapi_u32)); - if (r < 0) { + if (!r) { HM2_ERR("UART WRITE: hm2->llio->write failure %s\n", name); - return r; + return -1; } c = c + 4; } @@ -223,9 +233,9 @@ int hm2_uart_send(char *name, unsigned char data[], int count) buff = data[c]; r = hm2->llio->write(hm2->llio, hm2->uart.instance[inst].tx1_addr, &buff, sizeof(rtapi_u32)); - if (r < 0){ + if (!r){ HM2_ERR("UART WRITE: hm2->llio->write failure %s\n", name); - return r; + return -1; }else{ return c + 1; } @@ -234,9 +244,9 @@ int hm2_uart_send(char *name, unsigned char data[], int count) (data[c+1] << 8)); r = hm2->llio->write(hm2->llio, hm2->uart.instance[inst].tx2_addr, &buff, sizeof(rtapi_u32)); - if (r < 0){ + if (!r){ HM2_ERR("UART_WRITE: hm2->llio->write failure %s\n", name); - return r; + return -1; }else{ return c + 2; } @@ -246,9 +256,9 @@ int hm2_uart_send(char *name, unsigned char data[], int count) (data[c+2] << 16)); r = hm2->llio->write(hm2->llio, hm2->uart.instance[inst].tx3_addr, &buff, sizeof(rtapi_u32)); - if (r < 0){ + if (!r){ HM2_ERR("UART WRITE: hm2->llio->write failure %s\n", name); - return r; + return -1; }else{ return c + 3; } @@ -286,6 +296,10 @@ int hm2_uart_read(char *name, unsigned char data[]) r = hm2->llio->read(hm2->llio, hm2->uart.instance[inst].rx_fifo_count_addr, &buff, sizeof(rtapi_u32)); + if (!r) { + HM2_ERR("UART: hm2->llio->read failure %s\n", name); + return -1; + } count = buff & 0x1F; c = 0; @@ -293,9 +307,9 @@ int hm2_uart_read(char *name, unsigned char data[]) r = hm2->llio->read(hm2->llio, hm2->uart.instance[inst].rx4_addr, &buff, sizeof(rtapi_u32)); - if (r < 0) { + if (!r) { HM2_ERR("UART: hm2->llio->read failure %s\n", name); - return r; + return -1; } data[c] = (buff & 0x000000FF); @@ -311,18 +325,18 @@ int hm2_uart_read(char *name, unsigned char data[]) case 1: r = hm2->llio->read(hm2->llio, hm2->uart.instance[inst].rx1_addr, &buff, sizeof(rtapi_u32)); - if (r < 0) { + if (!r) { HM2_ERR("UART READ: hm2->llio->read failure %s\n", name); - return r; + return -1; } data[c] = (buff & 0x000000FF); return c + 1; case 2: r = hm2->llio->read(hm2->llio, hm2->uart.instance[inst].rx2_addr, &buff, sizeof(rtapi_u32)); - if (r < 0) { + if (!r) { HM2_ERR("UART READ: hm2->llio->read failure %s\n", name); - return r; + return -1; } data[c] = (buff & 0x000000FF); data[c+1] = (buff & 0x0000FF00) >> 8; @@ -330,9 +344,9 @@ int hm2_uart_read(char *name, unsigned char data[]) case 3: r = hm2->llio->read(hm2->llio, hm2->uart.instance[inst].rx3_addr, &buff, sizeof(rtapi_u32)); - if (r < 0) { + if (!r) { HM2_ERR("UART READ: hm2->llio->read failure %s\n", name); - return r; + return -1; } data[c] = (buff & 0x000000FF); data[c+1] = (buff & 0x0000FF00) >> 8;