diff --git a/README.md b/README.md index bb39ae7..4968cac 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## grblHAL ## -Latest build date is 20250305, see the [changelog](changelog.md) for details. +Latest build date is 20250311, see the [changelog](changelog.md) for details. > [!NOTE] > A settings reset will be performed on an update of builds prior to 20241208. Backup and restore of settings is recommended. @@ -89,4 +89,4 @@ G/M-codes not supported by [legacy Grbl](https://github.com/gnea/grbl/wiki) are Some [plugins](https://github.com/grblHAL/plugins) implements additional M-codes. --- -20250305 +20250311 diff --git a/changelog.md b/changelog.md index f839695..57307c8 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,31 @@ ## grblHAL changelog +Build 20250311 + +Core: + +* Some ioports HAL wrapper functions refactored. Fixes persisting issue with coprocessor control pins mentioned [here](https://github.com/grblHAL/core/discussions/675#discussioncomment-12434634). + +* Changed some parts to no longer reference deprecated code. + +* Added some display driver symbols \(for plugin use\). + +Drivers: + +* STM32F4xx: added flexi-HAL board, ref. PR [#](). + +* STM32F4xx, STM32F7xx: fix for regression causing axis drift when step delay was enabled with $29. Ref. issue [#220](https://github.com/grblHAL/STM32F4xx/issues/220). + +* ESP32: fixed board map errors.Ref issue [#150](https://github.com/grblHAL/ESP32/issues/150). Improved I2C driver code. + +Plugins: + +* Networking: workaround for iMXRT1062 compiler \(linker?\) issue. + +* OpenPNP: no longer references deprecated code. + +--- + Build 20250307 Core: diff --git a/gcode.c b/gcode.c index 052bfdc..a9f66b4 100644 --- a/gcode.c +++ b/gcode.c @@ -1368,14 +1368,15 @@ status_code_t gc_execute_block (char *block) case 63: case 64: case 65: - if(hal.port.digital_out == NULL || hal.port.num_digital_out == 0) + if(hal.port.digital_out == NULL || ioports_unclaimed(Port_Digital, Port_Output) == 0) FAIL(Status_GcodeUnsupportedCommand); // [Unsupported M command] word_bit.modal_group.M5 = On; port_command = (io_mcode_t)int_value; break; case 66: - if(hal.port.wait_on_input == NULL || (hal.port.num_digital_in == 0 && hal.port.num_analog_in == 0)) + if(hal.port.wait_on_input == NULL || (ioports_unclaimed(Port_Digital, Port_Input) == 0 && + ioports_unclaimed(Port_Analog, Port_Input) == 0)) FAIL(Status_GcodeUnsupportedCommand); // [Unsupported M command] word_bit.modal_group.M5 = On; port_command = (io_mcode_t)int_value; @@ -1383,7 +1384,7 @@ status_code_t gc_execute_block (char *block) case 67: case 68: - if(hal.port.analog_out == NULL || hal.port.num_analog_out == 0) + if(hal.port.analog_out == NULL || ioports_unclaimed(Port_Analog, Port_Output) == 0) FAIL(Status_GcodeUnsupportedCommand); // [Unsupported M command] word_bit.modal_group.M5 = On; port_command = (io_mcode_t)int_value; @@ -1942,7 +1943,7 @@ status_code_t gc_execute_block (char *block) FAIL(Status_GcodeValueWordMissing); if(gc_block.values.p < 0.0f) FAIL(Status_NegativeValue); - if((uint32_t)gc_block.values.p + 1 > hal.port.num_digital_out) + if((uint32_t)gc_block.values.p >= ioports_unclaimed(Port_Digital, Port_Output)) FAIL(Status_GcodeValueOutOfRange); gc_block.output_command.is_digital = true; gc_block.output_command.port = (uint8_t)gc_block.values.p; @@ -1966,7 +1967,7 @@ status_code_t gc_execute_block (char *block) if(gc_block.words.p) { if(gc_block.values.p < 0.0f) FAIL(Status_NegativeValue); - if((uint32_t)gc_block.values.p + 1 > hal.port.num_digital_in) + if((uint32_t)gc_block.values.p >= ioports_unclaimed(Port_Digital, Port_Input)) FAIL(Status_GcodeValueOutOfRange); gc_block.output_command.is_digital = true; @@ -1974,7 +1975,7 @@ status_code_t gc_execute_block (char *block) } if(gc_block.words.e) { - if((uint32_t)gc_block.values.e + 1 > hal.port.num_analog_in) + if((uint32_t)gc_block.values.e >= ioports_unclaimed(Port_Analog, Port_Input)) FAIL(Status_GcodeValueOutOfRange); if((wait_mode_t)gc_block.values.l != WaitMode_Immediate) FAIL(Status_GcodeValueOutOfRange); @@ -1990,7 +1991,7 @@ status_code_t gc_execute_block (char *block) case IoMCode_AnalogOutImmediate: if(!(gc_block.words.e || gc_block.words.q)) FAIL(Status_GcodeValueWordMissing); - if((uint32_t)gc_block.values.e + 1 > hal.port.num_analog_out) + if((uint32_t)gc_block.values.e >= ioports_unclaimed(Port_Analog, Port_Output)) FAIL(Status_GcodeRPMOutOfRange); gc_block.output_command.is_digital = false; gc_block.output_command.port = (uint8_t)gc_block.values.e; diff --git a/grbl.h b/grbl.h index 7af1126..a8c3290 100644 --- a/grbl.h +++ b/grbl.h @@ -42,7 +42,7 @@ #else #define GRBL_VERSION "1.1f" #endif -#define GRBL_BUILD 20250307 +#define GRBL_BUILD 20250311 #define GRBL_URL "https://github.com/grblHAL" diff --git a/ioports.c b/ioports.c index 56b1215..67eb8cb 100644 --- a/ioports.c +++ b/ioports.c @@ -38,8 +38,11 @@ typedef struct { io_ports_detail_t *ports; char port_names[8 * 6 + (MAX_PORTS - 8) * 7]; ioport_bus_t enabled; + int16_t count; + int16_t free; pin_function_t min_fn; pin_function_t max_fn; + uint8_t map[MAX_PORTS]; } io_ports_private_t; typedef struct { @@ -52,14 +55,21 @@ typedef struct { static driver_settings_load_ptr on_settings_loaded = NULL; static setting_changed_ptr on_setting_changed = NULL; static io_ports_cfg_t digital = { + .in.count = -1, + .in.free = -1, .in.min_fn = Input_Aux0, .in.max_fn = Input_AuxMax, + .out.count = -1, + .out.free = -1, .out.min_fn = Output_Aux0, .out.max_fn = Output_AuxMax }, analog = { + .in.count = -1, + .in.free = -1, .in.min_fn = Input_Analog_Aux0, .in.max_fn = Input_Analog_AuxMax, + .out.count = -1, + .out.free = -1, .out.min_fn = Output_Analog_Aux0, .out.max_fn = Output_Analog_AuxMax }; -static int16_t digital_in = -1, digital_out = -1, analog_in = -1, analog_out = -1; static inline io_ports_private_t *get_port_data (io_port_type_t type, io_port_direction_t dir) { @@ -72,50 +82,36 @@ static inline uint8_t resolve_portnum (io_ports_private_t *p_data, xbar_t *port) return port->function >= p_data->min_fn && port->function <= p_data->max_fn ? (port->function - p_data->min_fn) : ioports_map_reverse(p_data->ports, port->id); } -static uint8_t ioports_count (io_port_type_t type, io_port_direction_t dir) +static uint8_t ioports_count (io_port_type_t type, io_port_direction_t dir, io_ports_private_t *p_data) { xbar_t *port; - uint8_t n_ports = 0; + uint8_t n_ports = 0, n_remapped = 0; - // determine how many ports, including claimed ports, that are available - do { - if((port = hal.port.get_pin_info(type, dir, n_ports))) + // determine how many ports, including claimed ports, that are available. remapped ports may be excluded. + if(hal.port.get_pin_info) do { + if((port = hal.port.get_pin_info(type, dir, n_ports))) { n_ports++; + if(p_data && (port->function < p_data->min_fn || port->function > p_data->max_fn)) + n_remapped++; + } } while(port != NULL); - return n_ports; + return n_ports - n_remapped; } /*! \brief Get number of digital or analog ports available. \param type as an \a #io_port_type_t enum value. \param dir as an \a #io_port_direction_t enum value. -\returns number of ports available including claimed ports if the API implementation supports that. +\returns number of ports available excluding remapped ports but including claimed ports if the API implementation supports that. */ uint8_t ioports_available (io_port_type_t type, io_port_direction_t dir) { - uint8_t ports = 0; + io_ports_private_t *p_data = get_port_data(type, dir); - if(hal.port.get_pin_info) { + if(p_data->count == -1) + p_data->count = ioports_count(type, dir, get_port_data(type, dir)); - if(type == Port_Digital) { - if(dir == Port_Input) - ports = digital_in == -1 ? (digital_in = ioports_count(type, dir)) : (uint8_t)digital_in; - else - ports = digital_out == -1 ? (digital_out = ioports_count(type, dir)) : (uint8_t)digital_out; - } else { - if(dir == Port_Input) - ports = analog_in == -1 ? (analog_in = ioports_count(type, dir)) : (uint8_t)analog_in; - else - ports = analog_out == -1 ? (analog_out = ioports_count(type, dir)) : (uint8_t)analog_out; - } - } else { - if(type == Port_Digital) - ports = dir == Port_Input ? hal.port.num_digital_in : hal.port.num_digital_out; - else - ports = dir == Port_Input ? hal.port.num_analog_in : hal.port.num_analog_out; - } - - return ports; + return p_data->count; } /*! \brief Get number of unclaimed digital or analog ports available. @@ -125,15 +121,22 @@ uint8_t ioports_available (io_port_type_t type, io_port_direction_t dir) */ uint8_t ioports_unclaimed (io_port_type_t type, io_port_direction_t dir) { - xbar_t *port; - uint8_t idx = 0, n_ports = 0; + io_ports_private_t *p_data = get_port_data(type, dir); - if(hal.port.get_pin_info) do { - if((port = hal.port.get_pin_info(type, dir, idx++)) && !port->mode.claimed) - n_ports++; - } while(port); + if(p_data->free == -1) { - return n_ports; + xbar_t *port; + uint8_t idx = 0; + + p_data->free = 0; + + if(hal.port.get_pin_info) do { + if((port = hal.port.get_pin_info(type, dir, idx++)) && !port->mode.claimed) + p_data->free++; + } while(port); + } + + return p_data->free; } static struct ff_data { @@ -177,20 +180,56 @@ uint8_t ioport_find_free (io_port_type_t type, io_port_direction_t dir, pin_cap_ \param port the port aux number. \returns pointer to \a xbar_t struct if successful, NULL if not. */ -xbar_t *ioport_get_info (io_port_type_t type, io_port_direction_t dir, uint8_t port) +static xbar_t *get_info (io_port_type_t type, io_port_direction_t dir, uint8_t port, bool claim) { bool ok = false; - uint8_t n_ports = ioports_available(type, dir); - io_ports_private_t *p_data = get_port_data(type, dir); xbar_t *portinfo = NULL; + io_ports_private_t *p_data = get_port_data(type, dir); + uint8_t n_ports = p_data->ports ? p_data->ports->n_ports : 0; if(hal.port.get_pin_info && n_ports) do { - ok = (portinfo = hal.port.get_pin_info(type, dir, --n_ports)) && resolve_portnum(p_data, portinfo) == port; + ok = (portinfo = hal.port.get_pin_info(type, dir, --n_ports)) && !(claim && portinfo->mode.claimed) && resolve_portnum(p_data, portinfo) == port; } while(n_ports && !ok); return ok ? portinfo : NULL; } +/*! \brief Return information about a digital or analog port. +\param type as an \a #io_port_type_t enum value. +\param dir as an \a #io_port_direction_t enum value. +\param port the port aux number. +\returns pointer to \a xbar_t struct if successful, NULL if not. +*/ +xbar_t *ioport_get_info (io_port_type_t type, io_port_direction_t dir, uint8_t port) +{ + return get_info(type, dir, port, false); +} + + +/* code to keep deprecated data updated, to be removed */ + +static inline uint8_t get_hcount (io_port_type_t type, io_port_direction_t dir) +{ + return type == Port_Digital + ? (dir == Port_Input ? hal.port.num_digital_in : hal.port.num_digital_out) + : (dir == Port_Input ? hal.port.num_analog_in : hal.port.num_analog_out); +} + +static inline void dec_hcount (io_port_type_t type, io_port_direction_t dir) +{ + if(type == Port_Digital) { + if(dir == Port_Input) + hal.port.num_digital_in--; + else + hal.port.num_digital_out--; + } else if(dir == Port_Input) + hal.port.num_analog_in--; + else + hal.port.num_analog_out--; +} + +/* end deprecated */ + /*! \brief Claim a digital or analog port for exclusive use. \param type as an \a #io_port_type_t enum value. \param dir as an \a #io_port_direction_t enum value. @@ -200,35 +239,23 @@ xbar_t *ioport_get_info (io_port_type_t type, io_port_direction_t dir, uint8_t p */ bool ioport_claim (io_port_type_t type, io_port_direction_t dir, uint8_t *port, const char *description) { - bool ok; + bool ok = false; if(hal.port.claim) { xbar_t *portinfo; + uint8_t hcnt = get_hcount(type, dir); - ok = (portinfo = ioport_get_info(type, dir, *port)) && -// portinfo->cap.claimable && TODO: add? - !portinfo->mode.claimed && - hal.port.claim(type, dir, port, description); + if((ok = (portinfo = get_info(type, dir, *port, true)) && + // portinfo->cap.claimable && TODO: add? + !portinfo->mode.claimed && + hal.port.claim(type, dir, port, description))) { - } else { + get_port_data(type, dir)->free = -1; - uint_fast8_t count; - get_pin_info_ptr get_pin_info = hal.port.get_pin_info; - - hal.port.get_pin_info = NULL; // Force count of unclaimed ports only. - - if((ok = (count = ioports_available(type, dir)) > 0 && *port == count - 1 )) { - if(type == Port_Digital) - *port = dir == Port_Input ? --hal.port.num_digital_in : --hal.port.num_digital_out; - else - *port = dir == Port_Input ? --hal.port.num_analog_in : --hal.port.num_analog_out; - - if(hal.port.set_pin_description) - hal.port.set_pin_description(type, dir, *port, description); + if(get_hcount(type, dir) == hcnt) + dec_hcount(type, dir); } - - hal.port.get_pin_info = get_pin_info; } return ok; @@ -246,6 +273,7 @@ void ioport_assign_function (aux_ctrl_t *aux_ctrl, pin_function_t *function) *function = aux_ctrl->function; digital.inx.mask &= ~(1 << input->id); + digital.in.count = digital.in.free = -1; hal.signals_cap.mask |= aux_ctrl->cap.mask; if(aux_ctrl->function == Input_Probe || xbar_fn_to_signals_mask(aux_ctrl->function).mask) @@ -261,13 +289,14 @@ void ioport_assign_out_function (aux_ctrl_out_t *aux_ctrl, pin_function_t *funct *function = aux_ctrl->function; digital.outx.mask &= ~(1 << output->id); + digital.out.count = digital.out.free = -1; setting_remove_elements(Settings_IoPort_InvertOut, digital.outx.mask); } } /*! \brief Check if ports can be claimed by aux number or not. -\returns true if ports can be claimed by aux number, false if claimed ports are allocated by the API. +\returns true if ports can be claimed by aux number, false if not. */ bool ioport_can_claim_explicit (void) { @@ -277,18 +306,31 @@ bool ioport_can_claim_explicit (void) bool ioports_enumerate (io_port_type_t type, io_port_direction_t dir, pin_cap_t filter, ioports_enumerate_callback_ptr callback, void *data) { bool ok = false; - uint_fast16_t n_ports = ioports_available(type, dir); io_ports_private_t *p_data = get_port_data(type, dir); - if(n_ports && ioport_can_claim_explicit()) do { + if(p_data->ports && p_data->ports->n_ports && ioport_can_claim_explicit()) { - xbar_t *portinfo; + xbar_t *portinfo; + uint_fast16_t n_ports; - if((portinfo = hal.port.get_pin_info(type, dir, --n_ports)) && (portinfo->cap.mask & filter.mask) == filter.mask) { - if((ok = callback(portinfo, resolve_portnum(p_data, portinfo), data))) - break; - } - } while(n_ports); + if(filter.mask) { + + uint_fast16_t n_ports = p_data->ports->n_ports; + + do { + if((portinfo = hal.port.get_pin_info(type, dir, --n_ports)) && (portinfo->cap.mask & filter.mask) == filter.mask) { + if((ok = callback(portinfo, resolve_portnum(p_data, portinfo), data))) + break; + } + } while(n_ports); + + } else for(n_ports = 0; n_ports < p_data->ports->n_ports; n_ports++) { + if((portinfo = hal.port.get_pin_info(type, dir, n_ports))) { + if((ok = callback(portinfo, resolve_portnum(p_data, portinfo), data))) + break; + } + } + } return ok; } @@ -337,6 +379,25 @@ static char *get_pnum (io_ports_data_t *ports, uint8_t port) return ports->pnum ? (ports->pnum + (port * 3) + (port > 9 ? port - 10 : 0)) : NULL; } +static uint8_t add_ports (io_ports_detail_t *ports, uint8_t *map, io_port_type_t type, io_port_direction_t dir, uint8_t n_ports) +{ + io_ports_private_t *p_data = get_port_data(type, dir); + + ports->n_start = ioports_count(type, dir, NULL); + + if(ports->n_start + n_ports > MAX_PORTS) + n_ports = MAX_PORTS - ports->n_start; + + ports->n_ports = n_ports; + ports->idx_last += n_ports; + ports->map = map; + if(p_data->ports == NULL) // for now... + p_data->ports = ports; + p_data->count = -1; + + return n_ports; +} + bool ioports_add (io_ports_data_t *ports, io_port_type_t type, uint8_t n_in, uint8_t n_out) { uint_fast8_t n_ports; @@ -348,41 +409,21 @@ bool ioports_add (io_ports_data_t *ports, io_port_type_t type, uint8_t n_in, uin cfg = &digital; - if(n_in) { - ports->in.n_start = ioports_available(Port_Digital, Port_Input); - hal.port.num_digital_in += (ports->in.n_ports = n_in); - ports->in.map = malloc(ports->in.n_ports * sizeof(ports->in.n_ports)); - digital.in.ports = &ports->in; - digital_in = -1; - } + if(n_in) + hal.port.num_digital_in += add_ports(&ports->in, digital.in.map, type, Port_Input, n_in); - if(n_out) { - ports->out.n_start = ioports_available(Port_Digital, Port_Output); - hal.port.num_digital_out += (ports->out.n_ports = n_out); - ports->out.map = malloc(ports->out.n_ports * sizeof(ports->out.n_ports)); - digital.out.ports = &ports->out; - digital_out = -1; - } + if(n_out) + hal.port.num_digital_out += add_ports(&ports->out, digital.out.map, type, Port_Output, n_out); } else { cfg = &analog; - if(n_in) { - ports->in.n_start = ioports_available(Port_Analog, Port_Input); - hal.port.num_analog_in += (ports->in.n_ports = n_in); - ports->in.map = malloc(ports->in.n_ports * sizeof(ports->in.n_ports)); - analog.in.ports = &ports->in; - analog_in = -1; - } + if(n_in) + hal.port.num_analog_in += add_ports(&ports->in, analog.in.map, type, Port_Input, n_in); - if(n_out) { - ports->out.n_start = ioports_available(Port_Analog, Port_Output); - hal.port.num_analog_out += (ports->out.n_ports = n_out); - ports->out.map = malloc(ports->out.n_ports * sizeof(ports->out.n_ports)); - analog.out.ports = &ports->out; - analog_out = -1; - } + if(n_out) + hal.port.num_analog_out += add_ports(&ports->out, analog.out.map, type, Port_Output, n_out); } if((n_ports = max(ports->in.n_ports, ports->out.n_ports)) > 0) { @@ -432,6 +473,24 @@ bool ioports_add (io_ports_data_t *ports, io_port_type_t type, uint8_t n_in, uin return n_ports > 0; } +/* +bool ioports_add_digital (io_digital_t *digital) +{ + if(ioports_add(&digital, Port_Digital, digital->ports->in.n_ports, digital->ports->out.n_ports)) { + + if(digital->ports->in.n_ports) { + hal.port.wait_on_input = digital->wait_on_input; + hal.port.register_interrupt_handler = digital->register_interrupt_handler; + } + + if(digital->ports->out.n_ports) + hal.port.digital_out = digital->digital_out; + + hal.port.claim = digital->claim; + hal.port.get_pin_info = digital->get_pin_info; + } +} +*/ ISR_CODE uint8_t ISR_FUNC(ioports_map_reverse)(io_ports_detail_t *type, uint8_t port) { diff --git a/ioports.h b/ioports.h index 1c3a661..77e0e9b 100644 --- a/ioports.h +++ b/ioports.h @@ -147,6 +147,7 @@ struct io_ports_data; typedef struct { uint8_t n_ports; uint8_t n_start; + uint8_t idx_last; uint8_t *map; } io_ports_detail_t; @@ -157,6 +158,27 @@ typedef struct io_ports_data { char *(*get_pnum)(struct io_ports_data *data, uint8_t port); } io_ports_data_t; +/* +typedef struct { + io_ports_data_t *analog; + analog_out_ptr analog_out; //!< Handler for setting an analog output. + wait_on_input_ptr wait_on_input; //!< Handler for reading a digital or analog input. + set_pin_description_ptr set_pin_description; //!< Handler for setting a description of an auxiliary pin. + get_pin_info_ptr get_pin_info; //!< Handler for getting information about an auxiliary pin. + claim_port_ptr claim; //!< Handler for claiming an auxiliary pin for exclusive use. +} io_analog_t; + +typedef struct { + io_ports_data_t *ports; + digital_out_ptr digital_out; //!< Handler for setting a digital output. + wait_on_input_ptr wait_on_input; //!< Handler for reading a digital or analog input. + set_pin_description_ptr set_pin_description; //!< Handler for setting a description of an auxiliary pin. + get_pin_info_ptr get_pin_info; //!< Handler for getting information about an auxiliary pin. + claim_port_ptr claim; //!< Handler for claiming an auxiliary pin for exclusive use. + ioport_register_interrupt_handler_ptr register_interrupt_handler; +} io_digital_t; +*/ + //!* \brief Precalculated values that may be set/used by HAL driver to speed up analog input to PWM conversions. */ typedef struct { uint32_t f_clock; @@ -171,6 +193,8 @@ typedef struct { } ioports_pwm_t; bool ioports_add (io_ports_data_t *ports, io_port_type_t type, uint8_t n_in, uint8_t n_out); +//bool ioports_add_analog (io_analog_t *ports); +//bool ioports_add_digital (io_digital_t *ports); void ioports_add_settings (driver_settings_load_ptr settings_loaded, setting_changed_ptr setting_changed); void ioport_save_input_settings (xbar_t *xbar, gpio_in_config_t *config); void ioport_save_output_settings (xbar_t *xbar, gpio_out_config_t *config); diff --git a/plugins.h b/plugins.h index f5e47ad..47f9c04 100644 --- a/plugins.h +++ b/plugins.h @@ -264,6 +264,15 @@ typedef union { #define DISPLAY_I2C_LEDS ((1<<4)|DISPLAY_I2C) //!< 17 #define DISPLAY_I2C_LUC ((1<<5)|DISPLAY_I2C) //!< 33 +// Driver chips + +#define DISPLAY_DRIVER_SH1106 1 +#define DISPLAY_DRIVER_SSD1306 2 +#define DISPLAY_DRIVER_SSD1331 3 +#define DISPLAY_DRIVER_ILI9340 4 +#define DISPLAY_DRIVER_ILI9341 5 +#define DISPLAY_DRIVER_ILI9486 6 + // EEPROM/FRAM: typedef i2c_transfer_t nvs_transfer_t; diff --git a/report.c b/report.c index aebb071..44d63fd 100644 --- a/report.c +++ b/report.c @@ -2385,88 +2385,86 @@ static char *pull_mode (pull_mode_t mode) return "-"; } -status_code_t report_pin_states (sys_state_t state, char *args) +static bool print_aux_din (xbar_t *port, uint8_t pnum, void *data) { - xbar_t *port; - uint8_t idx, ports; + hal.stream.write("[PINSTATE:DIN|"); + hal.stream.write(port->description ? port->description : xbar_fn_to_pinname(port->function)); + hal.stream.write("|"); + hal.stream.write(uitoa(port->id)); + hal.stream.write("|"); + hal.stream.write(port->mode.inverted ? "I" : "N"); + hal.stream.write(pull_mode((pull_mode_t)port->mode.pull_mode)); + hal.stream.write(irq_mode((pin_irq_mode_t)port->mode.irq_mode)); + hal.stream.write(port->mode.debounce ? "D" : "-"); + hal.stream.write("|"); + hal.stream.write(port->cap.invert ? "I" : "-"); + hal.stream.write(pull_mode((pull_mode_t)port->cap.pull_mode)); + hal.stream.write(irq_mode((pin_irq_mode_t)port->cap.irq_mode)); + hal.stream.write(port->cap.debounce ? "D" : "-"); + hal.stream.write("|"); + hal.stream.write(port->get_value ? uitoa((uint32_t)port->get_value(port)) : "?"); + hal.stream.write("]" ASCII_EOL); - if((ports = ioports_available(Port_Digital, Port_Input))) { - for(idx = 0; idx < ports; idx++) { - if((port = hal.port.get_pin_info(Port_Digital, Port_Input, idx))) { - hal.stream.write("[PINSTATE:DIN|"); - hal.stream.write(port->description ? port->description : xbar_fn_to_pinname(port->function)); - hal.stream.write("|"); - hal.stream.write(uitoa(port->id)); - hal.stream.write("|"); - hal.stream.write(port->mode.inverted ? "I" : "N"); - hal.stream.write(pull_mode((pull_mode_t)port->mode.pull_mode)); - hal.stream.write(irq_mode((pin_irq_mode_t)port->mode.irq_mode)); - hal.stream.write(port->mode.debounce ? "D" : "-"); - hal.stream.write("|"); - hal.stream.write(port->cap.invert ? "I" : "-"); - hal.stream.write(pull_mode((pull_mode_t)port->cap.pull_mode)); - hal.stream.write(irq_mode((pin_irq_mode_t)port->cap.irq_mode)); - hal.stream.write(port->cap.debounce ? "D" : "-"); - hal.stream.write("|"); - hal.stream.write(port->get_value ? uitoa((uint32_t)port->get_value(port)) : "?"); - hal.stream.write("]" ASCII_EOL); - } - } - } + return false; +} - if((ports = ioports_available(Port_Digital, Port_Output))) { - for(idx = 0; idx < ports; idx++) { - if((port = hal.port.get_pin_info(Port_Digital, Port_Output, idx))) { - hal.stream.write("[PINSTATE:DOUT|"); - hal.stream.write(port->description ? port->description : xbar_fn_to_pinname(port->function)); - hal.stream.write("|"); - hal.stream.write(uitoa(port->id)); - hal.stream.write("|"); - hal.stream.write(port->mode.inverted ? "I" : "N"); +static bool print_aux_dout (xbar_t *port, uint8_t pnum, void *data) +{ + hal.stream.write("[PINSTATE:DOUT|"); + hal.stream.write(port->description ? port->description : xbar_fn_to_pinname(port->function)); + hal.stream.write("|"); + hal.stream.write(uitoa(port->id)); + hal.stream.write("|"); + hal.stream.write(port->mode.inverted ? "I" : "N"); // hal.stream.write(port->mode.pwm ? "P" : (port->mode.servo_pwm ? "S" : "N")); // hal.stream.write(port->mode.open_drain ? "O" : "-"); - hal.stream.write("|"); - hal.stream.write(port->cap.invert ? "I" : "-"); + hal.stream.write("|"); + hal.stream.write(port->cap.invert ? "I" : "-"); // hal.stream.write(port->cap.pwm ? "P" : (port->cap.servo_pwm ? "S" : "N")); // hal.stream.write(port->cap.open_drain ? "O" : "-"); - hal.stream.write("|"); - hal.stream.write(port->get_value ? uitoa((uint32_t)port->get_value(port)) : "?"); - hal.stream.write("]" ASCII_EOL); - } - } - } + hal.stream.write("|"); + hal.stream.write(port->get_value ? uitoa((uint32_t)port->get_value(port)) : "?"); + hal.stream.write("]" ASCII_EOL); - if((ports = ioports_available(Port_Analog, Port_Input))) { - for(idx = 0; idx < ports; idx++) { - if((port = hal.port.get_pin_info(Port_Analog, Port_Input, idx))) { - hal.stream.write("[PINSTATE:AIN|"); - hal.stream.write(port->description); - hal.stream.write("|"); - hal.stream.write(uitoa(port->id)); - hal.stream.write("|||"); - hal.stream.write(port->get_value ? ftoa((uint32_t)port->get_value(port), 2) : "?"); - hal.stream.write("]" ASCII_EOL); - } - } - } + return false; +} - if((ports = ioports_available(Port_Analog, Port_Output))) { - for(idx = 0; idx < ports; idx++) { - if((port = hal.port.get_pin_info(Port_Analog, Port_Output, idx))) { - hal.stream.write("[PINSTATE:AOUT|"); - hal.stream.write(port->description); - hal.stream.write("|"); - hal.stream.write(uitoa(port->id)); - hal.stream.write("|"); - hal.stream.write(port->mode.pwm ? "P" : (port->mode.servo_pwm ? "S" : "N")); - hal.stream.write("|"); - hal.stream.write(port->cap.pwm ? "P" : (port->cap.servo_pwm ? "S" : "N")); - hal.stream.write("|"); - hal.stream.write(port->get_value ? ftoa((uint32_t)port->get_value(port), 2) : "?"); - hal.stream.write("]" ASCII_EOL); - } - } - } +static bool print_aux_ain (xbar_t *port, uint8_t pnum, void *data) +{ + hal.stream.write("[PINSTATE:AIN|"); + hal.stream.write(port->description); + hal.stream.write("|"); + hal.stream.write(uitoa(port->id)); + hal.stream.write("|||"); + hal.stream.write(port->get_value ? ftoa((uint32_t)port->get_value(port), 2) : "?"); + hal.stream.write("]" ASCII_EOL); + + return false; +} + +static bool print_aux_aout (xbar_t *port, uint8_t pnum, void *data) +{ + hal.stream.write("[PINSTATE:AOUT|"); + hal.stream.write(port->description); + hal.stream.write("|"); + hal.stream.write(uitoa(port->id)); + hal.stream.write("|"); + hal.stream.write(port->mode.pwm ? "P" : (port->mode.servo_pwm ? "S" : "N")); + hal.stream.write("|"); + hal.stream.write(port->cap.pwm ? "P" : (port->cap.servo_pwm ? "S" : "N")); + hal.stream.write("|"); + hal.stream.write(port->get_value ? ftoa((uint32_t)port->get_value(port), 2) : "?"); + hal.stream.write("]" ASCII_EOL); + + return false; +} + +status_code_t report_pin_states (sys_state_t state, char *args) +{ + ioports_enumerate(Port_Digital, Port_Input, (pin_cap_t){}, print_aux_din, NULL); + ioports_enumerate(Port_Digital, Port_Output, (pin_cap_t){}, print_aux_dout, NULL); + ioports_enumerate(Port_Analog, Port_Input, (pin_cap_t){}, print_aux_ain, NULL); + ioports_enumerate(Port_Analog, Port_Output, (pin_cap_t){}, print_aux_aout, NULL); return Status_OK; } diff --git a/spindle_control.c b/spindle_control.c index cebab0e..d79b639 100644 --- a/spindle_control.c +++ b/spindle_control.c @@ -1124,13 +1124,15 @@ static bool check_pwm_ports (void) spindle1_pwm_settings_t *spindle1_settings_add (bool claim_ports) { - if((ports_ok = claim_ports && hal.port.num_digital_out > 0 && check_pwm_ports())) { + uint8_t n_out; - sp1_settings.port_on = hal.port.num_digital_out - 1; - sp1_settings.port_dir = hal.port.num_digital_out > 1 ? hal.port.num_digital_out - 2 : 255; + if((ports_ok = claim_ports && (n_out = ioports_available(Port_Digital, Port_Output)) && check_pwm_ports())) { + + sp1_settings.port_on = n_out - 1; + sp1_settings.port_dir = n_out > 1 ? n_out - 2 : 255; strcpy(max_aport, uitoa(sp1_settings.port_pwm)); - strcpy(max_dport, uitoa(hal.port.num_digital_out - 1)); + strcpy(max_dport, uitoa(n_out - 1)); } return nvs_address == 0 && (!claim_ports || ports_ok) && (nvs_address = nvs_alloc(sizeof(spindle1_pwm_settings_t))) ? &sp1_settings : NULL;