diff --git a/docs/src/man/man1/halrmt.1.adoc b/docs/src/man/man1/halrmt.1.adoc index 9086723abe6..65dd59824bc 100644 --- a/docs/src/man/man1/halrmt.1.adoc +++ b/docs/src/man/man1/halrmt.1.adoc @@ -2,221 +2,303 @@ == NAME -halrmt - remote-control interface for LinuxCNC +halrmt - remote-control interface for LinuxCNC/HAL == SYNOPSIS -*halrmt* [*--port* __] [*--name* __] [*--connectpw* __] [*--enablepw* __] [*--sessions* __] [*-ini* __] +*halrmt* [*--port* __] [*--name* __] [*--connectpw* __] [*--enablepw* __] [*--sessions* __] [*--ini* __] == OPTIONS ---port _port_:: Waits for socket connections (telnet) on specified -socket, without port specification it uses default port 5006. -(Note: linuxcncrsh uses 5007 as default.) ---name _server_name_:: Sets the server name to specified name for Hello. ---connectpw _password_:: Sets the connection password to 'password'. Default: EMC. ---enablepw _password_:: Sets the enable password to _password_. Default EMCTOO. ---sessions :: Sets the maximum number of simultaneous connextions to max sessions. Default is no limit (-1). --ini __:: Uses the specified _INI file_ instead of the default emc.ini. +-h,--help:: + Print a brief usage help message. -== DESCRIPTION - -The application *halrmt* supports six commands that are meant to be sent -to an instance of HAL that is running on another machine. Of these, the commands _set_ and _get_ contain HAL specific sub-commands that are based -on the commands supported by _halcmd_. - -Commands and most parameters are not case sensitive. -The exceptions are passwords, file paths and text strings. -The supported commands are as follows: - -Hello :: -If a valid password was entered the server will respond with "HELLO ACK -__ __" where server name and server version are -looked up from the implementation. If an invalid password or any other -syntax error occurs then the server responds with "HELLO NAK". - -Get:: The get command includes one of the HAL sub-commands, -described below and zero or more additional parameters. -Set:: The set command inclides one of the HAL sub-commands, -described below and one or more additional parameters. -Quit:: The quit command disconnects the associated socket connection. -Shutdown:: The shutdown command tells LinuxCNC to shut down -before quitting the connection. This command may only be issued if the -Hello has been successfully negotiated and the connection has control of -the CNC (see enable sub-command below). This command has no parameters. -Help:: The help command will return help information in text format over the -telnet connection. If no parameters are specified, it will itemize the -available commands. If a command is specified, it will provide usage -information for the specified command. Help will respond regardless of -whether a "Hello" has been successfully negotiated. - -*HAL sub-commands:* - -echo on | off:: With get will return the current echo -state, with set, sets the echo state. When echo is on, all commands will -be echoed upon receipt. This state is local to each connection. - -verbose on | off:: With get will return the current verbose state, with set, sets -the verbose state. When in verbose mode is on, all set commands return -positive acknowledgement in the form SET ACK. In addition, -text error messages will be issued when in verbose mode. This state is -local to each connection. - -enable | off:: With get will return On or -Off to indicate whether the current connection is enabled to perform -control functions. With set and a valid password, the current connection -is enabled for control functions. "OFF" may not be used as a password -and disables control functions for this connection. - -config [TBD] comm_mode ascii | binary:: With get, will return the current -communications mode. With set, will set the communications mode to the -specified mode. The binary protocol is TBD. - -comm_prot :: With get, returns the current protocol version used by the server, -with set, sets the server to use the specified protocol version, provided it is -lower than or equal to the highest version number supported by the server implementation. - -Comps []:: -Get only, returns all components beginning with the specified substring. -If no substring is specified then it returns all components. - -Pins []:: -Get only, returns all information about all pins beginning with the -specified substring. If no substring is specified then it returns all -pins. - -PinVals []:: -Get only, returns only value information about all pins beginning with -the specified substring. If no substring is specified then it returns -all pins. - -Signals []:: -Get only, returns all information about all signals beginning with the -specified substring. If no substring is specified then it returns all -signals. - -SigVals []:: -Get only, returns only value information about all signals beginning -with the specified substring. If no substring is specified then it -returns all pins. - -Params []:: -Get only, returns all information about all parameters beginning with -the specified substring. If no substring is specified then it returns -all parameters. - -ParamVals []:: -Get only, returns only value information about all parameters beginning -with the specified substring. If no substring is specified then it -returns all pins parameters. - -Functs []:: -Get only, returns all information about all functions beginning with the -specified substring. If no substring is specified then it returns all -functions. - -Threads:: -Get only, returns all information about all functions. +-n,--name _server_name_:: + Sets the server name to specified name for in reply to `HELLO` command. + Default: EMCNETSVR. -Comp :: -Get only, returns the component matching the specified name. +-p,--port _port_:: + Listen on TCP port _port_ for connection. + Both IPv4 and IPv6 connections are accepted. + Default port is 5006. + (Note: linuxcncrsh uses 5007 as default) -Pin :: -Get only, returns all information about the pin matching the specified name. +-w,--connectpw _password_:: + Sets the `HELLO` command password to _password_. + Default: EMC. -PinVal :: -Get only, returns the value of the pin matching the specified name. +-e,--enablepw _password_:: + Sets the `SET ENABLE` command password to _password_. + Default: EMCTOO. -Sig :: -Get only, returns all information about the pin matching the specified name. +-s,--sessions _max_sessions_:: + Sets the maximum number of simultaneous connextions to _max_sessions_. + Default is no limit (0). -SigVal :: -Get only, returns just the value of the signal matching the specified name. +-i,--ini _INI_file_:: + Uses the specified _INI_file_. + The default is to get the _INI_file_ name from the environment variable `INI_FILE_NAME`. -Param :: -Get only, returns all information about the parameter matching the specified name. +-q,--quiet:: + Don't print informational messages to the console. -ParamVal :: -Get only, returns just the value of the parameter matching the specified name. - -Funct :: -Get only, returns all information about the parameter matching the -specified name. - -Thread :: -Get only, returns all information about the thread matching the -specified name. - -LoadRt :: -Set only, loads the real time executable specified by name. - -Unload :: -Set only, unloads the executable specified by name. - -LoadUsr :: -Set only, loads the user executable specified by name. - -Linkps :: -Set only, links the specified pin to the specified signal. - -Linksp :: -Set only, links the specified signal to the specified pin. - -Linkpp :: -Set only, links the pin specified by pin 1 with the pin specified by pin 2. - -Net :: -Set only, nets the specified net list. - -Unlinkp :: -Set only, unlinks the specified pins. - -Lock +== DESCRIPTION -Unlock +The application *halrmt* supports six primary commands to manipulate the HAL of a remote LinuxCNC instance. +Of these, the commands `SET` and `GET` contain HAL specific sub-commands. +The sub-commands are based on the commands supported by *halcmd*(1). -NewSig :: -Set only, creates the signal specified by name and of type specified by -type. +=== COMMANDS -DelSig :: -Set only, deletes the signal specified by name. +Commands, sub-commands and most parameters are not case sensitive. +The exceptions are passwords, file paths and text strings. -SetP :: -Set only, sets the parameter specified by name to the value specified by -value. +The supported commands are as follows: -SetS :: -Set only, sets the signal specified by name to the value specified by -value. +hello []:: + If a valid _password_ was entered the server will respond with + + `HELLO ACK __ __` + + where server name and server version are looked up from the implementation. + If an invalid _password_ or any other syntax error occurs then the server responds with `HELLO NAK`. + +get [args...]:: + The get command includes one of the HAL sub-commands, + described below and zero or more additional parameters. + +set [args...]:: + The set command includes one of the HAL sub-commands, + described below and one or more additional parameters. + +quit:: + The quit command disconnects the associated socket connection. + +shutdown:: + The shutdown command disconnects all clients and tells *halrmt* to shut down. + This command may only be issued if the `HELLO` has been successfully negotiated. + The connection must be enabled. + +help [sub-command]:: + The help command will return information in text over the network connection. + If no parameters are specified, it will itemize the available commands. + If a command is specified, it will provide usage information for the specified command. + Command `HELP` will respond regardless of whether a `HELLO` has been successfully negotiated. + +=== SUBCOMMANDS + +A 'pattern' is a glob pattern as the shell implements it. +Backslash characters in a 'pattern' are not special (don't escape) and are case insensitive. + +set addf [arg [arg...]]:: + Adds the function specified by _name_, to the thread specified by _thread_. + Optional parameters may be specified by _arg_. + +get comp :: + Returns the component matching the specified _name_. + +get comps [pattern]:: + Returns information about all components matching _pattern_. + If no _pattern_ is specified then all components are returned. + +set delf :: + Deletes the function specified by _name_. + +set delsig |all:: + Deletes the signal specified by _signalname_. + Specifying 'all' will remove all signals in the system. + +get echo:: +set echo {on|off}:: + With get will return the current echo state. + With set, sets the echo state to the supplied argument. + When echo is on, all commands will be echoed upon receipt. + The _echo_ state is local to each connection. + + The echoed line is INI-variable expanded if `SET EXPAND` is set to 'On'. + This allows you to see the actual command being executed. + +get enable:: +set enable |off:: + With get will return 'On' or 'Off' to indicate whether the current connection is enabled to perform control functions. + With set and a valid password, the current connection is enabled for control functions. + The argument 'OFF' may not be used as a password and disables control functions for this connection. + +get expand:: +set expand {on|off}:: + Get or set INI-file variable expansion. + Setting the INI-file expansion to _on_ will pre-process every input line and substitute variables. + An INI-file variable is specified by `[SECTION]VAR` or `[SECTION](VAR)`. + Not using parentheses requires you to have trailing white-space or be at the end of the line. + INI-file expansion defaults to off and requires a valid INI-file. + Enabling expansion with no or an invalid INI-file will expand to an empty string. + Expansion is applied to the input line _before_ it is tokenized. + That means that all commands and sub-commands are subject to expansion. + Everything typed as input is first expanded before processed. + The _expand_ state is local to each connection. + +get funct :: + Returns all information about the parameter matching the specified _name_. + +get functs [pattern]:: + Returns information about functions matching _pattern_. + If no _pattern_ is specified then all functions are returned. + +get ini
:: + Return the variable \[__section__]_var_ from the current INI-file. + +get inifile:: +set inifile :: + Gets the current active INI-file's name or sets the active INI-file to _filename_. + A test is performed to validate the new INI-file when set. + Setting the INI-file is local to the connection. + +set linkps []:: + Add _pinname_ to signal with _signalname_. + Will act as `SET UNLINKP _pinname_` if no _signalname_ is provided. + +set linksp :: + Add _pinname_ to signal with _signalname_. + +set loadrt [arg [arg...]]:: + Load the real-time component _compname_ with optional arguments. + The real-time environment must have been started or an error will be returned. + +set loadusr [flags] [arg [arg...]]:: + Loads the user component _program_ and passes any optional arguments. + The _flags_ are on or more of: + * *-W* - to wait for the component to become ready. + The component is assumed to have the same name as the first argument of the command. + Use *-n* to override the component name to look for. + * *-n* _name_ - to wait for the component, which will have the given _name_. + * *-w* - to wait for the program to exit + * *-i* - to ignore the program return value (with *-w*) + +get lock:: +set lock {all|load|config|params|run|tune|none}:: + Gets the current HAL lock value or sets the HAL lock of the argument's value. + The _tune_ value is a combination of _load_ and _config_. + The values _all_, _none_ and _tune_ override any other values in the lock that may be present. + Doing `SET LOCK none` is equivalent to `SET UNLOCK all`. + +get net :: +set net [pinname [pinname...]]:: + Get shows all the pins connected to _signalname_. + Set creates a signal _signalname_ and adds all the _pinname_ pins to the signal. + +set newsig :: + Creates the signal specified by _signalname_ and of type specified by _type_. + +get param :: + Returns all information about the parameter matching the specified _paramname_. + +get params [pattern]:: + Returns information about parameters matching _pattern_. + If no _pattern_ is specified then all parameters are returned. + +get paramval :: + Returns just the value of the parameter matching the specified _paramname_. + +get paramvals [pattern]:: + Returns only value information about all parameters matching _pattern_. + If no _pattern_ is specified then all parameters are returned. + +get pin :: + Returns all information about the pin matching the specified _pinname_. + +get pins [pattern]:: + Returns all information about all pins matching _pattern_. + If no _pattern_ is specified then all pins are returned. + +get pinval :: + Returns the value of the pin matching the specified _pinname_. + +get pinvals [pattern]:: + Returns only value information about all pins matching _pattern_. + If no _pattern_ is specified then all pins are returned. + +set save {all|comp|sig|link|linka|net|neta|param|thread} []:: + Will return the saved content on the connection if no filename is provided. + Saves the specified set of data to file _filename_ instead if provided. + +set setp :: + Sets the pin or parameter specified by _pinname_/_paramname_ to the value specified by _value_. + +set sets :: + Sets the signal specified by _signalname_ to the value specified by _value_. + +get signal :: + Returns all information about the pin matching the specified _signalname_. + +get signals [pattern]:: + Returns all information about all signals matching _pattern_. + If no _pattern_ is specified then all signals are returned. + +get sigval :: + Returns just the value of the signal matching the specified _signalname_. -AddF []:: -Set only, adds the function specified by name, to the thread specified -by thread, with the optional parameters specified by parameters. +get sigvals [pattern]:: + Returns only value information about all signals matching _pattern_. + If no _pattern_ is specified then all signals are returned. + +set start:: + Start the real-time threads. + The real-time environment must have been started or an error will be returned. + +set stop:: + Stop the real-time threads. + The real-time environment must have been started or an error will be returned. + +get time:: + Returns the time, in seconds, from the start of the epoch. + The starting time depends on the platform. -DelF :: -Set only, deletes the function specified by name. +get timestamp:: +set timestamp {on|off} [{on|off}]:: + Enable or disable printing of a timestamp on messages sent back from the server to the user. + The optional format argument selects human readable date/time format and seconds since the epoch. + The format prints seconds when off and human readable when on. + +get thread :: + Returns all information about the thread matching the specified _name_. + +get threads [pattern]:: + Returns all information about all threads matching _pattern_. + If no _pattern_ is specified then all threads are returned. + +set unlinkp :: + Unlinks the specified _pinname_ from any signal it may be attached to. -Save +set unload :: + Unloads the real-time component _compname_. + The real-time environment must have been started or an error will be returned. -Start +set unlock {all|load|config|params|run|tune|none}:: + Removes the HAL lock of the argument's value. + The _tune_ value is a combination of _load_ and _config_. + Removing _none_ has no effect but may be useful in scripting. -Stop +get verbose:: +set verbose on | off:: + With get will return the current verbose state. + With set, sets the verbose state to the supplied argument. + When verbose mode is on, all `SET` commands return positive acknowledgement in the form `SET ACK`. + In addition, text error messages will be issued when in verbose mode. + The _verbose_ state is local to each connection. == SEE ALSO -linuxcnc(1) +*linuxcnc*(1), +*halcmd*(1). Much more information about LinuxCNC and HAL is available in the LinuxCNC and HAL User Manuals, found at /usr/share/doc/LinuxCNC/. == BUGS -It is not known if this interface currently works. +Probably, but it has been mostly rewritten after the last incarnation incurred som bit-rot and was deemed non-functional. == AUTHOR This man page written by Andy Pugh, as part of the LinuxCNC project. +Manual page updated by B.Stultiens after the rewrite. == REPORTING BUGS @@ -224,7 +306,8 @@ Report bugs at https://github.com/LinuxCNC/linuxcnc/issues. == COPYRIGHT -Copyright © 2020 Andy Pugh. +Copyright © 2020 Andy Pugh. + +Copyright © 2026 B.Stultiens. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR diff --git a/src/hal/Submakefile b/src/hal/Submakefile index 1827d7e10c8..a4144a67820 100644 --- a/src/hal/Submakefile +++ b/src/hal/Submakefile @@ -28,5 +28,14 @@ $(HALMODULE): $(call TOOBJS, $(HALMODULESRCS)) $(HALLIB) $(ECHO) Linking python module $(notdir $@) $(Q)$(CXX) $(LDFLAGS) -shared -o $@ $^ +HALQUERYSRCS := hal/halquery.c hal/utils/setps_util.c +PYSRCS += $(HALQUERYSRCS) + +HALQUERY := ../lib/python/halquery.so +$(HALQUERY): $(call TOOBJS, $(HALQUERYSRCS)) $(HALLIB) + $(ECHO) Linking python module $(notdir $@) + $(Q)$(CC) $(LDFLAGS) -shared -o $@ $^ + TARGETS += $(HALLIB) ../lib/liblinuxcnchal.so.0 PYTARGETS += $(HALMODULE) +PYTARGETS += $(HALQUERY) diff --git a/src/hal/drivers/mesa-hostmot2/abs_encoder.c b/src/hal/drivers/mesa-hostmot2/abs_encoder.c index 8a8c96bf910..12c60ac0155 100644 --- a/src/hal/drivers/mesa-hostmot2/abs_encoder.c +++ b/src/hal/drivers/mesa-hostmot2/abs_encoder.c @@ -141,7 +141,7 @@ int hm2_absenc_setup_ssi(hostmot2_t *hm2, hm2_sserial_remote_t *chan, if ( hm2_sserial_create_pins(hm2, chan)) return -EINVAL; - chan->params = hal_malloc(sizeof(hm2_sserial_params_t)); + chan->params = hal_malloc(sizeof(*chan->params)); hm2->absenc.clock_frequency = md->clock_freq; hm2->absenc.ssi_version = md->version; @@ -158,9 +158,12 @@ int hm2_absenc_setup_ssi(hostmot2_t *hm2, hm2_sserial_remote_t *chan, + (3 * md->register_stride); chan->data_written[0] = 0; - - chan->params->float_param = 500; - chan->params->timer_num = 0; + if (hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(chan->params->param.r), + 500.0, "%s.frequency-khz", chan->name)){ + HM2_ERR("error adding frequency param for %s, aborting\n", + chan->name); + return -EINVAL; + } return 0; } @@ -169,7 +172,7 @@ int hm2_absenc_setup_biss(hostmot2_t *hm2, hm2_sserial_remote_t *chan, if ( hm2_sserial_create_pins(hm2, chan)) return -EINVAL; - chan->params = hal_malloc(sizeof(hm2_sserial_params_t)); + chan->params = hal_malloc(sizeof(*chan->params)); hm2->absenc.clock_frequency = md->clock_freq; hm2->absenc.biss_version = md->version; @@ -185,9 +188,13 @@ int hm2_absenc_setup_biss(hostmot2_t *hm2, hm2_sserial_remote_t *chan, hm2->absenc.biss_global_start_addr = md->base_address + (3 * md->register_stride); chan->data_written[0] = 0; - - chan->params->float_param = 500; - chan->params->timer_num = 0; + + if (hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(chan->params->param.r), + 500.0, "%s.frequency-khz", chan->name)){ + HM2_ERR("error adding frequency param for %s, aborting\n", + chan->name); + return -EINVAL; + } return 0; } @@ -196,7 +203,7 @@ int hm2_absenc_setup_fabs(hostmot2_t *hm2, hm2_sserial_remote_t *chan, if ( hm2_sserial_create_pins(hm2, chan)) return -EINVAL; - chan->params = hal_malloc(sizeof(hm2_sserial_params_t)); + chan->params = hal_malloc(sizeof(*chan->params)); hm2->absenc.clock_frequency = md->clock_freq; hm2->absenc.fanuc_version = md->version; @@ -219,16 +226,23 @@ int hm2_absenc_setup_fabs(hostmot2_t *hm2, hm2_sserial_remote_t *chan, + (5 * md->register_stride); chan->data_written[0] = 0; - if (hal_param_u32_newf(HAL_RW, &(chan->params->u32_param), - hm2->llio->comp_id,"%s.filter", - chan->name)){ + // Note: + // This parameter was abused by first writing 1024.0 to the floating point + // part and then overwriting the lower part with 0x0000000F. It is now + // exclusively set to the unsigned value. + // Setting the frequency parameter would overwrite the filter setting and + // is now separated out into a separate param storage reference (fanucf). + if (hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(chan->params->param.u), + 0xF, "%s.filter", chan->name)) { HM2_ERR("error adding param fanuc param 2, aborting\n"); return -EINVAL; } - chan->params->float_param = 1024.0; - chan->params->u32_param = 0xF; - chan->params->timer_num = 0; - + if (hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(chan->params->fanucf), + 1024.0, "%s.frequency-khz", chan->name)){ + HM2_ERR("error adding frequency param for %s, aborting\n", + chan->name); + return -EINVAL; + } return 0; } @@ -355,7 +369,7 @@ int hm2_absenc_parse_format(hm2_sserial_remote_t *chan, hm2_absenc_format_t *de int hm2_absenc_parse_md(hostmot2_t *hm2, int md_index) { hm2_module_descriptor_t *md = &hm2->md[md_index]; - hm2_absenc_format_t *def = 0; + hm2_absenc_format_t *def = NULL; struct rtapi_list_head *ptr; int index; @@ -444,24 +458,15 @@ int hm2_absenc_parse_md(hostmot2_t *hm2, int md_index) { } // Set up the common pins - if (hal_pin_bit_newf(HAL_OUT, &(chan->params->error), - hm2->llio->comp_id,"%s.data-invalid", - chan->name)){ + if (hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(chan->params->error), + 0, "%s.data-invalid", chan->name)){ HM2_ERR("error adding %s over-run pin, aborting\n", chan->name); return -EINVAL; } // And Params - if (hal_param_float_newf(HAL_RW, &(chan->params->float_param), - hm2->llio->comp_id,"%s.frequency-khz", - chan->name)){ - HM2_ERR("error adding frequency param for %s, aborting\n", - chan->name); - return -EINVAL; - } - if (hal_param_u32_newf(HAL_RW, &(chan->params->timer_num), - hm2->llio->comp_id,"%s.timer-number", - chan->name)){ + if (hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(chan->params->timer_num), + 0, "%s.timer-number", chan->name)){ HM2_ERR("error adding %s timer number param, aborting\n", chan->name); return -EINVAL; @@ -528,7 +533,7 @@ void hm2_absenc_process_tram_read(hostmot2_t *hm2, long period) { HM2_ERR("Data transmission not complete on channel %s read." " You may need to change the timing of %s. This " "warning will not repeat\n", chan->name, - (chan->params->timer_num == 0) ? + (hal_get_ui32(chan->params->timer_num) == 0) ? "the trigger function" : "the hm2dpll timer"); err_tag[i] = 1; } @@ -540,14 +545,14 @@ void hm2_absenc_process_tram_read(hostmot2_t *hm2, long period) { if (err_count[i] < 5001) { ++err_count[i]; } else { - *chan->params->error = 1; + hal_set_bool(chan->params->error, 1); } } else { if (err_count[i] > 4950){ --err_count[i]; } else { - *chan->params->error = 0; + hal_set_bool(chan->params->error, 0); } } } @@ -562,14 +567,15 @@ void hm2_absenc_write(hostmot2_t *hm2){ for (i = 0; i < hm2->absenc.num_chans; i ++) { hm2_sserial_remote_t *chan = &hm2->absenc.chans[i]; + rtapi_u32 timer_num = hal_get_ui32(chan->params->timer_num); switch (chan->myinst){ case HM2_GTAG_SSI: - if (chan->params->timer_num > 4) chan->params->timer_num = 4; - buff = ((rtapi_u32)(0x10000 * (chan->params->float_param * 1000 + if (timer_num > 4) timer_num = hal_set_ui32(chan->params->timer_num, 4); + buff = ((rtapi_u32)(0x10000 * (hal_get_real(chan->params->param.r) * 1000 / hm2->absenc.clock_frequency))) << 16 - | chan->params->timer_num << 12 - | (chan->params->timer_num == 0) << 8 - | (chan->params->timer_num != 0) << 9 + | timer_num << 12 + | (timer_num == 0) << 8 + | (timer_num != 0) << 9 | chan->num_read_bits; if (buff != chan->data_written[0]){ hm2->llio->write(hm2->llio, @@ -581,8 +587,8 @@ void hm2_absenc_write(hostmot2_t *hm2){ break; case HM2_GTAG_BISS: - if (chan->params->timer_num > 4) chan->params->timer_num = 4; - dds = ((rtapi_u32)(0x10000 * (chan->params->float_param * 1000 + if (timer_num > 4) timer_num = hal_set_ui32(chan->params->timer_num, 4); + dds = ((rtapi_u32)(0x10000 * (hal_get_real(chan->params->param.r) * 1000 / hm2->absenc.clock_frequency))); filt = 0x8000/dds; // RX data filter set to 1/2 a clock period if (filt > 63) { filt = 63; } // bound so we dont splatter into adjacent fields @@ -598,9 +604,9 @@ void hm2_absenc_write(hostmot2_t *hm2){ sizeof(rtapi_u32)); chan->data_written[0] = buff; } - buff2 = chan->params->timer_num << 12 - | (chan->params->timer_num == 0) << 8 - | (chan->params->timer_num != 0) << 9; + buff2 = timer_num << 12 + | (timer_num == 0) << 8 + | (timer_num != 0) << 9; if (buff2 != chan->data_written[1]){ hm2->llio->write(hm2->llio, chan->rw_addr[2], @@ -611,16 +617,27 @@ void hm2_absenc_write(hostmot2_t *hm2){ break; case HM2_GTAG_FABS: - if (chan->params->timer_num > 4) chan->params->timer_num = 4; - if (chan->params->u32_param > 15) chan->params->u32_param = 15; - buff3 = chan->num_read_bits << 24 + // Note: + // The original calculation used an awkward overlapped parameter + // storage between floating point and an unsigned value. + // 'u32_param' would occupy the lower storage part of 'float_param. + // The float would be set to 1024.0 and the lower part would get + // set as an unsigned with 0x0000000F. The setting of the few lower + // mantissa bits has no real bearing on the value as a float. + // The paramater storage has now been split. + // Original: + // buff2 = (u32_param << 28) | (rtapi_u32)(0x100000 * (float_param * 1000 / hm2->absenc.clock_frequency)) + // Now + // buff2 = (u32_param << 28) | (rtapi_u32)(0x100000 * (fanucf * 1000 / hm2->absenc.clock_frequency)) + if (timer_num > 4) timer_num = hal_set_ui32(chan->params->timer_num, 4); + if (hal_get_ui32(chan->params->param.u) > 15) hal_set_ui32(chan->params->param.u, 15); + buff3 = (chan->num_read_bits << 24) | (rtapi_u32)(8.0e-6 * hm2->absenc.clock_frequency) << 14; - buff2 = chan->params->u32_param << 28 - | ((rtapi_u32)(0x100000 * (chan->params->float_param * 1000 - / hm2->absenc.clock_frequency))); - buff = chan->params->timer_num << 12 - | (chan->params->timer_num == 0) << 8 - | (chan->params->timer_num != 0) << 9 + buff2 = (hal_get_ui32(chan->params->param.u) << 28) + | ((rtapi_u32)(0x100000 * (hal_get_real(chan->params->fanucf) * 1000.0 / hm2->absenc.clock_frequency))); + buff = (timer_num << 12) + | (timer_num == 0) << 8 + | (timer_num != 0) << 9 | (buff3 != chan->data_written[2] || buff2 != chan->data_written[1]) << 7; if (buff != chan->data_written[0]){ // if necessary this will set the write flag, then next time through diff --git a/src/hal/drivers/mesa-hostmot2/bspi.c b/src/hal/drivers/mesa-hostmot2/bspi.c index e1c504ce691..64d3fbae2f7 100644 --- a/src/hal/drivers/mesa-hostmot2/bspi.c +++ b/src/hal/drivers/mesa-hostmot2/bspi.c @@ -75,8 +75,7 @@ int hm2_bspi_parse_md(hostmot2_t *hm2, int md_index) hm2->bspi.num_instances = hm2->config.num_bspis; } - hm2->bspi.instance = (hm2_bspi_instance_t *)hal_malloc(hm2->bspi.num_instances - * sizeof(hm2_bspi_instance_t)); + hm2->bspi.instance = hal_malloc(hm2->bspi.num_instances * sizeof(*hm2->bspi.instance)); if (hm2->bspi.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; diff --git a/src/hal/drivers/mesa-hostmot2/dpll.c b/src/hal/drivers/mesa-hostmot2/dpll.c index a8149bc8380..6b1377e0be7 100644 --- a/src/hal/drivers/mesa-hostmot2/dpll.c +++ b/src/hal/drivers/mesa-hostmot2/dpll.c @@ -70,46 +70,39 @@ int hm2_dpll_parse_md(hostmot2_t *hm2, int md_index) { hm2->dpll.hm2_dpll_sync_addr = md->base_address + 6 * md->register_stride; // export to HAL - hm2->dpll.pins = hal_malloc(sizeof(hm2_dpll_pins_t)); - - r = hal_pin_float_newf(HAL_IN, &(hm2->dpll.pins->time1_us), - hm2->llio->comp_id, "%s.dpll.01.timer-us", hm2->llio->name); - r += hal_pin_float_newf(HAL_IN, &(hm2->dpll.pins->time2_us), - hm2->llio->comp_id, "%s.dpll.02.timer-us", hm2->llio->name); - r += hal_pin_float_newf(HAL_IN, &(hm2->dpll.pins->time3_us), - hm2->llio->comp_id, "%s.dpll.03.timer-us", hm2->llio->name); - r += hal_pin_float_newf(HAL_IN, &(hm2->dpll.pins->time4_us), - hm2->llio->comp_id, "%s.dpll.04.timer-us", hm2->llio->name); - r += hal_pin_float_newf(HAL_IN, &(hm2->dpll.pins->base_freq), - hm2->llio->comp_id, "%s.dpll.base-freq-khz", hm2->llio->name); - r += hal_pin_float_newf(HAL_OUT, &(hm2->dpll.pins->phase_error), - hm2->llio->comp_id, "%s.dpll.phase-error-us", hm2->llio->name); - r += hal_pin_u32_newf(HAL_IN, &(hm2->dpll.pins->time_const), - hm2->llio->comp_id, "%s.dpll.time-const", hm2->llio->name); - r += hal_pin_u32_newf(HAL_IN, &(hm2->dpll.pins->plimit), - hm2->llio->comp_id, "%s.dpll.plimit", hm2->llio->name); - r += hal_pin_u32_newf(HAL_OUT, &(hm2->dpll.pins->ddssize), - hm2->llio->comp_id, "%s.dpll.ddsize", hm2->llio->name); - r += hal_pin_u32_newf(HAL_OUT, &(hm2->dpll.pins->prescale), - hm2->llio->comp_id, "%s.dpll.prescale", hm2->llio->name); - if (r < 0) { - HM2_ERR("error adding hm2_dpll timer pins, Aborting\n"); - goto fail0; - } - *hm2->dpll.pins->time1_us = 100.0; - *hm2->dpll.pins->time2_us = 100.0; - *hm2->dpll.pins->time3_us = 100.0; - *hm2->dpll.pins->time4_us = 100.0; - *hm2->dpll.pins->prescale = 1; - *hm2->dpll.pins->base_freq = -1; // An indication it needs init - /* This value is an empirical compromise between insensitivity to + hm2->dpll.pins = hal_malloc(sizeof(*hm2->dpll.pins)); + + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->dpll.pins->time1_us), + 100.0, "%s.dpll.01.timer-us", hm2->llio->name); + r += hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->dpll.pins->time2_us), + 100.0, "%s.dpll.02.timer-us", hm2->llio->name); + r += hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->dpll.pins->time3_us), + 100.0, "%s.dpll.03.timer-us", hm2->llio->name); + r += hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->dpll.pins->time4_us), + 100.0, "%s.dpll.04.timer-us", hm2->llio->name); + // init=-1 is an indication it needs init + r += hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->dpll.pins->base_freq), + -1.0, "%s.dpll.base-freq-khz", hm2->llio->name); + r += hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->dpll.pins->phase_error), + 0.0, "%s.dpll.phase-error-us", hm2->llio->name); + /* The init value is an empirical compromise between insensitivity to * single-cycle variations (larger values) and being resilient to changes to * the Linux CLOCK_MONOTONIC timescale, which can instantly change by up to * +-500ppm from its nominal value, usually by timekeeping software like ntp * and ntpdate. */ - *hm2->dpll.pins->time_const = 2000; - *hm2->dpll.pins->plimit = 0x400000; + r += hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->dpll.pins->time_const), + 2000, "%s.dpll.time-const", hm2->llio->name); + r += hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->dpll.pins->plimit), + 0x400000, "%s.dpll.plimit", hm2->llio->name); + r += hal_pin_new_ui32(hm2->llio->comp_id, HAL_OUT, &(hm2->dpll.pins->ddssize), + 0, "%s.dpll.ddsize", hm2->llio->name); + r += hal_pin_new_ui32(hm2->llio->comp_id, HAL_OUT, &(hm2->dpll.pins->prescale), + 1, "%s.dpll.prescale", hm2->llio->name); + if (r < 0) { + HM2_ERR("error adding hm2_dpll timer pins, Aborting\n"); + goto fail0; + } r = hm2_register_tram_read_region(hm2, hm2->dpll.hm2_dpll_sync_addr, sizeof(rtapi_u32), &hm2->dpll.hm2_dpll_sync_reg); @@ -138,9 +131,9 @@ void hm2_dpll_process_tram_read(hostmot2_t *hm2, long period){ pins = hm2->dpll.pins; - *pins->phase_error = (rtapi_s32)*hm2->dpll.hm2_dpll_sync_reg - * (period / 4294967296000.00) ; - *pins->ddssize = *hm2->dpll.control_reg1_read & 0xFF; + hal_set_real(pins->phase_error, (rtapi_s32)*hm2->dpll.hm2_dpll_sync_reg + * (period / 4294967296000.00)); + hal_set_ui32(pins->ddssize, *hm2->dpll.control_reg1_read & 0xFF); } void hm2_dpll_write(hostmot2_t *hm2, long period) { @@ -163,18 +156,21 @@ void hm2_dpll_write(hostmot2_t *hm2, long period) { pins = hm2->dpll.pins; - if (*pins->base_freq < 0 ) { - *pins->base_freq = 1000.0/period_us; + rtapi_real base_freq = hal_get_real(pins->base_freq); + if (base_freq < 0 ) { + base_freq = hal_set_real(pins->base_freq, 1000.0/period_us); } - *pins->prescale = (0x40000000LL * hm2->dpll.clock_frequency) - / ((1LL << *pins->ddssize) * *pins->base_freq * 1000.0); + rtapi_u32 ddssize = hal_get_ui32(pins->ddssize); + rtapi_u32 prescale = (0x40000000LL * hm2->dpll.clock_frequency) + / ((1LL << ddssize) * base_freq * 1000.0); - if (*pins->prescale < 1) *pins->prescale = 1; + if (prescale < 1) prescale = 1; + hal_set_ui32(pins->prescale, prescale); - buff = (rtapi_u32)((*pins->base_freq * 1000.0 - * (1LL << *pins->ddssize) - * *pins->prescale) + buff = (rtapi_u32)((base_freq * 1000.0 + * (1LL << ddssize) + * prescale) / hm2->dpll.clock_frequency); if (buff != hm2->dpll.base_rate_written){ @@ -184,8 +180,8 @@ void hm2_dpll_write(hostmot2_t *hm2, long period) { sizeof(rtapi_u32)); hm2->dpll.base_rate_written= buff; } - buff = (rtapi_u32)(*pins->prescale << 24 - | *pins->plimit); + buff = (rtapi_u32)(prescale << 24 + | hal_get_ui32(pins->plimit)); if (buff != hm2->dpll.control_reg0_written){ hm2->llio->write(hm2->llio, hm2->dpll.control_reg0_addr, @@ -193,7 +189,7 @@ void hm2_dpll_write(hostmot2_t *hm2, long period) { sizeof(rtapi_u32)); hm2->dpll.control_reg0_written= buff; } - buff = (rtapi_u32)(*pins->time_const << 16); + buff = (rtapi_u32)(hal_get_ui32(pins->time_const) << 16); if (buff != hm2->dpll.control_reg1_written){ hm2->llio->write(hm2->llio, hm2->dpll.control_reg1_addr, @@ -201,8 +197,8 @@ void hm2_dpll_write(hostmot2_t *hm2, long period) { sizeof(rtapi_u32)); hm2->dpll.control_reg1_written= buff; } - buff = (rtapi_u32)((-*hm2->dpll.pins->time2_us / period_us) * 0x10000) << 16 - | ((rtapi_u32)((-*hm2->dpll.pins->time1_us / period_us) * 0x10000) & 0xFFFF); + buff = (rtapi_u32)((-hal_get_real(hm2->dpll.pins->time2_us) / period_us) * 0x10000) << 16 + | ((rtapi_u32)((-hal_get_real(hm2->dpll.pins->time1_us) / period_us) * 0x10000) & 0xFFFF); if (buff != hm2->dpll.timer_12_written){ hm2->llio->write(hm2->llio, hm2->dpll.timer_12_addr, @@ -210,8 +206,8 @@ void hm2_dpll_write(hostmot2_t *hm2, long period) { sizeof(rtapi_u32)); hm2->dpll.timer_12_written = buff; } - buff = (rtapi_u32)((-*hm2->dpll.pins->time4_us / period_us) * 0x10000) << 16 - | ((rtapi_u32)((-*hm2->dpll.pins->time3_us / period_us) * 0x10000) & 0xFFFF); + buff = (rtapi_u32)((-hal_get_real(hm2->dpll.pins->time4_us) / period_us) * 0x10000) << 16 + | ((rtapi_u32)((-hal_get_real(hm2->dpll.pins->time3_us) / period_us) * 0x10000) & 0xFFFF); if (buff != hm2->dpll.timer_34_written){ hm2->llio->write(hm2->llio, hm2->dpll.timer_34_addr, diff --git a/src/hal/drivers/mesa-hostmot2/encoder.c b/src/hal/drivers/mesa-hostmot2/encoder.c index 31badad5e82..4ed8ad05e22 100644 --- a/src/hal/drivers/mesa-hostmot2/encoder.c +++ b/src/hal/drivers/mesa-hostmot2/encoder.c @@ -53,10 +53,10 @@ static void hm2_encoder_update_control_register(hostmot2_t *hm2) { int latch_polarity; for (i = 0; i < hm2->encoder.num_instances; i ++) { hm2_encoder_instance_t *e = &hm2->encoder.instance[i]; - int index_enable = *e->hal.pin.index_enable; + int index_enable = hal_get_bool(e->hal.pin.index_enable); if (hm2->encoder.firmware_supports_probe) { - latch_enable = *e->hal.pin.latch_enable; - latch_polarity = *e->hal.pin.latch_polarity; + latch_enable = hal_get_bool(e->hal.pin.latch_enable); + latch_polarity = hal_get_bool(e->hal.pin.latch_polarity); } else { latch_enable = 0; @@ -90,31 +90,31 @@ static void hm2_encoder_update_control_register(hostmot2_t *hm2) { do_flag( &hm2->encoder.control_reg[i], - e->hal.param.index_invert, + hal_get_bool(e->hal.param.index_invert), HM2_ENCODER_INDEX_POLARITY ); do_flag( &hm2->encoder.control_reg[i], - e->hal.param.index_mask, + hal_get_bool(e->hal.param.index_mask), HM2_ENCODER_INDEX_MASK ); do_flag( &hm2->encoder.control_reg[i], - e->hal.param.index_mask_invert, + hal_get_bool(e->hal.param.index_mask_invert), HM2_ENCODER_INDEX_MASK_POLARITY ); do_flag( &hm2->encoder.control_reg[i], - e->hal.param.counter_mode, + hal_get_bool(e->hal.param.counter_mode), HM2_ENCODER_COUNTER_MODE ); do_flag( &hm2->encoder.control_reg[i], - e->hal.param.filter, + hal_get_bool(e->hal.param.filter), HM2_ENCODER_FILTER ); do_flag( @@ -132,55 +132,55 @@ static void hm2_encoder_read_control_register(hostmot2_t *hm2) { for (i = 0; i < hm2->encoder.num_instances; i ++) { hm2_encoder_instance_t *e = &hm2->encoder.instance[i]; - if (*e->hal.pin.quadrature_error_enable) { + if (hal_get_bool(e->hal.pin.quadrature_error_enable)) { e->reset_quadrature_error=0; if(!e->prev_quadrature_error_enable){ // detect rising edge of pin quadrature_error_enable e->reset_quadrature_error = 1; hm2_encoder_force_write(hm2); } int state = ((hm2->encoder.read_control_reg[i] & HM2_ENCODER_CONTROL_MASK) & HM2_ENCODER_QUADRATURE_ERROR) && e->prev_quadrature_error_enable; - if ((*e->hal.pin.quadrature_error == 0) && state) { + if ((hal_get_bool(e->hal.pin.quadrature_error) == 0) && state) { HM2_ERR("Encoder %d: quadrature count error\n", i); } - *e->hal.pin.quadrature_error = (hal_bit_t) state; + hal_set_bool(e->hal.pin.quadrature_error, state); } else{ // quadrature error disabled, set reported error to 0 - *e->hal.pin.quadrature_error = 0; + hal_set_bool(e->hal.pin.quadrature_error, 0); } - e->prev_quadrature_error_enable = *e->hal.pin.quadrature_error_enable; + e->prev_quadrature_error_enable = hal_get_bool(e->hal.pin.quadrature_error_enable); - *e->hal.pin.input_a = hm2->encoder.read_control_reg[i] & HM2_ENCODER_INPUT_A; - *e->hal.pin.input_b = hm2->encoder.read_control_reg[i] & HM2_ENCODER_INPUT_B; - *e->hal.pin.input_idx = hm2->encoder.read_control_reg[i] & HM2_ENCODER_INPUT_INDEX; + hal_set_bool(e->hal.pin.input_a, hm2->encoder.read_control_reg[i] & HM2_ENCODER_INPUT_A); + hal_set_bool(e->hal.pin.input_b, hm2->encoder.read_control_reg[i] & HM2_ENCODER_INPUT_B); + hal_set_bool(e->hal.pin.input_idx, hm2->encoder.read_control_reg[i] & HM2_ENCODER_INPUT_INDEX); } } static void hm2_encoder_set_filter_rate_and_skew(hostmot2_t *hm2) { - rtapi_u32 filter_rate = hm2->encoder.clock_frequency/(*hm2->encoder.hal->pin.sample_frequency); + rtapi_u32 filter_rate = hm2->encoder.clock_frequency/hal_get_ui32(hm2->encoder.hal->pin.sample_frequency); if (filter_rate == 1) { filter_rate = 0xFFF; } else { filter_rate -= 2; } - *hm2->encoder.hal->pin.sample_frequency = hm2->encoder.clock_frequency/(filter_rate + 2); + hal_set_ui32(hm2->encoder.hal->pin.sample_frequency, hm2->encoder.clock_frequency/(filter_rate + 2)); HM2_DBG("Setting encoder QFilterRate to %d\n", filter_rate); if (hm2->encoder.has_skew) { rtapi_u32 divisor = (1e9/hm2->encoder.clock_frequency); // Unsigned division rounding for integers. This is only valid for unsigned division - rtapi_u32 skew = (*hm2->encoder.hal->pin.skew + (divisor/2))/divisor; + rtapi_u32 skew = (hal_get_ui32(hm2->encoder.hal->pin.skew) + (divisor/2))/divisor; if (skew > 15) { skew = 15; } HM2_DBG("Setting mux encoder skew to %d\n", skew); filter_rate |= (skew & 0xF) << 28; - *hm2->encoder.hal->pin.skew = skew*(1e9/hm2->encoder.clock_frequency); - hm2->encoder.written_skew = *hm2->encoder.hal->pin.skew; + hal_set_ui32(hm2->encoder.hal->pin.skew, skew*(1e9/hm2->encoder.clock_frequency)); + hm2->encoder.written_skew = hal_get_ui32(hm2->encoder.hal->pin.skew); } hm2->llio->write(hm2->llio, hm2->encoder.filter_rate_addr, &filter_rate, sizeof(rtapi_u32)); - hm2->encoder.written_sample_frequency = *hm2->encoder.hal->pin.sample_frequency; + hm2->encoder.written_sample_frequency = hal_get_ui32(hm2->encoder.hal->pin.sample_frequency); } static void hm2_encoder_set_dpll_timer_if_present(hostmot2_t *hm2) { @@ -209,16 +209,16 @@ void hm2_encoder_write(hostmot2_t *hm2) { } } - if (*hm2->encoder.hal->pin.sample_frequency != hm2->encoder.written_sample_frequency) { + if (hal_get_ui32(hm2->encoder.hal->pin.sample_frequency) != hm2->encoder.written_sample_frequency) { goto force_write; } if (hm2->encoder.has_skew) { - if (*hm2->encoder.hal->pin.skew != hm2->encoder.written_skew) { + if (hal_get_ui32(hm2->encoder.hal->pin.skew) != hm2->encoder.written_skew) { goto force_write; } } - if (*hm2->encoder.hal->pin.hires_timestamp != hm2->encoder.written_hires_timestamp) { // + if (hal_get_bool(hm2->encoder.hal->pin.hires_timestamp) != hm2->encoder.written_hires_timestamp) { // // Set the Timestamp Divisor Register // // We want the timestamp to count as quickly as possible, so we get the @@ -255,7 +255,7 @@ void hm2_encoder_write(hostmot2_t *hm2) { // seconds_per_clock = 1 / rate = (TSDiv+2) / ClockLow // - if (*hm2->encoder.hal->pin.hires_timestamp == 0) { + if (hal_get_bool(hm2->encoder.hal->pin.hires_timestamp) == 0) { hm2->encoder.timestamp_div_reg = (hm2->encoder.clock_frequency / 2e6) - 2; } else { hm2->encoder.timestamp_div_reg = (hm2->encoder.clock_frequency / 1e7) - 2; @@ -263,12 +263,12 @@ void hm2_encoder_write(hostmot2_t *hm2) { hm2->encoder.seconds_per_tsdiv_clock = (double)(hm2->encoder.timestamp_div_reg + 2) / (double)hm2->encoder.clock_frequency; - hm2->encoder.written_hires_timestamp = *hm2->encoder.hal->pin.hires_timestamp; + hm2->encoder.written_hires_timestamp = hal_get_bool(hm2->encoder.hal->pin.hires_timestamp); goto force_write; } if(hm2->encoder.dpll_timer_num_addr) { - int32_t dpll_timer_num = *hm2->encoder.hal->pin.dpll_timer_num; + int32_t dpll_timer_num = hal_get_si32(hm2->encoder.hal->pin.dpll_timer_num); if(dpll_timer_num < -1 || dpll_timer_num > 4) dpll_timer_num = -1; if(dpll_timer_num == -1) hm2->encoder.desired_dpll_timer_reg = 0; @@ -397,14 +397,14 @@ int hm2_encoder_parse_md(hostmot2_t *hm2, int md_index) { // allocate the module-global HAL shared memory - hm2->encoder.hal = (hm2_encoder_module_global_t *)hal_malloc(sizeof(hm2_encoder_module_global_t)); + hm2->encoder.hal = hal_malloc(sizeof(*hm2->encoder.hal)); if (hm2->encoder.hal == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; goto fail0; } - hm2->encoder.instance = (hm2_encoder_instance_t *)hal_malloc(hm2->encoder.num_instances * sizeof(hm2_encoder_instance_t)); + hm2->encoder.instance = hal_malloc(hm2->encoder.num_instances * sizeof(*hm2->encoder.instance)); if (hm2->encoder.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -459,269 +459,248 @@ int hm2_encoder_parse_md(hostmot2_t *hm2, int md_index) { // export the encoders to HAL - // FIXME: r hides the r in enclosing function, and it returns the wrong thing { - int i; - int r; - char name[HAL_NAME_LEN + 1]; - // these hal parameters affect all encoder instances + const char *sfpinname; if (md->gtag == HM2_GTAG_MUXED_ENCODER) { - rtapi_snprintf(name, sizeof(name), "%s.encoder.muxed-sample-frequency", hm2->llio->name); + sfpinname = "encoder.muxed-sample-frequency"; } else { - rtapi_snprintf(name, sizeof(name), "%s.encoder.sample-frequency", hm2->llio->name); + sfpinname = "encoder.sample-frequency"; } - r = hal_pin_u32_new(name, HAL_IN, &(hm2->encoder.hal->pin.sample_frequency), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->encoder.hal->pin.sample_frequency), + 0, "%s.%s", hm2->llio->name, sfpinname); if (r < 0) { - HM2_ERR("error adding pin %s, aborting\n", name); + HM2_ERR("error %d adding pin %s.%s, aborting\n", r, hm2->llio->name, sfpinname); goto fail1; } if ((md->gtag == HM2_GTAG_MUXED_ENCODER) && (md->version > 3 )) { // >3 to include modules with probe enable - rtapi_snprintf(name, sizeof(name), "%s.encoder.muxed-skew", hm2->llio->name); - r = hal_pin_u32_new(name, HAL_IN, &(hm2->encoder.hal->pin.skew), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->encoder.hal->pin.skew), + 0, "%s.encoder.muxed-skew", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pin %s, aborting\n", name); + HM2_ERR("error %d adding pin %s.encoder.muxed-skew, aborting\n", r, hm2->llio->name); goto fail1; } hm2->encoder.has_skew = 1; } if(hm2->encoder.dpll_timer_num_addr) { - r = hal_pin_s32_newf(HAL_IN, &(hm2->encoder.hal->pin.dpll_timer_num), hm2->llio->comp_id, "%s.encoder.timer-number", hm2->llio->name); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_IN, &(hm2->encoder.hal->pin.dpll_timer_num), + -1, "%s.encoder.timer-number", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pin %s, aborting\n", name); + HM2_ERR("error %d adding pin %s.encoder.timer-number, aborting\n", r, hm2->llio->name); goto fail1; } - *(hm2->encoder.hal->pin.dpll_timer_num) = -1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.hires-timestamp", hm2->llio->name); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->encoder.hal->pin.hires_timestamp), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->encoder.hal->pin.hires_timestamp), + 0, "%s.encoder.hires-timestamp", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pin %s, aborting\n", name); + HM2_ERR("error %d adding pin %s.encoder.hires-timestamp, aborting\n", r, hm2->llio->name); goto fail1; } - for (i = 0; i < hm2->encoder.num_instances; i ++) { + for (int i = 0; i < hm2->encoder.num_instances; i ++) { // pins - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.rawcounts", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.rawcounts), hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.rawcounts), + 0, "%s.encoder.%02d.rawcounts", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.rawcounts', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.rawlatch", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.rawlatch), hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.rawlatch), + 0, "%s.encoder.%02d.rawlatch", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.rawlatch', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.count", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.count), hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.count), + 0, "%s.encoder.%02d.count", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.count', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.count-latched", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.count_latch), hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.count_latch), + 0, "%s.encoder.%02d.count-latched", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.count-latched', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.position", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.position), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.position), + 0.0, "%s.encoder.%02d.position", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.position', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.position-interpolated", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.position_interpolated), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.position_interpolated), + 0.0, "%s.encoder.%02d.position-interpolated", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.position-interpolated', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.position-latched", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.position_latch), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.position_latch), + 0.0, "%s.encoder.%02d.position-latched", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.position-latched', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.velocity", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.velocity), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.velocity), + 0.0, "%s.encoder.%02d.velocity", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.velocity', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.velocity-rpm", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.velocity_rpm), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.velocity_rpm), + 0.0, "%s.encoder.%02d.velocity-rpm", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.velocity-rpm', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.reset", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->encoder.instance[i].hal.pin.reset), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->encoder.instance[i].hal.pin.reset), + 0, "%s.encoder.%02d.reset", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.reset', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.index-enable", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IO, &(hm2->encoder.instance[i].hal.pin.index_enable), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IO, &(hm2->encoder.instance[i].hal.pin.index_enable), + 0, "%s.encoder.%02d.index-enable", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.index-enable', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.no_clear_on_index", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->encoder.instance[i].hal.pin.no_clear_on_index), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->encoder.instance[i].hal.pin.no_clear_on_index), + 0, "%s.encoder.%02d.no_clear_on_index", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.no_clear_on_index', aborting\n", r, hm2->llio->name, i); goto fail1; } - + if (hm2->encoder.firmware_supports_probe) { - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.probe-enable", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->encoder.instance[i].hal.pin.latch_enable), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->encoder.instance[i].hal.pin.latch_enable), + 0, "%s.encoder.%02d.probe-enable", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.probe-enable', aborting\n", r, hm2->llio->name, i); goto fail1; } - - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.probe-invert", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->encoder.instance[i].hal.pin.latch_polarity), hm2->llio->comp_id); + + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->encoder.instance[i].hal.pin.latch_polarity), + 0, "%s.encoder.%02d.probe-invert", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.probe-invert', aborting\n", r, hm2->llio->name, i); goto fail1; } } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.quad-error", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.quadrature_error), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.quadrature_error), + 0, "%s.encoder.%02d.quad-error", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.quad-error', aborting\n", r, hm2->llio->name, i); goto fail1; } - - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.quad-error-enable", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->encoder.instance[i].hal.pin.quadrature_error_enable), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->encoder.instance[i].hal.pin.quadrature_error_enable), + 0, "%s.encoder.%02d.quad-error-enable", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.quad-error-enable', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.input-a", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.input_a), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.input_a), + 0, "%s.encoder.%02d.input-a", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.input-a', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.input-b", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.input_b), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.input_b), + 0, "%s.encoder.%02d.input-b", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.input-b', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.input-index", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.input_idx), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->encoder.instance[i].hal.pin.input_idx), + 0, "%s.encoder.%02d.input-index", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.encoder.%02d.input-index', aborting\n", r, hm2->llio->name, i); goto fail1; } // parameters - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.scale", hm2->llio->name, i); - r = hal_param_float_new(name, HAL_RW, &(hm2->encoder.instance[i].hal.param.scale), hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->encoder.instance[i].hal.param.scale), + 1.0, "%s.encoder.%02d.scale", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.encoder.%02d.scale', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.index-invert", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->encoder.instance[i].hal.param.index_invert), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->encoder.instance[i].hal.param.index_invert), + 0, "%s.encoder.%02d.index-invert", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.encoder.%02d.index-invert', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.index-mask", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->encoder.instance[i].hal.param.index_mask), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->encoder.instance[i].hal.param.index_mask), + 0, "%s.encoder.%02d.index-mask", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.encoder.%02d.index-mask', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.index-mask-invert", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->encoder.instance[i].hal.param.index_mask_invert), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->encoder.instance[i].hal.param.index_mask_invert), + 0, "%s.encoder.%02d.index-mask-invert", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.encoder.%02d.index-mask-invert', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.counter-mode", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->encoder.instance[i].hal.param.counter_mode), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->encoder.instance[i].hal.param.counter_mode), + 0, "%s.encoder.%02d.counter-mode", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.encoder.%02d.counter-mode', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.filter", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->encoder.instance[i].hal.param.filter), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->encoder.instance[i].hal.param.filter), + 1, "%s.encoder.%02d.filter", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.encoder.%02d.filter', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.encoder.%02d.vel-timeout", hm2->llio->name, i); - r = hal_param_float_new(name, HAL_RW, &(hm2->encoder.instance[i].hal.param.vel_timeout), hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->encoder.instance[i].hal.param.vel_timeout), + 0.5, "%s.encoder.%02d.vel-timeout", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.encoder.%02d.vel-timeout', aborting\n", r, hm2->llio->name, i); goto fail1; } - // - // init the hal objects that need it // the things not initialized here will be set by hm2_encoder_tram_init() // - - *hm2->encoder.instance[i].hal.pin.reset = 0; - *hm2->encoder.instance[i].hal.pin.index_enable = 0; - *hm2->encoder.instance[i].hal.pin.no_clear_on_index = 0; - - hm2->encoder.instance[i].hal.param.scale = 1.0; - hm2->encoder.instance[i].hal.param.index_invert = 0; - hm2->encoder.instance[i].hal.param.index_mask = 0; - hm2->encoder.instance[i].hal.param.index_mask_invert = 0; - hm2->encoder.instance[i].hal.param.counter_mode = 0; - hm2->encoder.instance[i].hal.param.filter = 1; - hm2->encoder.instance[i].hal.param.vel_timeout = 0.5; - hm2->encoder.instance[i].state = HM2_ENCODER_STOPPED; - } } - // initialize with hires off and force update + // initialize with hires off and force update // (with somewhat shady trick to force update if set true in halfile) - *hm2->encoder.hal->pin.hires_timestamp = 0; - hm2->encoder.written_hires_timestamp = 666; + hm2->encoder.written_hires_timestamp = 666; if (md->gtag == HM2_GTAG_ENCODER) { - *hm2->encoder.hal->pin.sample_frequency = 25000000; + hal_set_ui32(hm2->encoder.hal->pin.sample_frequency, 25000000); } else { - *hm2->encoder.hal->pin.sample_frequency = 8000000; + hal_set_ui32(hm2->encoder.hal->pin.sample_frequency, 8000000); } return hm2->encoder.num_instances; @@ -749,20 +728,20 @@ void hm2_encoder_tram_init(hostmot2_t *hm2) { count = hm2_encoder_get_reg_count(hm2, i); - *hm2->encoder.instance[i].hal.pin.rawcounts = count; - *hm2->encoder.instance[i].hal.pin.rawlatch = count; + hal_set_si32(hm2->encoder.instance[i].hal.pin.rawcounts, count); + hal_set_si32(hm2->encoder.instance[i].hal.pin.rawlatch, count); hm2->encoder.instance[i].rawcounts_64 = count; hm2->encoder.instance[i].rawlatch_64 = count; - *hm2->encoder.instance[i].hal.pin.count = 0; - *hm2->encoder.instance[i].hal.pin.count_latch = 0; + hal_set_si32(hm2->encoder.instance[i].hal.pin.count, 0); + hal_set_si32(hm2->encoder.instance[i].hal.pin.count_latch, 0); hm2->encoder.instance[i].count_64 = 0; hm2->encoder.instance[i].count_latch_64 = 0; - *hm2->encoder.instance[i].hal.pin.position = 0.0; - *hm2->encoder.instance[i].hal.pin.position_latch = 0.0; - *hm2->encoder.instance[i].hal.pin.velocity = 0.0; - *hm2->encoder.instance[i].hal.pin.velocity_rpm = 0.0; - *hm2->encoder.instance[i].hal.pin.quadrature_error = 0; + hal_set_real(hm2->encoder.instance[i].hal.pin.position, 0.0); + hal_set_real(hm2->encoder.instance[i].hal.pin.position_latch, 0.0); + hal_set_real(hm2->encoder.instance[i].hal.pin.velocity, 0.0); + hal_set_real(hm2->encoder.instance[i].hal.pin.velocity_rpm, 0.0); + hal_set_bool(hm2->encoder.instance[i].hal.pin.quadrature_error, 0); hm2->encoder.instance[i].zero_offset = count; @@ -818,7 +797,7 @@ static void hm2_encoder_instance_update_rawcounts_and_handle_index(hostmot2_t *h reg_count = hm2_encoder_get_reg_count(hm2, instance); e->rawcounts_64 = hal_extend_counter(e->rawcounts_64, reg_count, 16); - *e->hal.pin.rawcounts = (rtapi_s32)e->rawcounts_64; + hal_set_si32(e->hal.pin.rawcounts, (rtapi_s32)e->rawcounts_64); // @@ -840,13 +819,13 @@ static void hm2_encoder_instance_update_rawcounts_and_handle_index(hostmot2_t *h latched_count = (latch_ctrl >> 16) & 0xffff; latched_64 = hal_extend_counter(prev_rawcounts_64, latched_count, 16); - if (!*(e->hal.pin.no_clear_on_index)) { + if (!hal_get_bool(e->hal.pin.no_clear_on_index)) { e->zero_offset_64 = latched_64; e->zero_offset = (rtapi_s32)latched_64; } e->rawlatch_64 = latched_64; - *(e->hal.pin.rawlatch) = (rtapi_s32)latched_64; - *e->hal.pin.index_enable = 0; + hal_set_si32(e->hal.pin.rawlatch, (rtapi_s32)latched_64); + hal_set_bool(e->hal.pin.index_enable, 0); // may need to update interpolated position after index event because // this _may_ happen without a count but its pretty ugly... // *e->hal.pin.count = *e->hal.pin.rawcounts - e->zero_offset; @@ -867,8 +846,8 @@ static void hm2_encoder_instance_update_rawcounts_and_handle_index(hostmot2_t *h latched_64 = hal_extend_counter(prev_rawcounts_64, latched_count, 16); e->rawlatch_64 = latched_64; - *(e->hal.pin.rawlatch) = (rtapi_s32)latched_64; - *e->hal.pin.latch_enable = 0; + hal_set_si32(e->hal.pin.rawlatch, (rtapi_s32)latched_64); + hal_set_bool(e->hal.pin.latch_enable, 0); } } } @@ -913,12 +892,12 @@ static void hm2_encoder_instance_update_position(hostmot2_t *hm2, int instance) // reset count if the user wants us to (by just setting the zero offset to the current rawcounts) // - if (*e->hal.pin.reset) { - e->zero_offset = *e->hal.pin.rawcounts; + if (hal_get_bool(e->hal.pin.reset)) { + e->zero_offset = hal_get_si32(e->hal.pin.rawcounts); e->zero_offset_64 = e->rawcounts_64; - *e->hal.pin.rawlatch = e->zero_offset; + hal_set_si32(e->hal.pin.rawlatch, e->zero_offset); e->rawlatch_64 = e->zero_offset_64; - *e->hal.pin.position_interpolated = *e->hal.pin.position; + hal_set_real(e->hal.pin.position_interpolated, hal_get_real(e->hal.pin.position)); } @@ -930,9 +909,9 @@ static void hm2_encoder_instance_update_position(hostmot2_t *hm2, int instance) // From that we easily compute count and scaled position. // - *e->hal.pin.count = *e->hal.pin.rawcounts - e->zero_offset; + hal_set_si32(e->hal.pin.count, hal_get_si32(e->hal.pin.rawcounts) - e->zero_offset); e->count_64 = e->rawcounts_64 - e->zero_offset_64; - *e->hal.pin.count_latch = *e->hal.pin.rawlatch - e->zero_offset; + hal_set_si32(e->hal.pin.count_latch, hal_get_si32(e->hal.pin.rawlatch) - e->zero_offset); e->count_latch_64 = e->rawlatch_64 - e->zero_offset_64; @@ -942,8 +921,8 @@ static void hm2_encoder_instance_update_position(hostmot2_t *hm2, int instance) // to avoid wrap on high-resolution encoders. // - *e->hal.pin.position = e->count_64 / e->hal.param.scale; - *e->hal.pin.position_latch = e->count_latch_64 / e->hal.param.scale; + hal_set_real(e->hal.pin.position, e->count_64 / hal_get_real(e->hal.param.scale)); + hal_set_real(e->hal.pin.position_latch, e->count_latch_64 / hal_get_real(e->hal.param.scale)); } @@ -960,9 +939,9 @@ static void hm2_encoder_instance_process_tram_read(hostmot2_t *hm2, int instance e = &hm2->encoder.instance[instance]; // sanity check - if (e->hal.param.scale == 0.0) { + if (hal_get_real(e->hal.param.scale) == 0.0) { HM2_ERR("encoder.%02d.scale == 0.0, bogus, setting to 1.0\n", instance); - e->hal.param.scale = 1.0; + hal_set_real(e->hal.param.scale, 1.0); } @@ -985,7 +964,7 @@ static void hm2_encoder_instance_process_tram_read(hostmot2_t *hm2, int instance hm2_encoder_instance_update_rawcounts_and_handle_index(hm2, instance); hm2_encoder_instance_update_position(hm2, instance); - e->prev_event_rawcounts = *e->hal.pin.rawcounts; + e->prev_event_rawcounts = hal_get_si32(e->hal.pin.rawcounts); e->prev_event_reg_timestamp = hm2_encoder_get_reg_timestamp(hm2, instance); e->prev_dS_counts = 0; @@ -1031,31 +1010,31 @@ static void hm2_encoder_instance_process_tram_read(hostmot2_t *hm2, int instance dT_clocks = (time_of_interest - e->prev_event_reg_timestamp) + (e->tsc_num_rollovers << 16); dT_s = (double)dT_clocks * hm2->encoder.seconds_per_tsdiv_clock; - if (dT_s >= e->hal.param.vel_timeout) { - *e->hal.pin.velocity = 0.0; - *e->hal.pin.velocity_rpm = 0.0; - *e->hal.pin.position_interpolated = *e->hal.pin.position; + if (dT_s >= hal_get_real(e->hal.param.vel_timeout)) { + hal_set_real(e->hal.pin.velocity, 0.0); + hal_set_real(e->hal.pin.velocity_rpm, 0.0); + hal_set_real(e->hal.pin.position_interpolated, hal_get_real(e->hal.pin.position)); e->state = HM2_ENCODER_STOPPED; break; } - if ((*e->hal.pin.velocity * e->hal.param.scale) > 0.0) { + if ((hal_get_real(e->hal.pin.velocity) * hal_get_real(e->hal.param.scale)) > 0.0) { dS_counts = 1; } else { dS_counts = -1; } // if no counts, calculate interpolated position - *e->hal.pin.position_interpolated = *e->hal.pin.position + (dT_s * *e->hal.pin.velocity); + hal_set_real(e->hal.pin.position_interpolated, hal_get_real(e->hal.pin.position) + (dT_s * hal_get_real(e->hal.pin.velocity))); - dS_pos_units = dS_counts / e->hal.param.scale; + dS_pos_units = dS_counts / hal_get_real(e->hal.param.scale); // we can calculate velocity only if timestamp changed along with counts if (dT_clocks > 0) { // we know the encoder velocity is not faster than this vel = dS_pos_units / dT_s; - if (fabs(vel) < fabs(*e->hal.pin.velocity)) { - *e->hal.pin.velocity = vel; - *e->hal.pin.velocity_rpm = vel * 60.0; + if (fabs(vel) < fabs(hal_get_real(e->hal.pin.velocity))) { + hal_set_real(e->hal.pin.velocity, vel); + hal_set_real(e->hal.pin.velocity_rpm, vel * 60.0); } } @@ -1076,14 +1055,14 @@ static void hm2_encoder_instance_process_tram_read(hostmot2_t *hm2, int instance hm2_encoder_instance_update_rawcounts_and_handle_index(hm2, instance); hm2_encoder_instance_update_position(hm2, instance); - *e->hal.pin.position_interpolated = *e->hal.pin.position; + hal_set_real(e->hal.pin.position_interpolated, hal_get_real(e->hal.pin.position)); time_of_interest = hm2_encoder_get_reg_timestamp(hm2, instance); if (time_of_interest < e->prev_time_of_interest) { // tsc rollover! e->tsc_num_rollovers ++; } - dS_counts = *e->hal.pin.rawcounts - e->prev_event_rawcounts; + dS_counts = hal_get_si32(e->hal.pin.rawcounts) - e->prev_event_rawcounts; // If we reversed direction and moved exactly one edge, // we can't reliably estimate velocity. The encoder might @@ -1091,24 +1070,24 @@ static void hm2_encoder_instance_process_tram_read(hostmot2_t *hm2, int instance // small dT between adjacent edges, leading to misleadingly // large velocity estimates. So we just call it 0. if ( - (((*e->hal.pin.rawcounts - e->prev_event_rawcounts) == 1) && (e->prev_dS_counts < 0)) - || (((*e->hal.pin.rawcounts - e->prev_event_rawcounts) == -1) && (e->prev_dS_counts > 0)) + (((hal_get_si32(e->hal.pin.rawcounts) - e->prev_event_rawcounts) == 1) && (e->prev_dS_counts < 0)) + || (((hal_get_si32(e->hal.pin.rawcounts) - e->prev_event_rawcounts) == -1) && (e->prev_dS_counts > 0)) ) { - *e->hal.pin.velocity = 0.0; - *e->hal.pin.velocity_rpm = 0.0; - *e->hal.pin.position_interpolated = *e->hal.pin.position; + hal_set_real(e->hal.pin.velocity, 0.0); + hal_set_real(e->hal.pin.velocity_rpm, 0.0); + hal_set_real(e->hal.pin.position_interpolated, hal_get_real(e->hal.pin.position)); } else { dT_clocks = (time_of_interest - e->prev_event_reg_timestamp) + (e->tsc_num_rollovers << 16); dT_s = (double)dT_clocks * hm2->encoder.seconds_per_tsdiv_clock; - dS_pos_units = dS_counts / e->hal.param.scale; + dS_pos_units = dS_counts / hal_get_real(e->hal.param.scale); // we can calculate velocity only if timestamp changed along with counts if (dT_clocks > 0) { // finally time to do Relative-Time Velocity Estimation - *e->hal.pin.velocity = dS_pos_units / dT_s; - *e->hal.pin.velocity_rpm = *e->hal.pin.velocity * 60.0; + hal_set_real(e->hal.pin.velocity, dS_pos_units / dT_s); + hal_set_real(e->hal.pin.velocity_rpm, hal_get_real(e->hal.pin.velocity) * 60.0); } } @@ -1116,7 +1095,7 @@ static void hm2_encoder_instance_process_tram_read(hostmot2_t *hm2, int instance e->prev_dS_counts = dS_counts; - e->prev_event_rawcounts = *e->hal.pin.rawcounts; + e->prev_event_rawcounts = hal_get_si32(e->hal.pin.rawcounts); e->prev_event_reg_timestamp = time_of_interest; e->prev_time_of_interest = time_of_interest; diff --git a/src/hal/drivers/mesa-hostmot2/hm2_7i43.c b/src/hal/drivers/mesa-hostmot2/hm2_7i43.c index 92acf8c39a4..ac5e23fd508 100644 --- a/src/hal/drivers/mesa-hostmot2/hm2_7i43.c +++ b/src/hal/drivers/mesa-hostmot2/hm2_7i43.c @@ -215,7 +215,7 @@ int hm2_7i43_read(hm2_lowlevel_io_t *this, rtapi_u32 addr, void *buffer, int siz if (hm2_7i43_epp_check_for_timeout(board)) { THIS_PRINT("EPP timeout on data cycle of read(addr=0x%04x, size=%d)\n", addr, size); - (*this->io_error) = 1; + hal_set_bool(*this->io_error, 1); this->needs_reset = 1; hm2_7i43_epp_clear_timeout(board); return 0; // fail @@ -246,7 +246,7 @@ int hm2_7i43_write(hm2_lowlevel_io_t *this, rtapi_u32 addr, const void *buffer, if (hm2_7i43_epp_check_for_timeout(board)) { THIS_PRINT("EPP timeout on data cycle of write(addr=0x%04x, size=%d)\n", addr, size); - (*this->io_error) = 1; + hal_set_bool(*this->io_error, 1); this->needs_reset = 1; hm2_7i43_epp_clear_timeout(board); return 0; diff --git a/src/hal/drivers/mesa-hostmot2/hm2_7i90.c b/src/hal/drivers/mesa-hostmot2/hm2_7i90.c index 7d6bd0638a6..1275c02015c 100644 --- a/src/hal/drivers/mesa-hostmot2/hm2_7i90.c +++ b/src/hal/drivers/mesa-hostmot2/hm2_7i90.c @@ -211,7 +211,7 @@ int hm2_7i90_read(hm2_lowlevel_io_t *this, rtapi_u32 addr, void *buffer, int siz if (hm2_7i90_epp_check_for_timeout(board)) { THIS_PRINT("EPP timeout on data cycle of read(addr=0x%04x, size=%d)\n", addr, size); - (*this->io_error) = 1; + hal_set_bool(*this->io_error, 1); this->needs_reset = 1; hm2_7i90_epp_clear_timeout(board); return 0; // fail @@ -242,7 +242,7 @@ int hm2_7i90_write(hm2_lowlevel_io_t *this, rtapi_u32 addr, const void *buffer, if (hm2_7i90_epp_check_for_timeout(board)) { THIS_PRINT("EPP timeout on data cycle of write(addr=0x%04x, size=%d)\n", addr, size); - (*this->io_error) = 1; + hal_set_bool(*this->io_error, 1); this->needs_reset = 1; hm2_7i90_epp_clear_timeout(board); return 0; diff --git a/src/hal/drivers/mesa-hostmot2/hm2_eth.c b/src/hal/drivers/mesa-hostmot2/hm2_eth.c index b4efc4a8f79..c9f4c94b72e 100644 --- a/src/hal/drivers/mesa-hostmot2/hm2_eth.c +++ b/src/hal/drivers/mesa-hostmot2/hm2_eth.c @@ -96,7 +96,7 @@ RTAPI_MP_ARRAY_STRING(config, MAX_ETH_BOARDS, "config string for the AnyIO board int debug = 0; RTAPI_MP_INT(debug, "Developer/debug use only! Enable debug logging."); -static char *firewall = 0; +static char *firewall = NULL; RTAPI_MP_STRING(firewall, "Firewall backend for traffic isolation: auto (default), iptables, nft, or none."); static int boards_count = 0; @@ -1057,29 +1057,29 @@ static int hm2_eth_send_queued_reads(hm2_lowlevel_io_t *this) { static bool record_soft_error(hm2_eth_t *board) { if(!board->hal) return 1; // still early in hm2_eth_probe board->llio.needs_soft_reset = 1; - *board->hal->packet_error = 1; - *board->hal->packet_error_total += 1; - int32_t increment = board->hal->packet_error_increment; + hal_set_bool(board->hal->packet_error, 1); + hal_set_ui32(board->hal->packet_error_total, hal_get_ui32(board->hal->packet_error_total) + 1); + int32_t increment = hal_get_si32(board->hal->packet_error_increment); if(increment < 1) increment = 1; board->comm_error_counter += increment; - if(board->comm_error_counter < 0 || board->comm_error_counter > board->hal->packet_error_limit) - board->comm_error_counter = board->hal->packet_error_limit; - *board->hal->packet_error_level = board->comm_error_counter; - bool result = board->comm_error_counter < board->hal->packet_error_limit; - if(!result) *board->llio.io_error = true; - *board->hal->packet_error_exceeded = !result; + if(board->comm_error_counter < 0 || board->comm_error_counter > hal_get_si32(board->hal->packet_error_limit)) + board->comm_error_counter = hal_get_si32(board->hal->packet_error_limit); + hal_set_si32(board->hal->packet_error_level, board->comm_error_counter); + bool result = board->comm_error_counter < hal_get_si32(board->hal->packet_error_limit); + if(!result) hal_set_bool(*board->llio.io_error, true); + hal_set_bool(board->hal->packet_error_exceeded, !result); return result; } static void decrement_soft_error(hm2_eth_t *board) { if(!board->hal) return; // still early in hm2_eth_probe - int32_t decrement = board->hal->packet_error_decrement; + int32_t decrement = hal_get_si32(board->hal->packet_error_decrement); if(decrement < 1) decrement = 1; board->comm_error_counter -= decrement; if(board->comm_error_counter < 0) board->comm_error_counter = 0; - *board->hal->packet_error_level = board->comm_error_counter; - *board->hal->packet_error = 0; - *board->hal->packet_error_exceeded = 0; + hal_set_si32(board->hal->packet_error_level, board->comm_error_counter); + hal_set_bool(board->hal->packet_error, 0); + hal_set_bool(board->hal->packet_error_exceeded, 0); } static int hm2_eth_receive_queued_reads(hm2_lowlevel_io_t *this) { @@ -1093,11 +1093,11 @@ static int hm2_eth_receive_queued_reads(hm2_lowlevel_io_t *this) { // pin (or they did something else like fiddle with the error limit // during a run, in which case we don't care if we reset the counter // or not) - if(board->hal && board->comm_error_counter == board->hal->packet_error_limit && !*board->llio.io_error) { + if(board->hal && board->comm_error_counter == hal_get_si32(board->hal->packet_error_limit) && !hal_get_bool(*board->llio.io_error)) { board->comm_error_counter = 0; } - long read_timeout = board->hal ? board->hal->read_timeout : 1600000; + long read_timeout = board->hal ? hal_get_si32(board->hal->read_timeout) : 1600000; if(read_timeout <= 0)//less than or equal to 0, use 80% of the thread period. read_timeout = 80; if(read_timeout < 100)//less than 100 is interpreted as a percentage of the thread period. @@ -1705,69 +1705,37 @@ static int hm2_eth_items(hm2_eth_t *board) { board->hal = hal_malloc(sizeof(*board->hal)); if(!board->hal) return -ENOMEM; - if((r = hal_param_s32_newf(HAL_RW, - &board->hal->read_timeout, - board->llio.comp_id, - "%s.packet-read-timeout", - board->llio.name)) < 0) + if((r = hal_param_new_si32(board->llio.comp_id, HAL_RW, &board->hal->read_timeout, + 80, "%s.packet-read-timeout", board->llio.name)) < 0) return r; - board->hal->read_timeout = 80; - if((r = hal_param_s32_newf(HAL_RW, - &board->hal->packet_error_limit, - board->llio.comp_id, - "%s.packet-error-limit", - board->llio.name)) < 0) + if((r = hal_param_new_si32(board->llio.comp_id, HAL_RW, &board->hal->packet_error_limit, + 10, "%s.packet-error-limit", board->llio.name)) < 0) return r; - board->hal->packet_error_limit = 10; - if((r = hal_param_s32_newf(HAL_RW, - &board->hal->packet_error_increment, - board->llio.comp_id, - "%s.packet-error-increment", - board->llio.name)) < 0) + if((r = hal_param_new_si32(board->llio.comp_id, HAL_RW, &board->hal->packet_error_increment, + 2, "%s.packet-error-increment", board->llio.name)) < 0) return r; - board->hal->packet_error_increment = 2; - if((r = hal_param_s32_newf(HAL_RO, - &board->hal->packet_error_decrement, - board->llio.comp_id, - "%s.packet-error-decrement", - board->llio.name)) < 0) + if((r = hal_param_new_si32(board->llio.comp_id, HAL_RO, &board->hal->packet_error_decrement, + 1, "%s.packet-error-decrement", board->llio.name)) < 0) return r; - board->hal->packet_error_decrement = 1; - if((r = hal_pin_bit_newf(HAL_OUT, - &board->hal->packet_error, - board->llio.comp_id, - "%s.packet-error", - board->llio.name)) < 0) + if((r = hal_pin_new_bool(board->llio.comp_id, HAL_OUT, &board->hal->packet_error, + 0, "%s.packet-error", board->llio.name)) < 0) return r; - *board->hal->packet_error = 0; - if((r = hal_pin_u32_newf(HAL_IO, - &board->hal->packet_error_total, - board->llio.comp_id, - "%s.packet-error-total", - board->llio.name)) < 0) + if((r = hal_pin_new_ui32(board->llio.comp_id, HAL_IO, &board->hal->packet_error_total, + 0, "%s.packet-error-total", board->llio.name)) < 0) return r; - *board->hal->packet_error_total = 0; - if((r = hal_pin_s32_newf(HAL_OUT, - &board->hal->packet_error_level, - board->llio.comp_id, - "%s.packet-error-level", - board->llio.name)) < 0) + if((r = hal_pin_new_si32(board->llio.comp_id, HAL_OUT, &board->hal->packet_error_level, + 0, "%s.packet-error-level", board->llio.name)) < 0) return r; - *board->hal->packet_error_level = 0; - if((r = hal_pin_bit_newf(HAL_OUT, - &board->hal->packet_error_exceeded, - board->llio.comp_id, - "%s.packet-error-exceeded", - board->llio.name)) < 0) + if((r = hal_pin_new_bool(board->llio.comp_id, HAL_OUT, &board->hal->packet_error_exceeded, + 0, "%s.packet-error-exceeded", board->llio.name)) < 0) return r; - *board->hal->packet_error_exceeded = 0; return 0; } @@ -1789,7 +1757,7 @@ int rtapi_app_main(void) { for(i = 0, ret = 0; ret == 0 && imaxicharbits = 0; } - inst->hal->icdelay = inst->maxicharbits; + hal_set_ui32(inst->hal->icdelay, inst->maxicharbits); } // @@ -440,12 +440,12 @@ static int send_comms_change(hm2_modbus_inst_t *inst) inst->cfg_tx.drivedelay = cc->cmd.idrvdelay ? cc->cmd.idrvdelay : 1; // Expose to HAL - inst->hal->baudrate = baudrate; - inst->hal->parity = parity; - inst->hal->stopbits = stopbits; - inst->hal->rxdelay = inst->cfg_rx.ifdelay; - inst->hal->txdelay = inst->cfg_tx.ifdelay; - inst->hal->drvdelay = inst->cfg_tx.drivedelay; + hal_set_ui32(inst->hal->baudrate, baudrate); + hal_set_ui32(inst->hal->parity, parity); + hal_set_ui32(inst->hal->stopbits, stopbits); + hal_set_ui32(inst->hal->rxdelay, inst->cfg_rx.ifdelay); + hal_set_ui32(inst->hal->txdelay, inst->cfg_tx.ifdelay); + hal_set_ui32(inst->hal->drvdelay, inst->cfg_tx.drivedelay); // Redo the inter-character delay settings setup_icdelay(inst, baudrate, parity, stopbits, cc->cmd.iicdelay); @@ -460,18 +460,18 @@ static void set_error(hm2_modbus_inst_t *inst, int errcode) { if(handling_inits(inst)) { // No individual pins for init commands, use global - *(inst->hal->fault) = 1; - *(inst->hal->faultcmd) = inst->cmdidx; - *(inst->hal->lasterror) = errcode; + hal_set_bool(inst->hal->fault, 1); + hal_set_ui32(inst->hal->faultcmd, inst->cmdidx); + hal_set_ui32(inst->hal->lasterror, errcode); return; } hm2_modbus_cmd_t *cc = current_cmd(inst); if(++cc->errors >= MAX_ERRORS || cc->disabled) { cc->disabled = 1; - *(inst->hal->cmds[inst->cmdidx].disabled) = 1; - *(inst->hal->cmds[inst->cmdidx].errorcode) = errcode; + hal_set_bool(inst->hal->cmds[inst->cmdidx].disabled, 1); + hal_set_ui32(inst->hal->cmds[inst->cmdidx].errorcode, errcode); } - *(inst->hal->cmds[inst->cmdidx].error) = cc->errors; + hal_set_ui32(inst->hal->cmds[inst->cmdidx].error, cc->errors); } // @@ -612,15 +612,15 @@ static inline int next_command(hm2_modbus_inst_t *inst) // Reset the individual commands on request. // Using modulo index ensures we also reset index zero when we wrap. unsigned i = inst->cmdidx % inst->ncmds; - bool b = !!*(inst->hal->cmds[i].reset); + bool b = hal_get_bool(inst->hal->cmds[i].reset); if(inst->cmds[i].prevreset != b) { inst->cmds[i].prevreset = !inst->cmds[i].prevreset; if(inst->cmds[i].prevreset) { inst->cmds[i].disabled = 0; inst->cmds[i].errors = 0; - *(inst->hal->cmds[i].disabled) = 0; - *(inst->hal->cmds[i].error) = 0; - *(inst->hal->cmds[i].errorcode) = 0; + hal_set_bool(inst->hal->cmds[i].disabled, 0); + hal_set_ui32(inst->hal->cmds[i].error, 0); + hal_set_ui32(inst->hal->cmds[i].errorcode, 0); // Honor the writeflush flag when coming out of disable. write_flush_cmd(inst, i); } @@ -628,15 +628,15 @@ static inline int next_command(hm2_modbus_inst_t *inst) // The run-time disabling of a command takes precedens over reset. // Set it on the rising edge of the 'disable' pin - b = !!*(inst->hal->cmds[i].disable); + b = hal_get_bool(inst->hal->cmds[i].disable); if(inst->cmds[i].prevdisable != b) { inst->cmds[i].prevdisable = !inst->cmds[i].prevdisable; if(inst->cmds[i].prevdisable) { inst->cmds[i].disabled = 1; inst->cmds[i].errors = 0; - *(inst->hal->cmds[i].disabled) = 1; - *(inst->hal->cmds[i].error) = 0; - *(inst->hal->cmds[i].errorcode) = EAGAIN; + hal_set_bool(inst->hal->cmds[i].disabled, 1); + hal_set_ui32(inst->hal->cmds[i].error, 0); + hal_set_ui32(inst->hal->cmds[i].errorcode, EAGAIN); } } } while(inst->cmdidx < inst->ncmds && inst->cmds[inst->cmdidx].disabled); @@ -689,7 +689,7 @@ static inline void set_state(hm2_modbus_inst_t *inst, int newstate) inst->timeout = 25000000; // 25 milliseconds break; case STATE_START: - if(*(inst->hal->suspend)) { + if(hal_get_bool(inst->hal->suspend)) { inst->suspended = 1; } inst->ignoredata = 0; // Re-enable data handling @@ -721,9 +721,9 @@ static void do_timeout(hm2_modbus_inst_t *inst) MSG_DBG("Timeout reset cmd=%u %s(%d)\n", inst->cmdidx, state_names[inst->state], inst->state); force_resend(inst); queue_reset(inst); - *(inst->hal->lasterror) = ETIMEDOUT; - *(inst->hal->fault) = 1; - *(inst->hal->faultcmd) = inst->cmdidx; + hal_set_ui32(inst->hal->lasterror, ETIMEDOUT); + hal_set_bool(inst->hal->fault, 1); + hal_set_ui32(inst->hal->faultcmd, inst->cmdidx); set_error(inst, ETIMEDOUT); set_state(inst, STATE_START); } @@ -749,7 +749,7 @@ static void process(void *arg, long period) hm2_modbus_inst_t *inst = (hm2_modbus_inst_t *)arg; if(inst->suspended) { - if(!*(inst->hal->suspend)) { + if(!hal_get_bool(inst->hal->suspend)) { inst->suspended = 0; // When coming out of suspend, see if we want to suppress writes // because our local data will most likely not match the pin data. @@ -772,18 +772,18 @@ static void process(void *arg, long period) } // Re-enable all commands on rising edge of global reset pin - bool b = !!*(inst->hal->reset); // Make sure its value is bool-worthy + bool b = hal_get_bool(inst->hal->reset); if(inst->prevreset != b) { inst->prevreset = !inst->prevreset; if(inst->prevreset) { for(unsigned i = 0; i < inst->ncmds; i++) { if(inst->cmds[i].disabled) { inst->cmds[i].disabled = 0; - *(inst->hal->cmds[i].disabled) = 0; + hal_set_bool(inst->hal->cmds[i].disabled, 0); write_flush_cmd(inst, i); } - *(inst->hal->cmds[i].errorcode) = 0; - *(inst->hal->cmds[i].error) = 0; + hal_set_ui32(inst->hal->cmds[i].errorcode, 0); + hal_set_ui32(inst->hal->cmds[i].error, 0); inst->cmds[i].errors = 0; } } @@ -864,9 +864,9 @@ static void process(void *arg, long period) // If the next command is again the first, then we have no // messages we can send. if(next_command(inst)) { - *(inst->hal->lasterror) = ENODATA; - *(inst->hal->fault) = 1; - *(inst->hal->faultcmd) = 0; + hal_set_ui32(inst->hal->lasterror, ENODATA); + hal_set_bool(inst->hal->fault, 1); + hal_set_ui32(inst->hal->faultcmd, 0); break; } } @@ -962,7 +962,7 @@ static void process(void *arg, long period) if(inst->timeout < 0) { // Timeout of delay, proceed to next command set_state(inst, STATE_START); - *(inst->hal->fault) = 0; + hal_set_bool(inst->hal->fault, 0); } break; @@ -1086,7 +1086,7 @@ static void process(void *arg, long period) // more (new) data is pending, then that will also be out-of-band. // We can go to the start state and sort it out there. set_state(inst, STATE_START); - *(inst->hal->fault) = 0; + hal_set_bool(inst->hal->fault, 0); } break; @@ -1097,9 +1097,9 @@ static void process(void *arg, long period) default: MSG_ERR("%s: error: Unknown state (%d) in process(), setting START state\n", inst->name, inst->state); - *(inst->hal->fault) = 1; - *(inst->hal->lasterror) = EINVAL; - *(inst->hal->faultcmd) = inst->cmdidx; + hal_set_bool(inst->hal->fault, 1); + hal_set_ui32(inst->hal->lasterror, EINVAL); + hal_set_ui32(inst->hal->faultcmd, inst->cmdidx); set_state(inst, STATE_START); break; } @@ -1450,38 +1450,38 @@ static int build_data_frame(hm2_modbus_inst_t *inst) break; case MBCMD_W_COIL: // Write single coil CHK_RV(ch_append16(cc, cc->cmd.caddr)); - CHK_RV(ch_append16(cc, hal->pins[p].pin->b ? 0xFF00 : 0x0000)); + CHK_RV(ch_append16(cc, hal_get_bool(hal->pins[p].pin.b) ? 0xFF00 : 0x0000)); break; case MBCMD_W_REGISTER: // Write single register // The target mtype can only be MBT_AB or MBT_BA (single reg write) CHK_RV(ch_append16(cc, cc->cmd.caddr)); switch(cc->typeptr[0].htype) { - case HAL_BIT: - CHK_RV(map_u(cc, hal->pins[p].pin->b ? 1 : 0, 0)); + case HAL_BOOL: + CHK_RV(map_u(cc, hal_get_bool(hal->pins[p].pin.b) ? 1 : 0, 0)); break; case HAL_U32: switch(mtypetype(cc->typeptr[0].mtype)) { - case MBT_U: CHK_RV(map_u(cc, hal->pins[p].pin->u, 0)); break; - case MBT_S: CHK_RV(map_s(cc, map_us(hal->pins[p].pin->u), 0)); break; - case MBT_F: CHK_RV(map_f(cc, map_uf(hal->pins[p].pin->u), 0)); break; + case MBT_U: CHK_RV(map_u(cc, hal_get_ui32(hal->pins[p].pin.u), 0)); break; + case MBT_S: CHK_RV(map_s(cc, map_us(hal_get_ui32(hal->pins[p].pin.u)), 0)); break; + case MBT_F: CHK_RV(map_f(cc, map_uf(hal_get_ui32(hal->pins[p].pin.u)), 0)); break; } break; - case HAL_U64: + case HAL_UINT: switch(mtypetype(cc->typeptr[0].mtype)) { - case MBT_U: CHK_RV(map_u(cc, hal->pins[p].pin->lu, 0)); break; - case MBT_S: CHK_RV(map_s(cc, map_us(hal->pins[p].pin->lu), 0)); break; - case MBT_F: CHK_RV(map_f(cc, map_uf(hal->pins[p].pin->lu), 0)); break; + case MBT_U: CHK_RV(map_u(cc, hal_get_uint(hal->pins[p].pin.u), 0)); break; + case MBT_S: CHK_RV(map_s(cc, map_us(hal_get_uint(hal->pins[p].pin.u)), 0)); break; + case MBT_F: CHK_RV(map_f(cc, map_uf(hal_get_uint(hal->pins[p].pin.u)), 0)); break; } break; case HAL_S32: if(!haspinscale(&cc->typeptr[0])) { switch(mtypetype(cc->typeptr[0].mtype)) { - case MBT_U: CHK_RV(map_u(cc, map_su(hal->pins[p].pin->s), 0)); break; - case MBT_S: CHK_RV(map_s(cc, hal->pins[p].pin->s, 0)); break; - case MBT_F: CHK_RV(map_f(cc, map_sf(hal->pins[p].pin->s), 0)); break; + case MBT_U: CHK_RV(map_u(cc, map_su(hal_get_si32(hal->pins[p].pin.s)), 0)); break; + case MBT_S: CHK_RV(map_s(cc, hal_get_si32(hal->pins[p].pin.s), 0)); break; + case MBT_F: CHK_RV(map_f(cc, map_sf(hal_get_si32(hal->pins[p].pin.s)), 0)); break; } } else { - val64.f = (real_t)((rtapi_s64)hal->pins[p].pin->s - hal->pins[p].offset->s) * *(hal->pins[p].scale); + val64.f = (rtapi_real)((rtapi_s64)hal_get_si32(hal->pins[p].pin.s) - hal_get_si32(hal->pins[p].offset.s)) * hal_get_real(hal->pins[p].scale); switch(mtypetype(cc->typeptr[0].mtype)) { case MBT_U: CHK_RV(map_u(cc, map_fu(val64.f), 0)); break; case MBT_S: CHK_RV(map_s(cc, map_fs(val64.f), 0)); break; @@ -1489,15 +1489,15 @@ static int build_data_frame(hm2_modbus_inst_t *inst) } } break; - case HAL_S64: + case HAL_SINT: if(!haspinscale(&cc->typeptr[0])) { switch(mtypetype(cc->typeptr[0].mtype)) { - case MBT_U: CHK_RV(map_u(cc, map_su(hal->pins[p].pin->ls), 0)); break; - case MBT_S: CHK_RV(map_s(cc, hal->pins[p].pin->ls, 0)); break; - case MBT_F: CHK_RV(map_f(cc, map_sf(hal->pins[p].pin->ls), 0)); break; + case MBT_U: CHK_RV(map_u(cc, map_su(hal_get_sint(hal->pins[p].pin.s)), 0)); break; + case MBT_S: CHK_RV(map_s(cc, hal_get_sint(hal->pins[p].pin.s), 0)); break; + case MBT_F: CHK_RV(map_f(cc, map_sf(hal_get_sint(hal->pins[p].pin.s)), 0)); break; } } else { - val64.f = (real_t)(hal->pins[p].pin->ls - hal->pins[p].offset->ls) * *(hal->pins[p].scale); + val64.f = (rtapi_real)(hal_get_sint(hal->pins[p].pin.s) - hal_get_sint(hal->pins[p].offset.s)) * hal_get_real(hal->pins[p].scale); switch(mtypetype(cc->typeptr[0].mtype)) { case MBT_U: CHK_RV(map_u(cc, map_fu(val64.f), 0)); break; case MBT_S: CHK_RV(map_s(cc, map_fs(val64.f), 0)); break; @@ -1505,15 +1505,15 @@ static int build_data_frame(hm2_modbus_inst_t *inst) } } break; - case HAL_FLOAT: + case HAL_REAL: if(!haspinscale(&cc->typeptr[0])) { switch(mtypetype(cc->typeptr[0].mtype)) { - case MBT_U: CHK_RV(map_u(cc, map_fu(hal->pins[p].pin->f), 0)); break; - case MBT_S: CHK_RV(map_s(cc, map_fs(hal->pins[p].pin->f), 0)); break; - case MBT_F: CHK_RV(map_f(cc, hal->pins[p].pin->f, 0)); break; + case MBT_U: CHK_RV(map_u(cc, map_fu(hal_get_real(hal->pins[p].pin.r)), 0)); break; + case MBT_S: CHK_RV(map_s(cc, map_fs(hal_get_real(hal->pins[p].pin.r)), 0)); break; + case MBT_F: CHK_RV(map_f(cc, hal_get_real(hal->pins[p].pin.r), 0)); break; } } else { - val64.f = (hal->pins[p].pin->f - hal->pins[p].offset->f) * *(hal->pins[p].scale); + val64.f = (hal_get_real(hal->pins[p].pin.r) - hal_get_real(hal->pins[p].offset.r)) * hal_get_real(hal->pins[p].scale); switch(mtypetype(cc->typeptr[0].mtype)) { case MBT_U: CHK_RV(map_u(cc, map_fu(val64.f), 0)); break; case MBT_S: CHK_RV(map_s(cc, map_fs(val64.f), 0)); break; @@ -1531,7 +1531,7 @@ static int build_data_frame(hm2_modbus_inst_t *inst) CHK_RV(ch_append16(cc, cc->cmd.cpincnt)); CHK_RV(ch_append8(cc, (cc->cmd.cpincnt + 7) / 8)); for(unsigned i = 0; i < cc->cmd.cpincnt; i++) { - if(hal->pins[p++].pin->b) + if(hal_get_bool(hal->pins[p++].pin.b)) acc |= 1u << (i % 8); if((i % 8) == 7 || i == cc->cmd.cpincnt - 1u) { // time for the next byte CHK_RV(ch_append8(cc, acc)); @@ -1552,32 +1552,32 @@ static int build_data_frame(hm2_modbus_inst_t *inst) regpos++; } switch(cc->typeptr[i].htype) { - case HAL_BIT: - CHK_RV(map_u(cc, hal->pins[p].pin->b ? 1 : 0, i)); + case HAL_BOOL: + CHK_RV(map_u(cc, hal_get_bool(hal->pins[p].pin.b) ? 1 : 0, i)); break; case HAL_U32: switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: CHK_RV(map_u(cc, hal->pins[p].pin->u, i)); break; - case MBT_S: CHK_RV(map_s(cc, map_us(hal->pins[p].pin->u), i)); break; - case MBT_F: CHK_RV(map_f(cc, map_uf(hal->pins[p].pin->u), i)); break; + case MBT_U: CHK_RV(map_u(cc, hal_get_ui32(hal->pins[p].pin.u), i)); break; + case MBT_S: CHK_RV(map_s(cc, map_us(hal_get_ui32(hal->pins[p].pin.u)), i)); break; + case MBT_F: CHK_RV(map_f(cc, map_uf(hal_get_ui32(hal->pins[p].pin.u)), i)); break; } break; - case HAL_U64: + case HAL_UINT: switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: CHK_RV(map_u(cc, hal->pins[p].pin->lu, i)); break; - case MBT_S: CHK_RV(map_s(cc, map_us(hal->pins[p].pin->lu), i)); break; - case MBT_F: CHK_RV(map_f(cc, map_uf(hal->pins[p].pin->lu), i)); break; + case MBT_U: CHK_RV(map_u(cc, hal_get_uint(hal->pins[p].pin.u), i)); break; + case MBT_S: CHK_RV(map_s(cc, map_us(hal_get_uint(hal->pins[p].pin.u)), i)); break; + case MBT_F: CHK_RV(map_f(cc, map_uf(hal_get_uint(hal->pins[p].pin.u)), i)); break; } break; case HAL_S32: if(!haspinscale(&cc->typeptr[i])) { switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: CHK_RV(map_u(cc, map_su(hal->pins[p].pin->s), i)); break; - case MBT_S: CHK_RV(map_s(cc, hal->pins[p].pin->s, i)); break; - case MBT_F: CHK_RV(map_f(cc, map_sf(hal->pins[p].pin->s), i)); break; + case MBT_U: CHK_RV(map_u(cc, map_su(hal_get_si32(hal->pins[p].pin.s)), i)); break; + case MBT_S: CHK_RV(map_s(cc, hal_get_si32(hal->pins[p].pin.s), i)); break; + case MBT_F: CHK_RV(map_f(cc, map_sf(hal_get_si32(hal->pins[p].pin.s)), i)); break; } } else { - val64.f = (real_t)((rtapi_s64)hal->pins[p].pin->s - hal->pins[p].offset->s) * *(hal->pins[p].scale); + val64.f = (rtapi_real)((rtapi_s64)hal_get_si32(hal->pins[p].pin.s) - hal_get_si32(hal->pins[p].offset.s)) * hal_get_real(hal->pins[p].scale); switch(mtypetype(cc->typeptr[i].mtype)) { case MBT_U: CHK_RV(map_u(cc, map_fu(val64.f), i)); break; case MBT_S: CHK_RV(map_s(cc, map_fs(val64.f), i)); break; @@ -1585,15 +1585,15 @@ static int build_data_frame(hm2_modbus_inst_t *inst) } } break; - case HAL_S64: + case HAL_SINT: if(!haspinscale(&cc->typeptr[i])) { switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: CHK_RV(map_u(cc, map_su(hal->pins[p].pin->ls), i)); break; - case MBT_S: CHK_RV(map_s(cc, hal->pins[p].pin->ls, i)); break; - case MBT_F: CHK_RV(map_f(cc, map_sf(hal->pins[p].pin->ls), i)); break; + case MBT_U: CHK_RV(map_u(cc, map_su(hal_get_sint(hal->pins[p].pin.s)), i)); break; + case MBT_S: CHK_RV(map_s(cc, hal_get_sint(hal->pins[p].pin.s), i)); break; + case MBT_F: CHK_RV(map_f(cc, map_sf(hal_get_sint(hal->pins[p].pin.s)), i)); break; } } else { - val64.f = (real_t)(hal->pins[p].pin->ls - hal->pins[p].offset->ls) * *(hal->pins[p].scale); + val64.f = (rtapi_real)(hal_get_sint(hal->pins[p].pin.s) - hal_get_sint(hal->pins[p].offset.s)) * hal_get_real(hal->pins[p].scale); switch(mtypetype(cc->typeptr[i].mtype)) { case MBT_U: CHK_RV(map_u(cc, map_fu(val64.f), i)); break; case MBT_S: CHK_RV(map_s(cc, map_fs(val64.f), i)); break; @@ -1601,15 +1601,15 @@ static int build_data_frame(hm2_modbus_inst_t *inst) } } break; - case HAL_FLOAT: + case HAL_REAL: if(!haspinscale(&cc->typeptr[i])) { switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: CHK_RV(map_u(cc, map_fu(hal->pins[p].pin->f), i)); break; - case MBT_S: CHK_RV(map_s(cc, map_fs(hal->pins[p].pin->f), i)); break; - case MBT_F: CHK_RV(map_f(cc, hal->pins[p].pin->f, i)); break; + case MBT_U: CHK_RV(map_u(cc, map_fu(hal_get_real(hal->pins[p].pin.r)), i)); break; + case MBT_S: CHK_RV(map_s(cc, map_fs(hal_get_real(hal->pins[p].pin.r)), i)); break; + case MBT_F: CHK_RV(map_f(cc, hal_get_real(hal->pins[p].pin.r), i)); break; } } else { - val64.f = (hal->pins[p].pin->f - hal->pins[p].offset->f) * *(hal->pins[p].scale); + val64.f = (hal_get_real(hal->pins[p].pin.r) - hal_get_real(hal->pins[p].offset.r)) * hal_get_real(hal->pins[p].scale); switch(mtypetype(cc->typeptr[i].mtype)) { case MBT_U: CHK_RV(map_u(cc, map_fu(val64.f), i)); break; case MBT_S: CHK_RV(map_s(cc, map_fs(val64.f), i)); break; @@ -1861,7 +1861,7 @@ static int parse_data_frame(hm2_modbus_inst_t *inst) w = 3; // First data return byte {mbid, func, bytecount, ...} b = 0; for(unsigned i = 0; i < cc->cmd.cpincnt; i++) { - hal->pins[p++].pin->b = !!(bytes[w] & (1u << b)); + hal_set_bool(hal->pins[p++].pin.b, !!(bytes[w] & (1u << b))); if(++b >= 8) { b = 0; w++; } } break; @@ -1970,62 +1970,62 @@ static int parse_data_frame(hm2_modbus_inst_t *inst) } switch(cc->typeptr[i].htype) { - case HAL_BIT: - hal->pins[p].pin->b = 0 != val64.u; // Zero maps to false, anything else to true + case HAL_BOOL: + hal_set_bool(hal->pins[p].pin.b, 0 != val64.u); // Zero maps to false, anything else to true break; case HAL_U32: switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: hal->pins[p].pin->u = unmap32_uu(cc, val64.u, i); break; - case MBT_S: hal->pins[p].pin->u = unmap32_us(cc, val64.s, i); break; - case MBT_F: hal->pins[p].pin->u = unmap32_uf(cc, val64.f, i); break; + case MBT_U: hal_set_ui32(hal->pins[p].pin.u, unmap32_uu(cc, val64.u, i)); break; + case MBT_S: hal_set_ui32(hal->pins[p].pin.u, unmap32_us(cc, val64.s, i)); break; + case MBT_F: hal_set_ui32(hal->pins[p].pin.u, unmap32_uf(cc, val64.f, i)); break; } break; case HAL_S32: switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: hal->pins[p].pin->s = unmap32_su(cc, val64.u, i); break; - case MBT_S: hal->pins[p].pin->s = unmap32_ss(cc, val64.s, i); break; - case MBT_F: hal->pins[p].pin->s = unmap32_sf(cc, val64.f, i); break; + case MBT_U: hal_set_si32(hal->pins[p].pin.s, unmap32_su(cc, val64.u, i)); break; + case MBT_S: hal_set_si32(hal->pins[p].pin.s, unmap32_ss(cc, val64.s, i)); break; + case MBT_F: hal_set_si32(hal->pins[p].pin.s, unmap32_sf(cc, val64.f, i)); break; } if(haspinscale(&cc->typeptr[i])) { switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: *(hal->pins[p].scaled) = (real_t)(rtapi_s64)(val64.u - hal->pins[p].offset->lu) * *(hal->pins[p].scale); break; - case MBT_S: *(hal->pins[p].scaled) = (real_t)(val64.s - hal->pins[p].offset->ls) * *(hal->pins[p].scale); break; - case MBT_F: *(hal->pins[p].scaled) = (val64.f - hal->pins[p].offset->f) * *(hal->pins[p].scale); break; + case MBT_U: hal_set_real(hal->pins[p].scaled, (rtapi_real)(rtapi_s64)(val64.u - hal_get_uint(hal->pins[p].offset.u)) * hal_get_real(hal->pins[p].scale)); break; + case MBT_S: hal_set_real(hal->pins[p].scaled, (rtapi_real)(val64.s - hal_get_sint(hal->pins[p].offset.s)) * hal_get_real(hal->pins[p].scale)); break; + case MBT_F: hal_set_real(hal->pins[p].scaled, (val64.f - hal_get_real(hal->pins[p].offset.r)) * hal_get_real(hal->pins[p].scale)); break; } } break; - case HAL_U64: + case HAL_UINT: switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: hal->pins[p].pin->lu = val64.u; break; - case MBT_S: hal->pins[p].pin->lu = unmap64_us(cc, val64.s, i); break; - case MBT_F: hal->pins[p].pin->lu = unmap64_uf(cc, val64.f, i); break; + case MBT_U: hal_set_uint(hal->pins[p].pin.u, val64.u); break; + case MBT_S: hal_set_uint(hal->pins[p].pin.u, unmap64_us(cc, val64.s, i)); break; + case MBT_F: hal_set_uint(hal->pins[p].pin.u, unmap64_uf(cc, val64.f, i)); break; } break; - case HAL_S64: + case HAL_SINT: switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: hal->pins[p].pin->ls = unmap64_su(cc, val64.u, i); break; - case MBT_S: hal->pins[p].pin->ls = val64.s; break; - case MBT_F: hal->pins[p].pin->ls = unmap64_sf(cc, val64.f, i); break; + case MBT_U: hal_set_sint(hal->pins[p].pin.s, unmap64_su(cc, val64.u, i)); break; + case MBT_S: hal_set_sint(hal->pins[p].pin.s, val64.s); break; + case MBT_F: hal_set_sint(hal->pins[p].pin.s, unmap64_sf(cc, val64.f, i)); break; } if(haspinscale(&cc->typeptr[i])) { switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: *(hal->pins[p].scaled) = (real_t)(rtapi_s64)(val64.u - hal->pins[p].offset->lu) * *(hal->pins[p].scale); break; - case MBT_S: *(hal->pins[p].scaled) = (real_t)(val64.s - hal->pins[p].offset->ls) * *(hal->pins[p].scale); break; - case MBT_F: *(hal->pins[p].scaled) = (val64.f - hal->pins[p].offset->f) * *(hal->pins[p].scale); break; + case MBT_U: hal_set_real(hal->pins[p].scaled, (rtapi_real)(rtapi_s64)(val64.u - hal_get_uint(hal->pins[p].offset.u)) * hal_get_real(hal->pins[p].scale)); break; + case MBT_S: hal_set_real(hal->pins[p].scaled, (rtapi_real)(val64.s - hal_get_sint(hal->pins[p].offset.s)) * hal_get_real(hal->pins[p].scale)); break; + case MBT_F: hal_set_real(hal->pins[p].scaled, (val64.f - hal_get_real(hal->pins[p].offset.r)) * hal_get_real(hal->pins[p].scale)); break; } } break; - case HAL_FLOAT: + case HAL_REAL: switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: hal->pins[p].pin->f = val64.u; break; - case MBT_S: hal->pins[p].pin->f = val64.s; break; - case MBT_F: hal->pins[p].pin->f = val64.f; break; + case MBT_U: hal_set_real(hal->pins[p].pin.r, val64.u); break; + case MBT_S: hal_set_real(hal->pins[p].pin.r, val64.s); break; + case MBT_F: hal_set_real(hal->pins[p].pin.r, val64.f); break; } if(haspinscale(&cc->typeptr[i])) { switch(mtypetype(cc->typeptr[i].mtype)) { - case MBT_U: *(hal->pins[p].scaled) = (real_t)(rtapi_s64)(val64.u - hal->pins[p].offset->lu) * *(hal->pins[p].scale); break; - case MBT_S: *(hal->pins[p].scaled) = (real_t)(val64.s - hal->pins[p].offset->ls) * *(hal->pins[p].scale); break; - case MBT_F: *(hal->pins[p].scaled) = (val64.f - hal->pins[p].offset->f) * *(hal->pins[p].scale); break; + case MBT_U: hal_set_real(hal->pins[p].scaled, (rtapi_real)(rtapi_s64)(val64.u - hal_get_uint(hal->pins[p].offset.u)) * hal_get_real(hal->pins[p].scale)); break; + case MBT_S: hal_set_real(hal->pins[p].scaled, (rtapi_real)(val64.s - hal_get_sint(hal->pins[p].offset.s)) * hal_get_real(hal->pins[p].scale)); break; + case MBT_F: hal_set_real(hal->pins[p].scaled, (val64.f - hal_get_real(hal->pins[p].offset.r)) * hal_get_real(hal->pins[p].scale)); break; } } break; @@ -2259,12 +2259,12 @@ static ssize_t read_mbccb(const hm2_modbus_inst_t *inst, const char *fname, hm2_ static int check_htype(unsigned type) { switch(type) { - case HAL_BIT: // not valid in register read/write + case HAL_BOOL: // not valid in register read/write case HAL_U32: case HAL_S32: - case HAL_U64: - case HAL_S64: - case HAL_FLOAT: + case HAL_UINT: + case HAL_SINT: + case HAL_REAL: return 0; } return -1; @@ -2546,7 +2546,7 @@ static int load_mbccb(hm2_modbus_inst_t *inst, const char *fname) inst->name, c, cmdsptr[c].func, cmdsptr[c].cpincnt); goto errout; } - // These are implicit HAL_BIT + // These are implicit HAL_BOOL break; case MBCMD_R_REGISTERS: case MBCMD_R_INPUTREGS: @@ -2820,21 +2820,21 @@ int rtapi_app_main(void) goto errout; \ } \ } while(0) - CHECK(hal_param_u32_newf(HAL_RO, &(inst->hal->baudrate), comp_id, "%s.baudrate", inst->name)); - CHECK(hal_param_u32_newf(HAL_RO, &(inst->hal->parity), comp_id, "%s.parity", inst->name)); - CHECK(hal_param_u32_newf(HAL_RO, &(inst->hal->stopbits), comp_id, "%s.stopbits", inst->name)); - CHECK(hal_param_u32_newf(HAL_RO, &(inst->hal->icdelay), comp_id, "%s.icdelay", inst->name)); - CHECK(hal_param_u32_newf(HAL_RO, &(inst->hal->txdelay), comp_id, "%s.txdelay", inst->name)); - CHECK(hal_param_u32_newf(HAL_RO, &(inst->hal->rxdelay), comp_id, "%s.rxdelay", inst->name)); - CHECK(hal_param_u32_newf(HAL_RO, &(inst->hal->drvdelay), comp_id, "%s.drivedelay", inst->name)); - - CHECK(hal_pin_bit_newf(HAL_IN, &(inst->hal->suspend), comp_id, "%s.suspend", inst->name)); - CHECK(hal_pin_bit_newf(HAL_IN, &(inst->hal->reset), comp_id, "%s.reset", inst->name)); - CHECK(hal_pin_bit_newf(HAL_OUT, &(inst->hal->fault), comp_id, "%s.fault", inst->name)); - CHECK(hal_pin_u32_newf(HAL_OUT, &(inst->hal->faultcmd), comp_id, "%s.fault-command", inst->name)); - CHECK(hal_pin_u32_newf(HAL_OUT, &(inst->hal->lasterror), comp_id, "%s.last-error-code", inst->name)); - - inst->hal->baudrate = inst->cfg_rx.baudrate = inst->cfg_tx.baudrate = inst->mbccb->baudrate; + CHECK(hal_param_new_ui32(comp_id, HAL_RO, &(inst->hal->baudrate), 0, "%s.baudrate", inst->name)); + CHECK(hal_param_new_ui32(comp_id, HAL_RO, &(inst->hal->parity), 0, "%s.parity", inst->name)); + CHECK(hal_param_new_ui32(comp_id, HAL_RO, &(inst->hal->stopbits), 0, "%s.stopbits", inst->name)); + CHECK(hal_param_new_ui32(comp_id, HAL_RO, &(inst->hal->icdelay), 0, "%s.icdelay", inst->name)); + CHECK(hal_param_new_ui32(comp_id, HAL_RO, &(inst->hal->txdelay), 0, "%s.txdelay", inst->name)); + CHECK(hal_param_new_ui32(comp_id, HAL_RO, &(inst->hal->rxdelay), 0, "%s.rxdelay", inst->name)); + CHECK(hal_param_new_ui32(comp_id, HAL_RO, &(inst->hal->drvdelay), 0, "%s.drivedelay", inst->name)); + + CHECK(hal_pin_new_bool(comp_id, HAL_IN, &(inst->hal->suspend), 0, "%s.suspend", inst->name)); + CHECK(hal_pin_new_bool(comp_id, HAL_IN, &(inst->hal->reset), 0, "%s.reset", inst->name)); + CHECK(hal_pin_new_bool(comp_id, HAL_OUT, &(inst->hal->fault), 0, "%s.fault", inst->name)); + CHECK(hal_pin_new_ui32(comp_id, HAL_OUT, &(inst->hal->faultcmd), 0, "%s.fault-command", inst->name)); + CHECK(hal_pin_new_ui32(comp_id, HAL_OUT, &(inst->hal->lasterror), 0, "%s.last-error-code", inst->name)); + + hal_set_ui32(inst->hal->baudrate, inst->cfg_rx.baudrate = inst->cfg_tx.baudrate = inst->mbccb->baudrate); unsigned parity = 0; if(inst->mbccb->format & MBCCB_FORMAT_PARITYEN) { inst->cfg_rx.flags |= HM2_PKTUART_CONFIG_PARITYEN; @@ -2852,22 +2852,22 @@ int rtapi_app_main(void) inst->cfg_tx.flags |= HM2_PKTUART_CONFIG_STOPBITS2; stopbits = 2; } - inst->hal->parity = parity; - inst->hal->stopbits = stopbits; + hal_set_ui32(inst->hal->parity, parity); + hal_set_ui32(inst->hal->stopbits, stopbits); if(!inst->mbccb->rxdelay) // Auto - inst->hal->rxdelay = inst->cfg_rx.ifdelay = calc_ifdelay(inst, inst->mbccb->baudrate, parity, stopbits) - 1; + inst->cfg_rx.ifdelay = hal_set_ui32(inst->hal->rxdelay, calc_ifdelay(inst, inst->mbccb->baudrate, parity, stopbits) - 1); else // Manual - inst->hal->rxdelay = inst->cfg_rx.ifdelay = inst->mbccb->rxdelay; + inst->cfg_rx.ifdelay = hal_set_ui32(inst->hal->rxdelay, inst->mbccb->rxdelay); if(!inst->mbccb->txdelay) // Auto - inst->hal->txdelay = inst->cfg_tx.ifdelay = calc_ifdelay(inst, inst->mbccb->baudrate, parity, stopbits) + 1; + inst->cfg_tx.ifdelay = hal_set_ui32(inst->hal->txdelay, calc_ifdelay(inst, inst->mbccb->baudrate, parity, stopbits) + 1); else // Manual - inst->hal->txdelay = inst->cfg_tx.ifdelay = inst->mbccb->txdelay; + inst->cfg_tx.ifdelay = hal_set_ui32(inst->hal->txdelay, inst->mbccb->txdelay); if(!inst->mbccb->drvdelay) // Auto - inst->hal->drvdelay = inst->cfg_tx.drivedelay = 1; + inst->cfg_tx.drivedelay = hal_set_ui32(inst->hal->drvdelay, 1); else // Manual - inst->hal->drvdelay = inst->cfg_tx.drivedelay = inst->mbccb->drvdelay; + inst->cfg_tx.drivedelay = hal_set_ui32(inst->hal->drvdelay, inst->mbccb->drvdelay); inst->cfg_rx.filterrate = 0; // Zero means 2 times baudrate inst->cfg_rx.flags |= HM2_PKTUART_CONFIG_RXEN; @@ -2938,10 +2938,7 @@ int rtapi_app_main(void) stopbits > 1 ? '2' : '1', inst->cfg_rx.baudrate); - *(inst->hal->fault) = 0; - *(inst->hal->faultcmd) = 0; - *(inst->hal->lasterror) = 0; - *(inst->hal->suspend) = 0 != (inst->mbccb->format & MBCCB_FORMAT_SUSPEND); + hal_set_bool(inst->hal->suspend, 0 != (inst->mbccb->format & MBCCB_FORMAT_SUSPEND)); // Start with internal suspended bit set. The HAL pin will dictate to // move to the active state in the process() function. This enables to // use the WFLUSH setting each time we come out of suspend and, @@ -2954,24 +2951,24 @@ int rtapi_app_main(void) #define CPTR(x) ((const char *)((x) + 1)) for(unsigned c = 0; c < inst->ncmds; c++) { // First create command status pins - CHECK(hal_pin_bit_newf(HAL_IN, &(inst->hal->cmds[c].disable), - comp_id, "%s.command.%02d.disable", inst->name, c)); - CHECK(hal_pin_bit_newf(HAL_OUT, &(inst->hal->cmds[c].disabled), - comp_id, "%s.command.%02d.disabled", inst->name, c)); - CHECK(hal_pin_u32_newf(HAL_OUT, &(inst->hal->cmds[c].error), - comp_id, "%s.command.%02d.errors", inst->name, c)); - CHECK(hal_pin_u32_newf(HAL_OUT, &(inst->hal->cmds[c].errorcode), - comp_id, "%s.command.%02d.error-code", inst->name, c)); - CHECK(hal_pin_bit_newf(HAL_IN, &(inst->hal->cmds[c].reset), - comp_id, "%s.command.%02d.reset", inst->name, c)); + CHECK(hal_pin_new_bool(comp_id, HAL_IN, &(inst->hal->cmds[c].disable), + 0, "%s.command.%02d.disable", inst->name, c)); + CHECK(hal_pin_new_bool(comp_id, HAL_OUT, &(inst->hal->cmds[c].disabled), + 0, "%s.command.%02d.disabled", inst->name, c)); + CHECK(hal_pin_new_ui32(comp_id, HAL_OUT, &(inst->hal->cmds[c].error), + 0, "%s.command.%02d.errors", inst->name, c)); + CHECK(hal_pin_new_ui32(comp_id, HAL_OUT, &(inst->hal->cmds[c].errorcode), + 0, "%s.command.%02d.error-code", inst->name, c)); + CHECK(hal_pin_new_bool(comp_id, HAL_IN, &(inst->hal->cmds[c].reset), + 0, "%s.command.%02d.reset", inst->name, c)); hm2_modbus_cmd_t *cc = &inst->_cmds[c]; // If the command is disabled, set it so if(hasdisabled(cc)) { cc->disabled = 1; - *(inst->hal->cmds[c].disabled) = 1; - *(inst->hal->cmds[c].errorcode) = EAGAIN; + hal_set_bool(inst->hal->cmds[c].disabled, 1); + hal_set_ui32(inst->hal->cmds[c].errorcode, EAGAIN); } // Now create the pins associated with the command @@ -2986,8 +2983,8 @@ int rtapi_app_main(void) /* Fallthrough */ case MBCMD_W_COIL: case MBCMD_W_COILS: - CHECK(hal_pin_bit_newf(dir, (hal_bit_t**)&(inst->hal->pins[p++]), - comp_id, "%s.%s", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_bool(comp_id, dir, &(inst->hal->pins[p++].pin.b), + 0, "%s.%s", inst->name, CPTR(dptr))); break; case MBCMD_R_INPUTREGS: @@ -2998,112 +2995,108 @@ int rtapi_app_main(void) case MBCMD_W_REGISTERS: switch(cc->typeptr[j].htype) { default: - case HAL_BIT: - CHECK(hal_pin_bit_newf(dir, (hal_bit_t**)&(inst->hal->pins[p++]), - comp_id, "%s.%s", inst->name, CPTR(dptr))); + case HAL_BOOL: + CHECK(hal_pin_new_bool(comp_id, dir, &(inst->hal->pins[p++].pin.b), + 0, "%s.%s", inst->name, CPTR(dptr))); break; case HAL_U32: - CHECK(hal_pin_u32_newf(dir, (hal_u32_t**)&(inst->hal->pins[p++]), - comp_id, "%s.%s", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_ui32(comp_id, dir, &(inst->hal->pins[p++].pin.u), + 0, "%s.%s", inst->name, CPTR(dptr))); break; - case HAL_U64: - CHECK(hal_pin_u64_newf(dir, (hal_u64_t**)&(inst->hal->pins[p++]), - comp_id, "%s.%s", inst->name, CPTR(dptr))); + case HAL_UINT: + CHECK(hal_pin_new_uint(comp_id, dir, &(inst->hal->pins[p++].pin.u), + 0, "%s.%s", inst->name, CPTR(dptr))); break; case HAL_S32: - CHECK(hal_pin_s32_newf(dir, (hal_s32_t**)&(inst->hal->pins[p]), - comp_id, "%s.%s", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_si32(comp_id, dir, &(inst->hal->pins[p].pin.s), + 0, "%s.%s", inst->name, CPTR(dptr))); if(haspinscale(&cc->typeptr[j])) { - CHECK(hal_pin_float_newf(HAL_IN, &(inst->hal->pins[p].scale), - comp_id, "%s.%s.scale", inst->name, CPTR(dptr))); - *(inst->hal->pins[p].scale) = 1.0; + CHECK(hal_pin_new_real(comp_id, HAL_IN, &(inst->hal->pins[p].scale), + 1.0, "%s.%s.scale", inst->name, CPTR(dptr))); if(HAL_OUT == dir) { - CHECK(hal_pin_float_newf(HAL_OUT, &(inst->hal->pins[p].scaled), - comp_id, "%s.%s.scaled", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_real(comp_id, HAL_OUT, &(inst->hal->pins[p].scaled), + 0.0, "%s.%s.scaled", inst->name, CPTR(dptr))); switch(mtypetype(cc->typeptr[j].mtype)) { case MBT_U: - CHECK(hal_pin_u64_newf(HAL_IN, (hal_u64_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_uint(comp_id, HAL_IN, &(inst->hal->pins[p].offset.u), + 0, "%s.%s.offset", inst->name, CPTR(dptr))); break; case MBT_S: - CHECK(hal_pin_s64_newf(HAL_IN, (hal_s64_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_sint(comp_id, HAL_IN, &(inst->hal->pins[p].offset.s), + 0, "%s.%s.offset", inst->name, CPTR(dptr))); break; case MBT_F: - CHECK(hal_pin_float_newf(HAL_IN, (hal_float_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_real(comp_id, HAL_IN, &(inst->hal->pins[p].offset.r), + 0.0, "%s.%s.offset", inst->name, CPTR(dptr))); break; } } else { - CHECK(hal_pin_s32_newf(HAL_IN, (hal_s32_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_si32(comp_id, HAL_IN, &(inst->hal->pins[p].offset.s), + 0, "%s.%s.offset", inst->name, CPTR(dptr))); } } p++; break; - case HAL_S64: - CHECK(hal_pin_s64_newf(dir, (hal_s64_t**)&(inst->hal->pins[p]), - comp_id, "%s.%s", inst->name, CPTR(dptr))); + case HAL_SINT: + CHECK(hal_pin_new_sint(comp_id, dir, &(inst->hal->pins[p].pin.s), + 0, "%s.%s", inst->name, CPTR(dptr))); if(haspinscale(&cc->typeptr[j])) { - CHECK(hal_pin_float_newf(HAL_IN, &(inst->hal->pins[p].scale), - comp_id, "%s.%s.scale", inst->name, CPTR(dptr))); - *(inst->hal->pins[p].scale) = 1.0; + CHECK(hal_pin_new_real(comp_id, HAL_IN, &(inst->hal->pins[p].scale), + 1.0, "%s.%s.scale", inst->name, CPTR(dptr))); if(HAL_OUT == dir) { - CHECK(hal_pin_float_newf(HAL_OUT, &(inst->hal->pins[p].scaled), - comp_id, "%s.%s.scaled", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_real(comp_id, HAL_OUT, &(inst->hal->pins[p].scaled), + 0.0, "%s.%s.scaled", inst->name, CPTR(dptr))); switch(mtypetype(cc->typeptr[j].mtype)) { case MBT_U: - CHECK(hal_pin_u64_newf(HAL_IN, (hal_u64_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_uint(comp_id, HAL_IN, &(inst->hal->pins[p].offset.u), + 0, "%s.%s.offset", inst->name, CPTR(dptr))); break; case MBT_S: - CHECK(hal_pin_s64_newf(HAL_IN, (hal_s64_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_sint(comp_id, HAL_IN, &(inst->hal->pins[p].offset.s), + 0, "%s.%s.offset", inst->name, CPTR(dptr))); break; case MBT_F: - CHECK(hal_pin_float_newf(HAL_IN, (hal_float_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_real(comp_id, HAL_IN, &(inst->hal->pins[p].offset.r), + 0.0, "%s.%s.offset", inst->name, CPTR(dptr))); break; } } else { - CHECK(hal_pin_s64_newf(HAL_IN, (hal_s64_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_sint(comp_id, HAL_IN, &(inst->hal->pins[p].offset.s), + 0, "%s.%s.offset", inst->name, CPTR(dptr))); } } p++; break; - case HAL_FLOAT: - CHECK(hal_pin_float_newf(dir, (hal_float_t**)&(inst->hal->pins[p]), - comp_id, "%s.%s", inst->name, CPTR(dptr))); + case HAL_REAL: + CHECK(hal_pin_new_real(comp_id, dir, &(inst->hal->pins[p].pin.r), + 0.0, "%s.%s", inst->name, CPTR(dptr))); if(haspinscale(&cc->typeptr[j])) { - CHECK(hal_pin_float_newf(HAL_IN, &(inst->hal->pins[p].scale), - comp_id, "%s.%s.scale", inst->name, CPTR(dptr))); - *(inst->hal->pins[p].scale) = 1.0; + CHECK(hal_pin_new_real(comp_id, HAL_IN, &(inst->hal->pins[p].scale), + 1.0, "%s.%s.scale", inst->name, CPTR(dptr))); if(HAL_OUT == dir) { - CHECK(hal_pin_float_newf(HAL_OUT, &(inst->hal->pins[p].scaled), - comp_id, "%s.%s.scaled", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_real(comp_id, HAL_OUT, &(inst->hal->pins[p].scaled), + 0.0, "%s.%s.scaled", inst->name, CPTR(dptr))); switch(mtypetype(cc->typeptr[j].mtype)) { case MBT_U: - CHECK(hal_pin_u64_newf(HAL_IN, (hal_u64_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_uint(comp_id, HAL_IN, &(inst->hal->pins[p].offset.u), + 0, "%s.%s.offset", inst->name, CPTR(dptr))); break; case MBT_S: - CHECK(hal_pin_s64_newf(HAL_IN, (hal_s64_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_sint(comp_id, HAL_IN, &(inst->hal->pins[p].offset.s), + 0, "%s.%s.offset", inst->name, CPTR(dptr))); break; case MBT_F: - CHECK(hal_pin_float_newf(HAL_IN, (hal_float_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_real(comp_id, HAL_IN, &(inst->hal->pins[p].offset.r), + 0.0, "%s.%s.offset", inst->name, CPTR(dptr))); break; } } else { - CHECK(hal_pin_float_newf(HAL_IN, (hal_float_t**)&(inst->hal->pins[p].offset), - comp_id, "%s.%s.offset", inst->name, CPTR(dptr))); + CHECK(hal_pin_new_real(comp_id, HAL_IN, &(inst->hal->pins[p].offset.r), + 0.0, "%s.%s.offset", inst->name, CPTR(dptr))); } - inst->hal->pins[p].offset->f = 0.0; } p++; break; diff --git a/src/hal/drivers/mesa-hostmot2/hm2_spi.c b/src/hal/drivers/mesa-hostmot2/hm2_spi.c index 3b7af1c87d1..0e2114a87d3 100644 --- a/src/hal/drivers/mesa-hostmot2/hm2_spi.c +++ b/src/hal/drivers/mesa-hostmot2/hm2_spi.c @@ -152,12 +152,12 @@ static int queue_write(hm2_lowlevel_io_t *llio, rtapi_u32 addr, const void *buff if(r < 0) return r; } - PUT(write_command(addr, wsize), 0); + PUT(write_command(addr, wsize), NULL); const uint32_t *wbuffer = buffer; int i=0; for(i=0; illio->period = period; // if there are comm problems, wait for the user to fix it - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; hm2_tram_read(hm2); - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; hm2_raw_queue_read(hm2); hm2_tp_pwmgen_queue_read(hm2); - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; hm2_queue_read(hm2); hm2->llio->read_requested = true; hm2->llio->read_time = rtapi_get_time(); @@ -98,10 +98,10 @@ static void hm2_read(void *void_hm2, long period) { hm2->llio->read_requested = false; // if there are comm problems, wait for the user to fix it - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; // if there's a temporary read failure, don't sweat it if(hm2_finish_read(hm2) == -EAGAIN) return; - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; hm2_watchdog_process_tram_read(hm2); hm2_ioport_gpio_process_tram_read(hm2); @@ -127,7 +127,7 @@ static void hm2_write(void *void_hm2, long period) { hostmot2_t *hm2 = void_hm2; // if there are comm problems, wait for the user to fix it - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; if (!hm2->ddr_initialized) { hm2_ioport_initialize_ddr(hm2); @@ -183,7 +183,7 @@ static void hm2_read_gpio(void *void_hm2, long period) { hostmot2_t *hm2 = void_hm2; // if there are comm problems, wait for the user to fix it - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; hm2_ioport_gpio_read(hm2); } @@ -193,7 +193,7 @@ static void hm2_write_gpio(void *void_hm2, long period) { hostmot2_t *hm2 = void_hm2; // if there are comm problems, wait for the user to fix it - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; hm2_ioport_gpio_write(hm2); hm2_watchdog_write(hm2, period); @@ -957,7 +957,7 @@ static int hm2_parse_module_descriptors(hostmot2_t *hm2) { md_accepted = hm2_ioport_parse_md(hm2, md_index); - if ((*hm2->llio->io_error) != 0) { + if (hal_get_bool(*hm2->llio->io_error)) { HM2_ERR("IO error while parsing Module Descriptor %d\n", md_index); return -EIO; } @@ -1097,7 +1097,7 @@ static int hm2_parse_module_descriptors(hostmot2_t *hm2) { } - if ((*hm2->llio->io_error) != 0) { + if (hal_get_bool(*hm2->llio->io_error)) { HM2_ERR("IO error while parsing Module Descriptor %d\n", md_index); return -EIO; } @@ -1453,17 +1453,14 @@ int hm2_register(hm2_lowlevel_io_t *llio, char *config_string) { int r; char name[HAL_NAME_LEN + 1]; - llio->io_error = (hal_bit_t *)hal_malloc(sizeof(hal_bit_t)); + llio->io_error = hal_malloc(sizeof(*llio->io_error)); if (llio->io_error == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; goto fail0; } - (*llio->io_error) = 0; - - rtapi_snprintf(name, sizeof(name), "%s.io_error", llio->name); - r = hal_param_bit_new(name, HAL_RW, llio->io_error, llio->comp_id); + r = hal_param_new_bool(llio->comp_id, HAL_RW, llio->io_error, 0, "%s.io_error", llio->name); if (r < 0) { HM2_ERR("error adding param '%s', aborting\n", name); r = -EINVAL; @@ -1676,7 +1673,7 @@ int hm2_register(hm2_lowlevel_io_t *llio, char *config_string) { // final check for comm errors // - if ((*hm2->llio->io_error) != 0) { + if (hal_get_bool(*hm2->llio->io_error)) { HM2_ERR("comm errors while initializing firmware!\n"); goto fail1; } @@ -1776,7 +1773,7 @@ void hm2_unregister(hm2_lowlevel_io_t *llio) { // if there's a watchdog, set it to safe the board right away if (hm2->watchdog.num_instances > 0) { hm2->watchdog.instance[0].enable = 1; - hm2->watchdog.instance[0].hal.param.timeout_ns = 1; + hal_set_ui32(hm2->watchdog.instance[0].hal.param.timeout_ns, 1); hm2_watchdog_force_write(hm2); } diff --git a/src/hal/drivers/mesa-hostmot2/hostmot2.h b/src/hal/drivers/mesa-hostmot2/hostmot2.h index 569ee045c05..89850f312b9 100644 --- a/src/hal/drivers/mesa-hostmot2/hostmot2.h +++ b/src/hal/drivers/mesa-hostmot2/hostmot2.h @@ -194,15 +194,15 @@ typedef struct { struct { struct { - hal_bit_t *in; - hal_bit_t *in_not; - hal_bit_t *out; + hal_bool_t in; + hal_bool_t in_not; + hal_bool_t out; } pin; struct { - hal_bit_t is_output; - hal_bit_t is_opendrain; - hal_bit_t invert_output; + hal_bool_t is_output; + hal_bool_t is_opendrain; + hal_bool_t invert_output; } param; } hal; @@ -281,35 +281,35 @@ typedef struct { struct { struct { - hal_s32_t *rawcounts; // raw encoder counts (truncated view of 64-bit internal) - hal_s32_t *rawlatch; // raw encoder of latch (truncated view) - hal_s32_t *count; // (rawcounts - zero_offset), truncated view - hal_s32_t *count_latch; // (rawlatch - zero_offset), truncated view - hal_float_t *position; - hal_float_t *position_latch; - hal_float_t *position_interpolated; - hal_float_t *velocity; - hal_float_t *velocity_rpm; - hal_bit_t *reset; - hal_bit_t *index_enable; - hal_bit_t *latch_enable; - hal_bit_t *latch_polarity; - hal_bit_t *no_clear_on_index; - hal_bit_t *quadrature_error; - hal_bit_t *quadrature_error_enable; - hal_bit_t *input_a; - hal_bit_t *input_b; - hal_bit_t *input_idx; + hal_sint_t rawcounts; // raw encoder counts (truncated view of 64-bit internal) + hal_sint_t rawlatch; // raw encoder of latch (truncated view) + hal_sint_t count; // (rawcounts - zero_offset), truncated view + hal_sint_t count_latch; // (rawlatch - zero_offset), truncated view + hal_real_t position; + hal_real_t position_latch; + hal_real_t position_interpolated; + hal_real_t velocity; + hal_real_t velocity_rpm; + hal_bool_t reset; + hal_bool_t index_enable; + hal_bool_t latch_enable; + hal_bool_t latch_polarity; + hal_bool_t no_clear_on_index; + hal_bool_t quadrature_error; + hal_bool_t quadrature_error_enable; + hal_bool_t input_a; + hal_bool_t input_b; + hal_bool_t input_idx; } pin; struct { - hal_float_t scale; - hal_bit_t index_invert; - hal_bit_t index_mask; - hal_bit_t index_mask_invert; - hal_bit_t counter_mode; - hal_bit_t filter; - hal_float_t vel_timeout; + hal_real_t scale; + hal_bool_t index_invert; + hal_bool_t index_mask; + hal_bool_t index_mask_invert; + hal_bool_t counter_mode; + hal_bool_t filter; + hal_real_t vel_timeout; } param; @@ -331,8 +331,8 @@ typedef struct { rtapi_u32 prev_control; - hal_bit_t prev_quadrature_error_enable; // shadow for detecting rising edge on the quadrature_error_enable - hal_bit_t reset_quadrature_error; // bit to indicate if we want to reset the quadrature error + rtapi_bool prev_quadrature_error_enable; // shadow for detecting rising edge on the quadrature_error_enable + rtapi_bool reset_quadrature_error; // bit to indicate if we want to reset the quadrature error // these two are the datapoint last time we moved (only valid if state == HM2_ENCODER_MOVING) @@ -350,10 +350,10 @@ typedef struct { // these hal pins affect all encoder instances typedef struct { struct { - hal_u32_t *sample_frequency; - hal_u32_t *skew; - hal_s32_t *dpll_timer_num; - hal_bit_t *hires_timestamp; + hal_uint_t sample_frequency; + hal_uint_t skew; + hal_sint_t dpll_timer_num; + hal_bool_t hires_timestamp; } pin; } hm2_encoder_module_global_t; @@ -374,7 +374,7 @@ typedef struct { int has_skew; rtapi_u32 written_skew; rtapi_u32 written_hires_timestamp; - uint32_t desired_dpll_timer_reg, written_dpll_timer_reg; + rtapi_u32 desired_dpll_timer_reg, written_dpll_timer_reg; // hw registers rtapi_u32 counter_addr; @@ -386,7 +386,7 @@ typedef struct { rtapi_u32 timestamp_div_addr; rtapi_u32 timestamp_div_reg; // one register for the whole Function - hal_float_t seconds_per_tsdiv_clock; + rtapi_real seconds_per_tsdiv_clock; rtapi_u32 timestamp_count_addr; rtapi_u32 *timestamp_count_reg; @@ -442,23 +442,23 @@ typedef struct { struct { struct { - hal_s32_t *rawcounts; - hal_s32_t *count; - hal_float_t *angle; - hal_float_t *position; - hal_float_t *velocity; - hal_float_t *velocity_rpm; - hal_bit_t *reset; - hal_bit_t *index_enable; - hal_bit_t *error; - hal_float_t *joint_pos_fb; + hal_sint_t rawcounts; + hal_sint_t count; + hal_real_t angle; + hal_real_t position; + hal_real_t velocity; + hal_real_t velocity_rpm; + hal_bool_t reset; + hal_bool_t index_enable; + hal_bool_t error; + hal_real_t joint_pos_fb; } pin; struct { - hal_float_t scale; - hal_float_t vel_scale; - hal_u32_t index_div; - hal_bit_t use_abs; + hal_real_t scale; + hal_real_t vel_scale; + hal_uint_t index_div; + hal_bool_t use_abs; } param; } hal; @@ -472,7 +472,7 @@ typedef struct { typedef struct { struct { - hal_float_t excitation_khz; + hal_real_t excitation_khz; } param; } hm2_resolver_global_t; @@ -501,8 +501,8 @@ typedef struct { rtapi_u32 velocity_addr; rtapi_s32 *velocity_reg; - hal_float_t written_khz; - hal_float_t kHz; + rtapi_real written_khz; + rtapi_real kHz; } hm2_resolver_t; @@ -521,15 +521,15 @@ typedef struct { struct { struct { - hal_float_t *value; - hal_bit_t *enable; + hal_real_t value; + hal_bool_t enable; } pin; struct { - hal_float_t scale; - hal_bit_t offset_mode; - hal_s32_t output_type; - hal_bit_t dither; + hal_real_t scale; + hal_bool_t offset_mode; + hal_sint_t output_type; + hal_bool_t dither; } param; } hal; @@ -556,8 +556,8 @@ typedef struct { // these hal params affect all pwmgen instances typedef struct { struct { - hal_u32_t pwm_frequency; - hal_u32_t pdm_frequency; + hal_uint_t pwm_frequency; + hal_uint_t pdm_frequency; } param; } hm2_pwmgen_module_global_t; @@ -609,31 +609,31 @@ typedef struct { struct { struct { - hal_float_t *width1; - hal_float_t *width2; - hal_float_t *filter1; - hal_float_t *filter2; - hal_float_t *rate; - hal_u32_t *trigselect1; - hal_u32_t *trigselect2; - hal_bit_t *trigrise1; - hal_bit_t *trigrise2; - hal_bit_t *trigfall1; - hal_bit_t *trigfall2; - hal_bit_t *retrig1; - hal_bit_t *retrig2; - hal_bit_t *enable1; - hal_bit_t *enable2; - hal_bit_t *reset1; - hal_bit_t *reset2; - hal_bit_t *swtrig1; - hal_bit_t *swtrig2; - hal_bit_t *exttrig1; - hal_bit_t *exttrig2; - hal_bit_t *out1; - hal_bit_t *out2; + hal_real_t width1; + hal_real_t width2; + hal_real_t filter1; + hal_real_t filter2; + hal_real_t rate; + hal_uint_t trigselect1; + hal_uint_t trigselect2; + hal_bool_t trigrise1; + hal_bool_t trigrise2; + hal_bool_t trigfall1; + hal_bool_t trigfall2; + hal_bool_t retrig1; + hal_bool_t retrig2; + hal_bool_t enable1; + hal_bool_t enable2; + hal_bool_t reset1; + hal_bool_t reset2; + hal_bool_t swtrig1; + hal_bool_t swtrig2; + hal_bool_t exttrig1; + hal_bool_t exttrig2; + hal_bool_t out1; + hal_bool_t out2; - hal_s32_t *dpll_timer_num; + hal_sint_t dpll_timer_num; } pin; } hal; @@ -682,18 +682,18 @@ typedef struct { struct { struct { - hal_float_t *period; - hal_float_t *width; - hal_float_t *dutycycle; - hal_float_t *frequency; - hal_float_t *filtertc; - hal_float_t *dutyscale; - hal_float_t *dutyoffset; - hal_float_t *minfreq; - hal_u32_t *averages; - hal_bit_t *polarity; - hal_bit_t *valid; - hal_bit_t *input; + hal_real_t period; + hal_real_t width; + hal_real_t dutycycle; + hal_real_t frequency; + hal_real_t filtertc; + hal_real_t dutyscale; + hal_real_t dutyoffset; + hal_real_t minfreq; + hal_uint_t averages; + hal_bool_t polarity; + hal_bool_t valid; + hal_bool_t input; } pin; } hal; @@ -735,9 +735,9 @@ typedef struct { struct { struct { - hal_float_t *width; - hal_float_t *scale; - hal_float_t *offset; + hal_real_t width; + hal_real_t scale; + hal_real_t offset; } pin; } hal; @@ -747,7 +747,7 @@ typedef struct { // this hal pin affects all rcpwmgen instances typedef struct { struct { - hal_float_t *rate; + hal_real_t rate; } pin; } hm2_rcpwmgen_module_global_t; @@ -784,31 +784,30 @@ typedef struct { struct { struct { - hal_bit_t *filt_data[32]; - hal_bit_t *raw_data[32]; - hal_bit_t *filt_data_not[32]; - hal_bit_t *raw_data_not[32]; - hal_bit_t *slow[32] ; - hal_s32_t *enc0_count; - hal_s32_t *enc1_count; - hal_s32_t *enc2_count; - hal_s32_t *enc3_count; - hal_bit_t *enc0_reset; - hal_bit_t *enc1_reset; - hal_bit_t *enc2_reset; - hal_bit_t *enc3_reset; - + hal_bool_t filt_data[32]; + hal_bool_t raw_data[32]; + hal_bool_t filt_data_not[32]; + hal_bool_t raw_data_not[32]; + hal_bool_t slow[32]; + hal_sint_t enc0_count; + hal_sint_t enc1_count; + hal_sint_t enc2_count; + hal_sint_t enc3_count; + hal_bool_t enc0_reset; + hal_bool_t enc1_reset; + hal_bool_t enc2_reset; + hal_bool_t enc3_reset; } pin; struct { - hal_u32_t scan_rate; - hal_u32_t slow_scans; - hal_u32_t fast_scans; - hal_bit_t enc0_mode; - hal_bit_t enc1_mode; - hal_bit_t enc2_mode; - hal_bit_t enc3_mode; - hal_u32_t scan_width; + hal_uint_t scan_rate; + hal_uint_t slow_scans; + hal_uint_t fast_scans; + hal_bool_t enc0_mode; + hal_bool_t enc1_mode; + hal_bool_t enc2_mode; + hal_bool_t enc3_mode; + hal_uint_t scan_width; } param; } hal; @@ -879,30 +878,30 @@ typedef struct { struct { struct { - hal_bit_t *filt_data[32]; - hal_bit_t *raw_data[32]; - hal_bit_t *filt_data_not[32]; - hal_bit_t *raw_data_not[32]; - hal_bit_t *slow[32] ; - hal_s32_t *enc0_count; - hal_s32_t *enc1_count; - hal_s32_t *enc2_count; - hal_s32_t *enc3_count; - hal_bit_t *enc0_reset; - hal_bit_t *enc1_reset; - hal_bit_t *enc2_reset; - hal_bit_t *enc3_reset; + hal_bool_t filt_data[32]; + hal_bool_t raw_data[32]; + hal_bool_t filt_data_not[32]; + hal_bool_t raw_data_not[32]; + hal_bool_t slow[32]; + hal_sint_t enc0_count; + hal_sint_t enc1_count; + hal_sint_t enc2_count; + hal_sint_t enc3_count; + hal_bool_t enc0_reset; + hal_bool_t enc1_reset; + hal_bool_t enc2_reset; + hal_bool_t enc3_reset; } pin; struct { - hal_u32_t scan_rate; - hal_u32_t slow_scans; - hal_u32_t fast_scans; - hal_bit_t enc0_mode; - hal_bit_t enc1_mode; - hal_bit_t enc2_mode; - hal_bit_t enc3_mode; - hal_u32_t scan_width; + hal_uint_t scan_rate; + hal_uint_t slow_scans; + hal_uint_t fast_scans; + hal_bool_t enc0_mode; + hal_bool_t enc1_mode; + hal_bool_t enc2_mode; + hal_bool_t enc3_mode; + hal_uint_t scan_width; } param; } hal; @@ -979,53 +978,53 @@ typedef struct { struct { struct { - hal_float_t *accx_cmd; - hal_float_t *accy_cmd; - hal_float_t *velx_cmd; - hal_float_t *vely_cmd; - hal_float_t *posx_cmd; - hal_float_t *posy_cmd; - hal_float_t *velx_fb; - hal_float_t *vely_fb; - hal_float_t *posx_fb; - hal_float_t *posy_fb; - hal_float_t *posx_scale; - hal_float_t *posy_scale; - hal_bit_t *enable; - hal_u32_t *controlx; - hal_u32_t *controly; - hal_u32_t *commandx; - hal_u32_t *commandy; - hal_bit_t *mode18bitx; - hal_bit_t *mode18bity; - hal_bit_t *commandmodex; - hal_bit_t *commandmodey; - hal_u32_t *status; - hal_bit_t *posx_overflow; - hal_bit_t *posy_overflow; - hal_bit_t *velx_overflow; - hal_bit_t *vely_overflow; + hal_real_t accx_cmd; + hal_real_t accy_cmd; + hal_real_t velx_cmd; + hal_real_t vely_cmd; + hal_real_t posx_cmd; + hal_real_t posy_cmd; + hal_real_t velx_fb; + hal_real_t vely_fb; + hal_real_t posx_fb; + hal_real_t posy_fb; + hal_real_t posx_scale; + hal_real_t posy_scale; + hal_bool_t enable; + hal_uint_t controlx; + hal_uint_t controly; + hal_uint_t commandx; + hal_uint_t commandy; + hal_bool_t mode18bitx; + hal_bool_t mode18bity; + hal_bool_t commandmodex; + hal_bool_t commandmodey; + hal_uint_t status; + hal_bool_t posx_overflow; + hal_bool_t posy_overflow; + hal_bool_t velx_overflow; + hal_bool_t vely_overflow; } pin; } hal; //previous MPG counts for this instance - hal_float_t prev_accx_cmd; - hal_float_t prev_accy_cmd; - hal_float_t prev_velx_cmd; - hal_float_t prev_vely_cmd; - hal_float_t prev_posx_cmd; - hal_float_t prev_posy_cmd; + rtapi_real prev_accx_cmd; + rtapi_real prev_accy_cmd; + rtapi_real prev_velx_cmd; + rtapi_real prev_vely_cmd; + rtapi_real prev_posx_cmd; + rtapi_real prev_posy_cmd; } hm2_xy2mod_instance_t; -// these hal params affect all xy2mod instances +// these hal pins affect all xy2mod instances typedef struct { struct { - hal_s32_t *dpll_rtimer_num; - hal_s32_t *dpll_wtimer_num; + hal_sint_t dpll_rtimer_num; + hal_sint_t dpll_wtimer_num; } pin; } hm2_xy2mod_module_global_t; @@ -1041,8 +1040,8 @@ typedef struct { // module-global HAL objects... hm2_xy2mod_module_global_t *hal; - rtapi_u32 written_dpll_rtimer_num; - rtapi_u32 written_dpll_wtimer_num; + rtapi_s32 written_dpll_rtimer_num; + rtapi_s32 written_dpll_wtimer_num; rtapi_u32 accx_addr; @@ -1092,18 +1091,18 @@ typedef struct { struct { struct { - hal_float_t *Avalue; - hal_float_t *Bvalue; - hal_float_t *Cvalue; - hal_bit_t *fault; - hal_bit_t *enable; + hal_real_t Avalue; + hal_real_t Bvalue; + hal_real_t Cvalue; + hal_bool_t fault; + hal_bool_t enable; } pin; struct { - hal_float_t scale; - hal_float_t deadzone; - hal_bit_t faultpolarity; - hal_float_t sampletime; + hal_real_t scale; + hal_real_t deadzone; + hal_bool_t faultpolarity; + hal_real_t sampletime; } param; } hal; @@ -1112,14 +1111,14 @@ typedef struct { // know if an update-write is needed // enable is a little more complicated and is based on the read-back // of the fault/enable register - double written_deadzone; - int written_faultpolarity; - double written_sampletime; + rtapi_real written_deadzone; + rtapi_bool written_faultpolarity; + rtapi_real written_sampletime; } hm2_tp_pwmgen_instance_t; typedef struct { struct { - hal_u32_t pwm_frequency; // One PWM rate for all instances + hal_uint_t pwm_frequency; // One PWM rate for all instances } param; } hm2_tp_pwmgen_global_hal_t; @@ -1205,49 +1204,55 @@ typedef struct { struct { struct { - hal_float_t *position_cmd; - hal_float_t *velocity_cmd; - hal_s32_t *counts; - hal_float_t *position_fb; - hal_float_t *position_latch; - hal_float_t *velocity_fb; - hal_bit_t *enable; - hal_bit_t *control_type; // 0="position control", 1="velocity control" - hal_bit_t *position_reset; // reset position when true - hal_bit_t *index_enable; - hal_bit_t *index_polarity; - hal_bit_t *latch_enable; - hal_bit_t *latch_polarity; + hal_real_t position_cmd; + hal_real_t velocity_cmd; + hal_sint_t counts; + hal_real_t position_fb; + hal_real_t position_latch; + hal_real_t velocity_fb; + hal_bool_t enable; + hal_bool_t control_type; // 0="position control", 1="velocity control" + hal_bool_t position_reset; // reset position when true + hal_bool_t index_enable; + hal_bool_t index_polarity; + hal_bool_t latch_enable; + hal_bool_t latch_polarity; // debug pins - hal_float_t *dbg_ff_vel; - hal_float_t *dbg_vel_error; - hal_float_t *dbg_s_to_match; - hal_float_t *dbg_err_at_match; - hal_s32_t *dbg_step_rate; - hal_float_t *dbg_pos_minus_prev_cmd; + hal_real_t dbg_ff_vel; + hal_real_t dbg_vel_error; + hal_real_t dbg_s_to_match; + hal_real_t dbg_err_at_match; + hal_sint_t dbg_step_rate; + hal_real_t dbg_pos_minus_prev_cmd; } pin; struct { - hal_float_t position_scale; - hal_float_t maxvel; - hal_float_t maxaccel; - - hal_u32_t steplen; - hal_u32_t stepspace; - hal_u32_t dirsetup; - hal_u32_t dirhold; - - hal_u32_t step_type; - hal_bit_t swap_step_dir; - hal_u32_t table[5]; // the Fifth Element is used as a very crude hash + hal_real_t position_scale; + hal_real_t maxvel; + hal_real_t maxaccel; + + hal_uint_t steplen; + hal_uint_t stepspace; + hal_uint_t dirsetup; + hal_uint_t dirhold; + + hal_uint_t step_type; + hal_bool_t swap_step_dir; + hal_uint_t table[4]; + // the Fifth Element was moved below (used as a very crude hash) } param; } hal; + // This was originally the fifth parameter element in 'table'. It was moved + // here because there was no parameter allocated and is an instance value. + // Parameters work like pins now and cannot be used as local storage. + rtapi_u32 tablehash; + // this variable holds the previous position command, for // computing the feedforward velocity - hal_float_t old_position_cmd; + rtapi_real old_position_cmd; rtapi_u32 prev_accumulator; @@ -1275,7 +1280,7 @@ typedef struct { // these hal params affect all stepgen instances typedef struct { struct { - hal_s32_t *dpll_timer_num; + hal_sint_t dpll_timer_num; } pin; } hm2_stepgen_module_global_t; @@ -1335,7 +1340,6 @@ typedef struct { int conf_flag[16]; rtapi_u16 cd_addr; rtapi_u16 count_addr; - hal_u32_t *count; int num_frames; rtapi_u32 clock_freq; rtapi_u16 base_address; @@ -1426,16 +1430,16 @@ typedef struct { // typedef struct { - hal_float_t *time1_us; - hal_float_t *time2_us; - hal_float_t *time3_us; - hal_float_t *time4_us; - hal_float_t *base_freq; - hal_float_t *phase_error; - hal_u32_t *plimit; - hal_u32_t *ddssize; - hal_u32_t *time_const; - hal_u32_t *prescale; + hal_real_t time1_us; + hal_real_t time2_us; + hal_real_t time3_us; + hal_real_t time4_us; + hal_real_t base_freq; + hal_real_t phase_error; + hal_uint_t plimit; + hal_uint_t ddssize; + hal_uint_t time_const; + hal_uint_t prescale; } hm2_dpll_pins_t ; typedef struct { @@ -1470,11 +1474,11 @@ typedef struct { struct { struct { - hal_bit_t *has_bit; + hal_bool_t has_bit; } pin; struct { - hal_u32_t timeout_ns; + hal_uint_t timeout_ns; } param; } hal; @@ -1508,7 +1512,7 @@ typedef struct { // typedef struct { - hal_bit_t *led; + hal_bool_t led; } hm2_led_instance_t ; typedef struct { @@ -1533,9 +1537,9 @@ typedef struct { struct { struct { - hal_u32_t *rate; - hal_bit_t *out[32]; - hal_bit_t *invert[32]; + hal_uint_t rate; + hal_bool_t out[32]; + hal_bool_t invert[32]; } pin; } hal; @@ -1566,8 +1570,8 @@ typedef struct { struct { struct { - hal_bit_t *out[32]; - hal_bit_t *invert[32]; + hal_bool_t out[32]; + hal_bool_t invert[32]; } pin; } hal; @@ -1596,14 +1600,14 @@ typedef struct { typedef struct { struct { struct { - hal_u32_t *read_address; - hal_u32_t *read_data; + hal_uint_t read_address; + hal_uint_t read_data; - hal_u32_t *write_address; - hal_u32_t *write_data; - hal_bit_t *write_strobe; + hal_uint_t write_address; + hal_uint_t write_data; + hal_bool_t write_strobe; - hal_bit_t *dump_state; + hal_bool_t dump_state; } pin; } hal; } hm2_raw_t; diff --git a/src/hal/drivers/mesa-hostmot2/inm.c b/src/hal/drivers/mesa-hostmot2/inm.c index 22886f80801..596b9e2ba02 100644 --- a/src/hal/drivers/mesa-hostmot2/inm.c +++ b/src/hal/drivers/mesa-hostmot2/inm.c @@ -96,7 +96,7 @@ int hm2_inm_parse_md(hostmot2_t *hm2, int md_index) { hm2->inm.clock_frequency = md->clock_freq; hm2->inm.version = md->version; - hm2->inm.instance = (hm2_inm_instance_t *)hal_malloc(hm2->inm.num_instances * sizeof(hm2_inm_instance_t)); + hm2->inm.instance = hal_malloc(hm2->inm.num_instances * sizeof(*hm2->inm.instance)); if (hm2->inm.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -153,247 +153,244 @@ int hm2_inm_parse_md(hostmot2_t *hm2, int md_index) { // Export to HAL. // - { - int i; - int j; - int inm_number; - int temp; - char name[HAL_NAME_LEN + 1]; - - for (i = 0; i < hm2->inm.num_instances; i ++) { - hm2->inm.instance[i].enc0_present = false; - hm2->inm.instance[i].enc1_present = false; - hm2->inm.instance[i].enc2_present = false; - hm2->inm.instance[i].enc3_present = false; - temp = 0; - // Determine which MPG encoders have both pins so are useable - for (j = 0; j < hm2->num_pins; j++){ - if (hm2->pin[j].sec_tag == HM2_GTAG_INM && hm2->pin[j].sec_unit == i) { - inm_number = (hm2->pin[j].sec_pin & 0x7f) - 1; - if (inm_number < 8) { - temp = temp | (1 << inm_number); - } + for (int i = 0; i < hm2->inm.num_instances; i ++) { + hm2_inm_instance_t *inst = &hm2->inm.instance[i]; + inst->enc0_present = false; + inst->enc1_present = false; + inst->enc2_present = false; + inst->enc3_present = false; + rtapi_u32 temp = 0; + // Determine which MPG encoders have both pins so are useable + for (int j = 0; j < hm2->num_pins; j++){ + if (hm2->pin[j].sec_tag == HM2_GTAG_INM && hm2->pin[j].sec_unit == i) { + int inm_number = (hm2->pin[j].sec_pin & 0x7f) - 1; + if (inm_number < 8) { + temp = temp | (1 << inm_number); } } - if ((temp & 0x03) == 0x03) { - hm2->inm.instance[i].enc0_present = true; - } - if ((temp & 0x0C) == 0x0C) { - hm2->inm.instance[i].enc1_present = true; - } - if ((temp & 0x30) == 0x30) { - hm2->inm.instance[i].enc2_present = true; - } - if ((temp & 0xC0) == 0xC0) { - hm2->inm.instance[i].enc3_present = true; - } - // Do a low level read to determine the per instance scanwidth - hm2->llio->read(hm2->llio,hm2->inm.control_addr + (i * md->instance_stride),&temp, sizeof(rtapi_u32)); - temp = (temp & 0x0000001f) +1; - hm2->inm.instance[i].scanwidth = temp; - hm2->inm.instance[i].hal.param.scan_width = temp; - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.scan_rate", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->inm.instance[i].hal.param.scan_rate), hm2->llio->comp_id); + } + if ((temp & 0x03) == 0x03) { + inst->enc0_present = true; + } + if ((temp & 0x0C) == 0x0C) { + inst->enc1_present = true; + } + if ((temp & 0x30) == 0x30) { + inst->enc2_present = true; + } + if ((temp & 0xC0) == 0xC0) { + inst->enc3_present = true; + } + // Do a low level read to determine the per instance scanwidth + hm2->llio->read(hm2->llio,hm2->inm.control_addr + (i * md->instance_stride),&temp, sizeof(rtapi_u32)); + temp = (temp & 0x0000001f) +1; + inst->scanwidth = temp; + // init 20000: 20 KHz = 50 usec/scan + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.scan_rate), + 20000, "%s.inm.%02d.scan_rate", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding param '%s.inm.%02d.scan_rate', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + // init 500: 500*50 usec = 25 ms + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.slow_scans), + 500, "%s.inm.%02d.slow_scans", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding param '%s.inm.%02d.slow_scans', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + // init 5: 5*50 usec = 250 usec + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.fast_scans), + 5, "%s.inm.%02d.fast_scans", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding param '%s.inm.%02d.fast_scans', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + + if (inst->enc0_present) { + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.enc0_mode), + 0, "%s.inm.%02d.enc0_4xmode", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.inm.%02d.enc0_4xmode', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.slow_scans", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->inm.instance[i].hal.param.slow_scans), hm2->llio->comp_id); + } else { + r = hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(inst->hal.param.enc0_mode)); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d allocating fake param '%s.inm.%02d.enc0_4xmode', aborting\n", r, hm2->llio->name, i); goto fail1; - } - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.fast_scans", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->inm.instance[i].hal.param.fast_scans), hm2->llio->comp_id); + } + } + + if (inst->enc1_present) { + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.enc1_mode), + 0, "%s.inm.%02d.enc1_4xmode", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.inm.%02d.enc1_4xmode', aborting\n", r, hm2->llio->name, i); goto fail1; - } - - if (hm2->inm.instance[i].enc0_present) { - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc0_4xmode", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->inm.instance[i].hal.param.enc0_mode), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); - goto fail1; - } } - - if (hm2->inm.instance[i].enc1_present) { - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc1_4xmode", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->inm.instance[i].hal.param.enc1_mode), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); - goto fail1; - } + } else { + r = hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(inst->hal.param.enc1_mode)); + if (r < 0) { + HM2_ERR("error %d allocating fake param '%s.inm.%02d.enc1_4xmode', aborting\n", r, hm2->llio->name, i); + goto fail1; } - - if (hm2->inm.instance[i].enc2_present) { - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc2_4xmode", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->inm.instance[i].hal.param.enc2_mode), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); - goto fail1; - } + } + + if (inst->enc2_present) { + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.enc2_mode), + 0, "%s.inm.%02d.enc2_4xmode", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding param '%s.inm.%02d.enc2_4xmode', aborting\n", r, hm2->llio->name, i); + goto fail1; } - - if (hm2->inm.instance[i].enc3_present) { - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc3_4xmode", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->inm.instance[i].hal.param.enc3_mode), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); - goto fail1; - } + } else { + r = hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(inst->hal.param.enc2_mode)); + if (r < 0) { + HM2_ERR("error %d allocating fake param '%s.inm.%02d.enc2_4xmode', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + } + + if (inst->enc3_present) { + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.enc3_mode), + 0, "%s.inm.%02d.enc3_4xmode", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding param '%s.inm.%02d.enc3_4xmode', aborting\n", r, hm2->llio->name, i); + goto fail1; } - - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.scan_width", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RO, &(hm2->inm.instance[i].hal.param.scan_width), hm2->llio->comp_id); + } else { + r = hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(inst->hal.param.enc3_mode)); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d allocating fake param '%s.inm.%02d.enc3_4xmode', aborting\n", r, hm2->llio->name, i); goto fail1; } + } - int j = 0; - int inm_number; - for (j = 0; j < hm2->num_pins; j++){ - if (hm2->pin[j].sec_tag == HM2_GTAG_INM && hm2->pin[j].sec_unit == i) { - if ((hm2->pin[j].sec_pin & 0x80) != 00) { - HM2_ERR("Pin Descriptor %d has an inm pin that's not an input!\n", j); - r = -EINVAL; - goto fail0; - } - inm_number = (hm2->pin[j].sec_pin & 0x7f) - 1; - if (inm_number >= 32) { - HM2_ERR("Pin Descriptor %d has invalid secondary pin number %d for inm module!\n", j, inm_number); - r = -EINVAL; - goto fail0; - } - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.input-%02d", hm2->llio->name, i, inm_number); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->inm.instance[i].hal.pin.filt_data[inm_number]), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.raw-input-%02d", hm2->llio->name, i, inm_number); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->inm.instance[i].hal.pin.raw_data[inm_number]), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.input-%02d-not", hm2->llio->name, i, inm_number); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->inm.instance[i].hal.pin.filt_data_not[inm_number]), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.raw-input-%02d-not", hm2->llio->name, i, inm_number); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->inm.instance[i].hal.pin.raw_data_not[inm_number]), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.input-%02d-slow", hm2->llio->name, i, inm_number); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->inm.instance[i].hal.pin.slow[inm_number]), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RO, &(inst->hal.param.scan_width), + temp, "%s.inm.%02d.scan_width", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding param '%s.inm.%02d.scan_width', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + + for (int j = 0; j < hm2->num_pins; j++) { + if (hm2->pin[j].sec_tag == HM2_GTAG_INM && hm2->pin[j].sec_unit == i) { + if ((hm2->pin[j].sec_pin & 0x80) != 00) { + HM2_ERR("Pin Descriptor %d has an inm pin that's not an input!\n", j); + r = -EINVAL; + goto fail0; + } + int inm_number = (hm2->pin[j].sec_pin & 0x7f) - 1; + if (inm_number >= 32) { + HM2_ERR("Pin Descriptor %d has invalid secondary pin number %d for inm module!\n", j, inm_number); + r = -EINVAL; + goto fail0; } - } - if (hm2->inm.instance[i].enc0_present) { - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc0-count", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->inm.instance[i].hal.pin.enc0_count), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.filt_data[inm_number]), + 0, "%s.inm.%02d.input-%02d", hm2->llio->name, i, inm_number); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; + HM2_ERR("error %d adding pin '%s.inm.%02d.input-%02d', aborting\n", r, hm2->llio->name, i, inm_number); + goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc0-reset", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->inm.instance[i].hal.pin.enc0_reset), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.raw_data[inm_number]), + 0, "%s.inm.%02d.raw-input-%02d", hm2->llio->name, i, inm_number); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.inm.%02d.raw-input-%02d', aborting\n", r, hm2->llio->name, i, inm_number); goto fail1; } - } - - if (hm2->inm.instance[i].enc1_present) { - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc1-count", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->inm.instance[i].hal.pin.enc1_count), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.filt_data_not[inm_number]), + 0, "%s.inm.%02d.input-%02d-not", hm2->llio->name, i, inm_number); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.inm.%02d.input-%02d-not', aborting\n", r, hm2->llio->name, i, inm_number); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc1-reset", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->inm.instance[i].hal.pin.enc1_reset), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.raw_data_not[inm_number]), + 0, "%s.inm.%02d.raw-input-%02d-not", hm2->llio->name, i, inm_number); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.inm.%02d.raw-input-%02d-not', aborting\n", r, hm2->llio->name, i, inm_number); goto fail1; } - - if (hm2->inm.instance[i].enc2_present) { - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc2-count", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->inm.instance[i].hal.pin.enc2_count), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc2-reset", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->inm.instance[i].hal.pin.enc2_reset), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(inst->hal.pin.slow[inm_number]), + 0, "%s.inm.%02d.input-%02d-slow", hm2->llio->name, i, inm_number); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inm.%02d.input-%02d-slow', aborting\n", r, hm2->llio->name, i, inm_number); + goto fail1; } - if (hm2->inm.instance[i].enc3_present) { - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc3-count", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->inm.instance[i].hal.pin.enc3_count), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - rtapi_snprintf(name, sizeof(name), "%s.inm.%02d.enc3-reset", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->inm.instance[i].hal.pin.enc3_reset), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - } + } + } + if (inst->enc0_present) { + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.enc0_count), + 0, "%s.inm.%02d.enc0-count", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inm.%02d.enc0-count', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(inst->hal.pin.enc0_reset), + 0, "%s.inm.%02d.enc0-reset", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inm.%02d.enc0-reset', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + } + + if (inst->enc1_present) { + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.enc1_count), + 0, "%s.inm.%02d.enc1-count", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inm.%02d.enc1-count', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(inst->hal.pin.enc1_reset), + 0, "%s.inm.%02d.enc1-reset", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inm.%02d.enc1-reset', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + } + + if (inst->enc2_present) { + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.enc2_count), + 0, "%s.inm.%02d.enc2-count", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inm.%02d.enc2-count', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(inst->hal.pin.enc2_reset), + 0, "%s.inm.%02d.enc2-reset", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inm.%02d.enc2-reset', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + } + if (inst->enc3_present) { + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.enc3_count), + 0, "%s.inm.%02d.enc3-count", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inm.%02d.enc3-count', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(inst->hal.pin.enc3_reset), + 0, "%s.inm.%02d.enc3-reset", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inm.%02d.enc3-reset', aborting\n", r, hm2->llio->name, i); + goto fail1; } } } // - // Set inm default scanrate and filter values + // Set inm default scanrate and filter values // and remove initial MPG offset - { - int i; - int rawmpgs; - for (i = 0; i < hm2->inm.num_instances; i ++) { - hm2->inm.instance[i].hal.param.scan_rate = 20000; // 20 KHz = 50 usec/scan - hm2->inm.instance[i].hal.param.slow_scans = 500; // 500*50 usec = 25 ms - hm2->inm.instance[i].hal.param.fast_scans = 5; // 5*50 usec = 250 usec - hm2->llio->read(hm2->llio,hm2->inm.mpg_read_addr + (i * md->instance_stride),&rawmpgs, sizeof(rtapi_u32)); - if (hm2->inm.instance[i].enc0_present) { hm2->inm.instance[i].prev_enc0_count = (rtapi_s32)((rawmpgs >> 0) & 0x000000FF); } - if (hm2->inm.instance[i].enc1_present) { hm2->inm.instance[i].prev_enc1_count = (rtapi_s32)((rawmpgs >> 8) & 0x000000FF); } - if (hm2->inm.instance[i].enc2_present) { hm2->inm.instance[i].prev_enc2_count = (rtapi_s32)((rawmpgs >> 16) & 0x000000FF); } - if (hm2->inm.instance[i].enc3_present) { hm2->inm.instance[i].prev_enc3_count = (rtapi_s32)((rawmpgs >> 24) & 0x000000FF); } - - } - + for (int i = 0; i < hm2->inm.num_instances; i ++) { + hm2_inm_instance_t *inst = &hm2->inm.instance[i]; + rtapi_u32 rawmpgs; + hm2->llio->read(hm2->llio,hm2->inm.mpg_read_addr + (i * md->instance_stride),&rawmpgs, sizeof(rtapi_u32)); + if (inst->enc0_present) { inst->prev_enc0_count = (rtapi_s32)((rawmpgs >> 0) & 0x000000FF); } + if (inst->enc1_present) { inst->prev_enc1_count = (rtapi_s32)((rawmpgs >> 8) & 0x000000FF); } + if (inst->enc2_present) { inst->prev_enc2_count = (rtapi_s32)((rawmpgs >> 16) & 0x000000FF); } + if (inst->enc3_present) { inst->prev_enc3_count = (rtapi_s32)((rawmpgs >> 24) & 0x000000FF); } } return hm2->inm.num_instances; @@ -420,24 +417,24 @@ void hm2_inm_force_write(hostmot2_t *hm2) { // setup control register and mpg_write for (i = 0; i < hm2->inm.num_instances; i ++) { - scanrate = hm2->inm.instance[i].scanwidth * hm2->inm.instance[i].hal.param.scan_rate; + hm2_inm_instance_t *inst = &hm2->inm.instance[i]; + scanrate = inst->scanwidth * hal_get_ui32(inst->hal.param.scan_rate); if (scanrate > 10000000) { scanrate = 10000000; - hm2->inm.instance[i].hal.param.scan_rate = scanrate/hm2->inm.instance[i].scanwidth; + hal_set_ui32(inst->hal.param.scan_rate, scanrate/inst->scanwidth); } divisor = (hm2->inm.clock_frequency / (4 * scanrate)) - 1; - if (hm2->inm.instance[i].hal.param.fast_scans > 63) { - hm2->inm.instance[i].hal.param.fast_scans = 63; + 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); } - if (hm2->inm.instance[i].hal.param.slow_scans > 1023) { - hm2->inm.instance[i].hal.param.slow_scans = 1023; + rtapi_u32 slow_scans = hal_get_ui32(inst->hal.param.slow_scans); + if (slow_scans > 1023) { + slow_scans = hal_set_ui32(inst->hal.param.slow_scans, 1023); } - hm2->inm.control_reg[i] = (1 << 5) + -// global invert bit(5) fixed to true for now as this matches all existing hardware - (divisor << 6) + - (hm2->inm.instance[i].hal.param.fast_scans << 16) + - (hm2->inm.instance[i].hal.param.slow_scans << 22); + // global invert bit(5) fixed to true for now as this matches all existing hardware + hm2->inm.control_reg[i] = (1 << 5) + (divisor << 6) + (fast_scans << 16) + (slow_scans << 22); } size = hm2->inm.num_instances * sizeof(rtapi_u32); @@ -467,69 +464,69 @@ void hm2_inm_write(hostmot2_t *hm2) { for (i = 0; i < hm2->inm.num_instances; i ++) { - scanrate = hm2->inm.instance[i].scanwidth * hm2->inm.instance[i].hal.param.scan_rate; + hm2_inm_instance_t *inst = &hm2->inm.instance[i]; + scanrate = inst->scanwidth * hal_get_ui32(inst->hal.param.scan_rate); // bound scanrate maximum frequency if (scanrate > 10000000) { scanrate = 10000000; - hm2->inm.instance[i].hal.param.scan_rate = scanrate/hm2->inm.instance[i].scanwidth; - HM2_ERR("inm %d scanrate too high, resetting to %d \n", i,hm2->inm.instance[i].hal.param.scan_rate); + 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 )) { divisor = 1023; - hm2->inm.instance[i].hal.param.scan_rate = (hm2->inm.clock_frequency/4)/(divisor +1) - /hm2->inm.instance[i].scanwidth; - HM2_ERR("inm %d scanrate too low, resetting to %d \n", i,hm2->inm.instance[i].hal.param.scan_rate); + hal_set_ui32(inst->hal.param.scan_rate, (hm2->inm.clock_frequency/4)/(divisor +1) + /inst->scanwidth); + HM2_ERR("inm %d scanrate too low, resetting to %d \n", i, hal_get_ui32(inst->hal.param.scan_rate)); } - if (hm2->inm.instance[i].hal.param.fast_scans > 63) { - hm2->inm.instance[i].hal.param.fast_scans = 63; + 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); HM2_ERR("inm %d fastscans must be less than 63, resetting to %d \n", i,63); } - if (hm2->inm.instance[i].hal.param.slow_scans > 1023) { - hm2->inm.instance[i].hal.param.slow_scans = 1023; + rtapi_u32 slow_scans = hal_get_ui32(inst->hal.param.slow_scans); + if (slow_scans > 1023) { + slow_scans = hal_set_ui32(inst->hal.param.slow_scans, 1023); HM2_ERR("inm %d slowscans must be less than 1023, resetting to %d \n", i,1023); } - if (hm2->inm.instance[i].hal.param.fast_scans < 1 ) { - hm2->inm.instance[i].hal.param.fast_scans = 1; + if (fast_scans < 1 ) { + fast_scans = hal_set_ui32(inst->hal.param.fast_scans, 1); HM2_ERR("inm %d fastscans must be greater than 0, resetting to %d \n", i,1); } - if (hm2->inm.instance[i].hal.param.slow_scans < 1) { - hm2->inm.instance[i].hal.param.slow_scans = 1; + if (slow_scans < 1) { + slow_scans = hal_set_ui32(inst->hal.param.slow_scans, 1); HM2_ERR("inm %d slowscans must be greater than 0, resetting to %d \n", i,1); } - hm2->inm.control_reg[i] = (1 << 5) + -// global invert bit(5) fixed to true for now as this matches all existing hardware) - (divisor << 6) + - (hm2->inm.instance[i].hal.param.fast_scans << 16) + - (hm2->inm.instance[i].hal.param.slow_scans << 22); - if (hm2->inm.control_reg[i] != hm2->inm.instance[i].written_control_reg) { + // global invert bit(5) fixed to true for now as this matches all existing hardware) + hm2->inm.control_reg[i] = (1 << 5) + (divisor << 6) + (fast_scans << 16) + (slow_scans << 22); + if (hm2->inm.control_reg[i] != inst->written_control_reg) { hm2->llio->write(hm2->llio, hm2->inm.control_addr, hm2->inm.control_reg, size); - hm2->inm.instance[i].written_control_reg = hm2->inm.control_reg[i]; + inst->written_control_reg = hm2->inm.control_reg[i]; // HM2_PRINT(" Debug: updating inm control reg to = 0x%08X\n", hm2->inm.control_reg[i]); } hm2->inm.filter_reg[i] = 0; for (j = 0; j < hm2->num_pins; j++){ if (hm2->pin[j].sec_tag == HM2_GTAG_INM && hm2->pin[j].sec_unit == i) { inm_number = (hm2->pin[j].sec_pin & 0x7f) - 1; - hm2->inm.filter_reg[i] |= (*hm2->inm.instance[i].hal.pin.slow[inm_number] << inm_number); + hm2->inm.filter_reg[i] |= (hal_get_bool(inst->hal.pin.slow[inm_number]) << inm_number); } } - if (hm2->inm.filter_reg[i] != hm2->inm.instance[i].written_filter_reg) { + if (hm2->inm.filter_reg[i] != inst->written_filter_reg) { hm2->llio->write(hm2->llio, hm2->inm.filter_addr, hm2->inm.filter_reg, size); - hm2->inm.instance[i].written_filter_reg = hm2->inm.filter_reg[i]; + inst->written_filter_reg = hm2->inm.filter_reg[i]; // HM2_PRINT(" Debug: updating inm filter reg to = 0x%08X\n", hm2->inm.filter_reg[i]); } hm2->inm.mpg_mode_reg[i] = 0; - if (hm2->inm.instance[i].enc0_present) { hm2->inm.mpg_mode_reg[i] = hm2->inm.instance[i].hal.param.enc0_mode << 0; } - if (hm2->inm.instance[i].enc1_present) { hm2->inm.mpg_mode_reg[i] |= hm2->inm.instance[i].hal.param.enc1_mode << 8; } - if (hm2->inm.instance[i].enc2_present) { hm2->inm.mpg_mode_reg[i] |= hm2->inm.instance[i].hal.param.enc2_mode << 16; } - if (hm2->inm.instance[i].enc3_present) { hm2->inm.mpg_mode_reg[i] |= hm2->inm.instance[i].hal.param.enc3_mode << 24; } - if (hm2->inm.mpg_mode_reg[i] != hm2->inm.instance[i].written_mpg_mode_reg) { + if (inst->enc0_present) { hm2->inm.mpg_mode_reg[i] = hal_get_bool(inst->hal.param.enc0_mode) << 0; } + if (inst->enc1_present) { hm2->inm.mpg_mode_reg[i] |= hal_get_bool(inst->hal.param.enc1_mode) << 8; } + if (inst->enc2_present) { hm2->inm.mpg_mode_reg[i] |= hal_get_bool(inst->hal.param.enc2_mode) << 16; } + if (inst->enc3_present) { hm2->inm.mpg_mode_reg[i] |= hal_get_bool(inst->hal.param.enc3_mode) << 24; } + if (hm2->inm.mpg_mode_reg[i] != inst->written_mpg_mode_reg) { hm2->llio->write(hm2->llio, hm2->inm.mpg_mode_addr, hm2->inm.mpg_mode_reg, size); - hm2->inm.instance[i].written_mpg_mode_reg = hm2->inm.mpg_mode_reg[i]; + inst->written_mpg_mode_reg = hm2->inm.mpg_mode_reg[i]; // HM2_PRINT(" Debug: updating inm mpg mode reg to = 0x%08X\n", hm2->inm.mpg_mode_reg[i]); } } @@ -547,7 +544,7 @@ void hm2_inm_prepare_tram_write(hostmot2_t *hm2) { for (j = 0; j < hm2->num_pins; j++){ if (hm2->pin[j].sec_tag == HM2_GTAG_INM && hm2->pin[j].sec_unit == i) { inm_number = (hm2->pin[j].sec_pin & 0x7f) - 1; - hm2->inm.filter_reg[i] |= (*hm2->inm.instance[i].hal.pin.slow[inm_number] << inm_number); + hm2->inm.filter_reg[i] |= (hal_get_bool(hm2->inm.instance[i].hal.pin.slow[inm_number]) << inm_number); } } } @@ -564,60 +561,69 @@ void hm2_inm_process_tram_read(hostmot2_t *hm2) { return; } for (i = 0; i < hm2->inm.num_instances; i ++) { + hm2_inm_instance_t *inst = &hm2->inm.instance[i]; for (j = 0; j < hm2->num_pins; j++){ if (hm2->pin[j].sec_tag == HM2_GTAG_INM && hm2->pin[j].sec_unit == i) { inm_number = (hm2->pin[j].sec_pin & 0x7f) - 1; - *hm2->inm.instance[i].hal.pin.filt_data[inm_number] = (hm2->inm.filt_data_reg[i] >> inm_number) &1; - *hm2->inm.instance[i].hal.pin.raw_data[inm_number] = (hm2->inm.raw_data_reg[i] >> inm_number) &1; - *hm2->inm.instance[i].hal.pin.filt_data_not[inm_number] = !((hm2->inm.filt_data_reg[i] >> inm_number) &1); - *hm2->inm.instance[i].hal.pin.raw_data_not[inm_number] = !((hm2->inm.raw_data_reg[i] >> inm_number) &1); + hal_set_bool(inst->hal.pin.filt_data[inm_number], (hm2->inm.filt_data_reg[i] >> inm_number) & 1); + hal_set_bool(inst->hal.pin.raw_data[inm_number], (hm2->inm.raw_data_reg[i] >> inm_number) & 1); + hal_set_bool(inst->hal.pin.filt_data_not[inm_number], !((hm2->inm.filt_data_reg[i] >> inm_number) & 1)); + hal_set_bool(inst->hal.pin.raw_data_not[inm_number], !((hm2->inm.raw_data_reg[i] >> inm_number) & 1)); + } + } + + if (inst->enc0_present) { + raw_count = hm2->inm.mpg_read_reg[i] & 0x000000FF; + count_diff = (rtapi_s32)raw_count - inst->prev_enc0_count; + inst->prev_enc0_count = inst->prev_enc0_count + count_diff; + if (count_diff > 128) count_diff -= 256; + if (count_diff < -128) count_diff += 256; + if (!hal_get_bool(inst->hal.pin.enc0_reset)) { + hal_set_si32(inst->hal.pin.enc0_count, hal_get_si32(inst->hal.pin.enc0_count) + count_diff); + } else { + hal_set_si32(inst->hal.pin.enc0_count, 0); } } - if (hm2->inm.instance[i].enc0_present) { - raw_count = hm2->inm.mpg_read_reg[i] & 0x000000FF; - count_diff = (rtapi_s32)raw_count - hm2->inm.instance[i].prev_enc0_count; - hm2->inm.instance[i].prev_enc0_count = hm2->inm.instance[i].prev_enc0_count + count_diff; - if (count_diff > 128) count_diff -= 256; - if (count_diff < -128) count_diff += 256; - if (*hm2->inm.instance[i].hal.pin.enc0_reset == 0) { - *hm2->inm.instance[i].hal.pin.enc0_count = *hm2->inm.instance[i].hal.pin.enc0_count + count_diff; - } else { *hm2->inm.instance[i].hal.pin.enc0_count = 0;} - } - - if (hm2->inm.instance[i].enc1_present) { - raw_count = (hm2->inm.mpg_read_reg[i] >> 8) & 0x000000FF; - count_diff = (rtapi_s32)raw_count - hm2->inm.instance[i].prev_enc1_count; - hm2->inm.instance[i].prev_enc1_count = hm2->inm.instance[i].prev_enc1_count + count_diff; - if (count_diff > 128) count_diff -= 256; - if (count_diff < -128) count_diff += 256; - if (*hm2->inm.instance[i].hal.pin.enc1_reset == 0) { - *hm2->inm.instance[i].hal.pin.enc1_count = *hm2->inm.instance[i].hal.pin.enc1_count + count_diff; - } else { *hm2->inm.instance[i].hal.pin.enc1_count = 0;} - } - - if (hm2->inm.instance[i].enc2_present) { - raw_count = (hm2->inm.mpg_read_reg[i] >> 16) & 0x000000FF; - count_diff = (rtapi_s32)raw_count - hm2->inm.instance[i].prev_enc2_count; - hm2->inm.instance[i].prev_enc2_count = hm2->inm.instance[i].prev_enc2_count + count_diff; - if (count_diff > 128) count_diff -= 256; - if (count_diff < -128) count_diff += 256; - if (*hm2->inm.instance[i].hal.pin.enc2_reset == 0) { - *hm2->inm.instance[i].hal.pin.enc2_count = *hm2->inm.instance[i].hal.pin.enc2_count + count_diff; - } else { *hm2->inm.instance[i].hal.pin.enc2_count = 0;} - } - - if (hm2->inm.instance[i].enc3_present) { - raw_count = (hm2->inm.mpg_read_reg[i] >> 24) & 0x000000FF; - count_diff = (rtapi_s32)raw_count - hm2->inm.instance[i].prev_enc3_count; - hm2->inm.instance[i].prev_enc3_count = hm2->inm.instance[i].prev_enc3_count + count_diff; - if (count_diff > 128) count_diff -= 256; - if (count_diff < -128) count_diff += 256; - if (*hm2->inm.instance[i].hal.pin.enc3_reset == 0) { - *hm2->inm.instance[i].hal.pin.enc3_count = *hm2->inm.instance[i].hal.pin.enc3_count + count_diff; - } else { *hm2->inm.instance[i].hal.pin.enc3_count = 0;} - } - } + if (inst->enc1_present) { + raw_count = (hm2->inm.mpg_read_reg[i] >> 8) & 0x000000FF; + count_diff = (rtapi_s32)raw_count - inst->prev_enc1_count; + inst->prev_enc1_count = inst->prev_enc1_count + count_diff; + if (count_diff > 128) count_diff -= 256; + if (count_diff < -128) count_diff += 256; + if (!hal_get_bool(inst->hal.pin.enc1_reset)) { + hal_set_si32(inst->hal.pin.enc1_count, hal_get_si32(inst->hal.pin.enc1_count) + count_diff); + } else { + hal_set_si32(inst->hal.pin.enc1_count, 0); + } + } + + if (inst->enc2_present) { + raw_count = (hm2->inm.mpg_read_reg[i] >> 16) & 0x000000FF; + count_diff = (rtapi_s32)raw_count - inst->prev_enc2_count; + inst->prev_enc2_count = inst->prev_enc2_count + count_diff; + if (count_diff > 128) count_diff -= 256; + if (count_diff < -128) count_diff += 256; + if (!hal_get_bool(inst->hal.pin.enc2_reset)) { + hal_set_si32(inst->hal.pin.enc2_count, hal_get_si32(inst->hal.pin.enc2_count) + count_diff); + } else { + hal_set_si32(inst->hal.pin.enc2_count, 0); + } + } + + if (inst->enc3_present) { + raw_count = (hm2->inm.mpg_read_reg[i] >> 24) & 0x000000FF; + count_diff = (rtapi_s32)raw_count - inst->prev_enc3_count; + inst->prev_enc3_count = inst->prev_enc3_count + count_diff; + if (count_diff > 128) count_diff -= 256; + if (count_diff < -128) count_diff += 256; + if (!hal_get_bool(inst->hal.pin.enc3_reset)) { + hal_set_si32(inst->hal.pin.enc3_count, hal_get_si32(inst->hal.pin.enc3_count) + count_diff); + } else { + hal_set_si32(inst->hal.pin.enc3_count, 0); + } + } + } } void hm2_inm_cleanup(hostmot2_t *hm2) { diff --git a/src/hal/drivers/mesa-hostmot2/inmux.c b/src/hal/drivers/mesa-hostmot2/inmux.c index 5c26b7c6608..eee23922016 100644 --- a/src/hal/drivers/mesa-hostmot2/inmux.c +++ b/src/hal/drivers/mesa-hostmot2/inmux.c @@ -96,7 +96,7 @@ int hm2_inmux_parse_md(hostmot2_t *hm2, int md_index) { hm2->inmux.clock_frequency = md->clock_freq; hm2->inmux.version = md->version; - hm2->inmux.instance = (hm2_inmux_instance_t *)hal_malloc(hm2->inmux.num_instances * sizeof(hm2_inmux_instance_t)); + hm2->inmux.instance = hal_malloc(hm2->inmux.num_instances * sizeof(*hm2->inmux.instance)); if (hm2->inmux.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -154,199 +154,168 @@ int hm2_inmux_parse_md(hostmot2_t *hm2, int md_index) { // { - int i; - int temp; - char name[HAL_NAME_LEN + 1]; - - for (i = 0; i < hm2->inmux.num_instances; i ++) { - - + for (int i = 0; i < hm2->inmux.num_instances; i ++) { + hm2_inmux_instance_t *inst = &hm2->inmux.instance[i]; // first do a low level read to determine the per instance scanwidth + rtapi_u32 temp; hm2->llio->read(hm2->llio,hm2->inmux.control_addr + (i * md->instance_stride),&temp, sizeof(rtapi_u32)); temp = (temp & 0x0000001f) +1; - hm2->inmux.instance[i].scanwidth = temp; - hm2->inmux.instance[i].hal.param.scan_width = temp; + inst->scanwidth = temp; - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.scan_rate", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->inmux.instance[i].hal.param.scan_rate), hm2->llio->comp_id); + // init=20000: 20 KHz = 50 usec/scan + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.scan_rate), + 20000, "%s.inmux.%02d.scan_rate", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.inmux.%02d.scan_rate', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.slow_scans", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->inmux.instance[i].hal.param.slow_scans), hm2->llio->comp_id); + // init=500: 500*50 usec = 25 ms + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.slow_scans), + 500, "%s.inmux.%02d.slow_scans", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.inmux.%02d.slow_scans', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.fast_scans", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->inmux.instance[i].hal.param.fast_scans), hm2->llio->comp_id); + // init=5: 5*50 usec = 250 usec + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.fast_scans), + 5, "%s.inmux.%02d.fast_scans", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.inmux.%02d.fast_scans', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc0_4xmode", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->inmux.instance[i].hal.param.enc0_mode), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.enc0_mode), + 0, "%s.inmux.%02d.enc0_4xmode", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.inmux.%02d.enc0_4xmode', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc1_4xmode", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->inmux.instance[i].hal.param.enc1_mode), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.enc1_mode), + 0, "%s.inmux.%02d.enc1_4xmode", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.inmux.%02d.enc1_4xmode', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc2_4xmode", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->inmux.instance[i].hal.param.enc2_mode), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.enc2_mode), + 0, "%s.inmux.%02d.enc2_4xmode", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.inmux.%02d.enc2_4xmode', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc3_4xmode", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->inmux.instance[i].hal.param.enc3_mode), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(inst->hal.param.enc3_mode), + 0, "%s.inmux.%02d.enc3_4xmode", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.inmux.%02d.enc3_4xmode', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.scan_width", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RO, &(hm2->inmux.instance[i].hal.param.scan_width), hm2->llio->comp_id); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RO, &(inst->hal.param.scan_width), + temp, "%s.inmux.%02d.scan_width", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.inmux.%02d.scan_width', aborting\n", r, hm2->llio->name, i); goto fail1; } - { - unsigned j = 0; - for (j = 0; j < hm2->inmux.instance[i].scanwidth; j++){ - - - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.input-%02u", hm2->llio->name, i, j); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->inmux.instance[i].hal.pin.filt_data[j]), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.raw-input-%02u", hm2->llio->name, i, j); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->inmux.instance[i].hal.pin.raw_data[j]), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.input-%02u-not", hm2->llio->name, i, j); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->inmux.instance[i].hal.pin.filt_data_not[j]), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.raw-input-%02u-not", hm2->llio->name, i, j); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->inmux.instance[i].hal.pin.raw_data_not[j]), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.input-%02u-slow", hm2->llio->name, i, j); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->inmux.instance[i].hal.pin.slow[j]), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } - } - - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc0-count", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->inmux.instance[i].hal.pin.enc0_count), hm2->llio->comp_id); + for (unsigned j = 0; j < inst->scanwidth; j++) { + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.filt_data[j]), + 0, "%s.inmux.%02d.input-%02u", hm2->llio->name, i, j); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.inmux.%02d.input-%02u', aborting\n", r, hm2->llio->name, i, j); goto fail1; } - - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc1-count", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->inmux.instance[i].hal.pin.enc1_count), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.raw_data[j]), + 0, "%s.inmux.%02d.raw-input-%02u", hm2->llio->name, i, j); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.inmux.%02d.raw-input-%02u', aborting\n", r, hm2->llio->name, i, j); goto fail1; } - - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc2-count", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->inmux.instance[i].hal.pin.enc2_count), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.filt_data_not[j]), + 0, "%s.inmux.%02d.input-%02u-not", hm2->llio->name, i, j); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.inmux.%02d.input-%02u-not', aborting\n", r, hm2->llio->name, i, j); goto fail1; } - - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc3-count", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->inmux.instance[i].hal.pin.enc3_count), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.raw_data_not[j]), + 0, "%s.inmux.%02d.raw-input-%02u-not", hm2->llio->name, i, j); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.inmux.%02d.raw-input-%02u-not', aborting\n", r, hm2->llio->name, i, j); goto fail1; } - - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc0-reset", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->inmux.instance[i].hal.pin.enc0_reset), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(inst->hal.pin.slow[j]), + 0, "%s.inmux.%02d.input-%02u-slow", hm2->llio->name, i, j); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.inmux.%02d.input-%02u-slow', aborting\n", r, hm2->llio->name, i, j); goto fail1; } + } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc1-reset", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->inmux.instance[i].hal.pin.enc1_reset), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.enc0_count), + 0, "%s.inmux.%02d.enc0-count", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inmux.%02d.enc0-count', aborting\n", r, hm2->llio->name, i); + goto fail1; + } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc2-reset", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->inmux.instance[i].hal.pin.enc2_reset), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.enc1_count), + 0, "%s.inmux.%02d.enc1-count", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inmux.%02d.enc1-count', aborting\n", r, hm2->llio->name, i); + goto fail1; + } - rtapi_snprintf(name, sizeof(name), "%s.inmux.%02d.enc3-reset", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->inmux.instance[i].hal.pin.enc3_reset), hm2->llio->comp_id); - if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; - goto fail1; - } + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.enc2_count), + 0, "%s.inmux.%02d.enc2-count", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inmux.%02d.enc2-count', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(inst->hal.pin.enc3_count), + 0, "%s.inmux.%02d.enc3-count", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inmux.%02d.enc3-count', aborting\n", r, hm2->llio->name, i); + goto fail1; } - } + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(inst->hal.pin.enc0_reset), + 0, "%s.inmux.%02d.enc0-reset", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inmux.%02d.enc0-reset', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(inst->hal.pin.enc1_reset), + 0, "%s.inmux.%02d.enc1-reset", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inmux.%02d.enc1-reset', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(inst->hal.pin.enc2_reset), + 0, "%s.inmux.%02d.enc2-reset", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inmux.%02d.enc2-reset', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(inst->hal.pin.enc3_reset), + 0, "%s.inmux.%02d.enc3-reset", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.inmux.%02d.enc3-reset', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + } } // // Set inmux default scanrate and filter values // and remove initial MPG offset - { - int i; - int rawmpgs; - for (i = 0; i < hm2->inmux.num_instances; i ++) { - hm2->inmux.instance[i].hal.param.scan_rate = 20000; // 20 KHz = 50 usec/scan - hm2->inmux.instance[i].hal.param.slow_scans = 500; // 500*50 usec = 25 ms - hm2->inmux.instance[i].hal.param.fast_scans = 5; // 5*50 usec = 250 usec - hm2->llio->read(hm2->llio,hm2->inmux.mpg_read_addr + (i * md->instance_stride),&rawmpgs, sizeof(rtapi_u32)); - hm2->inmux.instance[i].prev_enc0_count = (rtapi_s32)((rawmpgs >> 0) & 0x000000FF); - hm2->inmux.instance[i].prev_enc1_count = (rtapi_s32)((rawmpgs >> 8) & 0x000000FF); - hm2->inmux.instance[i].prev_enc2_count = (rtapi_s32)((rawmpgs >> 16) & 0x000000FF); - hm2->inmux.instance[i].prev_enc3_count = (rtapi_s32)((rawmpgs >> 24) & 0x000000FF); - - } - + for (int i = 0; i < hm2->inmux.num_instances; i ++) { + rtapi_u32 rawmpgs; + hm2->llio->read(hm2->llio,hm2->inmux.mpg_read_addr + (i * md->instance_stride), &rawmpgs, sizeof(rtapi_u32)); + hm2->inmux.instance[i].prev_enc0_count = (rtapi_s32)((rawmpgs >> 0) & 0x000000FF); + hm2->inmux.instance[i].prev_enc1_count = (rtapi_s32)((rawmpgs >> 8) & 0x000000FF); + hm2->inmux.instance[i].prev_enc2_count = (rtapi_s32)((rawmpgs >> 16) & 0x000000FF); + hm2->inmux.instance[i].prev_enc3_count = (rtapi_s32)((rawmpgs >> 24) & 0x000000FF); } return hm2->inmux.num_instances; @@ -373,24 +342,24 @@ void hm2_inmux_force_write(hostmot2_t *hm2) { // setup control register and mpg_write for (i = 0; i < hm2->inmux.num_instances; i ++) { - muxrate = hm2->inmux.instance[i].scanwidth * hm2->inmux.instance[i].hal.param.scan_rate; + hm2_inmux_instance_t *inst = &hm2->inmux.instance[i]; + muxrate = inst->scanwidth * hal_get_ui32(inst->hal.param.scan_rate); if (muxrate > 5000000) { muxrate = 5000000; - hm2->inmux.instance[i].hal.param.scan_rate = muxrate/hm2->inmux.instance[i].scanwidth; + hal_set_ui32(inst->hal.param.scan_rate, muxrate/inst->scanwidth); } divisor = (hm2->inmux.clock_frequency / (4 * muxrate)) - 1; - if (hm2->inmux.instance[i].hal.param.fast_scans > 63) { - hm2->inmux.instance[i].hal.param.fast_scans = 63; + 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); } - if (hm2->inmux.instance[i].hal.param.slow_scans > 1023) { - hm2->inmux.instance[i].hal.param.slow_scans = 1023; + rtapi_u32 slow_scans = hal_get_ui32(inst->hal.param.slow_scans); + if (slow_scans > 1023) { + slow_scans = hal_set_ui32(inst->hal.param.slow_scans, 1023); } - hm2->inmux.control_reg[i] = (1 << 5) + -// global invert bit(5) fixed to true for now as this matches all existing hardware - (divisor << 6) + - (hm2->inmux.instance[i].hal.param.fast_scans << 16) + - (hm2->inmux.instance[i].hal.param.slow_scans << 22); + // global invert bit(5) fixed to true for now as this matches all existing hardware + hm2->inmux.control_reg[i] = (1 << 5) + (divisor << 6) + (fast_scans << 16) + (slow_scans << 22); } size = hm2->inmux.num_instances * sizeof(rtapi_u32); @@ -404,7 +373,6 @@ void hm2_inmux_force_write(hostmot2_t *hm2) { for (i = 0; i < hm2->inmux.num_instances; i ++) { hm2->inmux.instance[i].written_control_reg = hm2->inmux.control_reg[i]; hm2->inmux.instance[i].written_mpg_mode_reg = hm2->inmux.mpg_mode_reg[i]; - } } @@ -418,66 +386,66 @@ void hm2_inmux_write(hostmot2_t *hm2) { for (i = 0; i < hm2->inmux.num_instances; i ++) { - muxrate = hm2->inmux.instance[i].scanwidth * hm2->inmux.instance[i].hal.param.scan_rate; + hm2_inmux_instance_t *inst = &hm2->inmux.instance[i]; + muxrate = inst->scanwidth * hal_get_ui32(inst->hal.param.scan_rate); // bound muxrate maximum frequency if (muxrate > 5000000) { muxrate = 5000000; - hm2->inmux.instance[i].hal.param.scan_rate = muxrate/hm2->inmux.instance[i].scanwidth; - HM2_ERR("InMux %d scanrate too high, resetting to %d \n", i,hm2->inmux.instance[i].hal.param.scan_rate); + 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 )) { divisor = 1023; - hm2->inmux.instance[i].hal.param.scan_rate = (hm2->inmux.clock_frequency/4)/(divisor +1) - /hm2->inmux.instance[i].scanwidth; - HM2_ERR("InMux %d scanrate too low, resetting to %d \n", i,hm2->inmux.instance[i].hal.param.scan_rate); + hal_set_ui32(inst->hal.param.scan_rate, + (hm2->inmux.clock_frequency/4) / (divisor +1) / inst->scanwidth); + HM2_ERR("InMux %d scanrate too low, resetting to %d \n", i, hal_get_ui32(inst->hal.param.scan_rate)); } - if (hm2->inmux.instance[i].hal.param.fast_scans > 63) { - hm2->inmux.instance[i].hal.param.fast_scans = 63; + 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); HM2_ERR("InMux %d fastscans must be less than 63, resetting to %d \n", i,63); } - if (hm2->inmux.instance[i].hal.param.slow_scans > 1023) { - hm2->inmux.instance[i].hal.param.slow_scans = 1023; + rtapi_u32 slow_scans = hal_get_ui32(inst->hal.param.slow_scans); + if (slow_scans > 1023) { + slow_scans = hal_set_ui32(inst->hal.param.slow_scans, 1023); HM2_ERR("InMux %d slowscans must be less than 1023, resetting to %d \n", i,1023); } - if (hm2->inmux.instance[i].hal.param.fast_scans < 1 ) { - hm2->inmux.instance[i].hal.param.fast_scans = 1; + if (fast_scans < 1 ) { + fast_scans = hal_set_ui32(inst->hal.param.fast_scans, 1); HM2_ERR("InMux %d fastscans must be greater than 0, resetting to %d \n", i,1); } - if (hm2->inmux.instance[i].hal.param.slow_scans < 1) { - hm2->inmux.instance[i].hal.param.slow_scans = 1; + if (slow_scans < 1) { + slow_scans = hal_set_ui32(inst->hal.param.slow_scans, 1); HM2_ERR("InMux %d slowscans must be greater than 0, resetting to %d \n", i,1); } - hm2->inmux.control_reg[i] = (1 << 5) + -// global invert bit(5) fixed to true for now as this matches all existing hardware) - (divisor << 6) + - (hm2->inmux.instance[i].hal.param.fast_scans << 16) + - (hm2->inmux.instance[i].hal.param.slow_scans << 22); - if (hm2->inmux.control_reg[i] != hm2->inmux.instance[i].written_control_reg) { + // global invert bit(5) fixed to true for now as this matches all existing hardware) + hm2->inmux.control_reg[i] = (1 << 5) + (divisor << 6) + (fast_scans << 16) + (slow_scans << 22); + if (hm2->inmux.control_reg[i] != inst->written_control_reg) { hm2->llio->write(hm2->llio, hm2->inmux.control_addr, hm2->inmux.control_reg, size); - hm2->inmux.instance[i].written_control_reg = hm2->inmux.control_reg[i]; + inst->written_control_reg = hm2->inmux.control_reg[i]; // HM2_PRINT(" Debug: updating inmux control reg to = 0x%08X\n", hm2->inmux.control_reg[i]); } hm2->inmux.filter_reg[i] = 0; - for (unsigned j = 0; j < hm2->inmux.instance[i].scanwidth; j ++) { - hm2->inmux.filter_reg[i] |= (*hm2->inmux.instance[i].hal.pin.slow[j] << j); + for (unsigned j = 0; j < inst->scanwidth; j ++) { + hm2->inmux.filter_reg[i] |= (hal_get_bool(inst->hal.pin.slow[j]) << j); } - if (hm2->inmux.filter_reg[i] != hm2->inmux.instance[i].written_filter_reg) { + if (hm2->inmux.filter_reg[i] != inst->written_filter_reg) { hm2->llio->write(hm2->llio, hm2->inmux.filter_addr, hm2->inmux.filter_reg, size); - hm2->inmux.instance[i].written_filter_reg = hm2->inmux.filter_reg[i]; + inst->written_filter_reg = hm2->inmux.filter_reg[i]; // HM2_PRINT(" Debug: updating inmux filter reg to = 0x%08X\n", hm2->inmux.filter_reg[i]); } hm2->inmux.mpg_mode_reg[i] = - hm2->inmux.instance[i].hal.param.enc0_mode << 0 | - hm2->inmux.instance[i].hal.param.enc1_mode << 8 | - hm2->inmux.instance[i].hal.param.enc2_mode << 16 | - hm2->inmux.instance[i].hal.param.enc3_mode << 24; - if (hm2->inmux.mpg_mode_reg[i] != hm2->inmux.instance[i].written_mpg_mode_reg) { + hal_get_bool(inst->hal.param.enc0_mode) << 0 | + hal_get_bool(inst->hal.param.enc1_mode) << 8 | + hal_get_bool(inst->hal.param.enc2_mode) << 16 | + hal_get_bool(inst->hal.param.enc3_mode) << 24; + if (hm2->inmux.mpg_mode_reg[i] != inst->written_mpg_mode_reg) { hm2->llio->write(hm2->llio, hm2->inmux.mpg_mode_addr, hm2->inmux.mpg_mode_reg, size); - hm2->inmux.instance[i].written_mpg_mode_reg = hm2->inmux.mpg_mode_reg[i]; + inst->written_mpg_mode_reg = hm2->inmux.mpg_mode_reg[i]; // HM2_PRINT(" Debug: updating inmux mpg mode reg to = 0x%08X\n", hm2->inmux.mpg_mode_reg[i]); } } @@ -491,7 +459,7 @@ void hm2_inmux_prepare_tram_write(hostmot2_t *hm2) { for (i = 0; i < hm2->inmux.num_instances; i ++) { hm2->inmux.filter_reg[i] = 0; for (unsigned j = 0; j < hm2->inmux.instance[i].scanwidth; j ++) { - hm2->inmux.filter_reg[i] |= (*hm2->inmux.instance[i].hal.pin.slow[j] << j); + hm2->inmux.filter_reg[i] |= (hal_get_bool(hm2->inmux.instance[i].hal.pin.slow[j]) << j); } } } @@ -505,45 +473,54 @@ void hm2_inmux_process_tram_read(hostmot2_t *hm2) { return; } for (i = 0; i < hm2->inmux.num_instances; i ++) { - for (unsigned j = 0; j < hm2->inmux.instance[i].scanwidth; j ++) { - *hm2->inmux.instance[i].hal.pin.filt_data[j] = (hm2->inmux.filt_data_reg[i] >> j) &1; - *hm2->inmux.instance[i].hal.pin.raw_data[j] = (hm2->inmux.raw_data_reg[i] >> j) &1; - *hm2->inmux.instance[i].hal.pin.filt_data_not[j] = !((hm2->inmux.filt_data_reg[i] >> j) &1); - *hm2->inmux.instance[i].hal.pin.raw_data_not[j] = !((hm2->inmux.raw_data_reg[i] >> j) &1); + hm2_inmux_instance_t *inst = &hm2->inmux.instance[i]; + for (unsigned j = 0; j < inst->scanwidth; j ++) { + hal_set_bool(inst->hal.pin.filt_data[j], (hm2->inmux.filt_data_reg[i] >> j) & 1); + hal_set_bool(inst->hal.pin.raw_data[j], (hm2->inmux.raw_data_reg[i] >> j) & 1); + hal_set_bool(inst->hal.pin.filt_data_not[j], !((hm2->inmux.filt_data_reg[i] >> j) & 1)); + hal_set_bool(inst->hal.pin.raw_data_not[j], !((hm2->inmux.raw_data_reg[i] >> j) & 1)); } - raw_count = hm2->inmux.mpg_read_reg[i] & 0x000000FF; - count_diff = (rtapi_s32)raw_count - hm2->inmux.instance[i].prev_enc0_count; - hm2->inmux.instance[i].prev_enc0_count = hm2->inmux.instance[i].prev_enc0_count + count_diff; + raw_count = hm2->inmux.mpg_read_reg[i] & 0x000000FF; + count_diff = (rtapi_s32)raw_count - inst->prev_enc0_count; + inst->prev_enc0_count = inst->prev_enc0_count + count_diff; if (count_diff > 128) count_diff -= 256; if (count_diff < -128) count_diff += 256; - if (*hm2->inmux.instance[i].hal.pin.enc0_reset == 0) { - *hm2->inmux.instance[i].hal.pin.enc0_count = *hm2->inmux.instance[i].hal.pin.enc0_count + count_diff; - } else { *hm2->inmux.instance[i].hal.pin.enc0_count = 0;} - raw_count = (hm2->inmux.mpg_read_reg[i] >> 8) & 0x000000FF; - count_diff = (rtapi_s32)raw_count - hm2->inmux.instance[i].prev_enc1_count; - hm2->inmux.instance[i].prev_enc1_count = hm2->inmux.instance[i].prev_enc1_count + count_diff; + if (!hal_get_bool(inst->hal.pin.enc0_reset)) { + hal_set_si32(inst->hal.pin.enc0_count, hal_get_si32(inst->hal.pin.enc0_count) + count_diff); + } else { + hal_set_si32(inst->hal.pin.enc0_count, 0); + } + raw_count = (hm2->inmux.mpg_read_reg[i] >> 8) & 0x000000FF; + count_diff = (rtapi_s32)raw_count - inst->prev_enc1_count; + inst->prev_enc1_count = inst->prev_enc1_count + count_diff; if (count_diff > 128) count_diff -= 256; if (count_diff < -128) count_diff += 256; - if (*hm2->inmux.instance[i].hal.pin.enc1_reset == 0) { - *hm2->inmux.instance[i].hal.pin.enc1_count = *hm2->inmux.instance[i].hal.pin.enc1_count + count_diff; - } else { *hm2->inmux.instance[i].hal.pin.enc1_count = 0;} - raw_count = (hm2->inmux.mpg_read_reg[i] >> 16) & 0x000000FF; - count_diff = (rtapi_s32)raw_count - hm2->inmux.instance[i].prev_enc2_count; - hm2->inmux.instance[i].prev_enc2_count = hm2->inmux.instance[i].prev_enc2_count + count_diff; + if (!hal_get_bool(inst->hal.pin.enc1_reset)) { + hal_set_si32(inst->hal.pin.enc1_count, hal_get_si32(inst->hal.pin.enc1_count) + count_diff); + } else { + hal_set_si32(inst->hal.pin.enc1_count, 0); + } + raw_count = (hm2->inmux.mpg_read_reg[i] >> 16) & 0x000000FF; + count_diff = (rtapi_s32)raw_count - inst->prev_enc2_count; + inst->prev_enc2_count = inst->prev_enc2_count + count_diff; if (count_diff > 128) count_diff -= 256; if (count_diff < -128) count_diff += 256; - if (*hm2->inmux.instance[i].hal.pin.enc2_reset == 0) { - *hm2->inmux.instance[i].hal.pin.enc2_count = *hm2->inmux.instance[i].hal.pin.enc2_count + count_diff; - } else { *hm2->inmux.instance[i].hal.pin.enc2_count = 0;} - raw_count = (hm2->inmux.mpg_read_reg[i] >> 24) & 0x000000FF; - count_diff = (rtapi_s32)raw_count - hm2->inmux.instance[i].prev_enc3_count; - hm2->inmux.instance[i].prev_enc3_count = hm2->inmux.instance[i].prev_enc3_count + count_diff; + if (!hal_get_bool(inst->hal.pin.enc2_reset)) { + hal_set_si32(inst->hal.pin.enc2_count, hal_get_si32(inst->hal.pin.enc2_count) + count_diff); + } else { + hal_set_si32(inst->hal.pin.enc2_count, 0); + } + raw_count = (hm2->inmux.mpg_read_reg[i] >> 24) & 0x000000FF; + count_diff = (rtapi_s32)raw_count - inst->prev_enc3_count; + inst->prev_enc3_count = inst->prev_enc3_count + count_diff; if (count_diff > 128) count_diff -= 256; if (count_diff < -128) count_diff += 256; - if (*hm2->inmux.instance[i].hal.pin.enc3_reset == 0) { - *hm2->inmux.instance[i].hal.pin.enc3_count = *hm2->inmux.instance[i].hal.pin.enc3_count + count_diff; - } else { *hm2->inmux.instance[i].hal.pin.enc3_count = 0;} + if (!hal_get_bool(inst->hal.pin.enc3_reset)) { + hal_set_si32(inst->hal.pin.enc3_count, hal_get_si32(inst->hal.pin.enc3_count) + count_diff); + } else { + hal_set_si32(inst->hal.pin.enc3_count, 0); + } } } diff --git a/src/hal/drivers/mesa-hostmot2/ioport.c b/src/hal/drivers/mesa-hostmot2/ioport.c index 4cb43c90c57..4ed2428d12c 100644 --- a/src/hal/drivers/mesa-hostmot2/ioport.c +++ b/src/hal/drivers/mesa-hostmot2/ioport.c @@ -246,7 +246,7 @@ int hm2_ioport_gpio_export_hal(hostmot2_t *hm2) { for (i = 0; i < hm2->num_pins; i ++) { // all pins get *some* gpio HAL presence - hm2->pin[i].instance = (hm2_gpio_instance_t *)hal_malloc(sizeof(hm2_gpio_instance_t)); + hm2->pin[i].instance = hal_malloc(sizeof(*hm2->pin[i].instance)); if (hm2->pin[i].instance == NULL) { HM2_ERR("out of memory!\n"); return -ENOMEM; @@ -259,29 +259,17 @@ int hm2_ioport_gpio_export_hal(hostmot2_t *hm2) { // // pins - r = hal_pin_bit_newf( - HAL_OUT, - &(hm2->pin[i].instance->hal.pin.in), - hm2->llio->comp_id, - "%s.gpio.%03d.in", - hm2->llio->name, - i - ); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->pin[i].instance->hal.pin.in), + 0, "%s.gpio.%03d.in", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error %d adding gpio pin, aborting\n", r); + HM2_ERR("error %d adding pin '%s.gpio.%03d.in', aborting\n", r, hm2->llio->name, i); return -EINVAL; } - r = hal_pin_bit_newf( - HAL_OUT, - &(hm2->pin[i].instance->hal.pin.in_not), - hm2->llio->comp_id, - "%s.gpio.%03d.in_not", - hm2->llio->name, - i - ); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->pin[i].instance->hal.pin.in_not), + 0, "%s.gpio.%03d.in_not", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error %d adding gpio pin, aborting\n", r); + HM2_ERR("error %d adding pin '%s.gpio.%03d.in_not', aborting\n", r, hm2->llio->name, i); return -EINVAL; } @@ -295,34 +283,31 @@ int hm2_ioport_gpio_export_hal(hostmot2_t *hm2) { || (hm2->pin[i].direction_at_start == HM2_PIN_DIR_IS_OUTPUT) ) { - r = hal_param_bit_newf( - HAL_RW, - &(hm2->pin[i].instance->hal.param.invert_output), - hm2->llio->comp_id, - "%s.gpio.%03d.invert_output", - hm2->llio->name, - i - ); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->pin[i].instance->hal.param.invert_output), + 0, "%s.gpio.%03d.invert_output", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error %d adding gpio param, aborting\n", r); + HM2_ERR("error %d adding param '%s.gpio.%03d.invert_output', aborting\n", r, hm2->llio->name, i); return -EINVAL; } - r = hal_param_bit_newf( - HAL_RW, - &(hm2->pin[i].instance->hal.param.is_opendrain), - hm2->llio->comp_id, - "%s.gpio.%03d.is_opendrain", - hm2->llio->name, - i - ); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->pin[i].instance->hal.param.is_opendrain), + 0, "%s.gpio.%03d.is_opendrain", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error %d adding gpio param, aborting\n", r); + HM2_ERR("error %d adding param '%s.gpio.%03d.is_opendrain', aborting\n", r, hm2->llio->name, i); + return -EINVAL; + } + } else { + // Parameters allocated in conditional, make sure their memory is available + r = hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(hm2->pin[i].instance->hal.param.invert_output)); + if (r < 0) { + HM2_ERR("error %d allocating fake param '%s.gpio.%03d.invert_output', aborting\n", r, hm2->llio->name, i); + return -EINVAL; + } + r = hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(hm2->pin[i].instance->hal.param.is_opendrain)); + if (r < 0) { + HM2_ERR("error %d allocating fake param '%s.gpio.%03d.is_opendrain', aborting\n", r, hm2->llio->name, i); return -EINVAL; } - - hm2->pin[i].instance->hal.param.invert_output = 0; - hm2->pin[i].instance->hal.param.is_opendrain = 0; } @@ -332,36 +317,27 @@ int hm2_ioport_gpio_export_hal(hostmot2_t *hm2) { if (hm2->pin[i].gtag == HM2_GTAG_IOPORT) { - r = hal_pin_bit_newf( - HAL_IN, - &(hm2->pin[i].instance->hal.pin.out), - hm2->llio->comp_id, - "%s.gpio.%03d.out", - hm2->llio->name, - i - ); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->pin[i].instance->hal.pin.out), + 0, "%s.gpio.%03d.out", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error %d adding gpio pin, aborting\n", r); + HM2_ERR("error %d adding pin '%s.gpio.%03d.out', aborting\n", r, hm2->llio->name, i); return -EINVAL; } - *(hm2->pin[i].instance->hal.pin.out) = 0; - // parameters - r = hal_param_bit_newf( - HAL_RW, - &(hm2->pin[i].instance->hal.param.is_output), - hm2->llio->comp_id, - "%s.gpio.%03d.is_output", - hm2->llio->name, - i - ); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->pin[i].instance->hal.param.is_output), + 0, "%s.gpio.%03d.is_output", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error %d adding gpio param, aborting\n", r); + HM2_ERR("error %d adding param '%s.gpio.%03d.is_output', aborting\n", r, hm2->llio->name, i); + return -EINVAL; + } + } else { + // Parameter allocated in conditional, make sure its memory is available + r = hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(hm2->pin[i].instance->hal.param.is_output)); + if (r < 0) { + HM2_ERR("error %d allocating fake param '%s.gpio.%03d.is_output', aborting\n", r, hm2->llio->name, i); return -EINVAL; } - - hm2->pin[i].instance->hal.param.is_output = 0; } // it's an output of some other module @@ -492,7 +468,7 @@ void hm2_ioport_update(hostmot2_t *hm2) { int io_pin = (port * hm2->idrom.port_width) + port_pin; if (hm2->pin[io_pin].gtag == HM2_GTAG_IOPORT) { - if (hm2->pin[io_pin].instance->hal.param.is_output) { + if (hal_get_bool(hm2->pin[io_pin].instance->hal.param.is_output)) { hm2->pin[io_pin].direction = HM2_PIN_DIR_IS_OUTPUT; } else { hm2->pin[io_pin].direction = HM2_PIN_DIR_IS_INPUT; @@ -503,14 +479,14 @@ void hm2_ioport_update(hostmot2_t *hm2) { hm2->ioport.ddr_reg[port] |= (1 << port_pin); // set the bit in the ddr register // Open Drain Register - if (hm2->pin[io_pin].instance->hal.param.is_opendrain) { + if (hal_get_bool(hm2->pin[io_pin].instance->hal.param.is_opendrain)) { hm2->ioport.open_drain_reg[port] |= (1 << port_pin); // set the bit in the open drain register } else { hm2->ioport.open_drain_reg[port] &= ~(1 << port_pin); // clear the bit in the open drain register } // Invert Output Register - if (hm2->pin[io_pin].instance->hal.param.invert_output) { + if (hal_get_bool(hm2->pin[io_pin].instance->hal.param.invert_output)) { hm2->ioport.output_invert_reg[port] |= (1 << port_pin); // set the bit in the output invert register } else { hm2->ioport.output_invert_reg[port] &= ~(1 << port_pin); // clear the bit in the output invert register @@ -598,11 +574,9 @@ void hm2_ioport_gpio_process_tram_read(hostmot2_t *hm2) { for (port = 0; port < hm2->ioport.num_instances; port ++) { for (unsigned port_pin = 0; port_pin < hm2->idrom.port_width; port_pin ++) { int io_pin = (port * hm2->idrom.port_width) + port_pin; - hal_bit_t bit; - - bit = (hm2->ioport.data_read_reg[port] >> port_pin) & 0x1; - *hm2->pin[io_pin].instance->hal.pin.in = bit; - *hm2->pin[io_pin].instance->hal.pin.in_not = !bit; + rtapi_bool bit = (hm2->ioport.data_read_reg[port] >> port_pin) & 0x1; + hal_set_bool(hm2->pin[io_pin].instance->hal.pin.in, bit); + hal_set_bool(hm2->pin[io_pin].instance->hal.pin.in_not, !bit); } } } @@ -629,7 +603,7 @@ void hm2_ioport_gpio_prepare_tram_write(hostmot2_t *hm2) { if (hm2->pin[io_pin].gtag != HM2_GTAG_IOPORT) continue; hm2->ioport.data_write_reg[port] &= ~(1 << port_pin); // zero the bit - if(*(hm2->pin[io_pin].instance->hal.pin.out)) + if(hal_get_bool(hm2->pin[io_pin].instance->hal.pin.out)) hm2->ioport.data_write_reg[port] |= (1 << port_pin); // and set if appropriate } } @@ -654,13 +628,12 @@ void hm2_ioport_gpio_read(hostmot2_t *hm2) { for (port = 0; port < hm2->ioport.num_instances; port ++) { for (unsigned port_pin = 0; port_pin < hm2->idrom.port_width; port_pin ++) { int io_pin = (port * hm2->idrom.port_width) + port_pin; - hal_bit_t bit; if (hm2->pin[io_pin].direction != HM2_PIN_DIR_IS_INPUT) continue; - bit = (hm2->ioport.data_read_reg[port] >> port_pin) & 0x1; - *hm2->pin[io_pin].instance->hal.pin.in = bit; - *hm2->pin[io_pin].instance->hal.pin.in_not = !bit; + rtapi_bool bit = (hm2->ioport.data_read_reg[port] >> port_pin) & 0x1; + hal_set_bool(hm2->pin[io_pin].instance->hal.pin.in, bit); + hal_set_bool(hm2->pin[io_pin].instance->hal.pin.in_not, !bit); } } } @@ -682,7 +655,7 @@ void hm2_ioport_gpio_write(hostmot2_t *hm2) { if (hm2->pin[io_pin].gtag != HM2_GTAG_IOPORT) continue; hm2->ioport.data_write_reg[port] &= ~(1 << port_pin); // zero the bit - hm2->ioport.data_write_reg[port] |= (*(hm2->pin[io_pin].instance->hal.pin.out) << port_pin); // and set it as appropriate + hm2->ioport.data_write_reg[port] |= (hal_get_bool(hm2->pin[io_pin].instance->hal.pin.out) << port_pin); // and set it as appropriate } } diff --git a/src/hal/drivers/mesa-hostmot2/led.c b/src/hal/drivers/mesa-hostmot2/led.c index 48bbf661f83..e4866f7b79a 100644 --- a/src/hal/drivers/mesa-hostmot2/led.c +++ b/src/hal/drivers/mesa-hostmot2/led.c @@ -64,7 +64,7 @@ int hm2_led_parse_md(hostmot2_t *hm2, int md_index) { // allocate the module-global HAL shared memory - hm2->led.instance = (hm2_led_instance_t *)hal_malloc(hm2->config.num_leds * sizeof(hm2_led_instance_t)); + hm2->led.instance = hal_malloc(hm2->config.num_leds * sizeof(*hm2->led.instance)); if (hm2->led.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -84,13 +84,11 @@ int hm2_led_parse_md(hostmot2_t *hm2, int md_index) { // export to HAL { - int i; - char name[HAL_NAME_LEN+1]; - for (i = 0 ; i < hm2->config.num_leds ; i++) { - rtapi_snprintf(name, sizeof(name), "%s.led.CR%02d", hm2->llio->name, i + 1 ); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->led.instance[i].led), hm2->llio->comp_id); + for (int i = 0 ; i < hm2->config.num_leds ; i++) { + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->led.instance[i].led), + 0, "%s.led.CR%02d", hm2->llio->name, i + 1); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.led.CR%02d', aborting\n", r, hm2->llio->name, i + 1); goto fail1; } } @@ -111,7 +109,7 @@ void hm2_led_write(hostmot2_t *hm2) { int i; for (i = 0 ; i < hm2->config.num_leds; i++ ) { - if (*hm2->led.instance[i].led) { + if (hal_get_bool(hm2->led.instance[i].led)) { regval |= 1 << (31 - i); } } diff --git a/src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.c.tmpl b/src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.c.tmpl index 146adfd7e1d..e8c0e72865b 100644 --- a/src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.c.tmpl +++ b/src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.c.tmpl @@ -114,19 +114,19 @@ enum { }; typedef struct { - hal_data_u **pins; - hal_float_t **scale; - hal_data_u **pin2; + hal_refs_u *pins; + hal_real_t *scale; + hal_refs_u *pin2; rtapi_s64 *buff; - hal_bit_t *fault; - hal_u32_t *last_err; - hal_s32_t address; - hal_s32_t baudrate; - hal_s32_t parity; - hal_s32_t txdelay; - hal_s32_t rxdelay; - hal_s32_t drive_delay; - hal_float_t rate; + hal_bool_t fault; + hal_uint_t last_err; + hal_sint_t address; + hal_sint_t baudrate; + hal_sint_t parity; + hal_sint_t txdelay; + hal_sint_t rxdelay; + hal_sint_t drive_delay; + hal_real_t rate; } hm2_modbus_hal_t; typedef struct { @@ -219,12 +219,12 @@ int rtapi_app_main(void){ inst->num_pins += channels[c].count; } // Malloc structs and pins, some in main or kernel memory, some in HAL - inst->chans = (hm2_modbus_channel_t *)rtapi_kmalloc(inst->num_chans * sizeof(hm2_modbus_channel_t), RTAPI_GFP_KERNEL); - inst->hal = (hm2_modbus_hal_t *) hal_malloc(sizeof(hm2_modbus_hal_t)); - inst->hal->pins = (hal_data_u **) hal_malloc(inst->num_pins * sizeof(hal_data_u)); - inst->hal->scale = (hal_float_t **)hal_malloc(inst->num_pins * sizeof(hal_float_t)); - inst->hal->pin2 = (hal_data_u **) hal_malloc(inst->num_pins * sizeof(hal_data_u)); - inst->hal->buff = (rtapi_s64 *) hal_malloc(inst->num_pins * sizeof(rtapi_s64)); + inst->chans = (hm2_modbus_channel_t *)rtapi_kmalloc(inst->num_chans * sizeof(*inst->chans), RTAPI_GFP_KERNEL); + inst->hal = hal_malloc(sizeof(*inst->hal)); + inst->hal->pins = hal_malloc(inst->num_pins * sizeof(*inst->hal->pins)); + inst->hal->scale = hal_malloc(inst->num_pins * sizeof(*inst->hal->scale)); + inst->hal->pin2 = hal_malloc(inst->num_pins * sizeof(*inst->hal->pin2)); + inst->hal->buff = hal_malloc(inst->num_pins * sizeof(*inst->hal->buff)); rtapi_strlcpy(inst->port, ports[i], HAL_NAME_LEN); @@ -234,29 +234,20 @@ int rtapi_app_main(void){ goto fail0; } - retval = hal_param_s32_newf(HAL_RW, &(inst->hal->address), comp_id, COMP_NAME".%02i.address", i); - retval += hal_param_s32_newf(HAL_RW, &(inst->hal->baudrate), comp_id, COMP_NAME".%02i.baudrate", i); - retval += hal_param_s32_newf(HAL_RW, &(inst->hal->parity), comp_id, COMP_NAME".%02i.parity", i); - retval += hal_param_s32_newf(HAL_RW, &(inst->hal->txdelay), comp_id, COMP_NAME".%02i.txdelay", i); - retval += hal_param_s32_newf(HAL_RW, &(inst->hal->rxdelay), comp_id, COMP_NAME".%02i.rxdelay", i); - retval += hal_param_s32_newf(HAL_RW, &(inst->hal->drive_delay), comp_id, COMP_NAME".%02i.drive-delay", i); - retval += hal_param_float_newf(HAL_RW, &(inst->hal->rate), comp_id, COMP_NAME".%02i.update-hz", i); - retval += hal_pin_bit_newf(HAL_OUT, &(inst->hal->fault), comp_id, COMP_NAME".%02i.fault", i); - retval += hal_pin_u32_newf(HAL_OUT, &(inst->hal->last_err), comp_id, COMP_NAME".%02i.last-error", i); + retval = hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->address), 0x01, COMP_NAME".%02i.address", i); + retval += hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->baudrate), 9600, COMP_NAME".%02i.baudrate", i); + retval += hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->parity), 0, COMP_NAME".%02i.parity", i); + retval += hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->txdelay), 20, COMP_NAME".%02i.txdelay", i); + retval += hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->rxdelay), 15, COMP_NAME".%02i.rxdelay", i); + retval += hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->drive_delay), 0, COMP_NAME".%02i.drive-delay", i); + retval += hal_param_new_real(comp_id, HAL_RW, &(inst->hal->rate), 0.0, COMP_NAME".%02i.update-hz", i); + retval += hal_pin_new_bool(comp_id, HAL_OUT, &(inst->hal->fault), 0, COMP_NAME".%02i.fault", i); + retval += hal_pin_new_ui32(comp_id, HAL_OUT, &(inst->hal->last_err), 0, COMP_NAME".%02i.last-error", i); if (retval < 0) { rtapi_print_msg(RTAPI_MSG_ERR, COMP_NAME" ERROR: failed to create one or more pins/parameters\n"); goto fail0; } - inst->hal->address = 0x01; - inst->hal->baudrate = 9600; - inst->hal->parity = 0; - inst->hal->txdelay = 20; // should generally be larger than Rx Delay - inst->hal->rxdelay = 15; - inst->hal->drive_delay = 0; // delay between setting drive enable and sending data - *(inst->hal->fault) = 0; - *(inst->hal->last_err) = 0; - inst->state = START; do_setup(inst); @@ -295,15 +286,15 @@ int rtapi_app_main(void){ case 2: // read inputs if (ch->count > 1){ for (j = 0; j < ch->count; j++){ - retval = hal_pin_bit_newf(dir, - (hal_bit_t**)&(inst->hal->pins[p++]), - comp_id, COMP_NAME".%02i.%s-%02i", + retval = hal_pin_new_bool(comp_id, dir, + &(inst->hal->pins[p++].b), + 0, COMP_NAME".%02i.%s-%02i", i, channels[c].name, j); } } else { - retval = hal_pin_bit_newf(dir, - (hal_bit_t**)&(inst->hal->pins[p++]), - comp_id, COMP_NAME".%02i.%s", + retval = hal_pin_new_bool(comp_id, dir, + &(inst->hal->pins[p++].b), + 0, COMP_NAME".%02i.%s", i, channels[c].name); } break; @@ -331,79 +322,77 @@ int rtapi_app_main(void){ switch (ch->type){ case HAL_U32: if (ch->count > 1) { - retval = hal_pin_u32_newf(dir, - (hal_u32_t**)&(inst->hal->pins[p]), - comp_id, COMP_NAME".%02i.%s-%02i", + retval = hal_pin_new_ui32(comp_id, dir, + &(inst->hal->pins[p].u), + 0, COMP_NAME".%02i.%s-%02i", i, channels[c].name, j); } else { - retval = hal_pin_u32_newf(dir, - (hal_u32_t**)&(inst->hal->pins[p]), - comp_id, COMP_NAME".%02i.%s", + retval = hal_pin_new_ui32(comp_id, dir, + &(inst->hal->pins[p].u), + 0, COMP_NAME".%02i.%s", i, channels[c].name); } p++; break; case HAL_S32: if (ch->count > 1) { - retval = hal_pin_s32_newf(dir, - (hal_s32_t**)&(inst->hal->pins[p]), - comp_id, COMP_NAME".%02i.%s-%02i", + retval = hal_pin_new_si32(comp_id, dir, + &(inst->hal->pins[p].s), + 0, COMP_NAME".%02i.%s-%02i", i, channels[c].name, j); - retval = hal_pin_float_newf(HAL_IN, - (hal_float_t**)&(inst->hal->scale[p]), - comp_id, COMP_NAME".%02i.%s-%02i-scale", + retval = hal_pin_new_real(comp_id, HAL_IN, + &(inst->hal->scale[p]), + 1.0, COMP_NAME".%02i.%s-%02i-scale", i, channels[c].name, j); - retval = hal_pin_float_newf(dir, - (hal_float_t**)&(inst->hal->pin2[p]), - comp_id, COMP_NAME".%02i.%s-%02i-scaled", + retval = hal_pin_new_real(comp_id, dir, + &(inst->hal->pin2[p].r), + 0.0, COMP_NAME".%02i.%s-%02i-scaled", i, channels[c].name, j); } else { - retval = hal_pin_s32_newf(dir, - (hal_s32_t**)&(inst->hal->pins[p]), - comp_id, COMP_NAME".%02i.%s", + retval = hal_pin_new_si32(comp_id, dir, + &(inst->hal->pins[p].s), + 0, COMP_NAME".%02i.%s", i, channels[c].name); - retval = hal_pin_float_newf(HAL_IN, - (hal_float_t**)&(inst->hal->scale[p]), - comp_id, COMP_NAME".%02i.%s-scale", + retval = hal_pin_new_real(comp_id, HAL_IN, + &(inst->hal->scale[p]), + 1.0, COMP_NAME".%02i.%s-scale", i, channels[c].name); - retval = hal_pin_float_newf(dir, - (hal_float_t**)&(inst->hal->pin2[p]), - comp_id, COMP_NAME".%02i.%s-scaled", + retval = hal_pin_new_real(comp_id, dir, + &(inst->hal->pin2[p].r), + 0.0, COMP_NAME".%02i.%s-scaled", i, channels[c].name); } - *inst->hal->scale[p] = 1.0; inst->hal->buff[p] = 0; p++; break; case HAL_FLOAT: if (ch->count > 1) { - retval = hal_pin_float_newf(dir, - (hal_float_t**)&(inst->hal->pins[p]), - comp_id, COMP_NAME".%02i.%s-%02i", + retval = hal_pin_new_real(comp_id, dir, + &(inst->hal->pins[p].r), + 0.0, COMP_NAME".%02i.%s-%02i", i, channels[c].name, j); - retval = hal_pin_float_newf(HAL_IN, - (hal_float_t**)&(inst->hal->scale[p]), - comp_id, COMP_NAME".%02i.%s-%02i-scale", + retval = hal_pin_new_real(comp_id, HAL_IN, + &(inst->hal->scale[p]), + 1.0, COMP_NAME".%02i.%s-%02i-scale", i, channels[c].name, j); - retval = hal_pin_float_newf(HAL_IN, - (hal_float_t**)&(inst->hal->pin2[p]), - comp_id, COMP_NAME".%02i.%s-%02i-offset", + retval = hal_pin_new_real(comp_id, HAL_IN, + &(inst->hal->pin2[p].r), + 0.0, COMP_NAME".%02i.%s-%02i-offset", i, channels[c].name, j); } else { - retval = hal_pin_float_newf(dir, - (hal_float_t**)&(inst->hal->pins[p]), - comp_id, COMP_NAME".%02i.%s", + retval = hal_pin_new_real(comp_id, dir, + &(inst->hal->pins[p].r), + 0.0, COMP_NAME".%02i.%s", i, channels[c].name); - retval = hal_pin_float_newf(HAL_IN, - (hal_float_t**)&(inst->hal->scale[p]), - comp_id, COMP_NAME".%02i.%s-scale", + retval = hal_pin_new_real(comp_id, HAL_IN, + &(inst->hal->scale[p]), + 1.0, COMP_NAME".%02i.%s-scale", i, channels[c].name); - retval = hal_pin_float_newf(HAL_IN, - (hal_float_t**)&(inst->hal->pin2[p]), - comp_id, COMP_NAME".%02i.%s-offset", + retval = hal_pin_new_real(comp_id, HAL_IN, + &(inst->hal->pin2[p].r), + 0.0, COMP_NAME".%02i.%s-offset", i, channels[c].name); } - *(inst->hal->scale[p]) = 1; p++; break; default: @@ -435,19 +424,19 @@ static int do_setup(hm2_modbus_inst_t *inst){ int retval; - if (inst->baudrate == inst->hal->baudrate - && inst->parity == inst->hal->parity - && inst->txdelay == inst->hal->txdelay - && inst->rxdelay == inst->hal->rxdelay - && inst->drive_delay == inst->hal->drive_delay) return 0; - - if (inst->hal->txdelay > 0xFF) inst->hal->txdelay = 0xFF; - if (inst->hal->rxdelay > 0xFF) inst->hal->rxdelay = 0xFF; - inst->baudrate = inst->hal->baudrate; - inst->parity = inst->hal->parity; - inst->txdelay = inst->hal->txdelay; - inst->rxdelay = inst->hal->rxdelay; - inst->drive_delay = inst->hal->drive_delay; + if (inst->baudrate == hal_get_si32(inst->hal->baudrate) + && inst->parity == hal_get_si32(inst->hal->parity) + && inst->txdelay == hal_get_si32(inst->hal->txdelay) + && inst->rxdelay == hal_get_si32(inst->hal->rxdelay) + && inst->drive_delay == hal_get_si32(inst->hal->drive_delay)) return 0; + + if (hal_get_si32(inst->hal->txdelay) > 0xFF) hal_set_si32(inst->hal->txdelay, 0xFF); + if (hal_get_si32(inst->hal->rxdelay) > 0xFF) hal_set_si32(inst->hal->rxdelay, 0xFF); + inst->baudrate = hal_get_si32(inst->hal->baudrate); + inst->parity = hal_get_si32(inst->hal->parity); + inst->txdelay = hal_get_si32(inst->hal->txdelay); + inst->rxdelay = hal_get_si32(inst->hal->rxdelay); + inst->drive_delay = hal_get_si32(inst->hal->drive_delay); unsigned flg; flg = inst->parity != 0 ? HM2_PKTUART_CONFIG_PARITYEN : 0; @@ -508,8 +497,8 @@ static void do_timeout(hm2_modbus_inst_t *inst){ hm2_pktuart_reset(inst->port); inst->state = RESET_WAIT; inst->iter = 0; - *(inst->hal->last_err) = 11; - *(inst->hal->fault) = 1; + hal_set_ui32(inst->hal->last_err, 11); + hal_set_bool(inst->hal->fault, 1); inst->chans[inst->index].data[1] = 0xFF; // Write invalid data to force re-send } rtapi_print_msg(RTAPI_MSG_INFO, "%i timeout %i\r", inst->iter, inst->state); @@ -518,7 +507,7 @@ static void do_timeout(hm2_modbus_inst_t *inst){ static void process(void *arg, long period) { static long timer = 0; hm2_modbus_inst_t *inst = arg; - real_t rate; + rtapi_real rate; int r; rtapi_u32 rxstatus = hm2_pktuart_get_rx_status(inst->port); @@ -527,7 +516,7 @@ static void process(void *arg, long period) { switch (inst->state) { case START: - rate = inst->hal->rate; + rate = hal_get_real(inst->hal->rate); if (rate >= RATE_MIN && rate <= RATE_MAX && (timer -= period) > 0) break; rtapi_print_msg(RTAPI_MSG_INFO, "START txstatus = %08X rxstatus = %08X\n", txstatus, rxstatus); @@ -619,7 +608,7 @@ static void process(void *arg, long period) { rtapi_print_msg(RTAPI_MSG_INFO, "\r"); if (rxstatus & 0x200000) break; inst->state = START; - *(inst->hal->fault) = 0; + hal_set_bool(inst->hal->fault, 0); break; case RESET_WAIT: @@ -648,17 +637,17 @@ static int ch_append16(hm2_modbus_channel_t *ch, rtapi_u16 v){ return r; } -static int ch_init(hm2_modbus_channel_t *ch, hm2_modbus_hal_t hal){ +static int ch_init(hm2_modbus_channel_t *ch, hm2_modbus_hal_t *hal){ int r; ch->ptr = -1; - r = ch_append8(ch, hal.address); + r = ch_append8(ch, hal_get_si32(hal->address)); r = ch_append8(ch, ch->func); return r; } static int build_data_frame(hm2_modbus_inst_t *inst){ hm2_modbus_channel_t *ch = &(inst->chans[inst->index]); - hm2_modbus_hal_t hal = *inst->hal; + hm2_modbus_hal_t *hal = inst->hal; rtapi_u8 acc = 0; int r = 0; int p = ch->start_pin; @@ -679,7 +668,7 @@ static int build_data_frame(hm2_modbus_inst_t *inst){ break; case 5: // Write single coil r += ch_append16(ch, ch->addr); - if (hal.pins[p]->b){ + if (hal_get_bool(hal->pins[p].b)){ r += ch_append16(ch, 0xFF00); } else { r += ch_append16(ch, 0x0000); @@ -689,15 +678,15 @@ static int build_data_frame(hm2_modbus_inst_t *inst){ r += ch_append16(ch, ch->addr); switch (ch->type){ case HAL_U32: - r += ch_append16(ch, (rtapi_u16)hal.pins[p]->u); + r += ch_append16(ch, (rtapi_u16)hal_get_ui32(hal->pins[p].u)); break; case HAL_S32: - r += ch_append16(ch, (rtapi_s16)hal.pins[p]->s); + r += ch_append16(ch, (rtapi_s16)hal_get_si32(hal->pins[p].s)); break; case HAL_FLOAT: - rtapi_print_msg(RTAPI_MSG_INFO, "671 %f %f %f \n", hal.pins[p]->f, hal.pin2[p]->f, *hal.scale[p]); - if (*hal.scale[p] <= -EPSILON || *hal.scale[p] >= +EPSILON){ - r+= ch_append16(ch, (rtapi_u16)((hal.pins[p]->f - hal.pin2[p]->f) / *hal.scale[p])) ; + rtapi_print_msg(RTAPI_MSG_INFO, "671 %f %f %f \n", hal_get_real(hal->pins[p].r), hal_get_real(hal->pin2[p].r), hal_get_real(hal->scale[p])); + if (hal_get_real(hal->scale[p]) <= -EPSILON || hal_get_real(hal->scale[p]) >= +EPSILON){ + r+= ch_append16(ch, (rtapi_u16)((hal_get_real(hal->pins[p].r) - hal_get_real(hal->pin2[p].r)) / hal_get_real(hal->scale[p]))) ; } rtapi_print_msg(RTAPI_MSG_INFO, "678\n"); break; @@ -710,7 +699,7 @@ static int build_data_frame(hm2_modbus_inst_t *inst){ r += ch_append16(ch, ch->count); r += ch_append8(ch, ( ch->count + 8 - 1) / 8); for (i = 0; i < ch->count; i++){ - if (hal.pins[p++]->b) acc += 1 << (i % 8); + if (hal_get_bool(hal->pins[p++].b)) acc += 1 << (i % 8); if (i % 8 == 7 || i == (ch->count -1)) { // time for the next byte r += ch_append8(ch, acc); acc = 0; @@ -724,17 +713,17 @@ static int build_data_frame(hm2_modbus_inst_t *inst){ for (i = 0; i < ch->count; i++){ switch (ch->type){ case HAL_U32: - r += ch_append16(ch, (rtapi_u16)hal.pins[p]->u); + r += ch_append16(ch, (rtapi_u16)hal_get_ui32(hal->pins[p].u)); break; case HAL_S32: - r += ch_append16(ch, (rtapi_s16)hal.pins[p]->s); + r += ch_append16(ch, (rtapi_s16)hal_get_si32(hal->pins[p].s)); break; case HAL_FLOAT: - if (*hal.scale[p] <= -EPSILON || *hal.scale[p] >= +EPSILON){ - r+= ch_append16(ch, (rtapi_u16)((hal.pins[p]->f - hal.pin2[p]->f) / *hal.scale[p])) ; + if (hal_get_real(hal->scale[p]) <= -EPSILON || hal_get_real(hal->scale[p]) >= +EPSILON){ + r+= ch_append16(ch, (rtapi_u16)((hal_get_real(hal->pins[p].r) - hal_get_real(hal->pin2[p].r)) / hal_get_real(hal->scale[p]))) ; } else { // Prevent (near) divide-by-zero and assume scale 1.0 - r+= ch_append16(ch, (rtapi_u16)(hal.pins[p]->f - hal.pin2[p]->f)); + r+= ch_append16(ch, (rtapi_u16)(hal_get_real(hal->pins[p].r) - hal_get_real(hal->pin2[p].r))); } break; default: @@ -751,7 +740,7 @@ static int build_data_frame(hm2_modbus_inst_t *inst){ static int parse_data_frame(hm2_modbus_inst_t *inst){ hm2_modbus_channel_t *ch = &(inst->chans[inst->index]); - hm2_modbus_hal_t hal = *inst->hal; + hm2_modbus_hal_t *hal = inst->hal; rtapi_u32 *data = inst->rxdata; int count = inst->fsizes[inst->frame_index] & 0x3FF; int i; @@ -791,7 +780,7 @@ static int parse_data_frame(hm2_modbus_inst_t *inst){ w = 3; b = 0; for (i = 0; i < ch->count; i++){ - hal.pins[p++]->b = (bytes[w] & 1 << b); + hal_set_bool(hal->pins[p++].b, (bytes[w] & 1 << b)); if (++b >= 8) { b = 0; w++;} } break; @@ -801,24 +790,24 @@ static int parse_data_frame(hm2_modbus_inst_t *inst){ for (i = 0; i < bytes[2] / 2; i++){ switch (ch->type){ case HAL_U32: - hal.pins[p]->u = 256 * bytes[w] + bytes[w + 1]; + hal_set_ui32(hal->pins[p].u, 256 * bytes[w] + bytes[w + 1]); w += 2; p++; break; case HAL_S32: // wrap the result into the (s32) offset too - tmp = hal.pins[p]->s; - hal.pins[p]->s = bytes[w] * 256 + bytes[w + 1]; + tmp = hal_get_si32(hal->pins[p].s); + hal_set_si32(hal->pins[p].s, bytes[w] * 256 + bytes[w + 1]); w += 2; - tmp = hal.pins[p]->s - tmp; + tmp = hal_get_si32(hal->pins[p].s) - tmp; if (tmp > 32768) tmp -= 65536; if (tmp < -32768) tmp += 65536; - hal.buff[p] += tmp; - hal.pin2[p]->f = hal.buff[p] * *hal.scale[p]; + hal->buff[p] += tmp; + hal_set_real(hal->pin2[p].r, hal->buff[p] * hal_get_real(hal->scale[p])); p++; break; case HAL_FLOAT: - hal.pins[p]->f = (256 * bytes[w] + bytes[w + 1]) - * *(hal.scale[p]) + hal.pin2[p]->f; + hal_set_real(hal->pins[p].r, (256 * bytes[w] + bytes[w + 1]) + * hal_get_real(hal->scale[p]) + hal_get_real(hal->pin2[p].r)); w += 2; p++; break; diff --git a/src/hal/drivers/mesa-hostmot2/oneshot.c b/src/hal/drivers/mesa-hostmot2/oneshot.c index f56fd522095..3b4bf89fd1f 100644 --- a/src/hal/drivers/mesa-hostmot2/oneshot.c +++ b/src/hal/drivers/mesa-hostmot2/oneshot.c @@ -32,74 +32,74 @@ void hm2_oneshot_update_width1(hostmot2_t *hm2, int i) { // widths are in ms - hm2->oneshot.width1_reg[i] = (double)*hm2->oneshot.instance[i].hal.pin.width1 * ((double)hm2->oneshot.clock_frequency / (double)1e3); + hm2->oneshot.width1_reg[i] = hal_get_real(hm2->oneshot.instance[i].hal.pin.width1) * ((double)hm2->oneshot.clock_frequency / (double)1e3); if (hm2->oneshot.width1_reg[i] > 0x7FFFFFFF) { HM2_ERR("oneshot %d has invalid width1, resetting to max\n", i); hm2->oneshot.width1_reg[i] = 0x7FFFFFFF; - *hm2->oneshot.instance[i].hal.pin.width1 = (double)hm2->oneshot.width1_reg[i] * ((double)1e3 / (double)hm2->oneshot.clock_frequency); + hal_set_real(hm2->oneshot.instance[i].hal.pin.width1, (double)hm2->oneshot.width1_reg[i] * ((double)1e3 / (double)hm2->oneshot.clock_frequency)); } } void hm2_oneshot_update_width2(hostmot2_t *hm2, int i) { // widths are in ms - hm2->oneshot.width2_reg[i] = (double)*hm2->oneshot.instance[i].hal.pin.width2 * ((double)hm2->oneshot.clock_frequency / (double)1e3); + hm2->oneshot.width2_reg[i] = hal_get_real(hm2->oneshot.instance[i].hal.pin.width2) * ((double)hm2->oneshot.clock_frequency / (double)1e3); if (hm2->oneshot.width2_reg[i] > 0x7FFFFFFF) { HM2_ERR("oneshot %d has invalid width1, resetting to max\n", i); hm2->oneshot.width2_reg[i] = 0x7FFFFFFF; - *hm2->oneshot.instance[i].hal.pin.width2 = (double)hm2->oneshot.width2_reg[i] * ((double)1e3 / (double)hm2->oneshot.clock_frequency); + hal_set_real(hm2->oneshot.instance[i].hal.pin.width2, (double)hm2->oneshot.width2_reg[i] * ((double)1e3 / (double)hm2->oneshot.clock_frequency)); } } void hm2_oneshot_update_filter1(hostmot2_t *hm2, int i) { // widths are in ms - hm2->oneshot.filter1_reg[i] = (double)*hm2->oneshot.instance[i].hal.pin.filter1 * ((double)hm2->oneshot.clock_frequency / (double)1e3); + hm2->oneshot.filter1_reg[i] = hal_get_real(hm2->oneshot.instance[i].hal.pin.filter1) * ((double)hm2->oneshot.clock_frequency / (double)1e3); if (hm2->oneshot.filter1_reg[i] > 0xFFFFFF) { HM2_ERR("oneshot %d has invalid filter1 time, resetting to max\n", i); hm2->oneshot.width1_reg[i] = 0xFFFFFF; - *hm2->oneshot.instance[i].hal.pin.filter1 = (double)hm2->oneshot.filter1_reg[i] * ((double)1e3 / (double)hm2->oneshot.clock_frequency); + hal_set_real(hm2->oneshot.instance[i].hal.pin.filter1, (double)hm2->oneshot.filter1_reg[i] * ((double)1e3 / (double)hm2->oneshot.clock_frequency)); } } void hm2_oneshot_update_filter2(hostmot2_t *hm2, int i) { // widths are in ms - hm2->oneshot.filter2_reg[i] = (double)*hm2->oneshot.instance[i].hal.pin.filter2 * ((double)hm2->oneshot.clock_frequency / (double)1e3); + hm2->oneshot.filter2_reg[i] = hal_get_real(hm2->oneshot.instance[i].hal.pin.filter2) * ((double)hm2->oneshot.clock_frequency / (double)1e3); if (hm2->oneshot.filter2_reg[i] > 0xFFFFFF) { HM2_ERR("oneshot %d has invalid filter2 time, resetting to max\n", i); hm2->oneshot.width2_reg[i] = 0xFFFFFF; - *hm2->oneshot.instance[i].hal.pin.filter2 = (double)hm2->oneshot.filter2_reg[i] * ((double)1e3 / (double)hm2->oneshot.clock_frequency); + hal_set_real(hm2->oneshot.instance[i].hal.pin.filter2, (double)hm2->oneshot.filter2_reg[i] * ((double)1e3 / (double)hm2->oneshot.clock_frequency)); } } void hm2_oneshot_update_rate(hostmot2_t *hm2, int i) { - hm2->oneshot.rate_reg[i] = (uint32_t)(*hm2->oneshot.instance[i].hal.pin.rate * (4294967296.0 / (double)hm2->oneshot.clock_frequency)); + hm2->oneshot.rate_reg[i] = (uint32_t)(hal_get_real(hm2->oneshot.instance[i].hal.pin.rate) * (4294967296.0 / (double)hm2->oneshot.clock_frequency)); } void hm2_oneshot_update_control(hostmot2_t *hm2, int i) { rtapi_u32 controlbuff; - if(*hm2->oneshot.instance[i].hal.pin.trigselect1 > 7) { + if(hal_get_ui32(hm2->oneshot.instance[i].hal.pin.trigselect1) > 7) { HM2_ERR("oneshot %d has invalid trigger 1 select value , resetting to 0\n", i); - *hm2->oneshot.instance[i].hal.pin.trigselect1 = 0; + hal_set_ui32(hm2->oneshot.instance[i].hal.pin.trigselect1, 0); } - if(*hm2->oneshot.instance[i].hal.pin.trigselect2 > 7) { + if(hal_get_ui32(hm2->oneshot.instance[i].hal.pin.trigselect2) > 7) { HM2_ERR("oneshot %d has invalid trigger 2 select value , resetting to 0\n", i); - *hm2->oneshot.instance[i].hal.pin.trigselect2 = 0; + hal_set_ui32(hm2->oneshot.instance[i].hal.pin.trigselect2, 0); } controlbuff = 0; - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.trigselect1 << 0); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.trigrise1 << 3); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.trigfall1 << 4); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.retrig1 << 5); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.enable1 << 6); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.reset1 << 7); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.swtrig1 << 10); - controlbuff |= ((*hm2->oneshot.instance[i].hal.pin.dpll_timer_num & 7) << 12); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.trigselect2 << 16); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.trigrise2 << 19); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.trigfall2 << 20); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.retrig2 << 21); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.enable2 << 22); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.reset2 << 23); - controlbuff |= (*hm2->oneshot.instance[i].hal.pin.swtrig2 << 26); + controlbuff |= (hal_get_ui32(hm2->oneshot.instance[i].hal.pin.trigselect1) << 0); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.trigrise1) << 3); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.trigfall1) << 4); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.retrig1) << 5); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.enable1) << 6); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.reset1) << 7); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.swtrig1) << 10); + controlbuff |= ((hal_get_si32(hm2->oneshot.instance[i].hal.pin.dpll_timer_num) & 7) << 12); + controlbuff |= (hal_get_ui32(hm2->oneshot.instance[i].hal.pin.trigselect2) << 16); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.trigrise2) << 19); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.trigfall2) << 20); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.retrig2) << 21); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.enable2) << 22); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.reset2) << 23); + controlbuff |= (hal_get_bool(hm2->oneshot.instance[i].hal.pin.swtrig2) << 26); hm2->oneshot.control_reg[i] = controlbuff; } @@ -132,7 +132,7 @@ void hm2_oneshot_force_write(hostmot2_t *hm2) { hm2->llio->write(hm2->llio, hm2->oneshot.control_addr, hm2->oneshot.control_reg, (hm2->oneshot.num_instances * sizeof(rtapi_u32))); - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; } @@ -201,7 +201,7 @@ int hm2_oneshot_parse_md(hostmot2_t *hm2, int md_index) { - hm2->oneshot.instance = (hm2_oneshot_instance_t *)hal_malloc(hm2->oneshot.num_instances * sizeof(hm2_oneshot_instance_t)); + hm2->oneshot.instance = hal_malloc(hm2->oneshot.num_instances * sizeof(*hm2->oneshot.instance)); if (hm2->oneshot.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -263,204 +263,176 @@ int hm2_oneshot_parse_md(hostmot2_t *hm2, int md_index) { // export to HAL - // FIXME: r hides the r in enclosing function, and it returns the wrong thing { - int i; - int r; - char name[HAL_NAME_LEN + 1]; - - - for (i = 0; i < hm2->oneshot.num_instances; i ++) { + for (int i = 0; i < hm2->oneshot.num_instances; i ++) { // pins - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.width1", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.width1), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.width1), + 1.0, "%s.oneshot.%02d.width1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.width1', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.width2", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.width2), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.width2), + 1.0, "%s.oneshot.%02d.width2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.width2', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.filter1", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.filter1), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.filter1), + 0.1, "%s.oneshot.%02d.filter1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.filter1', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.filter2", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.filter2), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.filter2), + 0.1, "%s.oneshot.%02d.filter2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.filter2', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.rate", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.rate), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.rate), + 1000.0, "%s.oneshot.%02d.rate", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.rate', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.trigger_select1", hm2->llio->name, i); - r = hal_pin_u32_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigselect1), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigselect1), + 0, "%s.oneshot.%02d.trigger_select1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.trigger_select1', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.trigger_select2", hm2->llio->name, i); - r = hal_pin_u32_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigselect2), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigselect2), + 0, "%s.oneshot.%02d.trigger_select2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.trigger_select2', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.dpll_timer_number", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.dpll_timer_num), hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.dpll_timer_num), + 0, "%s.oneshot.%02d.dpll_timer_number", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.dpll_timer_number', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.trigger_on_rise1", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigrise1), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigrise1), + 0, "%s.oneshot.%02d.trigger_on_rise1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.trigger_on_rise1', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.trigger_on_rise2", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigrise2), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigrise2), + 0, "%s.oneshot.%02d.trigger_on_rise2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.trigger_on_rise2', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.trigger_on_fall1", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigfall1), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigfall1), + 0, "%s.oneshot.%02d.trigger_on_fall1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.trigger_on_fall1', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.trigger_on_fall2", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigfall2), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.trigfall2), + 0, "%s.oneshot.%02d.trigger_on_fall2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.trigger_on_fall2', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.retriggerable1", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.retrig1), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.retrig1), + 0, "%s.oneshot.%02d.retriggerable1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.retriggerable1', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.retriggerable2", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.retrig2), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.retrig2), + 0, "%s.oneshot.%02d.retriggerable2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.retriggerable2', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.enable1", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.enable1), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.enable1), + 0, "%s.oneshot.%02d.enable1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.enable1', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.enable2", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.enable2), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.enable2), + 0, "%s.oneshot.%02d.enable2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.enable2', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.reset1", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.reset1), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.reset1), + 0, "%s.oneshot.%02d.reset1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.reset1', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.reset2", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.reset2), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.reset2), + 0, "%s.oneshot.%02d.reset2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.reset2', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.swtrigger1", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.swtrig1), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.swtrig1), + 0, "%s.oneshot.%02d.swtrigger1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.swtrigger1', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.swtrigger2", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.swtrig2), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->oneshot.instance[i].hal.pin.swtrig2), + 0, "%s.oneshot.%02d.swtrigger2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.swtrigger2', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.exttrigger1", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->oneshot.instance[i].hal.pin.exttrig1), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->oneshot.instance[i].hal.pin.exttrig1), + 0, "%s.oneshot.%02d.exttrigger1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.exttrigger1', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.exttrigger2", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->oneshot.instance[i].hal.pin.exttrig2), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->oneshot.instance[i].hal.pin.exttrig2), + 0, "%s.oneshot.%02d.exttrigger2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.exttrigger2', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.out1", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->oneshot.instance[i].hal.pin.out1), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->oneshot.instance[i].hal.pin.out1), + 0, "%s.oneshot.%02d.out1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.out1', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.oneshot.%02d.out2", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->oneshot.instance[i].hal.pin.out2), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->oneshot.instance[i].hal.pin.out2), + 0, "%s.oneshot.%02d.out2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.oneshot.%02d.out2', aborting\n", r, hm2->llio->name, i); goto fail1; } - - - // init hal objects - *(hm2->oneshot.instance[i].hal.pin.width1) = 1.0; - *(hm2->oneshot.instance[i].hal.pin.width2) = 1.0; - *(hm2->oneshot.instance[i].hal.pin.filter1) = 0.1; - *(hm2->oneshot.instance[i].hal.pin.filter2) = 0.1; - *(hm2->oneshot.instance[i].hal.pin.rate) = 1000.0; - *(hm2->oneshot.instance[i].hal.pin.trigselect1) = 0; - *(hm2->oneshot.instance[i].hal.pin.trigselect2) = 0; - *(hm2->oneshot.instance[i].hal.pin.trigrise1) = 0; - *(hm2->oneshot.instance[i].hal.pin.trigrise2) = 0; - *(hm2->oneshot.instance[i].hal.pin.trigfall1) = 0; - *(hm2->oneshot.instance[i].hal.pin.trigfall2) = 0; - *(hm2->oneshot.instance[i].hal.pin.retrig1) = 0; - *(hm2->oneshot.instance[i].hal.pin.retrig2) = 0; - *(hm2->oneshot.instance[i].hal.pin.enable1) = 0; - *(hm2->oneshot.instance[i].hal.pin.enable2) = 0; - *(hm2->oneshot.instance[i].hal.pin.reset1) = 0; - *(hm2->oneshot.instance[i].hal.pin.reset2) = 0; - *(hm2->oneshot.instance[i].hal.pin.swtrig1) = 0; - *(hm2->oneshot.instance[i].hal.pin.swtrig2) = 0; } } @@ -530,10 +502,10 @@ void hm2_oneshot_process_tram_read(hostmot2_t *hm2) { rtapi_u32 control = 0; for (i = 0; i < hm2->oneshot.num_instances; i ++) { control = hm2->oneshot.control_read_reg[i]; - *hm2->oneshot.instance[i].hal.pin.out1 = ((control & (1 << 8)) != 0); - *hm2->oneshot.instance[i].hal.pin.out2 = ((control & (1 << 24)) != 0); - *hm2->oneshot.instance[i].hal.pin.exttrig1 = ((control & (1 << 9)) != 0); - *hm2->oneshot.instance[i].hal.pin.exttrig2 = ((control & (1 << 25)) != 0); + hal_set_bool(hm2->oneshot.instance[i].hal.pin.out1, ((control & (1 << 8)) != 0)); + hal_set_bool(hm2->oneshot.instance[i].hal.pin.out2, ((control & (1 << 24)) != 0)); + hal_set_bool(hm2->oneshot.instance[i].hal.pin.exttrig1, ((control & (1 << 9)) != 0)); + hal_set_bool(hm2->oneshot.instance[i].hal.pin.exttrig2, ((control & (1 << 25)) != 0)); } } diff --git a/src/hal/drivers/mesa-hostmot2/outm.c b/src/hal/drivers/mesa-hostmot2/outm.c index 41f4a4ba427..4bc32a78445 100644 --- a/src/hal/drivers/mesa-hostmot2/outm.c +++ b/src/hal/drivers/mesa-hostmot2/outm.c @@ -77,7 +77,7 @@ int hm2_outm_parse_md(hostmot2_t *hm2, int md_index) { hm2->outm.clock_freq = md->clock_freq; hm2->outm.version = md->version; - hm2->outm.instance = (hm2_outm_instance_t *)hal_malloc(hm2->outm.num_instances * sizeof(hm2_outm_instance_t)); + hm2->outm.instance = hal_malloc(hm2->outm.num_instances * sizeof(*hm2->outm.instance)); if (hm2->outm.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -115,10 +115,7 @@ int hm2_outm_parse_md(hostmot2_t *hm2, int md_index) { // { - int i; - char name[HAL_NAME_LEN + 1]; - - for (i = 0; i < hm2->outm.num_instances; i ++) { + for (int i = 0; i < hm2->outm.num_instances; i ++) { int j = 0; int outm_number; for (j = 0; j < hm2->num_pins; j++){ @@ -134,17 +131,17 @@ int hm2_outm_parse_md(hostmot2_t *hm2, int md_index) { r = -EINVAL; goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.outm.%02d.out-%02d", hm2->llio->name, i, outm_number); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->outm.instance[i].hal.pin.out[outm_number]), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->outm.instance[i].hal.pin.out[outm_number]), + 0, "%s.outm.%02d.out-%02d", hm2->llio->name, i, outm_number); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.outm.%02d.out-%02d', aborting\n", r, hm2->llio->name, i, outm_number); r = -ENOMEM; goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.outm.%02d.invert-%02d", hm2->llio->name, i, outm_number); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->outm.instance[i].hal.pin.invert[outm_number]), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->outm.instance[i].hal.pin.invert[outm_number]), + 0, "%s.outm.%02d.invert-%02d", hm2->llio->name, i, outm_number); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.outm.%02d.invert-%02d', aborting\n", r, hm2->llio->name, i, outm_number); r = -ENOMEM; goto fail0; } @@ -164,16 +161,7 @@ int hm2_outm_parse_md(hostmot2_t *hm2, int md_index) { { int i; for (i = 0; i < hm2->outm.num_instances; i ++) { - int pin; rtapi_u32 zero = 0; - - - for (pin = 0; pin < 32; pin ++) { - if (hm2->outm.instance[i].hal.pin.out[pin] != NULL) { - *hm2->outm.instance[i].hal.pin.out[pin] = 0; - *hm2->outm.instance[i].hal.pin.invert[pin] = 0; - } - } hm2->llio->write(hm2->llio, hm2->outm.data_addr + (i * md->instance_stride), &zero, sizeof(zero)); } } @@ -207,8 +195,8 @@ void hm2_outm_force_write(hostmot2_t *hm2) { hm2->outm.data_reg[i] = 0; for (pin = 0; pin < 32; pin ++) { if (hm2->outm.instance[i].hal.pin.out[pin] != NULL) { - hm2->outm.data_reg[i] |= *hm2->outm.instance[i].hal.pin.out[pin] << pin; - hm2->outm.data_reg[i] ^= *hm2->outm.instance[i].hal.pin.invert[pin] << pin; + hm2->outm.data_reg[i] |= hal_get_bool(hm2->outm.instance[i].hal.pin.out[pin]) << pin; + hm2->outm.data_reg[i] ^= hal_get_bool(hm2->outm.instance[i].hal.pin.invert[pin]) << pin; } } } @@ -238,8 +226,8 @@ void hm2_outm_prepare_tram_write(hostmot2_t *hm2) { hm2->outm.data_reg[i] = 0; for (pin = 0; pin < 32; pin ++) { if (hm2->outm.instance[i].hal.pin.out[pin] != NULL) { - hm2->outm.data_reg[i] |= *hm2->outm.instance[i].hal.pin.out[pin] << pin; - hm2->outm.data_reg[i] ^= *hm2->outm.instance[i].hal.pin.invert[pin] << pin; + hm2->outm.data_reg[i] |= hal_get_bool(hm2->outm.instance[i].hal.pin.out[pin]) << pin; + hm2->outm.data_reg[i] ^= hal_get_bool(hm2->outm.instance[i].hal.pin.invert[pin]) << pin; } } if (hm2->outm.data_reg[i] != hm2->outm.instance[i].written_data) { diff --git a/src/hal/drivers/mesa-hostmot2/periodm.c b/src/hal/drivers/mesa-hostmot2/periodm.c index 9c589f7b325..632edf6cfe7 100644 --- a/src/hal/drivers/mesa-hostmot2/periodm.c +++ b/src/hal/drivers/mesa-hostmot2/periodm.c @@ -33,36 +33,37 @@ void hm2_periodm_update_limit(hostmot2_t *hm2, int i) { - hm2->periodm.limit_reg[i] = ((double)hm2->periodm.clock_frequency / (double)*hm2->periodm.instance[i].hal.pin.minfreq) * *hm2->periodm.instance[i].hal.pin.averages; - if ((((double)hm2->periodm.clock_frequency / (double)*hm2->periodm.instance[i].hal.pin.minfreq) * *hm2->periodm.instance[i].hal.pin.averages ) > 0xFFFFFFFF) { + rtapi_u32 averages = hal_get_ui32(hm2->periodm.instance[i].hal.pin.averages); + rtapi_real minfreq = hal_get_real(hm2->periodm.instance[i].hal.pin.minfreq); + hm2->periodm.limit_reg[i] = ((double)hm2->periodm.clock_frequency / minfreq) * averages; + if ((((double)hm2->periodm.clock_frequency / minfreq) * averages ) > 0xFFFFFFFF) { HM2_ERR("periodm %d has invalid min freq time, resetting to min\n", i); - *hm2->periodm.instance[i].hal.pin.minfreq = (0.025 * *hm2->periodm.instance[i].hal.pin.averages); - hm2->periodm.limit_reg[i] = ((double)hm2->periodm.clock_frequency / (double)*hm2->periodm.instance[i].hal.pin.minfreq) * *hm2->periodm.instance[i].hal.pin.averages; + minfreq = hal_set_real(hm2->periodm.instance[i].hal.pin.minfreq, 0.025 * averages); + hm2->periodm.limit_reg[i] = ((double)hm2->periodm.clock_frequency / minfreq) * averages; } } void hm2_periodm_update_mode(hostmot2_t *hm2, int i) { rtapi_u32 modebuff; rtapi_u32 filterclocks; - rtapi_u32 averages; - filterclocks = (double)*hm2->periodm.instance[i].hal.pin.filtertc * ((double)hm2->periodm.clock_frequency / (double)1e6); + rtapi_u32 averages = hal_get_ui32(hm2->periodm.instance[i].hal.pin.averages); + filterclocks = (double)hal_get_real(hm2->periodm.instance[i].hal.pin.filtertc) * ((double)hm2->periodm.clock_frequency / (double)1e6); if (filterclocks > 0xFFFF) { HM2_ERR("periodm %d has invalid filter time constant, resetting to max\n", i); filterclocks = 0xFFFF; - *hm2->periodm.instance[i].hal.pin.filtertc = (double)filterclocks * ((double)1e6 / (double)hm2->periodm.clock_frequency); + hal_set_real(hm2->periodm.instance[i].hal.pin.filtertc, (double)filterclocks * ((double)1e6 / (double)hm2->periodm.clock_frequency)); } - if (*hm2->periodm.instance[i].hal.pin.averages > 0xFFF) { + if (averages > 0xFFF) { HM2_ERR("periodm %d has invalid averages number, resetting to max\n", i); - *hm2->periodm.instance[i].hal.pin.averages = 0xFFF; + averages = hal_set_ui32(hm2->periodm.instance[i].hal.pin.averages, 0xFFF); } - if (*hm2->periodm.instance[i].hal.pin.averages < 1) { + if (averages < 1) { HM2_ERR("periodm %d has invalid averages number, resetting to min\n", i); - *hm2->periodm.instance[i].hal.pin.averages = 1; + averages = hal_set_ui32(hm2->periodm.instance[i].hal.pin.averages, 1); } - averages = *hm2->periodm.instance[i].hal.pin.averages -1; modebuff = 0; - modebuff |= (*hm2->periodm.instance[i].hal.pin.polarity << 0); - modebuff |= (averages << 4); + modebuff |= (hal_get_bool(hm2->periodm.instance[i].hal.pin.polarity) << 0); + modebuff |= ((averages-1) << 4); modebuff |= (filterclocks << 16); hm2->periodm.mode_write_reg[i] = modebuff; @@ -86,7 +87,7 @@ void hm2_periodm_force_write(hostmot2_t *hm2) { hm2->llio->write(hm2->llio, hm2->periodm.mode_write_addr, hm2->periodm.mode_write_reg, (hm2->periodm.num_instances * sizeof(rtapi_u32))); hm2->llio->write(hm2->llio, hm2->periodm.limit_addr, hm2->periodm.limit_reg, (hm2->periodm.num_instances * sizeof(rtapi_u32))); - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; } @@ -152,7 +153,7 @@ int hm2_periodm_parse_md(hostmot2_t *hm2, int md_index) { - hm2->periodm.instance = (hm2_periodm_instance_t *)hal_malloc(hm2->periodm.num_instances * sizeof(hm2_periodm_instance_t)); + hm2->periodm.instance = hal_malloc(hm2->periodm.num_instances * sizeof(*hm2->periodm.instance)); if (hm2->periodm.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -200,107 +201,92 @@ int hm2_periodm_parse_md(hostmot2_t *hm2, int md_index) { // export to HAL - // FIXME: r hides the r in enclosing function, and it returns the wrong thing { - int i; - int r; - char name[HAL_NAME_LEN + 1]; - - - for (i = 0; i < hm2->periodm.num_instances; i ++) { + for (int i = 0; i < hm2->periodm.num_instances; i ++) { // pins - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.period_us", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.period), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.period), + 0.0, "%s.periodm.%02d.period_us", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.period_us', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.width_us", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.width), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.width), + 0.0, "%s.periodm.%02d.width_us", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.width_us', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.duty_cycle", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.dutycycle), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.dutycycle), + 0.0, "%s.periodm.%02d.duty_cycle", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.duty_cycle', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.duty_cycle_scale", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->periodm.instance[i].hal.pin.dutyscale), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->periodm.instance[i].hal.pin.dutyscale), + 100.0, "%s.periodm.%02d.duty_cycle_scale", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.duty_cycle_scale', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.duty_cycle_offset", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->periodm.instance[i].hal.pin.dutyoffset), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->periodm.instance[i].hal.pin.dutyoffset), + 0.0, "%s.periodm.%02d.duty_cycle_offset", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.duty_cycle_offset', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.frequency", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.frequency), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.frequency), + 0.0, "%s.periodm.%02d.frequency", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.frequency', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.filtertc_us", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->periodm.instance[i].hal.pin.filtertc), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->periodm.instance[i].hal.pin.filtertc), + 1.0, "%s.periodm.%02d.filtertc_us", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.filtertc_us', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.minimum_frequency", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->periodm.instance[i].hal.pin.minfreq), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->periodm.instance[i].hal.pin.minfreq), + 1.0, "%s.periodm.%02d.minimum_frequency", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.minimum_frequency', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.averages", hm2->llio->name, i); - r = hal_pin_u32_new(name, HAL_IO, &(hm2->periodm.instance[i].hal.pin.averages), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IO, &(hm2->periodm.instance[i].hal.pin.averages), + 1, "%s.periodm.%02d.averages", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.averages', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.invert", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IO, &(hm2->periodm.instance[i].hal.pin.polarity), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IO, &(hm2->periodm.instance[i].hal.pin.polarity), + 0, "%s.periodm.%02d.invert", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.invert', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.valid", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.valid), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.valid), + 0, "%s.periodm.%02d.valid", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.valid', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.periodm.%02d.input_status", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.input), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->periodm.instance[i].hal.pin.input), + 0, "%s.periodm.%02d.input_status", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.periodm.%02d.input_status', aborting\n", r, hm2->llio->name, i); goto fail1; } - - // init hal objects - *(hm2->periodm.instance[i].hal.pin.polarity) = 0; - *(hm2->periodm.instance[i].hal.pin.filtertc) = 1.0; - *(hm2->periodm.instance[i].hal.pin.averages) = 1; - *(hm2->periodm.instance[i].hal.pin.minfreq) = 1.0; - *(hm2->periodm.instance[i].hal.pin.dutyscale) = 100; - *(hm2->periodm.instance[i].hal.pin.dutyoffset) = 0; - } } @@ -361,19 +347,23 @@ void hm2_periodm_process_tram_read(hostmot2_t *hm2) { int i; rtapi_u32 mode = 0; for (i = 0; i < hm2->periodm.num_instances; i ++) { + rtapi_u32 averages = hal_get_ui32(hm2->periodm.instance[i].hal.pin.averages); mode = hm2->periodm.mode_read_reg[i]; -// *hm2->periodm.instance[i].hal.pin.polarity = ((mode & (1 << 0)) != 0); - *hm2->periodm.instance[i].hal.pin.valid = ((mode & (1 << 1)) != 0); - *hm2->periodm.instance[i].hal.pin.input = ((mode & (1 << 2)) != 0); - - *hm2->periodm.instance[i].hal.pin.period = (hm2->periodm.period_reg[i] / ((double)hm2->periodm.clock_frequency)) * (double)1e6 / *hm2->periodm.instance[i].hal.pin.averages; - *hm2->periodm.instance[i].hal.pin.width = (hm2->periodm.width_reg[i] / ((double)hm2->periodm.clock_frequency)) * (double)1e6 / *hm2->periodm.instance[i].hal.pin.averages; - if (*hm2->periodm.instance[i].hal.pin.period != 0) { - *hm2->periodm.instance[i].hal.pin.dutycycle = (((double)*hm2->periodm.instance[i].hal.pin.width - / (double)*hm2->periodm.instance[i].hal.pin.period) * (double)*hm2->periodm.instance[i].hal.pin.dutyscale) + *hm2->periodm.instance[i].hal.pin.dutyoffset; - *hm2->periodm.instance[i].hal.pin.frequency = (1.0 / (hm2->periodm.period_reg[i] / (double)hm2->periodm.clock_frequency)) * *hm2->periodm.instance[i].hal.pin.averages; - } - +// hal_set_bool(hm2->periodm.instance[i].hal.pin.polarity, (mode & (1 << 0)) != 0); + hal_set_bool(hm2->periodm.instance[i].hal.pin.valid, (mode & (1 << 1)) != 0); + hal_set_bool(hm2->periodm.instance[i].hal.pin.input, (mode & (1 << 2)) != 0); + + rtapi_real period = hal_set_real(hm2->periodm.instance[i].hal.pin.period, + (hm2->periodm.period_reg[i] / ((double)hm2->periodm.clock_frequency)) * (double)1e6 / averages); + rtapi_real width = hal_set_real(hm2->periodm.instance[i].hal.pin.width, + (hm2->periodm.width_reg[i] / ((double)hm2->periodm.clock_frequency)) * (double)1e6 / averages); + if (period != 0) { + hal_set_real(hm2->periodm.instance[i].hal.pin.dutycycle, + ((width / period) * hal_get_real(hm2->periodm.instance[i].hal.pin.dutyscale)) + + hal_get_real(hm2->periodm.instance[i].hal.pin.dutyoffset)); + hal_set_real(hm2->periodm.instance[i].hal.pin.frequency, + (1.0 / (hm2->periodm.period_reg[i] / (double)hm2->periodm.clock_frequency)) * averages); + } } } diff --git a/src/hal/drivers/mesa-hostmot2/pktuart.c b/src/hal/drivers/mesa-hostmot2/pktuart.c index 2c325cfd452..2198f4b7c5f 100644 --- a/src/hal/drivers/mesa-hostmot2/pktuart.c +++ b/src/hal/drivers/mesa-hostmot2/pktuart.c @@ -99,8 +99,7 @@ int hm2_pktuart_parse_md(hostmot2_t *hm2, int md_index) hm2->pktuart.num_instances = hm2->config.num_pktuarts; } - hm2->pktuart.instance = (hm2_pktuart_instance_t *)hal_malloc(hm2->pktuart.num_instances - * sizeof(hm2_pktuart_instance_t)); + hm2->pktuart.instance = hal_malloc(hm2->pktuart.num_instances * sizeof(*hm2->pktuart.instance)); if(hm2->pktuart.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -440,7 +439,7 @@ EXPORT_SYMBOL_GPL(hm2_pktuart_config); static void perform_reset(const char *name, int queue) { hostmot2_t *hm2; - hm2_pktuart_instance_t *inst = 0; + hm2_pktuart_instance_t *inst = NULL; rtapi_u32 buff = HM2_PKTUART_CLEAR; int i = hm2_get_pktuart(&hm2, name); if(i < 0) { @@ -496,7 +495,7 @@ EXPORT_SYMBOL_GPL(hm2_pktuart_queue_reset); int hm2_pktuart_setup(const char *name, unsigned bitrate, rtapi_s32 tx_mode, rtapi_s32 rx_mode, int txclear, int rxclear) { hostmot2_t *hm2; - hm2_pktuart_instance_t *inst = 0; + hm2_pktuart_instance_t *inst = NULL; rtapi_u32 buff; int i; int r = 0; diff --git a/src/hal/drivers/mesa-hostmot2/pwmgen.c b/src/hal/drivers/mesa-hostmot2/pwmgen.c index 5601b3aac2b..f19cb31efbc 100644 --- a/src/hal/drivers/mesa-hostmot2/pwmgen.c +++ b/src/hal/drivers/mesa-hostmot2/pwmgen.c @@ -34,9 +34,9 @@ void hm2_pwmgen_handle_pwm_frequency(hostmot2_t *hm2) { rtapi_u32 dds; - if (hm2->pwmgen.hal->param.pwm_frequency < 1) { - HM2_ERR("pwmgen.pwm_frequency %d is too low, setting to 1\n", hm2->pwmgen.hal->param.pwm_frequency); - hm2->pwmgen.hal->param.pwm_frequency = 1; + if (hal_get_ui32(hm2->pwmgen.hal->param.pwm_frequency) < 1) { + HM2_ERR("pwmgen.pwm_frequency %d is too low, setting to 1\n", hal_get_ui32(hm2->pwmgen.hal->param.pwm_frequency)); + hal_set_ui32(hm2->pwmgen.hal->param.pwm_frequency, 1); } @@ -65,7 +65,7 @@ void hm2_pwmgen_handle_pwm_frequency(hostmot2_t *hm2) { // // can we do it with 12 bits? - dds = ((double)hm2->pwmgen.hal->param.pwm_frequency * 65536.0 * 4096.0) / (double)hm2->pwmgen.clock_frequency; + dds = ((double)hal_get_ui32(hm2->pwmgen.hal->param.pwm_frequency) * 65536.0 * 4096.0) / (double)hm2->pwmgen.clock_frequency; if (dds < 65536) { hm2->pwmgen.pwmgen_master_rate_dds_reg = dds; hm2->pwmgen.pwm_bits = 12; @@ -73,7 +73,7 @@ void hm2_pwmgen_handle_pwm_frequency(hostmot2_t *hm2) { } // try 11 bits - dds = ((double)hm2->pwmgen.hal->param.pwm_frequency * 65536.0 * 2048.0) / (double)hm2->pwmgen.clock_frequency; + dds = ((double)hal_get_ui32(hm2->pwmgen.hal->param.pwm_frequency) * 65536.0 * 2048.0) / (double)hm2->pwmgen.clock_frequency; if (dds < 65536) { hm2->pwmgen.pwmgen_master_rate_dds_reg = dds; hm2->pwmgen.pwm_bits = 11; @@ -81,7 +81,7 @@ void hm2_pwmgen_handle_pwm_frequency(hostmot2_t *hm2) { } // try 10 bits - dds = ((double)hm2->pwmgen.hal->param.pwm_frequency * 65536.0 * 1024.0) / (double)hm2->pwmgen.clock_frequency; + dds = ((double)hal_get_ui32(hm2->pwmgen.hal->param.pwm_frequency) * 65536.0 * 1024.0) / (double)hm2->pwmgen.clock_frequency; if (dds < 65536) { hm2->pwmgen.pwmgen_master_rate_dds_reg = dds; hm2->pwmgen.pwm_bits = 10; @@ -89,7 +89,7 @@ void hm2_pwmgen_handle_pwm_frequency(hostmot2_t *hm2) { } // try 9 bits - dds = ((double)hm2->pwmgen.hal->param.pwm_frequency * 65536.0 * 512.0) / (double)hm2->pwmgen.clock_frequency; + dds = ((double)hal_get_ui32(hm2->pwmgen.hal->param.pwm_frequency) * 65536.0 * 512.0) / (double)hm2->pwmgen.clock_frequency; if (dds < 65536) { hm2->pwmgen.pwmgen_master_rate_dds_reg = dds; hm2->pwmgen.pwm_bits = 9; @@ -99,8 +99,8 @@ void hm2_pwmgen_handle_pwm_frequency(hostmot2_t *hm2) { // no joy, lower frequency until it'll work with 9 bits // From above: // PWMFreq = (ClockHigh * DDS) / (65536 * 2^PWMBits) - hm2->pwmgen.hal->param.pwm_frequency = ((double)hm2->pwmgen.clock_frequency * 65535.0) / (65536.0 * 512.0); - HM2_ERR("max PWM frequency is %d Hz\n", hm2->pwmgen.hal->param.pwm_frequency); + hal_set_ui32(hm2->pwmgen.hal->param.pwm_frequency, ((double)hm2->pwmgen.clock_frequency * 65535.0) / (65536.0 * 512.0)); + HM2_ERR("max PWM frequency is %d Hz\n", hal_get_ui32(hm2->pwmgen.hal->param.pwm_frequency)); hm2->pwmgen.pwmgen_master_rate_dds_reg = 65535; hm2->pwmgen.pwm_bits = 9; } @@ -110,9 +110,9 @@ void hm2_pwmgen_handle_pdm_frequency(hostmot2_t *hm2) { rtapi_u32 dds; - if (hm2->pwmgen.hal->param.pdm_frequency < 1) { - HM2_ERR("pwmgen.pdm_frequency %d is too low, setting to 1\n", hm2->pwmgen.hal->param.pdm_frequency); - hm2->pwmgen.hal->param.pdm_frequency = 1; + if (hal_get_ui32(hm2->pwmgen.hal->param.pdm_frequency) < 1) { + HM2_ERR("pwmgen.pdm_frequency %d is too low, setting to 1\n", hal_get_ui32(hm2->pwmgen.hal->param.pdm_frequency)); + hal_set_ui32(hm2->pwmgen.hal->param.pdm_frequency, 1); } @@ -151,14 +151,14 @@ void hm2_pwmgen_handle_pdm_frequency(hostmot2_t *hm2) { // // can we do it with 12 bits? - dds = ((double)hm2->pwmgen.hal->param.pdm_frequency * 65536.0) / (double)hm2->pwmgen.clock_frequency; + dds = ((double)hal_get_ui32(hm2->pwmgen.hal->param.pdm_frequency) * 65536.0) / (double)hm2->pwmgen.clock_frequency; if (dds == 0) { // too slow, set frequency to minimum // From above: // PulseFreq = (ClockHigh * DDS) / 65536 dds = 1; - hm2->pwmgen.hal->param.pdm_frequency = ((double)hm2->pwmgen.clock_frequency * (double)dds) / 65536.0; - HM2_ERR("min PDM frequency is %d Hz\n", hm2->pwmgen.hal->param.pdm_frequency); + hal_set_ui32(hm2->pwmgen.hal->param.pdm_frequency, ((double)hm2->pwmgen.clock_frequency * (double)dds) / 65536.0); + HM2_ERR("min PDM frequency is %d Hz\n", hal_get_ui32(hm2->pwmgen.hal->param.pdm_frequency)); hm2->pwmgen.pdmgen_master_rate_dds_reg = 1; return; } @@ -172,8 +172,8 @@ void hm2_pwmgen_handle_pdm_frequency(hostmot2_t *hm2) { // user wants too much, lower frequency until it'll work with 12 bits // From above: // PulseFreq = (ClockHigh * DDS) / 65536 - hm2->pwmgen.hal->param.pdm_frequency = ((double)hm2->pwmgen.clock_frequency * 65535.0) / 65536.0; - HM2_ERR("max PDM frequency is %d Hz\n", hm2->pwmgen.hal->param.pdm_frequency); + hal_set_ui32(hm2->pwmgen.hal->param.pdm_frequency, ((double)hm2->pwmgen.clock_frequency * 65535.0) / 65536.0); + HM2_ERR("max PDM frequency is %d Hz\n", hal_get_ui32(hm2->pwmgen.hal->param.pdm_frequency)); hm2->pwmgen.pdmgen_master_rate_dds_reg = 65535; } @@ -219,7 +219,7 @@ void hm2_pwmgen_force_write(hostmot2_t *hm2) { hm2->pwmgen.pwm_mode_reg[i] = pwm_width; - switch (hm2->pwmgen.instance[i].hal.param.output_type) { + switch (hal_get_si32(hm2->pwmgen.instance[i].hal.param.output_type)) { case HM2_PWMGEN_OUTPUT_TYPE_PWM: { // leave the Output Mode bits 0 double_buffered = 1; @@ -247,7 +247,7 @@ void hm2_pwmgen_force_write(hostmot2_t *hm2) { default: { // unknown pwm mode! complain and switch to pwm/dir HM2_ERR( "invalid pwmgen output_type %d requested\n", - hm2->pwmgen.instance[i].hal.param.output_type + hal_get_si32(hm2->pwmgen.instance[i].hal.param.output_type) ); HM2_ERR( "supported .output-type values are: %d (PWM & Dir), %d (Up & Down), %d (PDM & Dir), and %d (Dir & PWM)\n", @@ -257,7 +257,7 @@ void hm2_pwmgen_force_write(hostmot2_t *hm2) { HM2_PWMGEN_OUTPUT_TYPE_PWM_SWAPPED ); HM2_ERR("switching to 1 (PWM & Dir)\n"); - hm2->pwmgen.instance[i].hal.param.output_type = HM2_PWMGEN_OUTPUT_TYPE_PWM; + hal_set_si32(hm2->pwmgen.instance[i].hal.param.output_type, HM2_PWMGEN_OUTPUT_TYPE_PWM); double_buffered = 1; // leave the Output Mode bits 0 break; @@ -265,7 +265,7 @@ void hm2_pwmgen_force_write(hostmot2_t *hm2) { } hm2->pwmgen.pwm_mode_reg[i] |= (double_buffered << 5); - if (hm2->pwmgen.instance[i].hal.param.dither) { + if (hal_get_bool(hm2->pwmgen.instance[i].hal.param.dither)) { hm2->pwmgen.pwm_mode_reg[i] |= (1 << 6); } @@ -276,7 +276,7 @@ void hm2_pwmgen_force_write(hostmot2_t *hm2) { // update enable register hm2->pwmgen.enable_reg = 0; for (i = 0; i < hm2->pwmgen.num_instances; i ++) { - if (*(hm2->pwmgen.instance[i].hal.pin.enable)) { + if (hal_get_bool(hm2->pwmgen.instance[i].hal.pin.enable)) { hm2->pwmgen.enable_reg |= (1 << i); } } @@ -287,17 +287,17 @@ void hm2_pwmgen_force_write(hostmot2_t *hm2) { hm2->llio->write(hm2->llio, hm2->pwmgen.pwmgen_master_rate_dds_addr, &hm2->pwmgen.pwmgen_master_rate_dds_reg, sizeof(rtapi_u32)); hm2->llio->write(hm2->llio, hm2->pwmgen.pdmgen_master_rate_dds_addr, &hm2->pwmgen.pdmgen_master_rate_dds_reg, sizeof(rtapi_u32)); - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; for (i = 0; i < hm2->pwmgen.num_instances; i ++) { - hm2->pwmgen.instance[i].written_output_type = hm2->pwmgen.instance[i].hal.param.output_type; - hm2->pwmgen.instance[i].written_offset_mode = hm2->pwmgen.instance[i].hal.param.offset_mode; - hm2->pwmgen.instance[i].written_dither = hm2->pwmgen.instance[i].hal.param.dither; - hm2->pwmgen.instance[i].written_enable = *hm2->pwmgen.instance[i].hal.pin.enable; + hm2->pwmgen.instance[i].written_output_type = hal_get_si32(hm2->pwmgen.instance[i].hal.param.output_type); + hm2->pwmgen.instance[i].written_offset_mode = hal_get_bool(hm2->pwmgen.instance[i].hal.param.offset_mode); + hm2->pwmgen.instance[i].written_dither = hal_get_bool(hm2->pwmgen.instance[i].hal.param.dither); + hm2->pwmgen.instance[i].written_enable = hal_get_bool(hm2->pwmgen.instance[i].hal.pin.enable); } - hm2->pwmgen.written_pwm_frequency = hm2->pwmgen.hal->param.pwm_frequency; - hm2->pwmgen.written_pdm_frequency = hm2->pwmgen.hal->param.pdm_frequency; + hm2->pwmgen.written_pwm_frequency = hal_get_ui32(hm2->pwmgen.hal->param.pwm_frequency); + hm2->pwmgen.written_pdm_frequency = hal_get_ui32(hm2->pwmgen.hal->param.pdm_frequency); } @@ -314,30 +314,30 @@ void hm2_pwmgen_write(hostmot2_t *hm2) { // check output type for (i = 0; i < hm2->pwmgen.num_instances; i ++) { - if (hm2->pwmgen.instance[i].hal.param.output_type != hm2->pwmgen.instance[i].written_output_type) { + if (hal_get_si32(hm2->pwmgen.instance[i].hal.param.output_type) != hm2->pwmgen.instance[i].written_output_type) { goto force_write; } } // check offset mode for (i = 0; i < hm2->pwmgen.num_instances; i ++) { - if (hm2->pwmgen.instance[i].hal.param.offset_mode != hm2->pwmgen.instance[i].written_offset_mode) { + if (hal_get_bool(hm2->pwmgen.instance[i].hal.param.offset_mode) != hm2->pwmgen.instance[i].written_offset_mode) { goto force_write; } } // update dither? for (i = 0; i < hm2->pwmgen.num_instances; i ++) { - if (hm2->pwmgen.instance[i].hal.param.dither != hm2->pwmgen.instance[i].written_dither) { + if (hal_get_bool(hm2->pwmgen.instance[i].hal.param.dither) != hm2->pwmgen.instance[i].written_dither) { goto force_write; } // check pwm & pdm frequency - if (hm2->pwmgen.hal->param.pwm_frequency != hm2->pwmgen.written_pwm_frequency) goto force_write; - if (hm2->pwmgen.hal->param.pdm_frequency != hm2->pwmgen.written_pdm_frequency) goto force_write; + if (hal_get_ui32(hm2->pwmgen.hal->param.pwm_frequency) != hm2->pwmgen.written_pwm_frequency) goto force_write; + if (hal_get_ui32(hm2->pwmgen.hal->param.pdm_frequency) != hm2->pwmgen.written_pdm_frequency) goto force_write; // update enable register? for (i = 0; i < hm2->pwmgen.num_instances; i ++) { - if (*(hm2->pwmgen.instance[i].hal.pin.enable) != hm2->pwmgen.instance[i].written_enable) { + if (hal_get_bool(hm2->pwmgen.instance[i].hal.pin.enable) != hm2->pwmgen.instance[i].written_enable) { goto force_write; } } @@ -407,7 +407,7 @@ int hm2_pwmgen_parse_md(hostmot2_t *hm2, int md_index) { // allocate the module-global HAL shared memory - hm2->pwmgen.hal = (hm2_pwmgen_module_global_t *)hal_malloc(sizeof(hm2_pwmgen_module_global_t)); + hm2->pwmgen.hal = hal_malloc(sizeof(*hm2->pwmgen.hal)); if (hm2->pwmgen.hal == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -415,7 +415,7 @@ int hm2_pwmgen_parse_md(hostmot2_t *hm2, int md_index) { } - hm2->pwmgen.instance = (hm2_pwmgen_instance_t *)hal_malloc(hm2->pwmgen.num_instances * sizeof(hm2_pwmgen_instance_t)); + hm2->pwmgen.instance = hal_malloc(hm2->pwmgen.num_instances * sizeof(*hm2->pwmgen.instance)); if (hm2->pwmgen.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -445,101 +445,78 @@ int hm2_pwmgen_parse_md(hostmot2_t *hm2, int md_index) { } // export to HAL - // FIXME: r hides the r in enclosing function, and it returns the wrong thing { - int i; - int r; - char name[HAL_NAME_LEN + 1]; - - // these hal parameters affect all pwmgen instances - r = hal_param_u32_newf( - HAL_RW, - &(hm2->pwmgen.hal->param.pwm_frequency), - hm2->llio->comp_id, - "%s.pwmgen.pwm_frequency", - hm2->llio->name - ); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->pwmgen.hal->param.pwm_frequency), + 20000, "%s.pwmgen.pwm_frequency", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pwmgen.pwm_frequency param, aborting\n"); + HM2_ERR("error %d adding '%s.pwmgen.pwm_frequency' param, aborting\n", r, hm2->llio->name); goto fail1; } - hm2->pwmgen.hal->param.pwm_frequency = 20000; hm2->pwmgen.written_pwm_frequency = 0; - r = hal_param_u32_newf( - HAL_RW, - &(hm2->pwmgen.hal->param.pdm_frequency), - hm2->llio->comp_id, - "%s.pwmgen.pdm_frequency", - hm2->llio->name - ); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->pwmgen.hal->param.pdm_frequency), + 20000, "%s.pwmgen.pdm_frequency", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pwmgen.pdm_frequency param, aborting\n"); + HM2_ERR("error %d adding '%s.pwmgen.pdm_frequency' param, aborting\n", r, hm2->llio->name); goto fail1; } - hm2->pwmgen.hal->param.pdm_frequency = 20000; hm2->pwmgen.written_pdm_frequency = 0; - for (i = 0; i < hm2->pwmgen.num_instances; i ++) { + for (int i = 0; i < hm2->pwmgen.num_instances; i ++) { // pins - rtapi_snprintf(name, sizeof(name), "%s.pwmgen.%02d.value", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->pwmgen.instance[i].hal.pin.value), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->pwmgen.instance[i].hal.pin.value), + 0.0, "%s.pwmgen.%02d.value", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.pwmgen.%02d.value', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.pwmgen.%02d.enable", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->pwmgen.instance[i].hal.pin.enable), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->pwmgen.instance[i].hal.pin.enable), + 0, "%s.pwmgen.%02d.enable", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.pwmgen.%02d.enable', aborting\n", r, hm2->llio->name, i); goto fail1; } // parameters - rtapi_snprintf(name, sizeof(name), "%s.pwmgen.%02d.offset-mode", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->pwmgen.instance[i].hal.param.offset_mode), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->pwmgen.instance[i].hal.param.offset_mode), + 0, "%s.pwmgen.%02d.offset-mode", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.pwmgen.%02d.offset-mode', aborting\n", r, hm2->llio->name, i); goto fail1; } if (hm2->pwmgen.firmware_supports_dither) { - rtapi_snprintf(name, sizeof(name), "%s.pwmgen.%02d.dither", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->pwmgen.instance[i].hal.param.dither), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->pwmgen.instance[i].hal.param.dither), + 0, "%s.pwmgen.%02d.dither", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding param '%s.pwmgen.%02d.dither', aborting\n", r, hm2->llio->name, i); + goto fail1; + } + } else { + // Parameter allocated in conditional, make sure the memory is still available + r = hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(hm2->pwmgen.instance[i].hal.param.dither)); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d allocating fake param for '%s.pwmgen.%02d.dither', aborting\n", r, hm2->llio->name, i); goto fail1; } } - rtapi_snprintf(name, sizeof(name), "%s.pwmgen.%02d.scale", hm2->llio->name, i); - r = hal_param_float_new(name, HAL_RW, &(hm2->pwmgen.instance[i].hal.param.scale), hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->pwmgen.instance[i].hal.param.scale), + 1.0, "%s.pwmgen.%02d.scale", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.pwmgen.%02d.scale', aborting\n", r, hm2->llio->name, i); goto fail1; } - r = hal_param_s32_newf( - HAL_RW, - &(hm2->pwmgen.instance[i].hal.param.output_type), - hm2->llio->comp_id, - "%s.pwmgen.%02d.output-type", - hm2->llio->name, - i - ); + r = hal_param_new_si32(hm2->llio->comp_id, HAL_RW, &(hm2->pwmgen.instance[i].hal.param.output_type), + HM2_PWMGEN_OUTPUT_TYPE_PWM, "%s.pwmgen.%02d.output-type", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param, aborting\n"); + HM2_ERR("error %d adding param '%s.pwmgen.%02d.output-type', aborting\n", r, hm2->llio->name, i); goto fail1; } // init hal objects - *(hm2->pwmgen.instance[i].hal.pin.enable) = 0; - *(hm2->pwmgen.instance[i].hal.pin.value) = 0.0; - hm2->pwmgen.instance[i].hal.param.dither = 0; - hm2->pwmgen.instance[i].hal.param.scale = 1.0; - hm2->pwmgen.instance[i].hal.param.offset_mode = 0; - hm2->pwmgen.instance[i].hal.param.output_type = HM2_PWMGEN_OUTPUT_TYPE_PWM; hm2->pwmgen.instance[i].written_output_type = -666; // force an update at the start hm2->pwmgen.instance[i].written_enable = -666; // force an update at the start hm2->pwmgen.instance[i].written_dither = -666; // force an update at the start @@ -614,7 +591,7 @@ void hm2_pwmgen_prepare_tram_write(hostmot2_t *hm2) { double register_value; int bits; - scaled_value = *hm2->pwmgen.instance[i].hal.pin.value / hm2->pwmgen.instance[i].hal.param.scale; + scaled_value = hal_get_real(hm2->pwmgen.instance[i].hal.pin.value) / hal_get_real(hm2->pwmgen.instance[i].hal.param.scale); if (scaled_value > 1.0) scaled_value = 1.0; if (scaled_value < -1.0) scaled_value = -1.0; @@ -625,16 +602,16 @@ void hm2_pwmgen_prepare_tram_write(hostmot2_t *hm2) { // However, there apparently is equipment that does not behave this // way, and that benefits from having PWM & Dir go low when /Enable // goes high. (note that PWM will go to 50% when offset mode is enabled) - if (*hm2->pwmgen.instance[i].hal.pin.enable == 0) { + if (!hal_get_bool(hm2->pwmgen.instance[i].hal.pin.enable)) { scaled_value = 0.0; } abs_duty_cycle = fabs(scaled_value); // duty_cycle goes from 0.0 to 1.0, and needs to be puffed out to pwm_bits (if it's pwm) or 12 (if it's pdm) - if (hm2->pwmgen.instance[i].hal.param.offset_mode == 0) { + if (!hal_get_bool(hm2->pwmgen.instance[i].hal.param.offset_mode)) { //normal PWM/PDM modes - if (hm2->pwmgen.instance[i].hal.param.output_type == HM2_PWMGEN_OUTPUT_TYPE_PDM) { + if (hal_get_si32(hm2->pwmgen.instance[i].hal.param.output_type) == HM2_PWMGEN_OUTPUT_TYPE_PDM) { bits = 12; } else { bits = hm2->pwmgen.pwm_bits; @@ -642,7 +619,7 @@ void hm2_pwmgen_prepare_tram_write(hostmot2_t *hm2) { // With normal PWM, the max PWM register value is 0xNFF.X // but for dithered PWM the max value is 0xNFE.F // the topdrop value is chosen to generate these max values - if (hm2->pwmgen.instance[i].hal.param.dither == 0) { + if (!hal_get_bool(hm2->pwmgen.instance[i].hal.param.dither)) { topdrop = 1; } else { topdrop = 1.0625; @@ -651,7 +628,7 @@ void hm2_pwmgen_prepare_tram_write(hostmot2_t *hm2) { } else { // offset PWM/PDM modes where 0 PWM value = 50% duty cycle also choose active low - if (hm2->pwmgen.instance[i].hal.param.output_type == HM2_PWMGEN_OUTPUT_TYPE_PDM) { + if (hal_get_si32(hm2->pwmgen.instance[i].hal.param.output_type) == HM2_PWMGEN_OUTPUT_TYPE_PDM) { bits = 11; } else { bits = hm2->pwmgen.pwm_bits -1; @@ -659,7 +636,7 @@ void hm2_pwmgen_prepare_tram_write(hostmot2_t *hm2) { // With normal PWM, the max PWM register value is 0xNFF.X // but for dithered PWM the max value is 0xNFE.F // the topdrop value is chosen to generate these max values - if (hm2->pwmgen.instance[i].hal.param.dither == 0) { + if (!hal_get_bool(hm2->pwmgen.instance[i].hal.param.dither)) { topdrop = 1; } else { topdrop = 1.0625; diff --git a/src/hal/drivers/mesa-hostmot2/raw.c b/src/hal/drivers/mesa-hostmot2/raw.c index 7fb743b3b58..14a10634aab 100644 --- a/src/hal/drivers/mesa-hostmot2/raw.c +++ b/src/hal/drivers/mesa-hostmot2/raw.c @@ -32,73 +32,61 @@ int hm2_raw_setup(hostmot2_t *hm2) { int r; - char name[HAL_NAME_LEN + 1]; - if (hm2->config.enable_raw == 0) { return 0; } - hm2->raw = (hm2_raw_t *)hal_malloc(sizeof(hm2_raw_t)); + hm2->raw = hal_malloc(sizeof(*hm2->raw)); if (hm2->raw == NULL) { HM2_ERR("out of memory!\n"); hm2->config.enable_raw = 0; return -ENOMEM; } - rtapi_snprintf(name, sizeof(name), "%s.raw.read_address", hm2->llio->name); - r = hal_pin_u32_new(name, HAL_IN, &(hm2->raw->hal.pin.read_address), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->raw->hal.pin.read_address), + 0, "%s.raw.read_address", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.raw.read_address', aborting\n", r, hm2->llio->name); return -EINVAL; } - rtapi_snprintf(name, sizeof(name), "%s.raw.read_data", hm2->llio->name); - r = hal_pin_u32_new(name, HAL_OUT, &(hm2->raw->hal.pin.read_data), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_OUT, &(hm2->raw->hal.pin.read_data), + 0, "%s.raw.read_data", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.raw.read_data', aborting\n", r, hm2->llio->name); return -EINVAL; } - rtapi_snprintf(name, sizeof(name), "%s.raw.write_address", hm2->llio->name); - r = hal_pin_u32_new(name, HAL_IN, &(hm2->raw->hal.pin.write_address), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->raw->hal.pin.write_address), + 0, "%s.raw.write_address", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.raw.write_address', aborting\n", r, hm2->llio->name); return -EINVAL; } - rtapi_snprintf(name, sizeof(name), "%s.raw.write_data", hm2->llio->name); - r = hal_pin_u32_new(name, HAL_IN, &(hm2->raw->hal.pin.write_data), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->raw->hal.pin.write_data), + 0, "%s.raw.write_data", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.raw.write_data', aborting\n", r, hm2->llio->name); return -EINVAL; } - rtapi_snprintf(name, sizeof(name), "%s.raw.write_strobe", hm2->llio->name); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->raw->hal.pin.write_strobe), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->raw->hal.pin.write_strobe), + 0, "%s.raw.write_strobe", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.raw.write_strobe', aborting\n", r, hm2->llio->name); return -EINVAL; } - rtapi_snprintf(name, sizeof(name), "%s.raw.dump_state", hm2->llio->name); - r = hal_pin_bit_new(name, HAL_IO, &(hm2->raw->hal.pin.dump_state), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IO, &(hm2->raw->hal.pin.dump_state), + 0, "%s.raw.dump_state", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.raw.dump_state', aborting\n", r, hm2->llio->name); return -EINVAL; } - // init hal objects - *(hm2->raw->hal.pin.read_address) = 0; - *(hm2->raw->hal.pin.read_data) = 0; - - *(hm2->raw->hal.pin.write_address) = 0; - *(hm2->raw->hal.pin.write_data) = 0; - *(hm2->raw->hal.pin.write_strobe) = 0; - - *(hm2->raw->hal.pin.dump_state) = 0; - return 0; } @@ -110,14 +98,14 @@ void hm2_raw_queue_read(hostmot2_t *hm2) { hm2->llio->queue_read( hm2->llio, - *hm2->raw->hal.pin.read_address & 0xffff, + hal_get_ui32(hm2->raw->hal.pin.read_address) & 0xffff, (void *)hm2->raw->hal.pin.read_data, sizeof(rtapi_u32) ); - if (*hm2->raw->hal.pin.dump_state != 0) { + if (hal_get_bool(hm2->raw->hal.pin.dump_state)) { hm2_print_modules(hm2); - *hm2->raw->hal.pin.dump_state = 0; + hal_set_bool(hm2->raw->hal.pin.dump_state, 0); } } @@ -126,15 +114,15 @@ void hm2_raw_queue_read(hostmot2_t *hm2) { void hm2_raw_write(hostmot2_t *hm2) { if (hm2->config.enable_raw == 0) return; - if (*hm2->raw->hal.pin.write_strobe == 0) return; + if (!hal_get_bool(hm2->raw->hal.pin.write_strobe)) return; hm2->llio->write( hm2->llio, - *hm2->raw->hal.pin.write_address & 0xffff, + hal_get_ui32(hm2->raw->hal.pin.write_address) & 0xffff, (void *)hm2->raw->hal.pin.write_data, sizeof(rtapi_u32) ); - *hm2->raw->hal.pin.write_strobe = 0; + hal_set_bool(hm2->raw->hal.pin.write_strobe, 0); } diff --git a/src/hal/drivers/mesa-hostmot2/rcpwmgen.c b/src/hal/drivers/mesa-hostmot2/rcpwmgen.c index b13c60f43eb..4a5b17dfe7e 100644 --- a/src/hal/drivers/mesa-hostmot2/rcpwmgen.c +++ b/src/hal/drivers/mesa-hostmot2/rcpwmgen.c @@ -77,7 +77,7 @@ int hm2_rcpwmgen_parse_md(hostmot2_t *hm2, int md_index) { hm2->rcpwmgen.clock_frequency = md->clock_freq; hm2->rcpwmgen.version = md->version; // allocate the module-instance HAL shared memory - hm2->rcpwmgen.instance = (hm2_rcpwmgen_instance_t *)hal_malloc(hm2->rcpwmgen.num_instances * sizeof(hm2_rcpwmgen_instance_t)); + hm2->rcpwmgen.instance = hal_malloc(hm2->rcpwmgen.num_instances * sizeof(*hm2->rcpwmgen.instance)); if (hm2->rcpwmgen.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -85,7 +85,7 @@ int hm2_rcpwmgen_parse_md(hostmot2_t *hm2, int md_index) { } // allocate the module-global HAL shared memory - hm2->rcpwmgen.hal = (hm2_rcpwmgen_module_global_t *)hal_malloc(sizeof(hm2_rcpwmgen_module_global_t)); + hm2->rcpwmgen.hal = hal_malloc(sizeof(*hm2->rcpwmgen.hal)); if (hm2->rcpwmgen.hal == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -113,51 +113,40 @@ int hm2_rcpwmgen_parse_md(hostmot2_t *hm2, int md_index) { // // Export to HAL. // - + // initialize width to 0, scale to 1, offset 0 and rate to 50 Hz { - int i; - char name[HAL_NAME_LEN + 1]; - for (i = 0; i < hm2->rcpwmgen.num_instances; i ++) { - - rtapi_snprintf(name, sizeof(name), "%s.rcpwmgen.%02d.width", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->rcpwmgen.instance[i].hal.pin.width), hm2->llio->comp_id); + for (int i = 0; i < hm2->rcpwmgen.num_instances; i ++) { + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->rcpwmgen.instance[i].hal.pin.width), + 0.0, "%s.rcpwmgen.%02d.width", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.rcpwmgen.%02d.width', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.rcpwmgen.%02d.scale", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->rcpwmgen.instance[i].hal.pin.scale), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->rcpwmgen.instance[i].hal.pin.scale), + 1.0, "%s.rcpwmgen.%02d.scale", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.rcpwmgen.%02d.scale', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.rcpwmgen.%02d.offset", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->rcpwmgen.instance[i].hal.pin.offset), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->rcpwmgen.instance[i].hal.pin.offset), + 0.0, "%s.rcpwmgen.%02d.offset", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.rcpwmgen.%02d.offset', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail1; } } - rtapi_snprintf(name, sizeof(name), "%s.rcpwmgen.rate", hm2->llio->name); - r = hal_pin_float_new(name, HAL_IN, &(hm2->rcpwmgen.hal->pin.rate), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->rcpwmgen.hal->pin.rate), + 50.0, "%s.rcpwmgen.rate", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.rcpwmgen.rate', aborting\n", r, hm2->llio->name); goto fail1; } } - // initialize width to 0, scale to 1, offset 0 and rate to 50 Hz - *hm2->rcpwmgen.hal->pin.rate = 50; - int i; - for (i = 0; i < hm2->rcpwmgen.num_instances; i ++) { - *hm2->rcpwmgen.instance[i].hal.pin.width = 0; - *hm2->rcpwmgen.instance[i].hal.pin.scale = 1.0; - *hm2->rcpwmgen.instance[i].hal.pin.offset = 0; - } hm2->rcpwmgen.error_throttle = 0; return hm2->rcpwmgen.num_instances; @@ -191,9 +180,9 @@ void hm2_rcpwmgen_update_regs(hostmot2_t *hm2) { rtapi_u32 reg; // Set rate - double rate = *hm2->rcpwmgen.hal->pin.rate; + double rate = hal_get_real(hm2->rcpwmgen.hal->pin.rate); if (rate < 0.01) { - *hm2->rcpwmgen.hal->pin.rate = 0.01; + hal_set_real(hm2->rcpwmgen.hal->pin.rate, 0.01); rate = 0.01; if (hm2->rcpwmgen.error_throttle == 0) { HM2_ERR("rcpwmgen frequency must be >= .01, resetting to %.3lf \n",0.01); @@ -202,7 +191,7 @@ void hm2_rcpwmgen_update_regs(hostmot2_t *hm2) { } if (rate > 1000) { - *hm2->rcpwmgen.hal->pin.rate = 1000; + hal_set_real(hm2->rcpwmgen.hal->pin.rate, 1000); rate = 1000; if (hm2->rcpwmgen.error_throttle == 0) { HM2_ERR("rcpwmgen frequency must be <= 1000, resetting to %.3lf \n",1000.0); @@ -219,19 +208,19 @@ void hm2_rcpwmgen_update_regs(hostmot2_t *hm2) { int i; // Set width. for (i = 0; i < hm2->rcpwmgen.num_instances; i ++) { - if (*hm2->rcpwmgen.instance[i].hal.pin.scale == 0) { + if (hal_get_real(hm2->rcpwmgen.instance[i].hal.pin.scale) == 0) { if (hm2->rcpwmgen.error_throttle == 0) { HM2_ERR("rcpwmgen %d zero scale is illegal, resetting to %.3lf \n", i,1.0); hm2->rcpwmgen.error_throttle = 100; } - *hm2->rcpwmgen.instance[i].hal.pin.scale = 1.0; + hal_set_real(hm2->rcpwmgen.instance[i].hal.pin.scale, 1.0); } - double width = (*hm2->rcpwmgen.instance[i].hal.pin.width)/(*hm2->rcpwmgen.instance[i].hal.pin.scale)+(*hm2->rcpwmgen.instance[i].hal.pin.offset); + double width = hal_get_real(hm2->rcpwmgen.instance[i].hal.pin.width) / hal_get_real(hm2->rcpwmgen.instance[i].hal.pin.scale) + hal_get_real(hm2->rcpwmgen.instance[i].hal.pin.offset); // The `width` variable has the desired pulse width in milliseconds. // The width register sets the width to reg*(CLockLow/16+1) if (width < 0) { - *hm2->rcpwmgen.instance[i].hal.pin.width = 0.0; + hal_set_real(hm2->rcpwmgen.instance[i].hal.pin.width, 0.0); width = 0.0; if (hm2->rcpwmgen.error_throttle == 0) { HM2_ERR("rcpwmgen %d width must be >= 0, resetting to %.3lf \n", i,0.0); @@ -240,10 +229,10 @@ void hm2_rcpwmgen_update_regs(hostmot2_t *hm2) { } reg = ((hm2->rcpwmgen.clock_frequency/(16.0*1000.0)))*width -1; if ((reg +1) > 65535 ) { - *hm2->rcpwmgen.instance[i].hal.pin.width = 65535/(hm2->rcpwmgen.clock_frequency/(16.0*1000.0)); + hal_set_real(hm2->rcpwmgen.instance[i].hal.pin.width, 65535/(hm2->rcpwmgen.clock_frequency/(16.0*1000.0))); reg = 65535; if (hm2->rcpwmgen.error_throttle == 0) { - HM2_ERR("rcpwmgen %d width too large,resetting to %.3lf \n", i,*hm2->rcpwmgen.instance[i].hal.pin.width); + HM2_ERR("rcpwmgen %d width too large,resetting to %.3lf \n", i, hal_get_real(hm2->rcpwmgen.instance[i].hal.pin.width)); hm2->rcpwmgen.error_throttle = 100; } } @@ -261,8 +250,8 @@ void hm2_rcpwmgen_write(hostmot2_t *hm2) { // check rate - if ( *hm2->rcpwmgen.hal->pin.rate != hm2->rcpwmgen.written_rate) { - hm2->rcpwmgen.written_rate = *hm2->rcpwmgen.hal->pin.rate; + if ( hal_get_real(hm2->rcpwmgen.hal->pin.rate) != hm2->rcpwmgen.written_rate) { + hm2->rcpwmgen.written_rate = hal_get_real(hm2->rcpwmgen.hal->pin.rate); goto force_write; } diff --git a/src/hal/drivers/mesa-hostmot2/resolver.c b/src/hal/drivers/mesa-hostmot2/resolver.c index 0599eb39ae3..f8c3a064ac2 100644 --- a/src/hal/drivers/mesa-hostmot2/resolver.c +++ b/src/hal/drivers/mesa-hostmot2/resolver.c @@ -94,15 +94,13 @@ int hm2_resolver_parse_md(hostmot2_t *hm2, int md_index) { hm2->resolver.num_instances = md->instances; } - hm2->resolver.hal = (hm2_resolver_global_t *)hal_malloc( - sizeof(hm2_resolver_global_t)); + hm2->resolver.hal = hal_malloc(sizeof(*hm2->resolver.hal)); if (hm2->resolver.hal == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; goto fail0; } - hm2->resolver.instance = (hm2_resolver_instance_t *)hal_malloc( - hm2->resolver.num_resolvers * sizeof(hm2_resolver_instance_t)); + hm2->resolver.instance = hal_malloc(hm2->resolver.num_resolvers * sizeof(*hm2->resolver.instance)); if (hm2->resolver.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -142,161 +140,112 @@ int hm2_resolver_parse_md(hostmot2_t *hm2, int md_index) { // export the resolvers to HAL { - int i; - int ret; - char name[HAL_NAME_LEN + 1]; - - rtapi_snprintf(name, sizeof(name), "%s.resolver.excitation-khz", - hm2->llio->name); - ret= hal_param_float_new(name, HAL_RW, - &(hm2->resolver.hal->param.excitation_khz), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->resolver.hal->param.excitation_khz), + -1.0, "%s.resolver.excitation-khz", hm2->llio->name); + if (r < 0) { + HM2_ERR("error %d adding param '%s.resolver.excitation-khz', aborting\n", r, hm2->llio->name); goto fail1; } - for (i = 0; i < hm2->resolver.num_resolvers; i ++) { + for (int i = 0; i < hm2->resolver.num_resolvers; i ++) { // pins - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.position", - hm2->llio->name, i); - ret= hal_pin_float_new(name, HAL_OUT, - &(hm2->resolver.instance[i].hal.pin.position), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->resolver.instance[i].hal.pin.position), + 0.0, "%s.resolver.%02d.position", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.resolver.%02d.position', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.angle", - hm2->llio->name, i); - ret= hal_pin_float_new(name, HAL_OUT, - &(hm2->resolver.instance[i].hal.pin.angle), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->resolver.instance[i].hal.pin.angle), + 0.0, "%s.resolver.%02d.angle", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.resolver.%02d.angle', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.velocity", - hm2->llio->name, i); - ret= hal_pin_float_new(name, HAL_OUT, - &(hm2->resolver.instance[i].hal.pin.velocity), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->resolver.instance[i].hal.pin.velocity), + 0.0, "%s.resolver.%02d.velocity", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.resolver.%02d.velocity', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.velocity-rpm", - hm2->llio->name, i); - ret= hal_pin_float_new(name, HAL_OUT, - &(hm2->resolver.instance[i].hal.pin.velocity_rpm), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->resolver.instance[i].hal.pin.velocity_rpm), + 0.0, "%s.resolver.%02d.velocity-rpm", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.resolver.%02d.velocity-rpm', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.count", - hm2->llio->name, i); - ret= hal_pin_s32_new(name, HAL_OUT, - &(hm2->resolver.instance[i].hal.pin.count), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(hm2->resolver.instance[i].hal.pin.count), + 0, "%s.resolver.%02d.count", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.resolver.%02d.count', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.rawcounts", - hm2->llio->name, i); - ret= hal_pin_s32_new(name, HAL_OUT, - &(hm2->resolver.instance[i].hal.pin.rawcounts), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(hm2->resolver.instance[i].hal.pin.rawcounts), + 0, "%s.resolver.%02d.rawcounts", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.resolver.%02d.rawcounts', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.reset", - hm2->llio->name, i); - ret= hal_pin_bit_new(name, HAL_IN, - &(hm2->resolver.instance[i].hal.pin.reset), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->resolver.instance[i].hal.pin.reset), + 0, "%s.resolver.%02d.reset", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.resolver.%02d.reset', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.index-enable", - hm2->llio->name, i); - ret= hal_pin_bit_new(name, HAL_IO, - &(hm2->resolver.instance[i].hal.pin.index_enable), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IO, &(hm2->resolver.instance[i].hal.pin.index_enable), + 0, "%s.resolver.%02d.index-enable", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.resolver.%02d.index-enable', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.error", - hm2->llio->name, i); - ret= hal_pin_bit_new(name, HAL_OUT, - &(hm2->resolver.instance[i].hal.pin.error), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->resolver.instance[i].hal.pin.error), + 0, "%s.resolver.%02d.error", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.resolver.%02d.error', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.joint-pos-fb", - hm2->llio->name, i); - ret= hal_pin_float_new(name, HAL_IN, - &(hm2->resolver.instance[i].hal.pin.joint_pos_fb), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->resolver.instance[i].hal.pin.joint_pos_fb), + 0.0, "%s.resolver.%02d.joint-pos-fb", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding pin '%s.resolver.%02d.joint-pos-fb', aborting\n", r, hm2->llio->name, i); goto fail1; } // parameters - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.scale", - hm2->llio->name, i); - ret= hal_param_float_new(name, HAL_RW, - &(hm2->resolver.instance[i].hal.param.scale), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->resolver.instance[i].hal.param.scale), + 1.0, "%s.resolver.%02d.scale", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding param '%s.resolver.%02d.scale', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.velocity-scale", - hm2->llio->name, i); - ret= hal_param_float_new(name, HAL_RW, - &(hm2->resolver.instance[i].hal.param.vel_scale), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->resolver.instance[i].hal.param.vel_scale), + 1.0, "%s.resolver.%02d.velocity-scale", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding param '%s.resolver.%02d.velocity-scale', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.index-divisor", - hm2->llio->name, i); - ret= hal_param_u32_new(name, HAL_RW, - &(hm2->resolver.instance[i].hal.param.index_div), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->resolver.instance[i].hal.param.index_div), + 1, "%s.resolver.%02d.index-divisor", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding param '%s.resolver.%02d.index-divisor', aborting\n", r, hm2->llio->name, i); goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.resolver.%02d.use-position-file", - hm2->llio->name, i); - ret= hal_param_bit_new(name, HAL_RW, - &(hm2->resolver.instance[i].hal.param.use_abs), - hm2->llio->comp_id); - if (ret < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->resolver.instance[i].hal.param.use_abs), + 0, "%s.resolver.%02d.use-position-file", hm2->llio->name, i); + if (r < 0) { + HM2_ERR("error %d adding param '%s.resolver.%02d.use-position-file', aborting\n", r, hm2->llio->name, i); goto fail1; } @@ -304,12 +253,6 @@ int hm2_resolver_parse_md(hostmot2_t *hm2, int md_index) { // init the hal objects that need it // the things not initialized here will be set by hm2_resolver_tram_init() // - - *hm2->resolver.instance[i].hal.pin.reset = 0; - hm2->resolver.instance[i].hal.param.scale = 1.0; - hm2->resolver.instance[i].hal.param.vel_scale = 1.0; - hm2->resolver.instance[i].hal.param.index_div = 1; - hm2->resolver.hal->param.excitation_khz = -1; // don't-write hm2->resolver.kHz = (hm2->resolver.clock_frequency / 5000); } } @@ -341,23 +284,23 @@ void hm2_resolver_process_tram_read(hostmot2_t *hm2, long period) { res = &hm2->resolver.instance[i]; + scale = hal_get_real(res->hal.param.scale); + // sanity check - if (res->hal.param.scale == 0.0) { + if (scale == 0.0) { HM2_ERR("resolver.%02d.scale == 0.0, bogus, setting to 1.0\n", i); - res->hal.param.scale = 1.0; + scale = hal_set_real(res->hal.param.scale, 1.0); } - if (res->hal.param.vel_scale == 0.0) { + if (hal_get_real(res->hal.param.vel_scale) == 0.0) { HM2_ERR("resolver.%02d.velocity-scale == 0.0, bogus, setting to 1.0\n", i); - res->hal.param.vel_scale = 1.0; + hal_set_real(res->hal.param.vel_scale, 1.0); } - scale = res->hal.param.scale; - - if (res->hal.param.use_abs){ // pseudo-absolute behaviour enabled but not initialised + if (hal_get_bool(res->hal.param.use_abs)){ // pseudo-absolute behaviour enabled but not initialised double new_pos; int turns; - old_pos = *res->hal.pin.joint_pos_fb; + old_pos = hal_get_real(res->hal.pin.joint_pos_fb); if (old_pos == 0 && cycle_count++ < 5000 ) { // position.txt not updated yet. Or (small probability) position.txt = 0 continue; // stop and process next resolver } @@ -373,7 +316,7 @@ void hm2_resolver_process_tram_read(hostmot2_t *hm2, long period) { res->offset = -((turns * scale) - old_pos) * (0x1p32 / scale); res->old_reg = hm2->resolver.position_reg[i]; // prevent wrap detection at init. res->accum = hm2->resolver.position_reg[i]; //necessary to allow rawcounts to still work for commutation - res->hal.param.use_abs = 0; // tag as initialised + hal_set_bool(res->hal.param.use_abs, 0); // tag as initialised } // PROCESS THE REGISTERS, SET THE PINS @@ -382,38 +325,39 @@ 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 (*res->hal.pin.index_enable){ - int r = (res->index_cnts % res->hal.param.index_div); - if ((res->hal.param.index_div > 1 && r == 1) - || (res->hal.param.index_div == 1 && r == 0)){ + 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)){ res->offset = (res->accum - hm2->resolver.position_reg[i]); - *res->hal.pin.index_enable = 0; + hal_set_bool(res->hal.pin.index_enable, 0); } } } else if ((res->old_reg < hm2->resolver.position_reg[i]) && (hm2->resolver.position_reg[i] - res->old_reg > 0x80000000)){ res->index_cnts--; - if (*res->hal.pin.index_enable && (res->index_cnts % res->hal.param.index_div == 0)){ + if (hal_get_bool(res->hal.pin.index_enable) && (res->index_cnts % hal_get_ui32(res->hal.param.index_div) == 0)){ res->offset = (res->accum - hm2->resolver.position_reg[i] + 0x100000000LL); - *res->hal.pin.index_enable = 0; + hal_set_bool(res->hal.pin.index_enable, 0); } } - if (*res->hal.pin.reset){ + if (hal_get_bool(res->hal.pin.reset)){ res->offset = res->accum; } res->old_reg = hm2->resolver.position_reg[i]; - *res->hal.pin.angle = hm2->resolver.position_reg[i] / 0x1P32; - *res->hal.pin.rawcounts = (res->accum >> 8); - *res->hal.pin.count = (res->accum - res->offset) >> 8; - *res->hal.pin.position = (res->accum - res->offset) / 0x1P32 - * res->hal.param.scale; - *res->hal.pin.velocity = ((hm2->resolver.velocity_reg[i] / 0x1P32) - * hm2->resolver.kHz * res->hal.param.vel_scale); - *res->hal.pin.velocity_rpm = *res->hal.pin.velocity * 60.0; - *res->hal.pin.error = *hm2->resolver.status_reg & (1 << i); + hal_set_real(res->hal.pin.angle, hm2->resolver.position_reg[i] / 0x1P32); + hal_set_si32(res->hal.pin.rawcounts, (res->accum >> 8)); + hal_set_si32(res->hal.pin.count, (res->accum - res->offset) >> 8); + hal_set_real(res->hal.pin.position, (res->accum - res->offset) / 0x1P32 + * hal_get_real(res->hal.param.scale)); + hal_set_real(res->hal.pin.velocity, ((hm2->resolver.velocity_reg[i] / 0x1P32) + * hm2->resolver.kHz * hal_get_real(res->hal.param.vel_scale))); + hal_set_real(res->hal.pin.velocity_rpm, hal_get_real(res->hal.pin.velocity) * 60.0); + hal_set_bool(res->hal.pin.error, *hm2->resolver.status_reg & (1 << i)); } } @@ -424,27 +368,29 @@ void hm2_resolver_write(hostmot2_t *hm2, long period){ static rtapi_u32 cmd_val, data_val; static rtapi_u32 timer; rtapi_u32 buff; + rtapi_real exc; if (hm2->resolver.num_instances <= 0) return; switch (state){ case 0: // Idle/waiting - if (hm2->resolver.hal->param.excitation_khz < 0){ + exc = hal_get_real(hm2->resolver.hal->param.excitation_khz); + if (exc < 0){ return; } - if (hm2->resolver.hal->param.excitation_khz != hm2->resolver.written_khz){ - if (hm2->resolver.hal->param.excitation_khz > 8){ - hm2->resolver.hal->param.excitation_khz = 10; + if (exc != hm2->resolver.written_khz){ + if (exc > 8){ + hal_set_real(hm2->resolver.hal->param.excitation_khz, 10); hm2->resolver.written_khz = 10; hm2->resolver.kHz = (hm2->resolver.clock_frequency / 5000); cmd_val = 0x803; - } else if (hm2->resolver.hal->param.excitation_khz > 4){ - hm2->resolver.hal->param.excitation_khz = 5; + } else if (exc > 4){ + hal_set_real(hm2->resolver.hal->param.excitation_khz, 5); hm2->resolver.written_khz = 5; hm2->resolver.kHz = (hm2->resolver.clock_frequency / 10000); cmd_val = 0x802; }else{ - hm2->resolver.hal->param.excitation_khz = 2.5; + hal_set_real(hm2->resolver.hal->param.excitation_khz, 2.5); hm2->resolver.written_khz = 2.5; hm2->resolver.kHz= (hm2->resolver.clock_frequency / 20000); cmd_val = 0x801; diff --git a/src/hal/drivers/mesa-hostmot2/sserial.c b/src/hal/drivers/mesa-hostmot2/sserial.c index 97d4fc2f033..66051ead626 100644 --- a/src/hal/drivers/mesa-hostmot2/sserial.c +++ b/src/hal/drivers/mesa-hostmot2/sserial.c @@ -66,7 +66,7 @@ int hm2_sserial_wait(hostmot2_t *hm2, hm2_sserial_instance_t *inst, long period) // real-time wait function (relies on process data) *inst->command_reg_write = 0x80000000; // mask pointless writes inst->timer -= period; - *inst->debug = inst->timer; + hal_set_si32(inst->debug, inst->timer); if (*inst->command_reg_read != 0) { if (inst->timer > 0) { return 1; @@ -359,30 +359,30 @@ int hm2_sserial_get_param_value(hostmot2_t *hm2, r = hm2_sserial_get_bytes(hm2, chan, (void*)&(p->u32_written), g->ParmAddr, g->DataLength/8); if (r < 0) {HM2_ERR("SSerial Parameter read error\n") ; return -EINVAL;} - if (set_hal) p->u32_param = p->u32_written; - HM2_DBG("LBP_UNSIGNED %i %i \n", p->u32_param, p->u32_written); - if ((strcmp(g->NameString, "swrevision") == 0) && (p->u32_param < 14)) { + if (set_hal) hal_set_ui32(p->param.u, p->u32_written); + HM2_DBG("LBP_UNSIGNED %i %i \n", hal_get_ui32(p->param.u), p->u32_written); + if ((strcmp(g->NameString, "swrevision") == 0) && (hal_get_ui32(p->param.u) < 14)) { HM2_ERR("Warning: sserial remote device %s channel %d has old firmware that should be updated\n", chan->raw_name, chan->index); } break; case LBP_SIGNED: r = hm2_sserial_get_bytes(hm2, chan, (void*)&(p->s32_written), g->ParmAddr, g->DataLength/8); - if (set_hal) p->s32_param = p->s32_written; - HM2_DBG("LBP_SIGNED %i %i \n", p->s32_param, p->s32_written); + if (set_hal) hal_set_si32(p->param.s, p->s32_written); + HM2_DBG("LBP_SIGNED %i %i \n", hal_get_si32(p->param.s), p->s32_written); break; case LBP_NONVOL_UNSIGNED: r = hm2_sserial_read_nvram_word(hm2, chan, (void*)&(p->u32_written), g->ParmAddr, g->DataLength/8); - if (set_hal) p->u32_param = p->u32_written; - HM2_DBG("LBP_NONVOL_UNSIGNED %i %i \n", p->u32_param, p->u32_written); + if (set_hal) hal_set_ui32(p->param.u, p->u32_written); + HM2_DBG("LBP_NONVOL_UNSIGNED %i %i \n", hal_get_ui32(p->param.u), p->u32_written); break; case LBP_NONVOL_SIGNED: r = hm2_sserial_read_nvram_word(hm2, chan, (void*)&(p->s32_written), g->ParmAddr, g->DataLength/8); - if (set_hal) p->s32_param = p->s32_written; + if (set_hal) hal_set_si32(p->param.s, p->s32_written); case LBP_STREAM: break; // Have not seen a stream type yet case LBP_BOOLEAN: @@ -405,8 +405,8 @@ int hm2_sserial_get_param_value(hostmot2_t *hm2, HM2_ERR("sserial get param value: LBP_FLOAT of bit-length %i not handled\n", g->DataLength); } } - if (set_hal) p->float_param = p->float_written; - HM2_DBG("LBP_FLOAT %f %f \n", p->float_param, p->float_written); + if (set_hal) hal_set_real(p->param.r, p->float_written); + HM2_DBG("LBP_FLOAT %f %f \n", hal_get_real(p->param.r), p->float_written); break; case LBP_ENCODER_H: case LBP_ENCODER_L: @@ -423,7 +423,7 @@ int hm2_sserial_create_params(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ hm2_sserial_data_t global; int hal_dir; - chan->params = hal_malloc(chan->num_globals * sizeof(hm2_sserial_params_t)); + chan->params = hal_malloc(chan->num_globals * sizeof(*chan->params)); for (i = 0 ; i < chan->num_globals ; i++){ global = chan->globals[i]; @@ -437,9 +437,9 @@ int hm2_sserial_create_params(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ break; case LBP_UNSIGNED: case LBP_NONVOL_UNSIGNED: - r = hal_param_u32_newf(hal_dir, - &(chan->params[i].u32_param), - hm2->llio->comp_id, + r = hal_param_new_ui32(hm2->llio->comp_id, hal_dir, + &(chan->params[i].param.u), + 0, "%s.%s", chan->name, global.NameString); @@ -447,9 +447,9 @@ int hm2_sserial_create_params(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ break; case LBP_SIGNED: case LBP_NONVOL_SIGNED: - r = hal_param_s32_newf(hal_dir, - &(chan->params[i].s32_param), - hm2->llio->comp_id, + r = hal_param_new_si32(hm2->llio->comp_id, hal_dir, + &(chan->params[i].param.s), + 0, "%s.%s", chan->name, global.NameString); @@ -457,18 +457,23 @@ int hm2_sserial_create_params(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ break; case LBP_FLOAT: case LBP_NONVOL_FLOAT: - r = hal_param_float_newf(hal_dir, - &(chan->params[i].float_param), - hm2->llio->comp_id, + r = hal_param_new_real(hm2->llio->comp_id, hal_dir, + &(chan->params[i].param.r), + 0.0, "%s.%s", chan->name, global.NameString); if (r < 0) {HM2_ERR("Out of memory\n") ; return -ENOMEM;} + break; case LBP_STREAM: // Don't anticipate seeing these as params case LBP_BOOLEAN: case LBP_ENCODER: case LBP_ENCODER_H: case LBP_ENCODER_L: + default: + // Still make sure we have memory allocated for a fake parameter + r = hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(chan->params[i].param.r)); + if (r < 0) {HM2_ERR("Out of memory\n") ; return -ENOMEM;} break; } @@ -628,8 +633,7 @@ int hm2_sserial_parse_md(hostmot2_t *hm2, int md_index){ HM2_DBG("sserial_num_instances = %i\n", hm2->sserial.num_instances); // allocate the per-instance HAL shared memory - hm2->sserial.instance = (hm2_sserial_instance_t *) - hal_malloc(hm2->sserial.num_instances * sizeof(hm2_sserial_instance_t)); + hm2->sserial.instance = hal_malloc(hm2->sserial.num_instances * sizeof(*hm2->sserial.instance)); if (hm2->sserial.instance == NULL) { HM2_ERR("hm2_sserial_parse_md: hm2_sserial_instance: out of memory!\n"); r = -ENOMEM; @@ -849,97 +853,74 @@ int hm2_sserial_parse_md(hostmot2_t *hm2, int md_index){ int hm2_sserial_setup_channel(hostmot2_t *hm2, hm2_sserial_instance_t *inst, int index){ int r; - r = hal_pin_s32_newf(HAL_OUT, &(inst->debug), - hm2->llio->comp_id, - "%s.%i.debug", - hm2->llio->name, index); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(inst->debug), + 0, "%s.%i.debug", hm2->llio->name, index); if (r < 0) { - HM2_ERR("error adding pin %s.sserial.%1d.run. aborting\n", - hm2->llio->name, index); + HM2_ERR("error %d adding pin %s.sserial.%1d.run. aborting\n", + r, hm2->llio->name, index); return -EINVAL; } - r = hal_pin_bit_newf(HAL_IN, &(inst->run), - hm2->llio->comp_id, - "%s.sserial.port-%1d.run", - hm2->llio->name, index); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(inst->run), + true, "%s.sserial.port-%1d.run", hm2->llio->name, index); if (r < 0) { - HM2_ERR("error adding pin %s.sserial.%1d.run. aborting\n", - hm2->llio->name, index); + HM2_ERR("error %d adding pin %s.sserial.%1d.run. aborting\n", + r, hm2->llio->name, index); return -EINVAL; } - *inst->run = true; - r = hal_pin_u32_newf(HAL_OUT, &(inst->state), - hm2->llio->comp_id, - "%s.sserial.port-%1d.port_state", - hm2->llio->name, index); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_OUT, &(inst->state), + 0, "%s.sserial.port-%1d.port_state", hm2->llio->name, index); if (r < 0) { - HM2_ERR("error adding pin %s.sserial.%1d.port_state. aborting\n", - hm2->llio->name, index); + HM2_ERR("error %d adding pin %s.sserial.%1d.port_state. aborting\n", + r, hm2->llio->name, index); return -EINVAL; } - r = hal_pin_u32_newf(HAL_OUT, &(inst->state2), - hm2->llio->comp_id, - "%s.sserial.port-%1d.port_state2", - hm2->llio->name, index); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_OUT, &(inst->state2), + 0, "%s.sserial.port-%1d.port_state2", hm2->llio->name, index); if (r < 0) { - HM2_ERR("error adding pin %s.sserial.%1d.port_state. aborting\n", - hm2->llio->name, index); + HM2_ERR("error %d adding pin %s.sserial.%1d.port_state. aborting\n", + r, hm2->llio->name, index); return -EINVAL; } - r = hal_pin_u32_newf(HAL_OUT, &(inst->state3), - hm2->llio->comp_id, - "%s.sserial.port-%1d.port_state3", - hm2->llio->name, index); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_OUT, &(inst->state3), + 0, "%s.sserial.port-%1d.port_state3", hm2->llio->name, index); if (r < 0) { - HM2_ERR("error adding pin %s.sserial.%1d.port_state. aborting\n", - hm2->llio->name, index); + HM2_ERR("error %d adding pin %s.sserial.%1d.port_state. aborting\n", + r, hm2->llio->name, index); return -EINVAL; } - r = hal_pin_u32_newf(HAL_OUT, &(inst->fault_count), - hm2->llio->comp_id, - "%s.sserial.port-%1d.fault-count", - hm2->llio->name, index); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_OUT, &(inst->fault_count), + 0, "%s.sserial.port-%1d.fault-count", hm2->llio->name, index); if (r < 0) { - HM2_ERR("error adding pin %s.sserial.%1d.fault-count. aborting\n", - hm2->llio->name, index); + HM2_ERR("error %d adding pin %s.sserial.%1d.fault-count. aborting\n", + r, hm2->llio->name, index); return -EINVAL; } - r = hal_param_u32_newf(HAL_RW, &(inst->fault_inc), - hm2->llio->comp_id, - "%s.sserial.port-%1d.fault-inc", - hm2->llio->name, index); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(inst->fault_inc), + 10, "%s.sserial.port-%1d.fault-inc", hm2->llio->name, index); if (r < 0) { - HM2_ERR("error adding parameter %s.sserial.port-%1d.fault-inc" - " aborting\n",hm2->llio->name, index); + HM2_ERR("error %d adding parameter %s.sserial.port-%1d.fault-inc" + " aborting\n", r, hm2->llio->name, index); return -EINVAL; } - r = hal_param_u32_newf(HAL_RW, &(inst->fault_dec), - hm2->llio->comp_id, - "%s.sserial.port-%1d.fault-dec", - hm2->llio->name, index); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(inst->fault_dec), + 1, "%s.sserial.port-%1d.fault-dec", hm2->llio->name, index); if (r < 0) { - HM2_ERR("error adding parameter %s.sserial.port-%1d.fault-dec" - " aborting\n",hm2->llio->name, index); + HM2_ERR("error %d adding parameter %s.sserial.port-%1d.fault-dec" + " aborting\n", r, hm2->llio->name, index); return -EINVAL; } - r = hal_param_u32_newf(HAL_RW, &(inst->fault_lim), - hm2->llio->comp_id, - "%s.sserial.port-%1d.fault-lim", - hm2->llio->name, index); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(inst->fault_lim), + 200, "%s.sserial.port-%1d.fault-lim", hm2->llio->name, index); if (r < 0) { - HM2_ERR("error adding parameter %s.sserial.port-%1d.fault-lim" - " aborting\n",hm2->llio->name, index); + HM2_ERR("error %d adding parameter %s.sserial.port-%1d.fault-lim" + " aborting\n", r, hm2->llio->name, index); return -EINVAL; } - //parameter defaults; - inst->fault_dec = 1; - inst->fault_inc = 10; - inst->fault_lim = 200; // setup read-back in all modes @@ -1118,10 +1099,8 @@ int hm2_sserial_read_configs(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ int hm2_sserial_create_pins(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ int i, j; int r = 0; - char name[HAL_NAME_LEN + 1]; int data_dir; - chan->pins = (hm2_sserial_pins_t*)hal_malloc(chan->num_confs - * sizeof(hm2_sserial_pins_t)); + chan->pins = hal_malloc(chan->num_confs * sizeof(*chan->pins)); chan->num_read_bits = 0 ; chan->num_write_bits = 0; @@ -1173,51 +1152,31 @@ int hm2_sserial_create_pins(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ case LBP_PAD: break; case LBP_BITS: - chan->pins[i].bit_pins = (hal_bit_t**) - hal_malloc(chan->confs[i].DataLength * sizeof(hal_bit_t*)); - chan->pins[i].bit_pins_not = (hal_bit_t**) - hal_malloc(chan->confs[i].DataLength * sizeof(hal_bit_t*)); - chan->pins[i].invert = (hal_bit_t*) - hal_malloc(chan->confs[i].DataLength * sizeof(hal_bit_t)); + chan->pins[i].bit_pins = hal_malloc(chan->confs[i].DataLength * sizeof(*chan->pins[i].bit_pins)); + chan->pins[i].bit_pins_not = hal_malloc(chan->confs[i].DataLength * sizeof(*chan->pins[i].bit_pins_not)); + chan->pins[i].invert = hal_malloc(chan->confs[i].DataLength * sizeof(*chan->pins[i].invert)); for (j = 0; j < chan->confs[i].DataLength ; j++){ - rtapi_snprintf(name, sizeof(name), "%s.%s-%02d", - chan->name, - chan->confs[i].NameString, - j); - r = hal_pin_bit_new(name, - data_dir, - &(chan->pins[i].bit_pins[j]), - hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, data_dir, &(chan->pins[i].bit_pins[j]), + 0, "%s.%s-%02d", chan->name, chan->confs[i].NameString, j); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s-%02d', aborting\n", r, chan->name, chan->confs[i].NameString, j); return r; } if (data_dir == HAL_OUT) { - rtapi_snprintf(name, sizeof(name), "%s.%s-%02d-not", - chan->name, - chan->confs[i].NameString, - j); - r = hal_pin_bit_new(name, - data_dir, - &(chan->pins[i].bit_pins_not[j]), - hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, data_dir, &(chan->pins[i].bit_pins_not[j]), + 0, "%s.%s-%02d-not", chan->name, chan->confs[i].NameString, j); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s-%02d-not', aborting\n", r, chan->name, chan->confs[i].NameString, j); return r; } } if (data_dir == HAL_IN){ - rtapi_snprintf(name, sizeof(name), "%s.%s-%02d-invert", - chan->name, - chan->confs[i].NameString, - j); - r = hal_param_bit_new(name, - HAL_RW, - &(chan->pins[i].invert[j]), - hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(chan->pins[i].invert[j]), + 0, "%s.%s-%02d-invert", chan->name, chan->confs[i].NameString, j); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s-%02d-invert', aborting\n", + r, chan->name, chan->confs[i].NameString, j); return r; } } @@ -1225,54 +1184,31 @@ int hm2_sserial_create_pins(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ break; case LBP_UNSIGNED: case LBP_SIGNED: - rtapi_snprintf(name, sizeof(name), "%s.%s", - chan->name, - chan->confs[i].NameString); - r = hal_pin_float_new(name, - data_dir, - &(chan->pins[i].float_pin), - hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, data_dir, &(chan->pins[i].float_pin), + 0.0, "%s.%s", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s', aborting\n", r, chan->name, chan->confs[i].NameString); return r; } - rtapi_snprintf(name, sizeof(name), "%s.%s-scalemax", - chan->name, - chan->confs[i].NameString); - r = hal_param_float_new(name, - HAL_RW, - &(chan->pins[i].fullscale), - hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(chan->pins[i].fullscale), + chan->confs[i].ParmMax, "%s.%s-scalemax", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s-scalemax', aborting\n", r, chan->name, chan->confs[i].NameString); return r; } - chan->pins[i].fullscale = chan->confs[i].ParmMax; if (data_dir == HAL_OUT) {break;} - rtapi_snprintf(name, sizeof(name), "%s.%s-maxlim", - chan->name, - chan->confs[i].NameString); - r = hal_param_float_new(name, - HAL_RW, - &(chan->pins[i].maxlim), - hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(chan->pins[i].maxlim), + chan->confs[i].ParmMax, "%s.%s-maxlim", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s-maxlim', aborting\n", r, chan->name, chan->confs[i].NameString); return r; } - chan->pins[i].maxlim = chan->confs[i].ParmMax; - rtapi_snprintf(name, sizeof(name), "%s.%s-minlim", - chan->name, - chan->confs[i].NameString); - r = hal_param_float_new(name, - HAL_RW, - &(chan->pins[i].minlim), - hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(chan->pins[i].minlim), + chan->confs[i].ParmMin, "%s.%s-minlim", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s-minlim', aborting\n", r, chan->name, chan->confs[i].NameString); return r; } - chan->pins[i].minlim = chan->confs[i].ParmMin; break; case LBP_NONVOL_UNSIGNED: case LBP_NONVOL_SIGNED: @@ -1280,156 +1216,95 @@ int hm2_sserial_create_pins(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ "never happen. Aborting"); return r; case LBP_STREAM: - rtapi_snprintf(name, sizeof(name), "%s.%s", - chan->name, - chan->confs[i].NameString); - r = hal_pin_u32_new(name, - data_dir, - &(chan->pins[i].u32_pin), - hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, data_dir, &(chan->pins[i].u32_pin), + 0, "%s.%s", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s', aborting\n", r, chan->name, chan->confs[i].NameString); return r; } break; case LBP_BOOLEAN: - rtapi_snprintf(name, sizeof(name), "%s.%s", - chan->name, - chan->confs[i].NameString); - r = hal_pin_bit_new(name, - data_dir, - &(chan->pins[i].boolean), - hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, data_dir, &(chan->pins[i].boolean), + 0, "%s.%s", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s', aborting\n", r, chan->name, chan->confs[i].NameString); return r; } if (data_dir == HAL_OUT) { - rtapi_snprintf(name, sizeof(name), "%s.%s-not", - chan->name, - chan->confs[i].NameString); - r = hal_pin_bit_new(name, - data_dir, - &(chan->pins[i].boolean2), - hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, data_dir, &(chan->pins[i].boolean2), + 0, "%s.%s-not", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s-not', aborting\n", r, chan->name, chan->confs[i].NameString); return r; } } if (data_dir == HAL_IN) { - chan->pins[i].invert = hal_malloc(sizeof(hal_bit_t)); - rtapi_snprintf(name, sizeof(name), "%s.%s-invert", - chan->name, - chan->confs[i].NameString); - r = hal_param_bit_new(name, - HAL_RW, - chan->pins[i].invert, - hm2->llio->comp_id); + chan->pins[i].invert = hal_malloc(sizeof(*chan->pins[i].invert)); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, chan->pins[i].invert, + 0, "%s.%s-invert", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s-invert', aborting\n", r, chan->name, chan->confs[i].NameString); return r; } } break; case LBP_ENCODER: case LBP_ENCODER_H: - - rtapi_snprintf(name, sizeof(name), "%s.%s.count", - chan->name, - chan->confs[i].NameString); - r = hal_pin_s32_new(name, - HAL_OUT, - &(chan->pins[i].s32_pin), - hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(chan->pins[i].s32_pin), + 0, "%s.%s.count", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s.count', aborting\n", r, chan->name, chan->confs[i].NameString); return -EINVAL; } - rtapi_snprintf(name, sizeof(name), "%s.%s.rawcounts", - chan->name, - chan->confs[i].NameString); - r = hal_pin_s32_new(name, - HAL_OUT, - &(chan->pins[i].s32_pin2), - hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(chan->pins[i].s32_pin2), + 0, "%s.%s.rawcounts", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s.rawcounts', aborting\n", r, chan->name, chan->confs[i].NameString); return -EINVAL; } - rtapi_snprintf(name, sizeof(name), "%s.%s.position", - chan->name, - chan->confs[i].NameString); - r = hal_pin_float_new(name, - HAL_OUT, - &(chan->pins[i].float_pin), - hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(chan->pins[i].float_pin), + 0.0, "%s.%s.position", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s.position', aborting\n", r, chan->name, chan->confs[i].NameString); return -EINVAL; } - rtapi_snprintf(name, sizeof(name), "%s.%s.index-enable", - chan->name, - chan->confs[i].NameString); - r = hal_pin_bit_new(name, - HAL_IO, - &(chan->pins[i].boolean), - hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IO, &(chan->pins[i].boolean), + 0, "%s.%s.index-enable", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s.index-enable', aborting\n", r, chan->name, chan->confs[i].NameString); return -EINVAL; } - rtapi_snprintf(name, sizeof(name), "%s.%s.reset", - chan->name, - chan->confs[i].NameString); - r = hal_pin_bit_new(name, - HAL_IO, - &(chan->pins[i].boolean2), - hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IO, &(chan->pins[i].boolean2), + 0, "%s.%s.reset", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s.reset', aborting\n", r, chan->name, chan->confs[i].NameString); return -EINVAL; } - rtapi_snprintf(name, sizeof(name), "%s.%s.scale", - chan->name, - chan->confs[i].NameString); - r = hal_param_float_new(name, - HAL_RW, - &(chan->pins[i].fullscale), - hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(chan->pins[i].fullscale), + chan->confs[i].ParmMax, "%s.%s.scale", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s.scale', aborting\n", + r, chan->name, chan->confs[i].NameString); return -EINVAL; } - rtapi_snprintf(name, sizeof(name), "%s.%s.counts-per-rev", - chan->name, - chan->confs[i].NameString); - r = hal_param_u32_new(name, - HAL_RW, - &(chan->pins[i].u32_param), - hm2->llio->comp_id); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(chan->pins[i].u32_param), + 256, "%s.%s.counts-per-rev", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s.counts-per-rev', aborting\n", + r, chan->name, chan->confs[i].NameString); return -EINVAL; } - chan->pins[i].fullscale = chan->confs[i].ParmMax; - chan->pins[i].u32_param = 256; break; case LBP_ENCODER_L: //No pins for encoder L break; case LBP_FLOAT: - rtapi_snprintf(name, sizeof(name), "%s.%s", - chan->name, - chan->confs[i].NameString); - r = hal_pin_float_new(name, - data_dir, - &(chan->pins[i].float_pin), - hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, data_dir, &(chan->pins[i].float_pin), + 0.0, "%s.%s", chan->name, chan->confs[i].NameString); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.%s', aborting\n", r, chan->name, chan->confs[i].NameString); return r; } break; @@ -1499,11 +1374,11 @@ int hm2_sserial_register_tram(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ hm2_sserial_data_t *g; int shift; // used for floating point comparisons - switch (*inst->state2){ + switch (hal_get_ui32(inst->state2)){ case 0: // init loop counters inst->r_index = 0; inst->g_index = 0; - *inst->state2 = 1; + hal_set_ui32(inst->state2, 1); /* Fallthrough */ case 1: if (inst->num_remotes == 0) return 0; @@ -1512,29 +1387,27 @@ int hm2_sserial_register_tram(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ p = &(r->params[inst->g_index]); g = &(r->globals[inst->g_index]); } else { - *inst->state2 = 2; + hal_set_ui32(inst->state2, 2); break; } - switch (*inst->state3){ + switch (hal_get_ui32(inst->state3)){ //Commands are queued for TRAM write, so every change in //command needs a break to poll the thread int ret; default: - HM2_ERR("Unhandled state %i", *inst->state3); + HM2_ERR("Unhandled state %i", hal_get_ui32(inst->state3)); return 1; case 0: HM2_DBG("Checking Param %s datatype %02X\n", g->NameString, p->type); switch (p->type){ case LBP_SIGNED: case LBP_NONVOL_SIGNED: - if (p->s32_param != p->s32_written) break; - *inst->state2 = 2; // increment indices - return *inst->state2; + if (hal_get_si32(p->param.s) != p->s32_written) break; + return hal_set_ui32(inst->state2, 2); // increment indices case LBP_UNSIGNED: case LBP_NONVOL_UNSIGNED: - if (p->u32_param != p->u32_written) break; - *inst->state2 = 2; // increment indices - return *inst->state2; + if (hal_get_ui32(p->param.u) != p->u32_written) break; + return hal_set_ui32(inst->state2, 2); // increment indices case LBP_FLOAT: case LBP_NONVOL_FLOAT: // comparing floats that might have different sizes is not trivial @@ -1554,30 +1427,31 @@ int hm2_sserial_register_tram(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ case 64: shift = 0; } - if (xlabs((p->s64_param - p->s64_written) >> shift) > 2) break; - *inst->state2 = 2; // increment indices - return *inst->state2; + // FIXME: This overlayed s64 read is very wrong! + if (xlabs((hal_get_sint(p->param.s) - p->s64_written) >> shift) > 2) break; + return hal_set_ui32(inst->state2, 2); // increment indices default: - *inst->state2 = 2; // increment indices - return *inst->state2; + return hal_set_ui32(inst->state2, 2); // increment indices } HM2_WARN("Writing value of %s datatype %02X\n", g->NameString, p->type); - *inst->state3 = 1; + hal_set_ui32(inst->state3, 1); inst->timer = 20000000; *inst->command_reg_write = 0x800; // stop all break; case 1: ret = hm2_sserial_wait(hm2, inst, period); if (ret > 0) break; - if (ret < 0) *inst->state3 = 100; // quit and tidy up - *inst->state3 = 2; + // FIXME: Assigns 100 to state3 and then unconditionally assigns 2 + if (ret < 0) hal_set_ui32(inst->state3, 100); // quit and tidy up + hal_set_ui32(inst->state3, 2); inst->timer = 20000000; *inst->command_reg_write = 0xF00 | (1 << r->index); // channel in setup mode break; case 2: // Unlock Nonvol access ret = hm2_sserial_wait(hm2, inst, period); if (ret > 0) break; - if (ret < 0) *inst->state3 = 100; // quit and tidy up + // FIXME: Assigns 100 to state3 and then 3 or 4 inside the if/else. + if (ret < 0) hal_set_ui32(inst->state3, 100); // quit and tidy up if ( p->type == LBP_NONVOL_FLOAT || p->type == LBP_NONVOL_UNSIGNED || p->type == LBP_NONVOL_SIGNED){ @@ -1585,38 +1459,39 @@ int hm2_sserial_register_tram(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ *r->write[0] = LBPNONVOLEEPROM; *inst->command_reg_write = 0x1000 | (1 << r->index); // doit command inst->timer = 20000000; - *inst->state3 = 3; + hal_set_ui32(inst->state3, 3); HM2_PRINT("A non-volatile smart-serial parameter has been changed\n" "A full power-cycle will be needed before the effect is seen\n"); } else { - *inst->state3 = 4; + hal_set_ui32(inst->state3, 4); } break; case 3: // wait for doit clear ret = hm2_sserial_wait(hm2, inst, period); if (ret > 0) break; - if (ret < 0) *inst->state3 = 100; // quit and tidy up + // FIXME: Assigns 100 to state3 and then unconditionally assigns 4 + if (ret < 0) hal_set_ui32(inst->state3, 100); // quit and tidy up // NV access now enabled. HM2_DBG("NV Access unlocked: param %s\n", g->NameString); - *inst->state3 = 4; + hal_set_ui32(inst->state3, 4); break; case 4: // Now send the data switch (p->type){ case LBP_SIGNED: case LBP_NONVOL_SIGNED: - *r->write[0] = (rtapi_u32) p->s32_param; + *r->write[0] = (rtapi_u32)hal_get_si32(p->param.s); break; case LBP_UNSIGNED: case LBP_NONVOL_UNSIGNED: - *r->write[0] = p->u32_param; + *r->write[0] = hal_get_ui32(p->param.u); break; case LBP_FLOAT: case LBP_NONVOL_FLOAT: if (g->DataLength == sizeof(float) * 8 ){ - float temp = p->float_param; + float temp = hal_get_real(p->param.r); memcpy(r->write[0], &temp, sizeof(float)); // Data Value } else if (g->DataLength == sizeof(double) * 8){ - double temp = p->float_param; + double temp = hal_get_real(p->param.r); memcpy(r->write[0], &temp, sizeof(double)); } else { HM2_ERR("sserial write: LBP_FLOAT of bit-length %i not handled\n", g->DataLength); @@ -1642,26 +1517,27 @@ int hm2_sserial_register_tram(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ } *inst->command_reg_write = 0x1000 | (1 << r->index); // doit command inst->timer = 200000000; - *inst->state3 = 5; + hal_set_ui32(inst->state3, 5); break; case 5: // wait for doit clear ret = hm2_sserial_wait(hm2, inst, period); if (ret > 0) break; - if (ret < 0) *inst->state3 = 100; // quit and tidy up + // FIXME: Assigns 100 to state3 and then 7 or 8 inside the if/else. + if (ret < 0) hal_set_ui32(inst->state3, 100); // quit and tidy up // success? Set the written = param switch (p->type){ case LBP_SIGNED: case LBP_NONVOL_SIGNED: - p->s32_written = p->s32_param; + p->s32_written = hal_get_si32(p->param.s); break; case LBP_UNSIGNED: case LBP_NONVOL_UNSIGNED: - p->u32_written = p->u32_param; + p->u32_written = hal_get_ui32(p->param.u); break; case LBP_FLOAT: case LBP_NONVOL_FLOAT: - p->float_written = p->float_param; + p->float_written = hal_get_real(p->param.r); break; default: break; @@ -1676,52 +1552,54 @@ int hm2_sserial_register_tram(hostmot2_t *hm2, hm2_sserial_remote_t *chan){ *r->write[0] = LBPNONVOLCLEAR; *inst->command_reg_write = 0x1000 | (1 << r->index); // doit command inst->timer = 0x2000000; - *inst->state3 = 7; + hal_set_ui32(inst->state3, 7); } else { - *inst->state3 = 8; + hal_set_ui32(inst->state3, 8); } break; case 7: // wait for doit clear ret = hm2_sserial_wait(hm2, inst, period); if (ret > 0) break; - if (ret < 0) *inst->state3 = 100; // quit and tidy up + // FIXME: Assigns 100 to state3 and then unconditionally assigns 8 + if (ret < 0) hal_set_ui32(inst->state3, 100); // quit and tidy up // NV access now cleared HM2_DBG("NV Access Cleared: param %s\n", g->NameString); - * inst->state3 = 8; + hal_set_ui32(inst->state3, 8); break; case 8: // stop-all inst->timer = 0x2000000; *inst->command_reg_write = 0x800; //stop - *inst->state3 = 9; + hal_set_ui32(inst->state3, 9); break; case 9: //wait for final stop-all ret = hm2_sserial_wait(hm2, inst, period); if (ret > 0) break; - if (ret < 0) *inst->state3 = 100; // quit and tidy up + // FIXME: Assigns 100 to state3 and then unconditionally assigns 0 + if (ret < 0) hal_set_ui32(inst->state3, 100); // quit and tidy up // NV access now cleared HM2_DBG("Board out of setup mode: param %s\n", g->NameString); - *inst->state3 = 0; - *inst->state2 = 2; // increment indices + hal_set_ui32(inst->state3, 0); + hal_set_ui32(inst->state2, 2); // increment indices break; case 100: // error recovery HM2_ERR("Problem found writing sserial parameter %s\n", g->NameString); *inst->command_reg_write = 0x800; //stop all command - *inst->state3 = 0; - *inst->state2 = 2; // increment indices + hal_set_ui32(inst->state3, 0); + hal_set_ui32(inst->state2, 2); // increment indices break; } // End of switch(inst->state3) break; case 2: - *inst->state2 = 1; + hal_set_ui32(inst->state2, 1); if ((int)++inst->g_index >= inst->remotes[inst->r_index].num_globals){ inst->g_index = 0; if ((int)++inst->r_index >= inst->num_remotes){//checked them all - *inst->state2 = 0; + hal_set_ui32(inst->state2, 0); } } break; } // end of switch(inst->state2) - return *inst->state2; + return hal_get_ui32(inst->state2); } void hm2_sserial_write_pins(hostmot2_t *hm2, hm2_sserial_instance_t *inst){ @@ -1733,7 +1611,8 @@ void hm2_sserial_write_pins(hostmot2_t *hm2, hm2_sserial_instance_t *inst){ // the side effect of reporting this error will suffice (void)hm2_sserial_check_remote_errors(hm2, inst); - if (*inst->fault_count > inst->fault_lim) { + rtapi_u32 fault_count = hal_get_ui32(inst->fault_count); + if (fault_count > hal_get_ui32(inst->fault_lim)) { // If there have been a large percentage of misses, for quite // a long time, it's time to take it seriously. hm2_sserial_check_local_errors(hm2, inst); @@ -1741,9 +1620,9 @@ void hm2_sserial_write_pins(hostmot2_t *hm2, hm2_sserial_instance_t *inst){ "There have been more than %i errors in %i " "thread executions at least %i times. " "See other error messages for details.\n", - inst->fault_dec, - inst->fault_inc, - inst->fault_lim); + hal_get_ui32(inst->fault_dec), + hal_get_ui32(inst->fault_inc), + hal_get_ui32(inst->fault_lim)); HM2_ERR("***Smart Serial Port %i will be stopped***\n",inst->index); static bool printed; if(!inst->ever_read && !printed) { @@ -1753,7 +1632,7 @@ void hm2_sserial_write_pins(hostmot2_t *hm2, hm2_sserial_instance_t *inst){ "This error message will not repeat.\n"); printed = true; } - *inst->state = 10; + hal_set_ui32(inst->state, 10); *inst->command_reg_write = 0x800; // stop command return; } @@ -1767,20 +1646,20 @@ void hm2_sserial_write_pins(hostmot2_t *hm2, hm2_sserial_instance_t *inst){ "if this is happening frequently.\n", inst->index, hm2->llio->name, inst->index); } - *inst->fault_count += inst->fault_inc; + fault_count = hal_set_ui32(inst->fault_count, fault_count + hal_get_ui32(inst->fault_inc)); *inst->command_reg_write = 0x80000000; // set bit31 for ignored cmd return; // give the register chance to clear } if (*inst->data_reg_read & 0xff) { // indicates a failed transfer - *inst->fault_count += inst->fault_inc; + fault_count = hal_set_ui32(inst->fault_count, fault_count + hal_get_ui32(inst->fault_inc)); } - if (*inst->fault_count > inst->fault_dec) { - *inst->fault_count -= inst->fault_dec; + if (fault_count > hal_get_ui32(inst->fault_dec)) { + fault_count = hal_set_ui32(inst->fault_count, fault_count - hal_get_ui32(inst->fault_dec)); } else { - *inst->fault_count = 0; + fault_count = hal_set_ui32(inst->fault_count, 0); } // All seems well, handle the pins. @@ -1805,32 +1684,32 @@ void hm2_sserial_write_pins(hostmot2_t *hm2, hm2_sserial_instance_t *inst){ case LBP_BITS: buff = 0; for (b = 0 ; b < conf->DataLength ; b++){ - buff |= ((rtapi_u64)(*pin->bit_pins[b] != 0) << b) - ^ ((rtapi_u64)(pin->invert[b] != 0) << b); + buff |= ((rtapi_u64)(hal_get_bool(pin->bit_pins[b])) << b) + ^ ((rtapi_u64)hal_get_bool(pin->invert[b]) << b); } break; case LBP_UNSIGNED: - val = *pin->float_pin; - if (val > pin->maxlim) val = pin->maxlim; - if (val < pin->minlim) val = pin->minlim; - buff = (rtapi_u64)((val / pin->fullscale) + val = hal_get_real(pin->float_pin); + if (val > hal_get_real(pin->maxlim)) val = hal_get_real(pin->maxlim); + if (val < hal_get_real(pin->minlim)) val = hal_get_real(pin->minlim); + buff = (rtapi_u64)((val / hal_get_real(pin->fullscale)) * (~0ull >> (64 - conf->DataLength))); break; case LBP_SIGNED: //this only works if DataLength <= 32 - val = *pin->float_pin; - if (val > pin->maxlim) val = pin->maxlim; - if (val < pin->minlim) val = pin->minlim; - buff = (((rtapi_s32)(val / pin->fullscale * 2147483647)) + val = hal_get_real(pin->float_pin); + if (val > hal_get_real(pin->maxlim)) val = hal_get_real(pin->maxlim); + if (val < hal_get_real(pin->minlim)) val = hal_get_real(pin->minlim); + buff = (((rtapi_s32)(val / hal_get_real(pin->fullscale) * 2147483647)) >> (32 - conf->DataLength)) & (~0ull >> (64 - conf->DataLength)); break; case LBP_STREAM: - buff = *pin->u32_pin & (~0ull >> (64 - conf->DataLength)); + buff = hal_get_ui32(pin->u32_pin) & (~0ull >> (64 - conf->DataLength)); break; case LBP_BOOLEAN: buff = 0; - if (*pin->boolean ^ ((conf->DataDir == LBP_OUT)?(*pin->invert):0)){ + if (hal_get_bool(pin->boolean) ^ ((conf->DataDir == LBP_OUT)?(hal_get_bool(*pin->invert)):0)){ buff = (~0ull >> (64 - conf->DataLength)); } break; @@ -1840,10 +1719,10 @@ void hm2_sserial_write_pins(hostmot2_t *hm2, hm2_sserial_instance_t *inst){ break; case LBP_FLOAT: if (conf->DataLength == sizeof(float) * 8 ){ - float temp = *pin->float_pin; + float temp = hal_get_real(pin->float_pin); memcpy(&buff, &temp, sizeof(float)); } else if (conf->DataLength == sizeof(double) * 8){ - double temp = *pin->float_pin; + double temp = hal_get_real(pin->float_pin); memcpy(&buff, &temp, sizeof(double)); } else { HM2_ERR_NO_LL("sserial write: LBP_FLOAT of bit-length %i not handled\n", conf->DataLength); @@ -1877,28 +1756,28 @@ void hm2_sserial_prepare_tram_write(hostmot2_t *hm2, long period){ hm2_sserial_instance_t *inst = &(hm2->sserial.instance[i]); - switch ((*inst->state) & 0xFF){ + switch (hal_get_ui32(inst->state) & 0xFF){ case 0: // Idle - if (! *inst->run){ break; } + if (! hal_get_bool(inst->run)){ break; } // Check for any changed parameters if (hm2_sserial_update_params(hm2, inst, period) > 0) break; //set the modes for the cards hm2_sserial_setmode(hm2, inst); *inst->command_reg_write = 0x900 | inst->tag; HM2_DBG("Enabled Remotes tag = = %x\n", inst->tag); - *inst->fault_count = 0; + hal_set_ui32(inst->fault_count, 0); inst->doit_err_count = 0; inst->timer = 2100000000; - *inst->state = 2; + hal_set_ui32(inst->state, 2); break; case 2: // just transitioning to running if (hm2_sserial_wait(hm2, inst, period) > 0) break; - *inst->state = 3; + hal_set_ui32(inst->state, 3); break; case 3: // normal running - if (!*inst->run){ - *inst->state = 4; + if (!hal_get_bool(inst->run)){ + hal_set_ui32(inst->state, 4); break; } hm2_sserial_write_pins(hm2, inst); @@ -1906,21 +1785,21 @@ void hm2_sserial_prepare_tram_write(hostmot2_t *hm2, long period){ case 4: // run to stop transition *inst->command_reg_write = 0x800; inst->timer = 2100000000; - *inst->state = 5; + hal_set_ui32(inst->state, 5); break; case 5: if (hm2_sserial_wait(hm2, inst, period) > 0) break; - *inst->state = 0; + hal_set_ui32(inst->state, 0); break; case 10:// Do-nothing state for serious errors. require run pin to cycle *inst->command_reg_write = 0x80000000; // set bit31 for ignored cmd - if ( ! *inst->run){*inst->state = 0;} + if ( !hal_get_bool(inst->run)){hal_set_ui32(inst->state, 0);} break; default: // Should never happen HM2_ERR("Unhandled run/stop configuration in \n" "hm2_sserial_write (%x)\n", - *inst->state); - *inst->state = 0; + hal_get_ui32(inst->state)); + hal_set_ui32(inst->state, 0); } } } @@ -1948,8 +1827,8 @@ int hm2_sserial_read_pins(hm2_sserial_remote_t *chan){ break; case LBP_BITS: for (b = 0 ; b < conf->DataLength ; b++){ - *pin->bit_pins[b] = ((buff & (1LL << b)) != 0); - *pin->bit_pins_not[b] = ! *pin->bit_pins[b]; + rtapi_bool _v = hal_set_bool(pin->bit_pins[b], (buff & (1LL << b)) != 0); + hal_set_bool(pin->bit_pins_not[b], !_v); } break; case LBP_UNSIGNED: @@ -1961,21 +1840,19 @@ int hm2_sserial_read_pins(hm2_sserial_remote_t *chan){ } } - *pin->float_pin = (buff * pin->fullscale) - / ((1 << conf->DataLength) - 1); + hal_set_real(pin->float_pin, (buff * hal_get_real(pin->fullscale)) / ((1 << conf->DataLength) - 1)); break; case LBP_SIGNED: buff32 = (buff & 0xFFFFFFFFL) << (32 - conf->DataLength); - *pin->float_pin = (buff32 / 2147483647.0 ) - * pin->fullscale; + hal_set_real(pin->float_pin, (buff32 / 2147483647.0 ) * hal_get_real(pin->fullscale)); break; case LBP_STREAM: - *pin->u32_pin = buff & (~0ull >> (64 - conf->DataLength)); + hal_set_ui32(pin->u32_pin, buff & (~0ull >> (64 - conf->DataLength))); break; case LBP_BOOLEAN: - *pin->boolean = (buff != 0); + hal_set_bool(pin->boolean, buff != 0); if(conf->DataDir == LBP_IN){ - *pin->boolean2 = (buff == 0); + hal_set_bool(pin->boolean2, buff == 0); } break; case LBP_ENCODER_H: @@ -1998,7 +1875,7 @@ int hm2_sserial_read_pins(hm2_sserial_remote_t *chan){ int bitlength; rtapi_s32 rem1, rem2; rtapi_s64 previous; - rtapi_u32 ppr = pin->u32_param; + rtapi_u32 ppr = hal_get_ui32(pin->u32_param); if (conf->DataType == LBP_ENCODER){ bitlength = conf->DataLength; @@ -2031,10 +1908,10 @@ int hm2_sserial_read_pins(hm2_sserial_remote_t *chan){ pin->accum += (buff64 - pin->oldval); //reset - if (*pin->boolean2){pin->offset = pin->accum;} + if (hal_get_bool(pin->boolean2)){pin->offset = pin->accum;} //index-enable - if (*pin->boolean && ppr > 0){ // index-enable set + if (hal_get_bool(pin->boolean) && ppr > 0){ // index-enable set rtapi_div_s64_rem(previous, ppr, &rem1); rtapi_div_s64_rem(pin->accum, ppr, &rem2); if ((unsigned)abs(rem1 - rem2) > ppr / 2 @@ -2057,23 +1934,23 @@ int hm2_sserial_read_pins(hm2_sserial_remote_t *chan){ pin->offset = 0; } } - *pin->boolean = 0; + hal_set_bool(pin->boolean, 0); } } pin->oldval = buff64; - *pin->s32_pin = pin->accum - pin->offset; - *pin->s32_pin2 = pin->accum; - *pin->float_pin = (double)(pin->accum - pin->offset) / pin->fullscale ; + hal_set_si32(pin->s32_pin, pin->accum - pin->offset); + hal_set_si32(pin->s32_pin2, pin->accum); + hal_set_real(pin->float_pin, (double)(pin->accum - pin->offset) / hal_get_real(pin->fullscale)); break; case LBP_FLOAT: if (conf->DataLength == sizeof(float) * 8){ float temp; memcpy(&temp, &buff, sizeof(float)); - *pin->float_pin = temp; + hal_set_real(pin->float_pin, temp); } else if (conf->DataLength == sizeof(double) * 8){ double temp; memcpy(&temp, &buff, sizeof(double)); - *pin->float_pin = temp; + hal_set_real(pin->float_pin, temp); } else { HM2_ERR_NO_LL("sserial read: LBP_FLOAT of bit-length %i not handled\n", conf->DataLength); conf->DataType = 0; // Only warn once, then ignore @@ -2099,7 +1976,7 @@ void hm2_sserial_process_tram_read(hostmot2_t *hm2, long period){ for (i = 0 ; i < hm2->sserial.num_instances ; i++){ hm2_sserial_instance_t *inst = &hm2->sserial.instance[i]; inst->ever_read = true; - if (*inst->state != 3) continue ; // Only work on running instances + if (hal_get_ui32(inst->state) != 3) continue ; // Only work on running instances for (c = 0 ; c < inst->num_remotes ; c++ ) { hm2_sserial_remote_t *chan = &inst->remotes[c]; hm2_sserial_read_pins(chan); diff --git a/src/hal/drivers/mesa-hostmot2/sserial.h b/src/hal/drivers/mesa-hostmot2/sserial.h index e6391f30eb4..e033af49499 100644 --- a/src/hal/drivers/mesa-hostmot2/sserial.h +++ b/src/hal/drivers/mesa-hostmot2/sserial.h @@ -110,21 +110,21 @@ typedef struct { }hm2_sserial_mode_t; typedef struct { - hal_u32_t *u32_pin; - hal_s32_t *s32_pin; - hal_s32_t *s32_pin2; - hal_float_t *float_pin; - hal_bit_t **bit_pins; - hal_bit_t **bit_pins_not; - hal_bit_t *invert; - hal_bit_t *boolean; - hal_bit_t *boolean2; - hal_float_t maxlim; - hal_float_t minlim; - hal_float_t fullscale; - hal_u32_t u32_param; - hal_bit_t graycode; - hal_bit_t nowrap; + hal_uint_t u32_pin; + hal_sint_t s32_pin; + hal_sint_t s32_pin2; + hal_real_t float_pin; + hal_bool_t *bit_pins; + hal_bool_t *bit_pins_not; + hal_bool_t *invert; + hal_bool_t boolean; + hal_bool_t boolean2; + hal_real_t maxlim; + hal_real_t minlim; + hal_real_t fullscale; + hal_uint_t u32_param; + rtapi_bool graycode; + rtapi_bool nowrap; rtapi_s64 oldval; // not pins, but this way every pin can have one rtapi_s64 accum; // these two are only currently used by encoders rtapi_s64 offset; @@ -132,22 +132,17 @@ typedef struct { typedef struct { int type; + hal_refs_u param; union { - long long s64_param; - hal_u32_t u32_param; - hal_s32_t s32_param; - hal_float_t float_param; - hal_bit_t bit_param; + rtapi_u64 u64_written; + rtapi_s64 s64_written; + rtapi_u32 u32_written; + rtapi_s32 s32_written; + rtapi_real float_written; }; - union { - long long s64_written; - hal_u32_t u32_written; - hal_s32_t s32_written; - hal_float_t float_written; - hal_bit_t bit_written; - }; - hal_u32_t timer_num; - hal_bit_t *error; + hal_real_t fanucf; // HM2_GTAG_FABS frequency because 'param' above is used as filter + hal_uint_t timer_num; + hal_bool_t error; }hm2_sserial_params_t; typedef struct { @@ -164,8 +159,9 @@ typedef struct { hm2_sserial_data_t *globals; hm2_sserial_pins_t *pins; hm2_sserial_params_t *params; - hal_u32_t serialnumber; - hal_u32_t status, seen_remote_errors; + rtapi_u32 serialnumber; + rtapi_u32 status; + rtapi_u32 seen_remote_errors; rtapi_u32 *reg_cs_read; rtapi_u32 *reg_cs_write; @@ -196,18 +192,18 @@ typedef struct { rtapi_u32 data_reg_addr; rtapi_u32 *data_reg_read; rtapi_u32 *data_reg_write; - hal_u32_t *fault_count; - hal_u32_t fault_inc; - hal_u32_t fault_dec; - hal_u32_t fault_lim; + hal_uint_t fault_count; + hal_uint_t fault_inc; + hal_uint_t fault_dec; + hal_uint_t fault_lim; - hal_bit_t *run; - hal_u32_t *state; - hal_u32_t *state2; - hal_u32_t *state3; - hal_s32_t *debug; - hal_u32_t r_index; - hal_u32_t g_index; + hal_bool_t run; + hal_uint_t state; + hal_uint_t state2; + hal_uint_t state3; + hal_sint_t debug; + rtapi_u32 r_index; + rtapi_u32 g_index; int doit_err_count; rtapi_s32 timer; bool ever_read; diff --git a/src/hal/drivers/mesa-hostmot2/ssr.c b/src/hal/drivers/mesa-hostmot2/ssr.c index fb44c7dcafc..095b927ad82 100644 --- a/src/hal/drivers/mesa-hostmot2/ssr.c +++ b/src/hal/drivers/mesa-hostmot2/ssr.c @@ -82,7 +82,7 @@ int hm2_ssr_parse_md(hostmot2_t *hm2, int md_index) { hm2->ssr.clock_freq = md->clock_freq; hm2->ssr.version = md->version; - hm2->ssr.instance = (hm2_ssr_instance_t *)hal_malloc(hm2->ssr.num_instances * sizeof(hm2_ssr_instance_t)); + hm2->ssr.instance = hal_malloc(hm2->ssr.num_instances * sizeof(*hm2->ssr.instance)); if (hm2->ssr.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -126,22 +126,18 @@ int hm2_ssr_parse_md(hostmot2_t *hm2, int md_index) { // { - int i; - char name[HAL_NAME_LEN + 1]; - - for (i = 0; i < hm2->ssr.num_instances; i ++) { - rtapi_snprintf(name, sizeof(name), "%s.ssr.%02d.rate", hm2->llio->name, i); - r = hal_pin_u32_new(name, HAL_IN, &(hm2->ssr.instance[i].hal.pin.rate), hm2->llio->comp_id); + for (int i = 0; i < hm2->ssr.num_instances; i ++) { + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->ssr.instance[i].hal.pin.rate), + 1000*1000, "%s.ssr.%02d.rate", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.ssr.%02d.rate', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail1; } { - int j = 0; int ssr_number; - for (j = 0; j < hm2->num_pins; j++){ + for (int j = 0; j < hm2->num_pins; j++){ if (hm2->pin[j].sec_tag == HM2_GTAG_SSR && hm2->pin[j].sec_unit == i) { if ((hm2->pin[j].sec_pin & 0x80) != 0x80) { HM2_ERR("Pin Descriptor %d has an SSR pin that's not an output!\n", j); @@ -160,17 +156,17 @@ int hm2_ssr_parse_md(hostmot2_t *hm2, int md_index) { goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.ssr.%02d.out-%02d", hm2->llio->name, i, ssr_number); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->ssr.instance[i].hal.pin.out[ssr_number]), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->ssr.instance[i].hal.pin.out[ssr_number]), + 0, "%s.ssr.%02d.out-%02d", hm2->llio->name, i, ssr_number); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.ssr.%02d.out-%02d', aborting\n", r, hm2->llio->name, i, ssr_number); r = -ENOMEM; goto fail1; } - rtapi_snprintf(name, sizeof(name), "%s.ssr.%02d.invert-%02d", hm2->llio->name, i, ssr_number); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->ssr.instance[i].hal.pin.invert[ssr_number]), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->ssr.instance[i].hal.pin.invert[ssr_number]), + 0, "%s.ssr.%02d.invert-%02d", hm2->llio->name, i, ssr_number); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.ssr.%02d.invert-%02d', aborting\n", r, hm2->llio->name, i, ssr_number); r = -ENOMEM; goto fail1; } @@ -192,17 +188,7 @@ int hm2_ssr_parse_md(hostmot2_t *hm2, int md_index) { { int i; for (i = 0; i < hm2->ssr.num_instances; i ++) { - int pin; rtapi_u32 zero = 0; - - *hm2->ssr.instance[i].hal.pin.rate = 1000*1000; - - for (pin = 0; pin < 32; pin ++) { - if (hm2->ssr.instance[i].hal.pin.out[pin] != NULL) { - *hm2->ssr.instance[i].hal.pin.out[pin] = 0; - *hm2->ssr.instance[i].hal.pin.invert[pin] = 0; - } - } hm2->llio->write(hm2->llio, hm2->ssr.rate_addr + (i * md->instance_stride), &zero, sizeof(zero)); hm2->llio->write(hm2->llio, hm2->ssr.data_addr + (i * md->instance_stride), &zero, sizeof(zero)); } @@ -232,16 +218,17 @@ static void hm2_ssr_compute_rate_regs(hostmot2_t *hm2) { for (i = 0; i < hm2->ssr.num_instances; i ++) { rtapi_u32 reg; - if (*hm2->ssr.instance[i].hal.pin.rate <= 0) { + rtapi_u32 urate = hal_get_ui32(hm2->ssr.instance[i].hal.pin.rate); + if (urate <= 0) { // Writing all bits zero to the Rate register clears bit 12, // the enable bit. reg = 0; } else { - double rate = *hm2->ssr.instance[i].hal.pin.rate; + double rate = urate; - if (*hm2->ssr.instance[i].hal.pin.rate < 25000) { + if (urate < 25000) { rate = 25000; - } else if (*hm2->ssr.instance[i].hal.pin.rate > (25*1000*1000)) { + } else if (urate > (25*1000*1000)) { rate = 25*1000*1000; } @@ -286,8 +273,8 @@ void hm2_ssr_force_write(hostmot2_t *hm2) { hm2->ssr.data_reg[i] = 0; for (pin = 0; pin < 32; pin ++) { if (hm2->ssr.instance[i].hal.pin.out[pin] != NULL) { - hm2->ssr.data_reg[i] |= *hm2->ssr.instance[i].hal.pin.out[pin] << pin; - hm2->ssr.data_reg[i] ^= *hm2->ssr.instance[i].hal.pin.invert[pin] << pin; + hm2->ssr.data_reg[i] |= hal_get_bool(hm2->ssr.instance[i].hal.pin.out[pin]) << pin; + hm2->ssr.data_reg[i] ^= hal_get_bool(hm2->ssr.instance[i].hal.pin.invert[pin]) << pin; } } } @@ -330,8 +317,8 @@ void hm2_ssr_prepare_tram_write(hostmot2_t *hm2) { hm2->ssr.data_reg[i] = 0; for (pin = 0; pin < 32; pin ++) { if (hm2->ssr.instance[i].hal.pin.out[pin] != NULL) { - hm2->ssr.data_reg[i] |= *hm2->ssr.instance[i].hal.pin.out[pin] << pin; - hm2->ssr.data_reg[i] ^= *hm2->ssr.instance[i].hal.pin.invert[pin] << pin; + hm2->ssr.data_reg[i] |= hal_get_bool(hm2->ssr.instance[i].hal.pin.out[pin]) << pin; + hm2->ssr.data_reg[i] ^= hal_get_bool(hm2->ssr.instance[i].hal.pin.invert[pin]) << pin; } } if (hm2->ssr.data_reg[i] != hm2->ssr.instance[i].written_data) { diff --git a/src/hal/drivers/mesa-hostmot2/stepgen.c b/src/hal/drivers/mesa-hostmot2/stepgen.c index 4ec1122f805..9e11cd0e6a5 100644 --- a/src/hal/drivers/mesa-hostmot2/stepgen.c +++ b/src/hal/drivers/mesa-hostmot2/stepgen.c @@ -43,6 +43,7 @@ void hm2_stepgen_process_tram_read(hostmot2_t *hm2, long l_period_ns) { rtapi_u32 mode = 0; rtapi_u32 latch = 0; for (i = 0; i < hm2->stepgen.num_instances; i ++) { + hm2_stepgen_instance_t *inst = &hm2->stepgen.instance[i]; rtapi_u32 acc = hm2->stepgen.accumulator_reg[i]; if (hm2->stepgen.firmware_supports_index) { mode = hm2->stepgen.mode_reg[i] & HM2_STEPGEN_MODE_MASK ; @@ -52,12 +53,13 @@ void hm2_stepgen_process_tram_read(hostmot2_t *hm2, long l_period_ns) { rtapi_s64 latch_delta; // those tricky users are always trying to get us to divide by zero - if (fabs(hm2->stepgen.instance[i].hal.param.position_scale) < 1e-6) { - if (hm2->stepgen.instance[i].hal.param.position_scale >= 0.0) { - hm2->stepgen.instance[i].hal.param.position_scale = 1.0; + rtapi_real position_scale = hal_get_real(inst->hal.param.position_scale); + if (fabs(position_scale) < 1e-6) { + if (position_scale >= 0.0) { + position_scale = hal_set_real(inst->hal.param.position_scale, 1.0); HM2_ERR("stepgen %d position_scale is too close to 0, resetting to 1.0\n", i); } else { - hm2->stepgen.instance[i].hal.param.position_scale = -1.0; + position_scale = hal_set_real(inst->hal.param.position_scale, -1.0); HM2_ERR("stepgen %d position_scale is too close to 0, resetting to -1.0\n", i); } } @@ -66,7 +68,7 @@ void hm2_stepgen_process_tram_read(hostmot2_t *hm2, long l_period_ns) { // representation of the current stepper position. // The fractional part gives accurate velocity at low speeds, and // sub-step position feedback (like sw stepgen). - acc_delta = (rtapi_s64)acc - (rtapi_s64)hm2->stepgen.instance[i].prev_accumulator; + acc_delta = (rtapi_s64)acc - (rtapi_s64)inst->prev_accumulator; if (acc_delta > RTAPI_INT32_MAX) { acc_delta -= RTAPI_UINT32_MAX; } else if (acc_delta < RTAPI_INT32_MIN) { @@ -76,49 +78,49 @@ void hm2_stepgen_process_tram_read(hostmot2_t *hm2, long l_period_ns) { if (hm2->stepgen.firmware_supports_index) { - if (hm2->stepgen.instance[i].written_index_enable) { // searching for index + if (inst->written_index_enable) { // searching for index if ((mode & HM2_STEPGEN_LATCH_ON_INDEX) == 0) { // hardware index detected and position at index latched - latch_delta = (rtapi_s64)latch - (rtapi_s64)hm2->stepgen.instance[i].prev_accumulator; + latch_delta = (rtapi_s64)latch - (rtapi_s64)inst->prev_accumulator; if (latch_delta > RTAPI_INT32_MAX) { latch_delta -= RTAPI_UINT32_MAX; } else if (latch_delta < RTAPI_INT32_MIN) { latch_delta += RTAPI_UINT32_MAX; } - *hm2->stepgen.instance[i].hal.pin.position_latch = ((double)(hm2->stepgen.instance[i].subcounts+latch_delta) / 65536.0) / hm2->stepgen.instance[i].hal.param.position_scale; + hal_set_real(inst->hal.pin.position_latch, ((double)(inst->subcounts+latch_delta) / 65536.0) / position_scale); acc_delta -= latch_delta; - hm2->stepgen.instance[i].subcounts = 0; - *hm2->stepgen.instance[i].hal.pin.index_enable = 0; - hm2->stepgen.instance[i].written_index_enable = 0; + inst->subcounts = 0; + hal_set_bool(inst->hal.pin.index_enable, 0); + inst->written_index_enable = 0; } } - else if (hm2->stepgen.instance[i].written_probe_enable) { + else if (inst->written_probe_enable) { if ((mode & HM2_STEPGEN_LATCH_ON_PROBE) == 0) { - latch_delta = (rtapi_s64)latch - (rtapi_s64)hm2->stepgen.instance[i].prev_accumulator; + latch_delta = (rtapi_s64)latch - (rtapi_s64)inst->prev_accumulator; if (latch_delta > RTAPI_INT32_MAX) { latch_delta -= RTAPI_UINT32_MAX; } else if (latch_delta < RTAPI_INT32_MIN) { latch_delta += RTAPI_UINT32_MAX; } - *hm2->stepgen.instance[i].hal.pin.position_latch = ((double)(hm2->stepgen.instance[i].subcounts+latch_delta) / 65536.0) / hm2->stepgen.instance[i].hal.param.position_scale; - *hm2->stepgen.instance[i].hal.pin.latch_enable = 0; - hm2->stepgen.instance[i].written_probe_enable = 0; + hal_set_real(inst->hal.pin.position_latch, ((double)(inst->subcounts+latch_delta) / 65536.0) / position_scale); + hal_set_bool(inst->hal.pin.latch_enable, 0); + inst->written_probe_enable = 0; } } } - hm2->stepgen.instance[i].subcounts += acc_delta; + inst->subcounts += acc_delta; - if ((*hm2->stepgen.instance[i].hal.pin.position_reset) != 0) { - hm2->stepgen.instance[i].subcounts = 0; + if (hal_get_bool(inst->hal.pin.position_reset)) { + inst->subcounts = 0; } - *(hm2->stepgen.instance[i].hal.pin.counts) = hm2->stepgen.instance[i].subcounts >> 16; + hal_set_si32(inst->hal.pin.counts, inst->subcounts >> 16); // note that it's important to use "subcounts/65536.0" instead of just // "counts" when computing position_fb, because position_fb needs sub-count // precision - *(hm2->stepgen.instance[i].hal.pin.position_fb) = ((double)hm2->stepgen.instance[i].subcounts / 65536.0) / hm2->stepgen.instance[i].hal.param.position_scale; - hm2->stepgen.instance[i].prev_accumulator = acc; + hal_set_real(inst->hal.pin.position_fb, ((double)inst->subcounts / 65536.0) / position_scale); + inst->prev_accumulator = acc; } } @@ -144,16 +146,18 @@ static void hm2_stepgen_instance_position_control(hostmot2_t *hm2, long l_period hm2_stepgen_instance_t *s = &hm2->stepgen.instance[i]; - (*s->hal.pin.dbg_pos_minus_prev_cmd) = (*s->hal.pin.position_fb) - s->old_position_cmd; + hal_set_real(s->hal.pin.dbg_pos_minus_prev_cmd, hal_get_real(s->hal.pin.position_fb) - s->old_position_cmd); // calculate feed-forward velocity in machine units per second - ff_vel = ((*s->hal.pin.position_cmd) - s->old_position_cmd) / f_period_s; - (*s->hal.pin.dbg_ff_vel) = ff_vel; + rtapi_real position_cmd = hal_get_real(s->hal.pin.position_cmd); + ff_vel = (position_cmd - s->old_position_cmd) / f_period_s; + hal_set_real(s->hal.pin.dbg_ff_vel, ff_vel); - s->old_position_cmd = (*s->hal.pin.position_cmd); + s->old_position_cmd = position_cmd; - velocity_error = (*s->hal.pin.velocity_fb) - ff_vel; - (*s->hal.pin.dbg_vel_error) = velocity_error; + rtapi_real velocity_fb = hal_get_real(s->hal.pin.velocity_fb); + velocity_error = velocity_fb - ff_vel; + hal_set_real(s->hal.pin.dbg_vel_error, velocity_error); // Do we need to change speed to match the speed of position-cmd? // If maxaccel is 0, there's no accel limit: fix this velocity error @@ -162,16 +166,18 @@ static void hm2_stepgen_instance_position_control(hostmot2_t *hm2, long l_period // If maxaccel is not zero, the user has specified a maxaccel and we // adhere to that. if (velocity_error > 0.0) { - if (s->hal.param.maxaccel == 0) { + rtapi_real maxaccel = hal_get_real(s->hal.param.maxaccel); + if (maxaccel == 0) { match_accel = -velocity_error / f_period_s; } else { - match_accel = -s->hal.param.maxaccel; + match_accel = -maxaccel; } } else if (velocity_error < 0.0) { - if (s->hal.param.maxaccel == 0) { + rtapi_real maxaccel = hal_get_real(s->hal.param.maxaccel); + if (maxaccel == 0) { match_accel = velocity_error / f_period_s; } else { - match_accel = s->hal.param.maxaccel; + match_accel = maxaccel; } } else { match_accel = 0; @@ -183,21 +189,21 @@ static void hm2_stepgen_instance_position_control(hostmot2_t *hm2, long l_period } else { seconds_to_vel_match = -velocity_error / match_accel; } - *s->hal.pin.dbg_s_to_match = seconds_to_vel_match; + hal_set_real(s->hal.pin.dbg_s_to_match, seconds_to_vel_match); // compute expected position at the time of velocity match // Note: this is "feedback position at the beginning of the servo period after we attain velocity match" { double avg_v; - avg_v = (ff_vel + *s->hal.pin.velocity_fb) * 0.5; - position_at_match = *s->hal.pin.position_fb + (avg_v * (seconds_to_vel_match + f_period_s)); + avg_v = (ff_vel + velocity_fb) * 0.5; + position_at_match = hal_get_real(s->hal.pin.position_fb) + (avg_v * (seconds_to_vel_match + f_period_s)); } // Note: this assumes that position-cmd keeps the current velocity - position_cmd_at_match = *s->hal.pin.position_cmd + (ff_vel * seconds_to_vel_match); + position_cmd_at_match = position_cmd + (ff_vel * seconds_to_vel_match); error_at_match = position_at_match - position_cmd_at_match; - *s->hal.pin.dbg_err_at_match = error_at_match; + hal_set_real(s->hal.pin.dbg_err_at_match, error_at_match); if (seconds_to_vel_match < f_period_s) { // we can match velocity in one period @@ -205,11 +211,12 @@ static void hm2_stepgen_instance_position_control(hostmot2_t *hm2, long l_period velocity_cmd = ff_vel - (0.5 * error_at_match / f_period_s); // apply accel limits? - if (s->hal.param.maxaccel > 0) { - if (velocity_cmd > (*s->hal.pin.velocity_fb + (s->hal.param.maxaccel * f_period_s))) { - velocity_cmd = *s->hal.pin.velocity_fb + (s->hal.param.maxaccel * f_period_s); - } else if (velocity_cmd < (*s->hal.pin.velocity_fb - (s->hal.param.maxaccel * f_period_s))) { - velocity_cmd = *s->hal.pin.velocity_fb - (s->hal.param.maxaccel * f_period_s); + rtapi_real maxaccel = hal_get_real(s->hal.param.maxaccel); + if (maxaccel > 0) { + if (velocity_cmd > (velocity_fb + (maxaccel * f_period_s))) { + velocity_cmd = velocity_fb + (maxaccel * f_period_s); + } else if (velocity_cmd < (velocity_fb - (maxaccel * f_period_s))) { + velocity_cmd = velocity_fb - (maxaccel * f_period_s); } } @@ -230,7 +237,7 @@ static void hm2_stepgen_instance_position_control(hostmot2_t *hm2, long l_period } /* and do it */ - velocity_cmd = *s->hal.pin.velocity_fb + (match_accel * f_period_s); + velocity_cmd = velocity_fb + (match_accel * f_period_s); } *new_vel = velocity_cmd; @@ -263,47 +270,50 @@ static void hm2_stepgen_instance_prepare_tram_write(hostmot2_t *hm2, long l_peri // maxvel must be >= 0.0, and may not be faster than 1 step per (steplen+stepspace) seconds { - double min_ns_per_step = s->hal.param.steplen + s->hal.param.stepspace; + double min_ns_per_step = hal_get_ui32(s->hal.param.steplen) + hal_get_ui32(s->hal.param.stepspace); double max_steps_per_s = 1.0e9 / min_ns_per_step; - physical_maxvel = max_steps_per_s / fabs(s->hal.param.position_scale); + physical_maxvel = max_steps_per_s / fabs(hal_get_real(s->hal.param.position_scale)); physical_maxvel = force_precision(physical_maxvel); - if (s->hal.param.maxvel < 0.0) { + rtapi_real pmaxvel = hal_get_real(s->hal.param.maxvel); + if (pmaxvel < 0.0) { HM2_ERR("stepgen.%02d.maxvel < 0, setting to its absolute value\n", i); - s->hal.param.maxvel = fabs(s->hal.param.maxvel); + pmaxvel = hal_set_real(s->hal.param.maxvel, fabs(pmaxvel)); } - if (s->hal.param.maxvel > physical_maxvel) { + if (pmaxvel > physical_maxvel) { HM2_ERR("stepgen.%02d.maxvel is too big for current step timings & position-scale, clipping to max possible\n", i); - s->hal.param.maxvel = physical_maxvel; + pmaxvel= hal_set_real(s->hal.param.maxvel, physical_maxvel); } - if (s->hal.param.maxvel == 0.0) { + if (pmaxvel == 0.0) { maxvel = physical_maxvel; } else { - maxvel = s->hal.param.maxvel; + maxvel = pmaxvel; } } // maxaccel may not be negative - if (s->hal.param.maxaccel < 0.0) { + rtapi_real maxaccel = hal_get_real(s->hal.param.maxaccel); + if (maxaccel < 0.0) { HM2_ERR("stepgen.%02d.maxaccel < 0, setting to its absolute value\n", i); - s->hal.param.maxaccel = fabs(s->hal.param.maxaccel); + maxaccel = hal_set_real(s->hal.param.maxaccel, fabs(maxaccel)); } // select the new velocity we want - if (*s->hal.pin.control_type == 0) { + if (!hal_get_bool(s->hal.pin.control_type)) { hm2_stepgen_instance_position_control(hm2, l_period_ns, i, &new_vel); } else { // velocity-mode control is easy - new_vel = *s->hal.pin.velocity_cmd; - if (s->hal.param.maxaccel > 0.0) { - if (((new_vel - *s->hal.pin.velocity_fb) / f_period_s) > s->hal.param.maxaccel) { - new_vel = (*s->hal.pin.velocity_fb) + (s->hal.param.maxaccel * f_period_s); - } else if (((new_vel - *s->hal.pin.velocity_fb) / f_period_s) < -s->hal.param.maxaccel) { - new_vel = (*s->hal.pin.velocity_fb) - (s->hal.param.maxaccel * f_period_s); + new_vel = hal_get_real(s->hal.pin.velocity_cmd); + rtapi_real velocity_fb = hal_get_real(s->hal.pin.velocity_fb); + if (maxaccel > 0.0) { + if (((new_vel - velocity_fb) / f_period_s) > maxaccel) { + new_vel = velocity_fb + (maxaccel * f_period_s); + } else if (((new_vel - velocity_fb) / f_period_s) < -maxaccel) { + new_vel = velocity_fb - (maxaccel * f_period_s); } } } @@ -316,26 +326,26 @@ static void hm2_stepgen_instance_prepare_tram_write(hostmot2_t *hm2, long l_peri } - *s->hal.pin.velocity_fb = (hal_float_t)new_vel; + hal_set_real(s->hal.pin.velocity_fb, (rtapi_real)new_vel); - steps_per_sec_cmd = new_vel * s->hal.param.position_scale; + steps_per_sec_cmd = new_vel * hal_get_real(s->hal.param.position_scale); // the double cast here is intentional. (uint32_t)(-1.0) is undefined in // C (and in practice it gives the undesired value 0 on arm systems), but // (uint32_t)(int32-t)(-1.0) is defined and gives the desired value on all // systems. hm2->stepgen.step_rate_reg[i] = (uint32_t)(int32_t)(steps_per_sec_cmd * (4294967296.0 / (double)hm2->stepgen.clock_frequency)); - *s->hal.pin.dbg_step_rate = hm2->stepgen.step_rate_reg[i]; + hal_set_si32(s->hal.pin.dbg_step_rate, hm2->stepgen.step_rate_reg[i]); } void hm2_stepgen_prepare_tram_write(hostmot2_t *hm2, long l_period_ns) { int i; for (i = 0; i < hm2->stepgen.num_instances; i ++) { - if (*(hm2->stepgen.instance[i].hal.pin.enable) == 0) { + if (!hal_get_bool(hm2->stepgen.instance[i].hal.pin.enable)) { hm2->stepgen.step_rate_reg[i] = 0; - hm2->stepgen.instance[i].old_position_cmd = *(hm2->stepgen.instance[i].hal.pin.position_cmd); - *(hm2->stepgen.instance[i].hal.pin.velocity_fb) = 0; + hm2->stepgen.instance[i].old_position_cmd = hal_get_real(hm2->stepgen.instance[i].hal.pin.position_cmd); + hal_set_real(hm2->stepgen.instance[i].hal.pin.velocity_fb, 0); } else { hm2_stepgen_instance_prepare_tram_write(hm2, l_period_ns, i); } @@ -346,46 +356,50 @@ void hm2_stepgen_prepare_tram_write(hostmot2_t *hm2, long l_period_ns) { static void hm2_stepgen_update_dir_setup_time(hostmot2_t *hm2, int i) { - hm2->stepgen.dir_setup_time_reg[i] = (double)hm2->stepgen.instance[i].hal.param.dirsetup * ((double)hm2->stepgen.clock_frequency / (double)1e9); + rtapi_u32 dirsetup = hal_get_ui32(hm2->stepgen.instance[i].hal.param.dirsetup); + hm2->stepgen.dir_setup_time_reg[i] = (double)dirsetup * ((double)hm2->stepgen.clock_frequency / (double)1e9); if (hm2->stepgen.dir_setup_time_reg[i] > 0x3FFF) { HM2_ERR("stepgen %d has invalid dirsetup, resetting to max\n", i); hm2->stepgen.dir_setup_time_reg[i] = 0x3FFF; - hm2->stepgen.instance[i].hal.param.dirsetup = (double)hm2->stepgen.dir_setup_time_reg[i] * ((double)1e9 / (double)hm2->stepgen.clock_frequency); + dirsetup = hal_set_ui32(hm2->stepgen.instance[i].hal.param.dirsetup, (double)hm2->stepgen.dir_setup_time_reg[i] * ((double)1e9 / (double)hm2->stepgen.clock_frequency)); } - hm2->stepgen.instance[i].written_dirsetup = hm2->stepgen.instance[i].hal.param.dirsetup; + hm2->stepgen.instance[i].written_dirsetup = dirsetup; } static void hm2_stepgen_update_dir_hold_time(hostmot2_t *hm2, int i) { - hm2->stepgen.dir_hold_time_reg[i] = (double)hm2->stepgen.instance[i].hal.param.dirhold * ((double)hm2->stepgen.clock_frequency / (double)1e9); + rtapi_u32 dirhold = hal_get_ui32(hm2->stepgen.instance[i].hal.param.dirhold); + hm2->stepgen.dir_hold_time_reg[i] = (double)dirhold * ((double)hm2->stepgen.clock_frequency / (double)1e9); if (hm2->stepgen.dir_hold_time_reg[i] > 0x3FFF) { HM2_ERR("stepgen %d has invalid dirhold, resetting to max\n", i); hm2->stepgen.dir_hold_time_reg[i] = 0x3FFF; - hm2->stepgen.instance[i].hal.param.dirhold = (double)hm2->stepgen.dir_hold_time_reg[i] * ((double)1e9 / (double)hm2->stepgen.clock_frequency); + dirhold = hal_set_ui32(hm2->stepgen.instance[i].hal.param.dirhold, (double)hm2->stepgen.dir_hold_time_reg[i] * ((double)1e9 / (double)hm2->stepgen.clock_frequency)); } - hm2->stepgen.instance[i].written_dirhold = hm2->stepgen.instance[i].hal.param.dirhold; + hm2->stepgen.instance[i].written_dirhold = dirhold; } static void hm2_stepgen_update_pulse_idle_width(hostmot2_t *hm2, int i) { - hm2->stepgen.pulse_idle_width_reg[i] = (double)hm2->stepgen.instance[i].hal.param.stepspace * ((double)hm2->stepgen.clock_frequency / (double)1e9); + rtapi_u32 stepspace = hal_get_ui32(hm2->stepgen.instance[i].hal.param.stepspace); + hm2->stepgen.pulse_idle_width_reg[i] = (double)stepspace * ((double)hm2->stepgen.clock_frequency / (double)1e9); if (hm2->stepgen.pulse_idle_width_reg[i] > 0x3FFF) { HM2_ERR("stepgen %d has invalid stepspace, resetting to max\n", i); hm2->stepgen.pulse_idle_width_reg[i] = 0x3FFF; - hm2->stepgen.instance[i].hal.param.stepspace = (double)hm2->stepgen.pulse_idle_width_reg[i] * ((double)1e9 / (double)hm2->stepgen.clock_frequency); + stepspace = hal_set_ui32(hm2->stepgen.instance[i].hal.param.stepspace, (double)hm2->stepgen.pulse_idle_width_reg[i] * ((double)1e9 / (double)hm2->stepgen.clock_frequency)); } - hm2->stepgen.instance[i].written_stepspace = hm2->stepgen.instance[i].hal.param.stepspace; + hm2->stepgen.instance[i].written_stepspace = stepspace; } static void hm2_stepgen_update_pulse_width(hostmot2_t *hm2, int i) { - hm2->stepgen.pulse_width_reg[i] = (double)hm2->stepgen.instance[i].hal.param.steplen * ((double)hm2->stepgen.clock_frequency / (double)1e9); + rtapi_u32 steplen = hal_get_ui32(hm2->stepgen.instance[i].hal.param.steplen); + hm2->stepgen.pulse_width_reg[i] = (double)steplen * ((double)hm2->stepgen.clock_frequency / (double)1e9); if (hm2->stepgen.pulse_width_reg[i] > 0x3FFF) { HM2_ERR("stepgen %d has invalid steplen, resetting to max\n", i); hm2->stepgen.pulse_width_reg[i] = 0x3FFF; - hm2->stepgen.instance[i].hal.param.steplen = (double)hm2->stepgen.pulse_width_reg[i] * ((double)1e9 / (double)hm2->stepgen.clock_frequency); + steplen = hal_set_ui32(hm2->stepgen.instance[i].hal.param.steplen, (double)hm2->stepgen.pulse_width_reg[i] * ((double)1e9 / (double)hm2->stepgen.clock_frequency)); } - hm2->stepgen.instance[i].written_steplen = hm2->stepgen.instance[i].hal.param.steplen; + hm2->stepgen.instance[i].written_steplen = steplen; } @@ -396,40 +410,41 @@ static void hm2_stepgen_update_mode(hostmot2_t *hm2, int i) { hm2_stepgen_instance_t *inst = &hm2->stepgen.instance[i]; // No point coming back unless something changes - inst->written_step_type = inst->hal.param.step_type; + rtapi_u32 step_type = hal_get_ui32(inst->hal.param.step_type); + inst->written_step_type = step_type; if (hm2->stepgen.firmware_supports_swap) { - inst->written_swap_step_dir = inst->hal.param.swap_step_dir; + inst->written_swap_step_dir = hal_get_bool(inst->hal.param.swap_step_dir); } if (hm2->stepgen.firmware_supports_index) { - inst->written_index_polarity = *inst->hal.pin.index_polarity; - inst->written_probe_polarity = *inst->hal.pin.latch_polarity; + inst->written_index_polarity = hal_get_bool(inst->hal.pin.index_polarity); + inst->written_probe_polarity = hal_get_bool(inst->hal.pin.latch_polarity); } - inst->hal.param.table[4] = (((inst->hal.param.table[0] ^ inst->hal.param.table[1]) - ^ inst->hal.param.table[2]) ^ inst->hal.param.table[3]); + inst->tablehash = (((hal_get_ui32(inst->hal.param.table[0]) ^ hal_get_ui32(inst->hal.param.table[1])) + ^ hal_get_ui32(inst->hal.param.table[2])) ^ hal_get_ui32(inst->hal.param.table[3])); - modebuff = inst->hal.param.step_type; // start with the step mode + modebuff = step_type; // start with the step mode if (hm2->stepgen.firmware_supports_index) { // or in the index/probe control bits if needed - if (*inst->hal.pin.index_enable) { + if (hal_get_bool(inst->hal.pin.index_enable)) { modebuff |= HM2_STEPGEN_LATCH_ON_INDEX; } - if (*inst->hal.pin.index_polarity) { + if (hal_get_bool(inst->hal.pin.index_polarity)) { modebuff |= HM2_STEPGEN_INDEX_POLARITY; } - if (*inst->hal.pin.latch_enable) { + if (hal_get_bool(inst->hal.pin.latch_enable)) { modebuff |= HM2_STEPGEN_LATCH_ON_PROBE; } - if (*inst->hal.pin.latch_polarity) { + if (hal_get_bool(inst->hal.pin.latch_polarity)) { modebuff |= HM2_STEPGEN_PROBE_POLARITY; } } - if (inst->hal.param.step_type <= 2) { + if (step_type <= 2) { if (hm2->stepgen.firmware_supports_swap) { - if (inst->hal.param.swap_step_dir) { + if (hal_get_bool(inst->hal.param.swap_step_dir)) { modebuff |= HM2_STEPGEN_SWAP_STEP_DIR; } } @@ -437,32 +452,36 @@ static void hm2_stepgen_update_mode(hostmot2_t *hm2, int i) { return; } - if (inst->table_width < inst->hal.param.step_type){ + if (inst->table_width < step_type){ HM2_ERR("the firmware only supports %i pins in the step pattern for " "stepgen instance %i, you asked for %i. Reverting to step type 0\n", inst->table_width, i, - inst->hal.param.step_type); + step_type); hm2->stepgen.mode_reg[i] = 0; } - if (inst->hal.param.step_type > 16){ + if (step_type > 16){ HM2_ERR("the firmware only supports tables up to a depth of 16, you" "requested %i. Reverting to step type 0\n", - inst->hal.param.step_type); + step_type); hm2->stepgen.mode_reg[i] = 0; + // Assure that we do not index outside the param.table[] array in the + // loop below. But the code may be off anyway and the result is + // anybody's guess. + step_type = 16; } // In that case, we can assume that we have been fed a step table and the // step_type is actually the table length. - for (j = inst->hal.param.step_type - 1; j >= 0 ; j--){ - buff = ((inst->hal.param.table[j / 4] >> ((j % 4) * 8)) & 0xFF); + for (j = step_type - 1; j >= 0 ; j--){ + buff = ((hal_get_ui32(inst->hal.param.table[j / 4]) >> ((j % 4) * 8)) & 0xFF); hm2->llio->write(hm2->llio, hm2->stepgen.table_sequence_data_setup_addr + (i * sizeof(rtapi_u32)), &buff, sizeof(rtapi_u32)); } hm2->stepgen.mode_reg[i] = 3 | modebuff; // force 2 LSbs to 1,1 to select table mode in stepgen hardware - buff = inst->hal.param.step_type -1; + buff = step_type -1; hm2->llio->write(hm2->llio, hm2->stepgen.table_sequence_length_addr + (i * sizeof(rtapi_u32)), &buff, sizeof(rtapi_u32)); @@ -471,15 +490,15 @@ static void hm2_stepgen_update_mode(hostmot2_t *hm2, int i) { static void hm2_stepgen_set_dpll_timer(hostmot2_t *hm2) { rtapi_u32 data = 0; - - if ((*hm2->stepgen.hal->pin.dpll_timer_num < -1) || (*hm2->stepgen.hal->pin.dpll_timer_num > 4)) { - *hm2->stepgen.hal->pin.dpll_timer_num = 0; + rtapi_s32 dpll_timer_num = hal_get_si32(hm2->stepgen.hal->pin.dpll_timer_num); + if ((dpll_timer_num < -1) || (dpll_timer_num > 4)) { + dpll_timer_num = hal_set_si32(hm2->stepgen.hal->pin.dpll_timer_num, 0); } - if (*hm2->stepgen.hal->pin.dpll_timer_num > -1) { - data = (*hm2->stepgen.hal->pin.dpll_timer_num << 12) | (1 << 15); + if (dpll_timer_num > -1) { + data = (dpll_timer_num << 12) | (1 << 15); } hm2->llio->write(hm2->llio, hm2->stepgen.dpll_timer_num_addr, &data, sizeof(rtapi_u32)); - hm2->stepgen.written_dpll_timer_num = *hm2->stepgen.hal->pin.dpll_timer_num; + hm2->stepgen.written_dpll_timer_num = dpll_timer_num; } @@ -490,46 +509,46 @@ void hm2_stepgen_write(hostmot2_t *hm2) { // FIXME for (i = 0; i < hm2->stepgen.num_instances; i ++) { hm2_stepgen_instance_t *inst = &hm2->stepgen.instance[i]; - if (inst->hal.param.dirsetup != inst->written_dirsetup) { + if (hal_get_ui32(inst->hal.param.dirsetup) != inst->written_dirsetup) { hm2_stepgen_update_dir_setup_time(hm2, i); hm2->llio->write(hm2->llio, hm2->stepgen.dir_setup_time_addr + (i * sizeof(rtapi_u32)), &hm2->stepgen.dir_setup_time_reg[i], sizeof(rtapi_u32)); } - if (inst->hal.param.dirhold != inst->written_dirhold) { + if (hal_get_ui32(inst->hal.param.dirhold) != inst->written_dirhold) { hm2_stepgen_update_dir_hold_time(hm2, i); hm2->llio->write(hm2->llio, hm2->stepgen.dir_hold_time_addr + (i * sizeof(rtapi_u32)), &hm2->stepgen.dir_hold_time_reg[i], sizeof(rtapi_u32)); } - if (inst->hal.param.steplen != inst->written_steplen) { + if (hal_get_ui32(inst->hal.param.steplen) != inst->written_steplen) { hm2_stepgen_update_pulse_width(hm2, i); hm2->llio->write(hm2->llio, hm2->stepgen.pulse_width_addr + (i * sizeof(rtapi_u32)), &hm2->stepgen.pulse_width_reg[i], sizeof(rtapi_u32)); } - if (inst->hal.param.stepspace != inst->written_stepspace) { + if (hal_get_ui32(inst->hal.param.stepspace) != inst->written_stepspace) { hm2_stepgen_update_pulse_idle_width(hm2, i); hm2->llio->write(hm2->llio, hm2->stepgen.pulse_idle_width_addr + (i * sizeof(rtapi_u32)), &hm2->stepgen.pulse_idle_width_reg[i], sizeof(rtapi_u32)); } need_mode_update=0; - if ((inst->hal.param.step_type != inst->written_step_type) - || (((inst->hal.param.table[0] ^ inst->hal.param.table[1]) - ^ inst->hal.param.table[2]) ^ inst->hal.param.table[3]) - != inst->hal.param.table[4]) { + if ((hal_get_ui32(inst->hal.param.step_type) != inst->written_step_type) + || (((hal_get_ui32(inst->hal.param.table[0]) ^ hal_get_ui32(inst->hal.param.table[1])) + ^ hal_get_ui32(inst->hal.param.table[2])) ^ hal_get_ui32(inst->hal.param.table[3])) + != inst->tablehash) { need_mode_update = 1; } if (hm2->stepgen.firmware_supports_swap) { - if (inst->hal.param.swap_step_dir != inst->written_swap_step_dir) { + if (hal_get_bool(inst->hal.param.swap_step_dir) != inst->written_swap_step_dir) { need_mode_update |= 1; } } if (hm2->stepgen.firmware_supports_index) { - if ((*inst->hal.pin.index_enable != inst->written_index_enable) - || (*inst->hal.pin.latch_enable != inst->written_probe_enable) - || (*inst->hal.pin.index_polarity != inst->written_index_polarity) - || (*inst->hal.pin.latch_polarity != inst->written_probe_polarity)) { + if ((hal_get_bool(inst->hal.pin.index_enable) != inst->written_index_enable) + || (hal_get_bool(inst->hal.pin.latch_enable) != inst->written_probe_enable) + || (hal_get_bool(inst->hal.pin.index_polarity) != inst->written_index_polarity) + || (hal_get_bool(inst->hal.pin.latch_polarity) != inst->written_probe_polarity)) { need_mode_update |= 1; } } @@ -537,14 +556,14 @@ void hm2_stepgen_write(hostmot2_t *hm2) { hm2_stepgen_update_mode(hm2, i); hm2->llio->write(hm2->llio, hm2->stepgen.mode_addr + (i * sizeof(rtapi_u32)), &hm2->stepgen.mode_reg[i], sizeof(rtapi_u32)); if (hm2->stepgen.firmware_supports_index) { - inst->written_index_enable = *inst->hal.pin.index_enable; // we need to update these only after the write has occurred - inst->written_probe_enable = *inst->hal.pin.latch_enable; // to avoid a race condition (index detected before index enable has been set) + inst->written_index_enable = hal_get_bool(inst->hal.pin.index_enable); // we need to update these only after the write has occurred + inst->written_probe_enable = hal_get_bool(inst->hal.pin.latch_enable); // to avoid a race condition (index detected before index enable has been set) } } } if (hm2->stepgen.num_instances > 0 && hm2->dpll_module_present) { - if (*hm2->stepgen.hal->pin.dpll_timer_num != (int)hm2->stepgen.written_dpll_timer_num) { + if (hal_get_si32(hm2->stepgen.hal->pin.dpll_timer_num) != (int)hm2->stepgen.written_dpll_timer_num) { hm2_stepgen_set_dpll_timer(hm2); } } @@ -658,7 +677,7 @@ void hm2_stepgen_tram_init(hostmot2_t *hm2) { for (i = 0; i < hm2->stepgen.num_instances; i ++) { hm2->stepgen.instance[i].prev_accumulator = hm2->stepgen.accumulator_reg[i]; - hm2->stepgen.instance[i].old_position_cmd = *hm2->stepgen.instance[i].hal.pin.position_cmd; + hm2->stepgen.instance[i].old_position_cmd = hal_get_real(hm2->stepgen.instance[i].hal.pin.position_cmd); } } @@ -757,14 +776,14 @@ int hm2_stepgen_parse_md(hostmot2_t *hm2, int md_index) { // allocate the module-global HAL shared memory - hm2->stepgen.hal = (hm2_stepgen_module_global_t *)hal_malloc(sizeof(hm2_stepgen_module_global_t)); + hm2->stepgen.hal = hal_malloc(sizeof(*hm2->stepgen.hal)); if (hm2->stepgen.hal == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; goto fail0; } - hm2->stepgen.instance = (hm2_stepgen_instance_t *)hal_malloc(hm2->stepgen.num_instances * sizeof(hm2_stepgen_instance_t)); + hm2->stepgen.instance = hal_malloc(hm2->stepgen.num_instances * sizeof(*hm2->stepgen.instance)); if (hm2->stepgen.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -853,26 +872,21 @@ int hm2_stepgen_parse_md(hostmot2_t *hm2, int md_index) { // export to HAL { - int i; - char name[HAL_NAME_LEN + 1]; - if (hm2->dpll_module_present) { - rtapi_snprintf(name, sizeof(name), "%s.stepgen.timer-number", hm2->llio->name); - r = hal_pin_s32_new(name, HAL_IN, &(hm2->stepgen.hal->pin.dpll_timer_num), hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_IN, &(hm2->stepgen.hal->pin.dpll_timer_num), + -1, "%s.stepgen.timer-number", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding timer number param, aborting\n"); + HM2_ERR("error %d adding pin '%s.stepgen.timer-number', aborting\n", r, hm2->llio->name); return -EINVAL; } - *(hm2->stepgen.hal->pin.dpll_timer_num) = -1; } - for (i = 0; i < hm2->stepgen.num_instances; i ++) { + for (int i = 0; i < hm2->stepgen.num_instances; i ++) { // Work out if table setup registers are needed. { - int j = 0; hm2->stepgen.instance[i].table_width = 0; - for (j = 0; j < hm2->num_pins; j++){ + for (int j = 0; j < hm2->num_pins; j++){ if (hm2->pin[j].sec_tag == HM2_GTAG_STEPGEN && hm2->pin[j].sec_unit == i){ if (hm2->pin[j].sec_pin > hm2->stepgen.instance[i].table_width){ hm2->stepgen.instance[i].table_width = hm2->pin[j].sec_pin; @@ -881,108 +895,108 @@ int hm2_stepgen_parse_md(hostmot2_t *hm2, int md_index) { } } // pins - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.position-cmd", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.position_cmd), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.position_cmd), + 0.0, "%s.stepgen.%02d.position-cmd", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.position-cmd', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.velocity-cmd", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.velocity_cmd), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.velocity_cmd), + 0.0, "%s.stepgen.%02d.velocity-cmd", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.velocity-cmd', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.velocity-fb", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.velocity_fb), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.velocity_fb), + 0.0, "%s.stepgen.%02d.velocity-fb", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.velocity-fb', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.position-fb", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.position_fb), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.position_fb), + 0.0, "%s.stepgen.%02d.position-fb", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.position-fb', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.counts", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.counts), hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.counts), + 0, "%s.stepgen.%02d.counts", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.counts', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.enable", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.enable), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.enable), + 0, "%s.stepgen.%02d.enable", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.enable', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.control-type", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.control_type), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.control_type), + 0, "%s.stepgen.%02d.control-type", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.control-type', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.position-reset", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.position_reset), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.position_reset), + 0, "%s.stepgen.%02d.position-reset", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.position-reset', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } if (hm2->stepgen.firmware_supports_index) { - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.position-latch", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.position_latch), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.position_latch), + 0.0, "%s.stepgen.%02d.position-latch", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.position-latch', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.index-enable", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IO, &(hm2->stepgen.instance[i].hal.pin.index_enable), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IO, &(hm2->stepgen.instance[i].hal.pin.index_enable), + 0, "%s.stepgen.%02d.index-enable", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.index-enable', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.probe-enable", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IO, &(hm2->stepgen.instance[i].hal.pin.latch_enable), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IO, &(hm2->stepgen.instance[i].hal.pin.latch_enable), + 0, "%s.stepgen.%02d.probe-enable", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.probe-enable', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.index-invert", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.index_polarity), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.index_polarity), + 0, "%s.stepgen.%02d.index-invert", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.index-invert', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.probe-invert", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.latch_polarity), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->stepgen.instance[i].hal.pin.latch_polarity), + 0, "%s.stepgen.%02d.probe-invert", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.probe-invert', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } @@ -990,206 +1004,192 @@ int hm2_stepgen_parse_md(hostmot2_t *hm2, int md_index) { // debug pins - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.dbg_pos_minus_prev_cmd", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_pos_minus_prev_cmd), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_pos_minus_prev_cmd), + 0.0, "%s.stepgen.%02d.dbg_pos_minus_prev_cmd", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.dbg_pos_minus_prev_cmd', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.dbg_ff_vel", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_ff_vel), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_ff_vel), + 0.0, "%s.stepgen.%02d.dbg_ff_vel", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.dbg_ff_vel', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.dbg_s_to_match", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_s_to_match), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_s_to_match), + 0.0, "%s.stepgen.%02d.dbg_s_to_match", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.dbg_s_to_match', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.dbg_vel_error", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_vel_error), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_vel_error), + 0.0, "%s.stepgen.%02d.dbg_vel_error", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.dbg_vel_error', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.dbg_err_at_match", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_err_at_match), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_err_at_match), + 0.0, "%s.stepgen.%02d.dbg_err_at_match", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.dbg_err_at_match', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.dbg_step_rate", hm2->llio->name, i); - r = hal_pin_s32_new(name, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_step_rate), hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_OUT, &(hm2->stepgen.instance[i].hal.pin.dbg_step_rate), + 0, "%s.stepgen.%02d.dbg_step_rate", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.stepgen.%02d.dbg_step_rate', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } // parameters - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.position-scale", hm2->llio->name, i); - r = hal_param_float_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.position_scale), hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.position_scale), + 1.0, "%s.stepgen.%02d.position-scale", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.position-scale', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.maxvel", hm2->llio->name, i); - r = hal_param_float_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.maxvel), hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.maxvel), + 0.0, "%s.stepgen.%02d.maxvel", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.maxvel', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.maxaccel", hm2->llio->name, i); - r = hal_param_float_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.maxaccel), hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.maxaccel), + 1.0, "%s.stepgen.%02d.maxaccel", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.maxaccel', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.steplen", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.steplen), hm2->llio->comp_id); + // start out the slowest possible, let the user speed up if they want + rtapi_u32 v = (double)0x3FFF * ((double)1e9 / (double)hm2->stepgen.clock_frequency); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.steplen), + v, "%s.stepgen.%02d.steplen", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.steplen', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.stepspace", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.stepspace), hm2->llio->comp_id); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.stepspace), + v, "%s.stepgen.%02d.stepspace", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.stepspace', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.dirsetup", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.dirsetup), hm2->llio->comp_id); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.dirsetup), + v, "%s.stepgen.%02d.dirsetup", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.dirsetup', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.dirhold", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.dirhold), hm2->llio->comp_id); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.dirhold), + v, "%s.stepgen.%02d.dirhold", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.dirhold', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.step_type", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.step_type), hm2->llio->comp_id); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.step_type), + 0, "%s.stepgen.%02d.step_type", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.step_type', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } if (hm2->stepgen.firmware_supports_swap) { - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.swap_step_dir", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.swap_step_dir), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.swap_step_dir), + 0, "%s.stepgen.%02d.swap_step_dir", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.swap_step_dir', aborting\n", r, hm2->llio->name, i); + r = -ENOMEM; + goto fail5; + } + } else { + r = hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(hm2->stepgen.instance[i].hal.param.swap_step_dir)); + if (r < 0) { + HM2_ERR("error %d allocating fake param '%s.stepgen.%02d.swap_step_dir', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } } if (hm2->stepgen.instance[i].table_width > 2){ - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.table-data-0", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.table[0]), hm2->llio->comp_id); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.table[0]), + 0, "%s.stepgen.%02d.table-data-0", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.table-data-0', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.table-data-1", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.table[1]), hm2->llio->comp_id); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.table[1]), + 0, "%s.stepgen.%02d.table-data-1", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.table-data-1', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.table-data-2", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.table[2]), hm2->llio->comp_id); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.table[2]), + 0, "%s.stepgen.%02d.table-data-2", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.table-data-2', aborting\n", r, hm2->llio->name, i); r = -ENOMEM; goto fail5; } - rtapi_snprintf(name, sizeof(name), "%s.stepgen.%02d.table-data-3", hm2->llio->name, i); - r = hal_param_u32_new(name, HAL_RW, &(hm2->stepgen.instance[i].hal.param.table[3]), hm2->llio->comp_id); + r = hal_param_new_ui32(hm2->llio->comp_id, HAL_RW, &(hm2->stepgen.instance[i].hal.param.table[3]), + 0, "%s.stepgen.%02d.table-data-3", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.stepgen.%02d.table-data-3', aborting\n", r, hm2->llio->name, i); + r = -ENOMEM; + goto fail5; + } + } else { + // Still allocate storage to prevent crashing when dereferencing the table + r = hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(hm2->stepgen.instance[i].hal.param.table[0])); + r += hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(hm2->stepgen.instance[i].hal.param.table[1])); + r += hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(hm2->stepgen.instance[i].hal.param.table[2])); + r += hal_param_new_fake(hm2->llio->comp_id, (hal_refs_u *)&(hm2->stepgen.instance[i].hal.param.table[3])); + if (r < 0) { + HM2_ERR("error allocating fake param '%s.stepgen.%02d.table-data-N', aborting\n", hm2->llio->name, i); r = -ENOMEM; goto fail5; } - } // init - *(hm2->stepgen.instance[i].hal.pin.position_cmd) = 0.0; - *(hm2->stepgen.instance[i].hal.pin.counts) = 0; - *(hm2->stepgen.instance[i].hal.pin.position_fb) = 0.0; - *(hm2->stepgen.instance[i].hal.pin.velocity_fb) = 0.0; - *(hm2->stepgen.instance[i].hal.pin.enable) = 0; - *(hm2->stepgen.instance[i].hal.pin.control_type) = 0; - *(hm2->stepgen.instance[i].hal.pin.position_reset) = 0; - if (hm2->stepgen.firmware_supports_index) { - *(hm2->stepgen.instance[i].hal.pin.index_enable) = 0; - *(hm2->stepgen.instance[i].hal.pin.latch_enable) = 0; - *(hm2->stepgen.instance[i].hal.pin.index_polarity) = 0; - *(hm2->stepgen.instance[i].hal.pin.latch_polarity) = 0; - } - hm2->stepgen.instance[i].hal.param.position_scale = 1.0; - hm2->stepgen.instance[i].hal.param.maxvel = 0.0; - hm2->stepgen.instance[i].hal.param.maxaccel = 1.0; - hm2->stepgen.instance[i].subcounts = 0; - // start out the slowest possible, let the user speed up if they want - hm2->stepgen.instance[i].hal.param.steplen = (double)0x3FFF * ((double)1e9 / (double)hm2->stepgen.clock_frequency); - hm2->stepgen.instance[i].hal.param.stepspace = (double)0x3FFF * ((double)1e9 / (double)hm2->stepgen.clock_frequency); - hm2->stepgen.instance[i].hal.param.dirsetup = (double)0x3FFF * ((double)1e9 / (double)hm2->stepgen.clock_frequency); - hm2->stepgen.instance[i].hal.param.dirhold = (double)0x3FFF * ((double)1e9 / (double)hm2->stepgen.clock_frequency); - - hm2->stepgen.instance[i].hal.param.step_type = 0; // step & dir - - if (hm2->stepgen.firmware_supports_swap) { - hm2->stepgen.instance[i].hal.param.swap_step_dir = 0; // no swap - } hm2->stepgen.instance[i].written_steplen = 0; hm2->stepgen.instance[i].written_stepspace = 0; hm2->stepgen.instance[i].written_dirsetup = 0; hm2->stepgen.instance[i].written_dirhold = 0; hm2->stepgen.instance[i].written_step_type = 0xffffffff; - hm2->stepgen.instance[i].hal.param.table[0] = 0; - hm2->stepgen.instance[i].hal.param.table[1] = 0; - hm2->stepgen.instance[i].hal.param.table[2] = 0; - hm2->stepgen.instance[i].hal.param.table[3] = 0; hm2->stepgen.instance[i].prev_accumulator = 0; - } } @@ -1237,15 +1237,15 @@ void hm2_stepgen_print_module(hostmot2_t *hm2) { HM2_PRINT(" master_dds_addr: 0x%04X\n", hm2->stepgen.master_dds_addr); for (i = 0; i < hm2->stepgen.num_instances; i ++) { HM2_PRINT(" instance %d:\n", i); - HM2_PRINT(" enable = %d\n", *hm2->stepgen.instance[i].hal.pin.enable); + HM2_PRINT(" enable = %d\n", (int)hal_get_bool(hm2->stepgen.instance[i].hal.pin.enable)); HM2_PRINT(" hw:\n"); HM2_PRINT(" step_rate = 0x%08X\n", hm2->stepgen.step_rate_reg[i]); HM2_PRINT(" accumulator = 0x%08X\n", hm2->stepgen.accumulator_reg[i]); HM2_PRINT(" mode = 0x%08X\n", hm2->stepgen.mode_reg[i]); - HM2_PRINT(" dir_setup_time = 0x%08X (%u ns)\n", hm2->stepgen.dir_setup_time_reg[i], hm2->stepgen.instance[i].hal.param.dirsetup); - HM2_PRINT(" dir_hold_time = 0x%08X (%u ns)\n", hm2->stepgen.dir_hold_time_reg[i], hm2->stepgen.instance[i].hal.param.dirhold); - HM2_PRINT(" pulse_width = 0x%08X (%u ns)\n", hm2->stepgen.pulse_width_reg[i], hm2->stepgen.instance[i].hal.param.steplen); - HM2_PRINT(" pulse_idle_width = 0x%08X (%u ns)\n", hm2->stepgen.pulse_idle_width_reg[i], hm2->stepgen.instance[i].hal.param.stepspace); + HM2_PRINT(" dir_setup_time = 0x%08X (%u ns)\n", hm2->stepgen.dir_setup_time_reg[i], hal_get_ui32(hm2->stepgen.instance[i].hal.param.dirsetup)); + HM2_PRINT(" dir_hold_time = 0x%08X (%u ns)\n", hm2->stepgen.dir_hold_time_reg[i], hal_get_ui32(hm2->stepgen.instance[i].hal.param.dirhold)); + HM2_PRINT(" pulse_width = 0x%08X (%u ns)\n", hm2->stepgen.pulse_width_reg[i], hal_get_ui32(hm2->stepgen.instance[i].hal.param.steplen)); + HM2_PRINT(" pulse_idle_width = 0x%08X (%u ns)\n", hm2->stepgen.pulse_idle_width_reg[i], hal_get_ui32(hm2->stepgen.instance[i].hal.param.stepspace)); } } diff --git a/src/hal/drivers/mesa-hostmot2/tp_pwmgen.c b/src/hal/drivers/mesa-hostmot2/tp_pwmgen.c index b5539e96a04..1be71efbf8c 100644 --- a/src/hal/drivers/mesa-hostmot2/tp_pwmgen.c +++ b/src/hal/drivers/mesa-hostmot2/tp_pwmgen.c @@ -33,10 +33,10 @@ void hm2_tp_pwmgen_handle_pwm_frequency(hostmot2_t *hm2) { int deadtime; int i; - if (hm2->tp_pwmgen.hal->param.pwm_frequency < 1) { - HM2_ERR("3pwmgen.pwm_frequency %d is too low, setting to 1\n", - hm2->tp_pwmgen.hal->param.pwm_frequency); - hm2->tp_pwmgen.hal->param.pwm_frequency = 1; + rtapi_u32 pwm_frequency = hal_get_ui32(hm2->tp_pwmgen.hal->param.pwm_frequency); + if (pwm_frequency < 1) { + HM2_ERR("3pwmgen.pwm_frequency %d is too low, setting to 1\n", pwm_frequency); + pwm_frequency = hal_set_ui32(hm2->tp_pwmgen.hal->param.pwm_frequency, 1); } @@ -57,7 +57,7 @@ void hm2_tp_pwmgen_handle_pwm_frequency(hostmot2_t *hm2) { // // check that the frequency is achievable - dds = ((double)hm2->tp_pwmgen.hal->param.pwm_frequency * 65536.0 * 2048.0) + dds = ((double)pwm_frequency * 65536.0 * 2048.0) / (double)hm2->tp_pwmgen.clock_frequency; if (dds < 65536) { hm2->tp_pwmgen.pwmgen_master_rate_dds_reg = dds; @@ -65,11 +65,10 @@ void hm2_tp_pwmgen_handle_pwm_frequency(hostmot2_t *hm2) { // not possible so try the fastest we can // PWMFreq = (ClockHigh * DDS) / (65536 * 2048) dds = 65535; - hm2->tp_pwmgen.hal->param.pwm_frequency = + pwm_frequency = hal_set_ui32(hm2->tp_pwmgen.hal->param.pwm_frequency, ((double)hm2->tp_pwmgen.clock_frequency * 65535.0) - / (65536.0 * 2048.0); - HM2_ERR("max PWM frequency is %d Hz\n", - hm2->tp_pwmgen.hal->param.pwm_frequency); + / (65536.0 * 2048.0)); + HM2_ERR("max PWM frequency is %d Hz\n", pwm_frequency); hm2->tp_pwmgen.pwmgen_master_rate_dds_reg = dds; } @@ -78,37 +77,38 @@ void hm2_tp_pwmgen_handle_pwm_frequency(hostmot2_t *hm2) { // = (2*65536*1e9 / ClockHigh*dds)nS for (i=0; i < hm2->tp_pwmgen.num_instances; i++) { - if (hm2->tp_pwmgen.instance[i].hal.param.sampletime > 1){ + rtapi_real sampletime = hal_get_real(hm2->tp_pwmgen.instance[i].hal.param.sampletime); + if (sampletime > 1){ HM2_ERR("Max sampletime is 1 (end of PWM cycle"); - hm2->tp_pwmgen.instance[i].hal.param.sampletime = 1; + sampletime = hal_set_real(hm2->tp_pwmgen.instance[i].hal.param.sampletime, 1); } - else if (hm2->tp_pwmgen.instance[i].hal.param.sampletime < 0){ + else if (sampletime < 0){ HM2_ERR("Min sampletime is 0 (beginning of PWM cycle"); - hm2->tp_pwmgen.instance[i].hal.param.sampletime = 0; + sampletime = hal_set_real(hm2->tp_pwmgen.instance[i].hal.param.sampletime, 0); } - deadtime = (hm2->tp_pwmgen.instance[i].hal.param.deadzone + deadtime = (hal_get_real(hm2->tp_pwmgen.instance[i].hal.param.deadzone) * hm2->tp_pwmgen.clock_frequency * dds) / (2 * 65536 * 1e9); if (deadtime > 511){ deadtime = 511; - hm2->tp_pwmgen.instance[i].hal.param.deadzone = + hal_set_real(hm2->tp_pwmgen.instance[i].hal.param.deadzone, ((double)deadtime * 2.0 * 65536.0 * 1.0e9) - /((double)hm2->tp_pwmgen.clock_frequency * dds); + /((double)hm2->tp_pwmgen.clock_frequency * dds)); HM2_ERR("At this PWM frequency the maximum deadtime is %dnS\n", - (int)hm2->tp_pwmgen.instance[i].hal.param.deadzone); + (int)hal_get_real(hm2->tp_pwmgen.instance[i].hal.param.deadzone)); } else if (deadtime < 0) { HM2_ERR("Deadtime must be positive"); deadtime = 0; - hm2->tp_pwmgen.instance[i].hal.param.deadzone = 0; + hal_set_real(hm2->tp_pwmgen.instance[i].hal.param.deadzone, 0); } // Now setup the control register hm2->tp_pwmgen.setup_reg[i] = ( - ((int)(hm2->tp_pwmgen.instance[i].hal.param.sampletime*1023) << 16) - +((hm2->tp_pwmgen.instance[i].hal.param.faultpolarity != 0) << 15) + ((int)(sampletime*1023) << 16) + +(hal_get_bool(hm2->tp_pwmgen.instance[i].hal.param.faultpolarity) << 15) +(deadtime)); } } @@ -125,7 +125,7 @@ void hm2_tp_pwmgen_force_write(hostmot2_t *hm2) { // update enable and setup registers for (i = 0; i < hm2->tp_pwmgen.num_instances; i ++) { - if (*hm2->tp_pwmgen.instance[i].hal.pin.enable) + if (hal_get_bool(hm2->tp_pwmgen.instance[i].hal.pin.enable)) hm2->tp_pwmgen.enable_reg[i] = 1; else hm2->tp_pwmgen.enable_reg[i] = 0; @@ -136,15 +136,15 @@ void hm2_tp_pwmgen_force_write(hostmot2_t *hm2) { hm2->llio->write(hm2->llio, hm2->tp_pwmgen.enable_addr, hm2->tp_pwmgen.enable_reg, (hm2->tp_pwmgen.num_instances * sizeof(rtapi_u32))); hm2->llio->write(hm2->llio, hm2->tp_pwmgen.pwmgen_master_rate_dds_addr, &hm2->tp_pwmgen.pwmgen_master_rate_dds_reg, sizeof(rtapi_u32)); - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; for (i = 0; i < hm2->tp_pwmgen.num_instances; i ++) { - hm2->tp_pwmgen.instance[i].written_faultpolarity = hm2->tp_pwmgen.instance[i].hal.param.faultpolarity; - hm2->tp_pwmgen.instance[i].written_deadzone = hm2->tp_pwmgen.instance[i].hal.param.deadzone; - hm2->tp_pwmgen.instance[i].written_sampletime = hm2->tp_pwmgen.instance[i].hal.param.sampletime; + hm2->tp_pwmgen.instance[i].written_faultpolarity = hal_get_bool(hm2->tp_pwmgen.instance[i].hal.param.faultpolarity); + hm2->tp_pwmgen.instance[i].written_deadzone = hal_get_real(hm2->tp_pwmgen.instance[i].hal.param.deadzone); + hm2->tp_pwmgen.instance[i].written_sampletime = hal_get_real(hm2->tp_pwmgen.instance[i].hal.param.sampletime); } - hm2->tp_pwmgen.written_pwm_frequency = hm2->tp_pwmgen.hal->param.pwm_frequency; + hm2->tp_pwmgen.written_pwm_frequency = hal_get_ui32(hm2->tp_pwmgen.hal->param.pwm_frequency); } @@ -158,13 +158,14 @@ void hm2_tp_pwmgen_write(hostmot2_t *hm2) { if (hm2->tp_pwmgen.num_instances == 0) return; // check pwm frequency - if (hm2->tp_pwmgen.hal->param.pwm_frequency != hm2->tp_pwmgen.written_pwm_frequency) goto force_write; + if (hal_get_ui32(hm2->tp_pwmgen.hal->param.pwm_frequency) != hm2->tp_pwmgen.written_pwm_frequency) goto force_write; // update enable register? for (i = 0; i < hm2->tp_pwmgen.num_instances; i ++) { - if ((hm2->tp_pwmgen.instance[i].hal.param.deadzone != hm2->tp_pwmgen.instance[i].written_deadzone) - || (hm2->tp_pwmgen.instance[i].hal.param.sampletime != hm2->tp_pwmgen.instance[i].written_sampletime) - || (hm2->tp_pwmgen.instance[i].hal.param.faultpolarity != hm2->tp_pwmgen.instance[i].written_faultpolarity)) + hm2_tp_pwmgen_instance_t *inst = &hm2->tp_pwmgen.instance[i]; + if ((hal_get_real(inst->hal.param.deadzone) != inst->written_deadzone) + || (hal_get_real(inst->hal.param.sampletime) != inst->written_sampletime) + || (hal_get_bool(inst->hal.param.faultpolarity) != inst->written_faultpolarity)) goto force_write; // The enable register is a little odd. Writing a 1 to bit0 of the @@ -174,7 +175,7 @@ void hm2_tp_pwmgen_write(hostmot2_t *hm2) { // enable if there is a mismatch between the hal-pin and the enable // bit. - if ((*hm2->tp_pwmgen.instance[i].hal.pin.enable != (hm2->tp_pwmgen.enable_reg[i] & 1))) + if ((hal_get_bool(inst->hal.pin.enable) != (hm2->tp_pwmgen.enable_reg[i] & 1))) goto force_write; } @@ -194,8 +195,7 @@ void hm2_tp_pwmgen_queue_read(hostmot2_t *hm2) { void hm2_tp_pwmgen_process_read(hostmot2_t *hm2) { int i; for (i = 0 ; i < hm2->tp_pwmgen.num_instances ; i++) { - *hm2->tp_pwmgen.instance[i].hal.pin.fault - = (hm2->tp_pwmgen.enable_reg[i] & 2); + hal_set_bool(hm2->tp_pwmgen.instance[i].hal.pin.fault, (hm2->tp_pwmgen.enable_reg[i] & 2)); } } @@ -249,14 +249,14 @@ int hm2_tp_pwmgen_parse_md(hostmot2_t *hm2, int md_index) { // allocate the module-global HAL shared memory - hm2->tp_pwmgen.instance = (hm2_tp_pwmgen_instance_t *)hal_malloc(hm2->tp_pwmgen.num_instances * sizeof(hm2_tp_pwmgen_instance_t)); + hm2->tp_pwmgen.instance = hal_malloc(hm2->tp_pwmgen.num_instances * sizeof(*hm2->tp_pwmgen.instance)); if (hm2->tp_pwmgen.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; goto fail0; } - hm2->tp_pwmgen.hal = (hm2_tp_pwmgen_global_hal_t *)hal_malloc(sizeof(hm2_tp_pwmgen_global_hal_t)); + hm2->tp_pwmgen.hal = hal_malloc(sizeof(*hm2->tp_pwmgen.hal)); if (hm2->tp_pwmgen.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -294,17 +294,13 @@ int hm2_tp_pwmgen_parse_md(hostmot2_t *hm2, int md_index) { } // export to HAL - // FIXME: r hides the r in enclosing function, and it returns the wrong thing { - int i; - int r; - char name[HAL_NAME_LEN + 1]; - // this hal parameter affects all the 3-Phase pwmgen instances - r = hal_param_u32_newf( + r = hal_param_new_ui32( + hm2->llio->comp_id, HAL_RW, &(hm2->tp_pwmgen.hal->param.pwm_frequency), - hm2->llio->comp_id, + 20000, "%s.3pwmgen.frequency", hm2->llio->name ); @@ -313,89 +309,76 @@ int hm2_tp_pwmgen_parse_md(hostmot2_t *hm2, int md_index) { goto fail2; } - hm2->tp_pwmgen.hal->param.pwm_frequency = 20000; hm2->tp_pwmgen.written_pwm_frequency = 0; // force a write - for (i = 0; i < hm2->tp_pwmgen.num_instances; i ++) { + for (int i = 0; i < hm2->tp_pwmgen.num_instances; i ++) { // pins - rtapi_snprintf(name, sizeof(name), "%s.3pwmgen.%02d.A-value", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->tp_pwmgen.instance[i].hal.pin.Avalue), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->tp_pwmgen.instance[i].hal.pin.Avalue), + 0.0, "%s.3pwmgen.%02d.A-value", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.3pwmgen.%02d.A-value', aborting\n", r, hm2->llio->name, i); goto fail2; } - rtapi_snprintf(name, sizeof(name), "%s.3pwmgen.%02d.B-value", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->tp_pwmgen.instance[i].hal.pin.Bvalue), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->tp_pwmgen.instance[i].hal.pin.Bvalue), + 0.0, "%s.3pwmgen.%02d.B-value", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.3pwmgen.%02d.B-value', aborting\n", r, hm2->llio->name, i); goto fail2; } - rtapi_snprintf(name, sizeof(name), "%s.3pwmgen.%02d.C-value", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->tp_pwmgen.instance[i].hal.pin.Cvalue), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->tp_pwmgen.instance[i].hal.pin.Cvalue), + 0.0, "%s.3pwmgen.%02d.C-value", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.3pwmgen.%02d.C-value', aborting\n", r, hm2->llio->name, i); goto fail2; } - rtapi_snprintf(name, sizeof(name), "%s.3pwmgen.%02d.enable", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->tp_pwmgen.instance[i].hal.pin.enable), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->tp_pwmgen.instance[i].hal.pin.enable), + 0, "%s.3pwmgen.%02d.enable", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.3pwmgen.%02d.enable', aborting\n", r, hm2->llio->name, i); goto fail2; } - rtapi_snprintf(name, sizeof(name), "%s.3pwmgen.%02d.fault", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->tp_pwmgen.instance[i].hal.pin.fault), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->tp_pwmgen.instance[i].hal.pin.fault), + 0, "%s.3pwmgen.%02d.fault", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); + HM2_ERR("error %d adding pin '%s.3pwmgen.%02d.fault', aborting\n", r, hm2->llio->name, i); goto fail2; } // parameters - rtapi_snprintf(name, sizeof(name), "%s.3pwmgen.%02d.scale", hm2->llio->name, i); - r = hal_param_float_new(name, HAL_RW, &(hm2->tp_pwmgen.instance[i].hal.param.scale), hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->tp_pwmgen.instance[i].hal.param.scale), + 1.0, "%s.3pwmgen.%02d.scale", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.3pwmgen.%02d.scale', aborting\n", r, hm2->llio->name, i); goto fail2; } - rtapi_snprintf(name, sizeof(name), "%s.3pwmgen.%02d.deadtime", hm2->llio->name, i); - r = hal_param_float_new(name, HAL_RW, &(hm2->tp_pwmgen.instance[i].hal.param.deadzone), hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->tp_pwmgen.instance[i].hal.param.deadzone), + 5000.0, "%s.3pwmgen.%02d.deadtime", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.3pwmgen.%02d.deadtime', aborting\n", r, hm2->llio->name, i); goto fail2; } - rtapi_snprintf(name, sizeof(name), "%s.3pwmgen.%02d.fault-invert", hm2->llio->name, i); - r = hal_param_bit_new(name, HAL_RW, &(hm2->tp_pwmgen.instance[i].hal.param.faultpolarity), hm2->llio->comp_id); + r = hal_param_new_bool(hm2->llio->comp_id, HAL_RW, &(hm2->tp_pwmgen.instance[i].hal.param.faultpolarity), + 0, "%s.3pwmgen.%02d.fault-invert", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.3pwmgen.%02d.fault-invert', aborting\n", r, hm2->llio->name, i); goto fail2; } - rtapi_snprintf(name, sizeof(name), "%s.3pwmgen.%02d.sample-time", hm2->llio->name, i); - r = hal_param_float_new(name, HAL_RW, &(hm2->tp_pwmgen.instance[i].hal.param.sampletime), hm2->llio->comp_id); + r = hal_param_new_real(hm2->llio->comp_id, HAL_RW, &(hm2->tp_pwmgen.instance[i].hal.param.sampletime), + 0.5, "%s.3pwmgen.%02d.sample-time", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding param '%s', aborting\n", name); + HM2_ERR("error %d adding param '%s.3pwmgen.%02d.sample-time', aborting\n", r, hm2->llio->name, i); goto fail2; } - - // init hal objects - *(hm2->tp_pwmgen.instance[i].hal.pin.enable) = 0; - *(hm2->tp_pwmgen.instance[i].hal.pin.Avalue) = 0.0; - *(hm2->tp_pwmgen.instance[i].hal.pin.Bvalue) = 0.0; - *(hm2->tp_pwmgen.instance[i].hal.pin.Cvalue) = 0.0; - - hm2->tp_pwmgen.instance[i].hal.param.scale = 1.0; - hm2->tp_pwmgen.instance[i].hal.param.sampletime = 0.5; - hm2->tp_pwmgen.instance[i].hal.param.faultpolarity = 0.0; //active low - hm2->tp_pwmgen.instance[i].hal.param.deadzone = 5000; // 5000nS conservative deadzone for safety - hm2->tp_pwmgen.instance[i].written_sampletime = -666; // force an update at the start } } @@ -448,14 +431,15 @@ void hm2_tp_pwmgen_prepare_tram_write(hostmot2_t *hm2) { // pwmgen) // Check for /0 problems - if (hm2->tp_pwmgen.instance[i].hal.param.scale ==0) { - hm2->tp_pwmgen.instance[i].hal.param.scale = 1; - HM2_ERR("3pwmgen scale must be greater than zero. Scale set to %i", (int)hm2->tp_pwmgen.instance[i].hal.param.scale); + rtapi_real scale = hal_get_real(hm2->tp_pwmgen.instance[i].hal.param.scale); + if (scale ==0) { + scale = hal_set_real(hm2->tp_pwmgen.instance[i].hal.param.scale, 1); + HM2_ERR("3pwmgen scale must be greater than zero. Scale set to %i", (int)scale); } - scaled_Avalue = (*hm2->tp_pwmgen.instance[i].hal.pin.Avalue / hm2->tp_pwmgen.instance[i].hal.param.scale); - scaled_Bvalue = (*hm2->tp_pwmgen.instance[i].hal.pin.Bvalue / hm2->tp_pwmgen.instance[i].hal.param.scale); - scaled_Cvalue = (*hm2->tp_pwmgen.instance[i].hal.pin.Cvalue / hm2->tp_pwmgen.instance[i].hal.param.scale); + scaled_Avalue = hal_get_real(hm2->tp_pwmgen.instance[i].hal.pin.Avalue) / scale; + scaled_Bvalue = hal_get_real(hm2->tp_pwmgen.instance[i].hal.pin.Bvalue) / scale; + scaled_Cvalue = hal_get_real(hm2->tp_pwmgen.instance[i].hal.pin.Cvalue) / scale; if (scaled_Avalue > 1.0) scaled_Avalue = 1.0; else if (scaled_Avalue < -1.0) scaled_Avalue = -1.0; diff --git a/src/hal/drivers/mesa-hostmot2/uart.c b/src/hal/drivers/mesa-hostmot2/uart.c index 609835b18f9..426f4b08511 100644 --- a/src/hal/drivers/mesa-hostmot2/uart.c +++ b/src/hal/drivers/mesa-hostmot2/uart.c @@ -79,8 +79,7 @@ int hm2_uart_parse_md(hostmot2_t *hm2, int md_index) hm2->uart.num_instances = hm2->config.num_uarts; } - hm2->uart.instance = (hm2_uart_instance_t *)hal_malloc(hm2->uart.num_instances - * sizeof(hm2_uart_instance_t)); + hm2->uart.instance = hal_malloc(hm2->uart.num_instances * sizeof(*hm2->uart.instance)); if (hm2->uart.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -141,7 +140,7 @@ EXPORT_SYMBOL_GPL(hm2_uart_setup); // use -1 for tx_mode and rx_mode to leave the mode unchanged int hm2_uart_setup(char *name, int bitrate, rtapi_s32 tx_mode, rtapi_s32 rx_mode){ hostmot2_t *hm2; - hm2_uart_instance_t *inst = 0; + hm2_uart_instance_t *inst = NULL; rtapi_u32 buff; int i,r; diff --git a/src/hal/drivers/mesa-hostmot2/watchdog.c b/src/hal/drivers/mesa-hostmot2/watchdog.c index 07422bdfdd3..b1512e60904 100644 --- a/src/hal/drivers/mesa-hostmot2/watchdog.c +++ b/src/hal/drivers/mesa-hostmot2/watchdog.c @@ -35,7 +35,7 @@ void hm2_watchdog_process_tram_read(hostmot2_t *hm2) { if (hm2->watchdog.num_instances == 0) return; // if there are comm problems, wait for the user to fix it - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; // if we've already noticed the board needs to be reset, don't re-read // the watchdog has-bit bit @@ -48,7 +48,7 @@ void hm2_watchdog_process_tram_read(hostmot2_t *hm2) { // see if the watchdog has bit since then if (hm2->watchdog.status_reg[0] & 0x1) { HM2_ERR("Watchdog has bit! (set the .has-bit pin to False to resume)\n"); - *hm2->watchdog.instance[0].hal.pin.has_bit = 1; + hal_set_bool(hm2->watchdog.instance[0].hal.pin.has_bit, 1); hm2->llio->needs_reset = 1; } } @@ -93,7 +93,7 @@ int hm2_watchdog_parse_md(hostmot2_t *hm2, int md_index) { hm2->watchdog.num_instances = 1; - hm2->watchdog.instance = (hm2_watchdog_instance_t *)hal_malloc(hm2->watchdog.num_instances * sizeof(hm2_watchdog_instance_t)); + hm2->watchdog.instance = hal_malloc(hm2->watchdog.num_instances * sizeof(*hm2->watchdog.instance)); if (hm2->watchdog.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -137,10 +137,11 @@ int hm2_watchdog_parse_md(hostmot2_t *hm2, int md_index) { // // pins - r = hal_pin_bit_newf( + r = hal_pin_new_bool( + hm2->llio->comp_id, HAL_IO, &(hm2->watchdog.instance[0].hal.pin.has_bit), - hm2->llio->comp_id, + 0, "%s.watchdog.has_bit", hm2->llio->name ); @@ -151,10 +152,12 @@ int hm2_watchdog_parse_md(hostmot2_t *hm2, int md_index) { } // params - r = hal_param_u32_newf( + // default timeout is 5 milliseconds (5*1000*1000 nanoseconds) + r = hal_param_new_ui32( + hm2->llio->comp_id, HAL_RW, &(hm2->watchdog.instance[0].hal.param.timeout_ns), - hm2->llio->comp_id, + 5 * 1000 * 1000, "%s.watchdog.timeout_ns", hm2->llio->name ); @@ -168,8 +171,6 @@ int hm2_watchdog_parse_md(hostmot2_t *hm2, int md_index) { // initialize the watchdog // - *hm2->watchdog.instance[0].hal.pin.has_bit = 0; - hm2->watchdog.instance[0].hal.param.timeout_ns = 5 * 1000 * 1000; // default timeout is 5 milliseconds hm2->watchdog.instance[0].enable = 0; // the first pet_watchdog will turn it on return hm2->watchdog.num_instances; @@ -195,8 +196,8 @@ void hm2_watchdog_print_module(hostmot2_t *hm2) { HM2_PRINT(" reset_addr: 0x%04X\n", hm2->watchdog.reset_addr); for (i = 0; i < hm2->watchdog.num_instances; i ++) { HM2_PRINT(" instance %d:\n", i); - HM2_PRINT(" param timeout_ns = %u\n", hm2->watchdog.instance[i].hal.param.timeout_ns); - HM2_PRINT(" pin has_bit = %d\n", (*hm2->watchdog.instance[i].hal.pin.has_bit)); + HM2_PRINT(" param timeout_ns = %u\n", hal_get_ui32(hm2->watchdog.instance[i].hal.param.timeout_ns)); + HM2_PRINT(" pin has_bit = %d\n", (int)hal_get_bool(hm2->watchdog.instance[i].hal.pin.has_bit)); HM2_PRINT(" reg timer = 0x%08X\n", hm2->watchdog.timer_reg[i]); } } @@ -222,25 +223,27 @@ void hm2_watchdog_force_write(hostmot2_t *hm2) { if (hm2->watchdog.num_instances != 1) return; + rtapi_u32 timeout_ns = hal_get_ui32(hm2->watchdog.instance[0].hal.param.timeout_ns); if (hm2->watchdog.instance[0].enable == 0) { // watchdog is disabled, MSb=1 is secret handshake with FPGA hm2->watchdog.timer_reg[0] = 0x80000000; } else { - tmp = (hm2->watchdog.instance[0].hal.param.timeout_ns * ((double)hm2->watchdog.clock_frequency / (double)(1000 * 1000 * 1000))) - 1; + tmp = (timeout_ns * ((double)hm2->watchdog.clock_frequency / (double)(1000 * 1000 * 1000))) - 1; if (tmp < 0x80000000) { hm2->watchdog.timer_reg[0] = tmp; } else { // truncate watchdog timeout tmp = 0x7FFFFFFF; hm2->watchdog.timer_reg[0] = tmp; - hm2->watchdog.instance[0].hal.param.timeout_ns = (tmp + 1) / ((double)hm2->watchdog.clock_frequency / (double)(1000 * 1000 * 1000)); - HM2_ERR("requested watchdog timeout is out of range, setting it to max: %u ns\n", hm2->watchdog.instance[0].hal.param.timeout_ns); + timeout_ns = hal_set_ui32(hm2->watchdog.instance[0].hal.param.timeout_ns, + (tmp + 1) / ((double)hm2->watchdog.clock_frequency / (double)(1000 * 1000 * 1000))); + HM2_ERR("requested watchdog timeout is out of range, setting it to max: %u ns\n", timeout_ns); } } // set the watchdog timeout (we'll check for i/o errors later) hm2->llio->write(hm2->llio, hm2->watchdog.timer_addr, hm2->watchdog.timer_reg, (hm2->watchdog.num_instances * sizeof(rtapi_u32))); - hm2->watchdog.instance[0].written_timeout_ns = hm2->watchdog.instance[0].hal.param.timeout_ns; + hm2->watchdog.instance[0].written_timeout_ns = timeout_ns; hm2->watchdog.instance[0].written_enable = hm2->watchdog.instance[0].enable; // clear the has-bit bit @@ -253,10 +256,10 @@ void hm2_watchdog_write(hostmot2_t *hm2, long period_ns) { if (hm2->watchdog.num_instances != 1) return; // if there are comm problems, wait for the user to fix it - if ((*hm2->llio->io_error) != 0) return; + if (hal_get_bool(*hm2->llio->io_error)) return; // if the watchdog has bit, wait for the user to reset it - if (*hm2->watchdog.instance[0].hal.pin.has_bit) return; + if (hal_get_bool(hm2->watchdog.instance[0].hal.pin.has_bit)) return; // writing to the watchdog wakes it up, and now we can't stop or it will bite! hm2->watchdog.instance[0].enable = 1; @@ -271,7 +274,7 @@ void hm2_watchdog_write(hostmot2_t *hm2, long period_ns) { // write all settings out to the FPGA hm2_force_write(hm2); - if ((*hm2->llio->io_error) != 0) { + if (hal_get_bool(*hm2->llio->io_error)) { HM2_PRINT("error recovery failed\n"); return; } @@ -281,8 +284,9 @@ void hm2_watchdog_write(hostmot2_t *hm2, long period_ns) { hm2->llio->needs_reset = hm2->llio->needs_soft_reset = 0; } + rtapi_u32 timeout_ns = hal_get_ui32(hm2->watchdog.instance[0].hal.param.timeout_ns); if ( - (hm2->watchdog.instance[0].hal.param.timeout_ns == hm2->watchdog.instance[0].written_timeout_ns) + (timeout_ns == hm2->watchdog.instance[0].written_timeout_ns) && (hm2->watchdog.instance[0].enable == hm2->watchdog.instance[0].written_enable) ) { @@ -290,10 +294,10 @@ void hm2_watchdog_write(hostmot2_t *hm2, long period_ns) { } // if the requested timeout is dangerously short compared to the petting-period, warn the user once - if (hm2->watchdog.instance[0].hal.param.timeout_ns < (1.5 * period_ns)) { + if (timeout_ns < (1.5 * period_ns)) { HM2_PRINT( "Watchdog timeout (%u ns) is dangerously short compared to hm2_write() period (%ld ns)\n", - hm2->watchdog.instance[0].hal.param.timeout_ns, + timeout_ns, period_ns ); } diff --git a/src/hal/drivers/mesa-hostmot2/xy2mod.c b/src/hal/drivers/mesa-hostmot2/xy2mod.c index 42f0508feeb..35f10a03fd5 100644 --- a/src/hal/drivers/mesa-hostmot2/xy2mod.c +++ b/src/hal/drivers/mesa-hostmot2/xy2mod.c @@ -38,58 +38,58 @@ void hm2_xy2mod_process_tram_read(hostmot2_t *hm2) { int i; for (i = 0; i < hm2->xy2mod.num_instances; i ++) { - hm2_xy2mod_instance_t *s = &hm2->xy2mod.instance[i]; + hm2_xy2mod_instance_t *s = &hm2->xy2mod.instance[i]; rtapi_u32 posx = hm2->xy2mod.posx_reg[i]; rtapi_u32 posy = hm2->xy2mod.posy_reg[i]; rtapi_u32 velx = hm2->xy2mod.velx_reg[i]; rtapi_u32 vely = hm2->xy2mod.vely_reg[i]; - rtapi_u32 mode = hm2->xy2mod.mode_reg[i]; - rtapi_u32 status = hm2->xy2mod.status_reg[i]; + rtapi_u32 mode = hm2->xy2mod.mode_reg[i]; + rtapi_u32 status = hm2->xy2mod.status_reg[i]; // those tricky users are always trying to get us to divide by zero - if (fabs(*s->hal.pin.posx_scale) < 1e-6) { - if (*s->hal.pin.posx_scale >= 0.0) { - *s->hal.pin.posx_scale = 1.0; + rtapi_real posx_scale = hal_get_real(s->hal.pin.posx_scale); + if (fabs(posx_scale) < 1e-6) { + if (posx_scale >= 0.0) { + posx_scale = hal_set_real(s->hal.pin.posx_scale, 1.0); HM2_ERR("xy2mod %d position_scalex is too close to 0, resetting to 1.0\n", i); } else { - *s->hal.pin.posx_scale = -1.0; + posx_scale = hal_set_real(s->hal.pin.posx_scale, -1.0); HM2_ERR("xy2mod %d position_scalxe is too close to 0, resetting to -1.0\n", i); } } - if (fabs(*s->hal.pin.posy_scale) < 1e-6) { - if (*s->hal.pin.posy_scale >= 0.0) { - *s->hal.pin.posy_scale = 1.0; + rtapi_real posy_scale = hal_get_real(s->hal.pin.posy_scale); + if (fabs(posy_scale) < 1e-6) { + if (posy_scale >= 0.0) { + posy_scale = hal_set_real(s->hal.pin.posy_scale, 1.0); HM2_ERR("xy2mod %d position_scaley is too close to 0, resetting to 1.0\n", i); } else { - *s->hal.pin.posy_scale = -1.0; + posy_scale = hal_set_real(s->hal.pin.posy_scale, -1.0); HM2_ERR("xy2mod %d position_scaley is too close to 0, resetting to -1.0\n", i); } } - + // The xy2mod position Registers are a 16.16 bit fixed-point // representation of the current galvanometer position. // The fractional part gives accurate velocity at low speeds, and // sub bit position feedback - // need to "unscale" the position registers to return to machine units - - *(s->hal.pin.posx_fb) = ((double)(int32_t)(posx) / 2147483647.0) / *s->hal.pin.posx_scale; - *(s->hal.pin.posy_fb) = ((double)(int32_t)(posy) / 2147483647.0) / *s->hal.pin.posy_scale; + // need to "unscale" the position registers to return to machine units - // need to "unscale" the velocity registers to return to machine units + hal_set_real(s->hal.pin.posx_fb, ((double)(int32_t)(posx) / 2147483647.0) / posx_scale); + hal_set_real(s->hal.pin.posy_fb, ((double)(int32_t)(posy) / 2147483647.0) / posy_scale); - *(s->hal.pin.velx_fb) = ((double)(int32_t)velx) / (*s->hal.pin.posx_scale * (256*2147483647.0/(double)hm2->xy2mod.clock_frequency)); - *(s->hal.pin.vely_fb) = ((double)(int32_t)vely) / (*s->hal.pin.posy_scale * (256*2147483647.0/(double)hm2->xy2mod.clock_frequency)); - - *(s->hal.pin.posx_overflow) = (mode & (1 << 6)); - *(s->hal.pin.posy_overflow) = (mode & (1 << 7)); - *(s->hal.pin.velx_overflow) = (mode & (1 << 8)); - *(s->hal.pin.vely_overflow) = (mode & (1 << 9)); - *(s->hal.pin.status) = (status & 0x000FFFFF); + // need to "unscale" the velocity registers to return to machine units + hal_set_real(s->hal.pin.velx_fb, ((double)(int32_t)velx) / (posx_scale * (256*2147483647.0/(double)hm2->xy2mod.clock_frequency))); + hal_set_real(s->hal.pin.vely_fb, ((double)(int32_t)vely) / (posy_scale * (256*2147483647.0/(double)hm2->xy2mod.clock_frequency))); + hal_set_bool(s->hal.pin.posx_overflow, mode & (1 << 6)); + hal_set_bool(s->hal.pin.posy_overflow, mode & (1 << 7)); + hal_set_bool(s->hal.pin.velx_overflow, mode & (1 << 8)); + hal_set_bool(s->hal.pin.vely_overflow, mode & (1 << 9)); + hal_set_ui32(s->hal.pin.status, status & 0x000FFFFF); } } @@ -112,99 +112,107 @@ static void hm2_xy2mod_instance_write(hostmot2_t *hm2, int i) { hm2_xy2mod_instance_t *s = &hm2->xy2mod.instance[i]; istride = i * sizeof(rtapi_u32); - - if (*s->hal.pin.enable != 0) { + + if (hal_get_bool(s->hal.pin.enable)) { // position setting - stepsx_cmd =( *s->hal.pin.posx_cmd * 2147483647.0) / *s->hal.pin.posx_scale; - stepsy_cmd =( *s->hal.pin.posy_cmd * 2147483647.0) / *s->hal.pin.posy_scale; + rtapi_real posx_scale = hal_get_real(s->hal.pin.posx_scale); + rtapi_real posy_scale = hal_get_real(s->hal.pin.posy_scale); + rtapi_real posx_cmd = hal_get_real(s->hal.pin.posx_cmd); + rtapi_real posy_cmd = hal_get_real(s->hal.pin.posy_cmd); + stepsx_cmd = (posx_cmd * 2147483647.0) / posx_scale; + stepsy_cmd = (posy_cmd * 2147483647.0) / posy_scale; // the double cast here is intentional. (uint32_t)(-1.0) is undefined in // C (and in practice it gives the undesired value 0 on arm systems), but // (uint32_t)(int32-t)(-1.0) is defined and gives the desired value on all // systems. - if (*s->hal.pin.posx_cmd != s->prev_posx_cmd) { - lposx_reg = (int32_t)(stepsx_cmd); + if (posx_cmd != s->prev_posx_cmd) { + lposx_reg = (int32_t)(stepsx_cmd); hm2->xy2mod.posx_reg[i] = lposx_reg; // HM2_PRINT("StepsX register set to: %f\n",stepsx_cmd); // HM2_PRINT("POSX register set to:0x%08X\n",lposx_reg); hm2->llio->write(hm2->llio, hm2->xy2mod.posx_addr + istride, &hm2->xy2mod.posx_reg[i], sizeof(rtapi_u32)); - s->prev_posx_cmd = *s->hal.pin.posx_cmd; + s->prev_posx_cmd = posx_cmd; } - if (*s->hal.pin.posy_cmd != s->prev_posy_cmd) { + if (posy_cmd != s->prev_posy_cmd) { lposy_reg = (int32_t)(stepsy_cmd); hm2->xy2mod.posy_reg[i] = lposy_reg; // HM2_PRINT("Stepsy register set to: %fhalcmd\n",stepsy_cmd); // HM2_PRINT("POSY register set to:0x%08X\n",lposy_reg); hm2->llio->write(hm2->llio, hm2->xy2mod.posy_addr + istride, &hm2->xy2mod.posy_reg[i], sizeof(rtapi_u32)); - s->prev_posy_cmd = *s->hal.pin.posy_cmd; + s->prev_posy_cmd = posy_cmd; } // velocity setting - steps_per_secx_cmd = *s->hal.pin.velx_cmd * *s->hal.pin.posx_scale; - steps_per_secy_cmd = *s->hal.pin.vely_cmd * *s->hal.pin.posy_scale; + rtapi_real velx_cmd = hal_get_real(s->hal.pin.velx_cmd); + rtapi_real vely_cmd = hal_get_real(s->hal.pin.vely_cmd); + steps_per_secx_cmd = velx_cmd * posx_scale; + steps_per_secy_cmd = vely_cmd * posy_scale; // the double cast here is intentional. (uint32_t)(-1.0) is undefined in // C (and in practice it gives the undesired value 0 on arm systems), but // (uint32_t)(int32-t)(-1.0) is defined and gives the desired value on all // systems. - // Note 256 factor is from velocity scaling in xy2mod hardware (velocity added only every 256 clocks) - if (*s->hal.pin.velx_cmd != s->prev_velx_cmd) { + // Note 256 factor is from velocity scaling in xy2mod hardware (velocity added only every 256 clocks) + if (velx_cmd != s->prev_velx_cmd) { lvelx_reg = (uint32_t)(int32_t)(steps_per_secx_cmd * (256*2147483648.0 / (double)hm2->xy2mod.clock_frequency)); hm2->xy2mod.velx_reg[i] = lvelx_reg; // HM2_PRINT("VELX register set to:0x%08X\n",lvelx_reg); hm2->llio->write(hm2->llio, hm2->xy2mod.velx_addr + istride, &hm2->xy2mod.velx_reg[i], sizeof(rtapi_u32)); - s->prev_velx_cmd = *s->hal.pin.velx_cmd; + s->prev_velx_cmd = velx_cmd; } - if (*s->hal.pin.vely_cmd != s->prev_vely_cmd) { + if (vely_cmd != s->prev_vely_cmd) { lvely_reg = (uint32_t)(int32_t)(steps_per_secy_cmd * (256*2147483648.0 / (double)hm2->xy2mod.clock_frequency)); hm2->xy2mod.vely_reg[i] = lvely_reg; // HM2_PRINT("VELY register set to:0x%08X\n",lvely_reg); hm2->llio->write(hm2->llio, hm2->xy2mod.vely_addr + istride, &hm2->xy2mod.vely_reg[i], sizeof(rtapi_u32)); - s->prev_vely_cmd = *s->hal.pin.vely_cmd; + s->prev_vely_cmd = vely_cmd; } // acceleration setting no idea if anywhere near reality - steps_per_sec2x_cmd = *s->hal.pin.accx_cmd * *s->hal.pin.posx_scale; - steps_per_sec2y_cmd = *s->hal.pin.accy_cmd * *s->hal.pin.posy_scale; + rtapi_real accx_cmd = hal_get_real(s->hal.pin.accx_cmd); + rtapi_real accy_cmd = hal_get_real(s->hal.pin.accy_cmd); + steps_per_sec2x_cmd = accx_cmd * posx_scale; + steps_per_sec2y_cmd = accy_cmd * posy_scale; // the double cast here is intentional. (uint32_t)(-1.0) is undefined in // C (and in practice it gives the undesired value 0 on arm systems), but // (uint32_t)(int32-t)(-1.0) is defined and gives the desired value on all // systems. - if (*s->hal.pin.accx_cmd != s->prev_accx_cmd) { + if (accx_cmd != s->prev_accx_cmd) { laccx_reg = (uint32_t)(int32_t)(steps_per_sec2x_cmd * (double)(4096.0*4294967296.0*32768.0) / ((double)(hm2->xy2mod.clock_frequency*(double)hm2->xy2mod.clock_frequency*256))); hm2->xy2mod.accx_reg[i] = laccx_reg; // HM2_PRINT("ACCX register set to:0x%08X\n",laccx_reg); hm2->llio->write(hm2->llio, hm2->xy2mod.accx_addr + istride, &hm2->xy2mod.accx_reg[i], sizeof(rtapi_u32)); - s->prev_accx_cmd = *s->hal.pin.accx_cmd; + s->prev_accx_cmd = accx_cmd; } - if (*s->hal.pin.accy_cmd != s->prev_accy_cmd) { - laccy_reg = (uint32_t)(int32_t)(steps_per_sec2y_cmd * (double)(4096.0*4294967296.0*32768.0) / ((double)(hm2->xy2mod.clock_frequency*(double)hm2->xy2mod.clock_frequency*256))); - hm2->xy2mod.accy_reg[i] = laccy_reg; + if (accy_cmd != s->prev_accy_cmd) { + laccy_reg = (uint32_t)(int32_t)(steps_per_sec2y_cmd * (double)(4096.0*4294967296.0*32768.0) / ((double)(hm2->xy2mod.clock_frequency*(double)hm2->xy2mod.clock_frequency*256))); + hm2->xy2mod.accy_reg[i] = laccy_reg; // HM2_PRINT("ACCY register set to:0x%08X\n",laccy_reg); - hm2->llio->write(hm2->llio, hm2->xy2mod.accy_addr + istride, &hm2->xy2mod.accy_reg[i], sizeof(rtapi_u32)); - s->prev_accy_cmd = *s->hal.pin.accy_cmd; + hm2->llio->write(hm2->llio, hm2->xy2mod.accy_addr + istride, &hm2->xy2mod.accy_reg[i], sizeof(rtapi_u32)); + s->prev_accy_cmd = accy_cmd; } - *s->hal.pin.controlx = (*s->hal.pin.controlx & 7); - *s->hal.pin.controly = (*s->hal.pin.controly & 7); + hal_set_ui32(s->hal.pin.controlx, hal_get_ui32(s->hal.pin.controlx) & 7); + hal_set_ui32(s->hal.pin.controly, hal_get_ui32(s->hal.pin.controly) & 7); - hm2->xy2mod.mode_reg[i] = - *s->hal.pin.controlx << 0 | - *s->hal.pin.controly << 3 | - *s->hal.pin.mode18bitx<< 10 | - *s->hal.pin.mode18bity<< 11 | - *s->hal.pin.commandmodex<< 12 | - *s->hal.pin.commandmodey<< 13; + hm2->xy2mod.mode_reg[i] = + (hal_get_ui32(s->hal.pin.controlx) << 0) | + (hal_get_ui32(s->hal.pin.controly) << 3) | + (hal_get_bool(s->hal.pin.mode18bitx)<< 10) | + (hal_get_bool(s->hal.pin.mode18bity)<< 11) | + (hal_get_bool(s->hal.pin.commandmodex)<< 12) | + (hal_get_bool(s->hal.pin.commandmodey)<< 13); hm2->llio->write(hm2->llio,hm2->xy2mod.mode_addr + istride, &hm2->xy2mod.mode_reg[i], sizeof(rtapi_u32)); - *s->hal.pin.commandx = (*s->hal.pin.commandx & 0xFFFF); - *s->hal.pin.commandy = (*s->hal.pin.commandy & 0xFFFF); + hal_set_ui32(s->hal.pin.commandx, hal_get_ui32(s->hal.pin.commandx) & 0xFFFF); + hal_set_ui32(s->hal.pin.commandy, hal_get_ui32(s->hal.pin.commandy) & 0xFFFF); - hm2->xy2mod.command_reg[i] = - *s->hal.pin.commandx << 0 | - *s->hal.pin.commandy << 16; + hm2->xy2mod.command_reg[i] = + (hal_get_ui32(s->hal.pin.commandx) << 0) | + (hal_get_ui32(s->hal.pin.commandy) << 16); hm2->llio->write(hm2->llio,hm2->xy2mod.command_addr + istride, &hm2->xy2mod.command_reg[i], sizeof(rtapi_u32)); @@ -213,43 +221,43 @@ static void hm2_xy2mod_instance_write(hostmot2_t *hm2, int i) { // may eventually want to spilt out resetting the overflow flags // reset position registers - *s->hal.pin.posx_cmd = 0; - s->prev_posx_cmd = 0; + hal_set_real(s->hal.pin.posx_cmd, 0); + s->prev_posx_cmd = 0; hm2->xy2mod.posx_reg[i] =0; hm2->llio->write(hm2->llio, hm2->xy2mod.posx_addr + istride, &hm2->xy2mod.posx_reg[i], sizeof(rtapi_u32)); - *s->hal.pin.posy_cmd = 0; - s->prev_posy_cmd = 0; + hal_set_real(s->hal.pin.posy_cmd, 0); + s->prev_posy_cmd = 0; hm2->xy2mod.posy_reg[i] =0; hm2->llio->write(hm2->llio, hm2->xy2mod.posy_addr + istride, &hm2->xy2mod.posy_reg[i], sizeof(rtapi_u32)); // reset velocity registers - *s->hal.pin.velx_cmd = 0; + hal_set_real(s->hal.pin.velx_cmd, 0); s->prev_velx_cmd = 0; hm2->xy2mod.velx_reg[i] = 0; hm2->llio->write(hm2->llio, hm2->xy2mod.velx_addr + istride, &hm2->xy2mod.velx_reg[i], sizeof(rtapi_u32)); - *s->hal.pin.vely_cmd = 0; + hal_set_real(s->hal.pin.vely_cmd, 0); s->prev_vely_cmd = 0; hm2->xy2mod.vely_reg[i] = 0; hm2->llio->write(hm2->llio, hm2->xy2mod.vely_addr + istride, &hm2->xy2mod.vely_reg[i], sizeof(rtapi_u32)); // reset acceleration registers - *s->hal.pin.accx_cmd = 0; + hal_set_real(s->hal.pin.accx_cmd, 0); s->prev_accx_cmd = 0; hm2->xy2mod.accx_reg[i] = 0; hm2->llio->write(hm2->llio, hm2->xy2mod.accx_addr + istride, &hm2->xy2mod.accx_reg[i], sizeof(rtapi_u32)); - *s->hal.pin.accy_cmd = 0; + hal_set_real(s->hal.pin.accy_cmd, 0); s->prev_accy_cmd = 0; hm2->xy2mod.accy_reg[i] = 0; hm2->llio->write(hm2->llio, hm2->xy2mod.accy_addr + istride, &hm2->xy2mod.accy_reg[i], sizeof(rtapi_u32)); //reset control bits and overflow flags - *s->hal.pin.controlx = 1; // default to 16 bit mode - *s->hal.pin.controly = 1; + hal_set_ui32(s->hal.pin.controlx, 1); // default to 16 bit mode + hal_set_ui32(s->hal.pin.controly, 1); hm2->xy2mod.mode_reg[i] = 0x000003C9; // reset X and Y overflow bits when disabled hm2->llio->write(hm2->llio, hm2->xy2mod.mode_addr + istride, &hm2->xy2mod.mode_reg[i], sizeof(rtapi_u32)); } @@ -258,28 +266,30 @@ static void hm2_xy2mod_instance_write(hostmot2_t *hm2, int i) { static void hm2_xy2mod_set_dpll_rtimer(hostmot2_t *hm2) { rtapi_u32 data = 0; + rtapi_s32 dpll_rtimer_num = hal_get_si32(hm2->xy2mod.hal->pin.dpll_rtimer_num); - if ((*hm2->xy2mod.hal->pin.dpll_rtimer_num < -1) || (*hm2->xy2mod.hal->pin.dpll_rtimer_num > 4)) { - *hm2->xy2mod.hal->pin.dpll_rtimer_num = 0; + if ((dpll_rtimer_num < -1) || (dpll_rtimer_num > 4)) { + dpll_rtimer_num = hal_set_si32(hm2->xy2mod.hal->pin.dpll_rtimer_num, 0); } - if (*hm2->xy2mod.hal->pin.dpll_rtimer_num > -1) { - data = (*hm2->xy2mod.hal->pin.dpll_rtimer_num << 12) | (1 << 15); + if (dpll_rtimer_num > -1) { + data = (dpll_rtimer_num << 12) | (1 << 15); } hm2->llio->write(hm2->llio, hm2->xy2mod.dpll_rtimer_num_addr, &data, sizeof(rtapi_u32)); - hm2->xy2mod.written_dpll_rtimer_num = *hm2->xy2mod.hal->pin.dpll_rtimer_num; + hm2->xy2mod.written_dpll_rtimer_num = dpll_rtimer_num; } static void hm2_xy2mod_set_dpll_wtimer(hostmot2_t *hm2) { rtapi_u32 data = 0; + rtapi_s32 dpll_wtimer_num = hal_get_si32(hm2->xy2mod.hal->pin.dpll_wtimer_num); - if ((*hm2->xy2mod.hal->pin.dpll_wtimer_num < -1) || (*hm2->xy2mod.hal->pin.dpll_wtimer_num > 4)) { - *hm2->xy2mod.hal->pin.dpll_wtimer_num = 0; + if ((dpll_wtimer_num < -1) || (dpll_wtimer_num > 4)) { + dpll_wtimer_num = hal_set_si32(hm2->xy2mod.hal->pin.dpll_wtimer_num, 0); } - if (*hm2->xy2mod.hal->pin.dpll_wtimer_num > -1) { - data = (*hm2->xy2mod.hal->pin.dpll_wtimer_num << 12) | (1 << 15); + if (dpll_wtimer_num > -1) { + data = (dpll_wtimer_num << 12) | (1 << 15); } hm2->llio->write(hm2->llio, hm2->xy2mod.dpll_wtimer_num_addr, &data, sizeof(rtapi_u32)); - hm2->xy2mod.written_dpll_wtimer_num = *hm2->xy2mod.hal->pin.dpll_wtimer_num; + hm2->xy2mod.written_dpll_wtimer_num = dpll_wtimer_num; } @@ -289,10 +299,10 @@ void hm2_xy2mod_write(hostmot2_t *hm2) { hm2_xy2mod_instance_write(hm2, i); } if (hm2->xy2mod.num_instances > 0 && hm2->dpll_module_present) { - if (*hm2->xy2mod.hal->pin.dpll_rtimer_num != (int)hm2->xy2mod.written_dpll_rtimer_num) { + if (hal_get_si32(hm2->xy2mod.hal->pin.dpll_rtimer_num) != hm2->xy2mod.written_dpll_rtimer_num) { hm2_xy2mod_set_dpll_rtimer(hm2); } - if (*hm2->xy2mod.hal->pin.dpll_wtimer_num != (int)hm2->xy2mod.written_dpll_wtimer_num) { + if (hal_get_si32(hm2->xy2mod.hal->pin.dpll_wtimer_num) != hm2->xy2mod.written_dpll_wtimer_num) { hm2_xy2mod_set_dpll_wtimer(hm2); } } @@ -322,16 +332,13 @@ void hm2_xy2mod_force_write(hostmot2_t *hm2) { void hm2_xy2mod_tram_init(hostmot2_t *hm2) { - int i; - - for (i = 0; i < hm2->xy2mod.num_instances; i ++) { - - *hm2->xy2mod.instance[i].hal.pin.posx_cmd = 0; - *hm2->xy2mod.instance[i].hal.pin.posy_cmd = 0; - *hm2->xy2mod.instance[i].hal.pin.velx_cmd = 0; - *hm2->xy2mod.instance[i].hal.pin.vely_cmd = 0; - *hm2->xy2mod.instance[i].hal.pin.accx_cmd = 0; - *hm2->xy2mod.instance[i].hal.pin.accy_cmd = 0; + for (int i = 0; i < hm2->xy2mod.num_instances; i ++) { + hal_set_real(hm2->xy2mod.instance[i].hal.pin.posx_cmd, 0); + hal_set_real(hm2->xy2mod.instance[i].hal.pin.posy_cmd, 0); + hal_set_real(hm2->xy2mod.instance[i].hal.pin.velx_cmd, 0); + hal_set_real(hm2->xy2mod.instance[i].hal.pin.vely_cmd, 0); + hal_set_real(hm2->xy2mod.instance[i].hal.pin.accx_cmd, 0); + hal_set_real(hm2->xy2mod.instance[i].hal.pin.accy_cmd, 0); } } @@ -417,14 +424,14 @@ int hm2_xy2mod_parse_md(hostmot2_t *hm2, int md_index) { // allocate the module-global HAL shared memory - hm2->xy2mod.hal = (hm2_xy2mod_module_global_t *)hal_malloc(sizeof(hm2_xy2mod_module_global_t)); + hm2->xy2mod.hal = hal_malloc(sizeof(*hm2->xy2mod.hal)); if (hm2->xy2mod.hal == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; goto fail0; } - hm2->xy2mod.instance = (hm2_xy2mod_instance_t *)hal_malloc(hm2->xy2mod.num_instances * sizeof(hm2_xy2mod_instance_t)); + hm2->xy2mod.instance = hal_malloc(hm2->xy2mod.num_instances * sizeof(*hm2->xy2mod.instance)); if (hm2->xy2mod.instance == NULL) { HM2_ERR("out of memory!\n"); r = -ENOMEM; @@ -513,268 +520,208 @@ int hm2_xy2mod_parse_md(hostmot2_t *hm2, int md_index) { // export to HAL { - int i; - char name[HAL_NAME_LEN + 1]; - if (hm2->dpll_module_present) { - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.read-timer-number", hm2->llio->name); - r = hal_pin_s32_new(name, HAL_IN, &(hm2->xy2mod.hal->pin.dpll_rtimer_num), hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.hal->pin.dpll_rtimer_num), + -1, "%s.xy2mod.read-timer-number", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding read timer number param, aborting\n"); + HM2_ERR("error %d adding pin '%s.xy2mod.read-timer-number', aborting\n", r, hm2->llio->name); return -EINVAL; } - *(hm2->xy2mod.hal->pin.dpll_rtimer_num) = -1; - } - if (hm2->dpll_module_present) { - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.write-timer-number", hm2->llio->name); - r = hal_pin_s32_new(name, HAL_IN, &(hm2->xy2mod.hal->pin.dpll_wtimer_num), hm2->llio->comp_id); + r = hal_pin_new_si32(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.hal->pin.dpll_wtimer_num), + -1, "%s.xy2mod.write-timer-number", hm2->llio->name); if (r < 0) { - HM2_ERR("error adding write timer number param, aborting\n"); + HM2_ERR("error %d adding pin '%s.xy2mod.write-timer-number', aborting\n", r, hm2->llio->name); return -EINVAL; } - *(hm2->xy2mod.hal->pin.dpll_wtimer_num) = -1; } - for (i = 0; i < hm2->xy2mod.num_instances; i ++) { - + for (int i = 0; i < hm2->xy2mod.num_instances; i ++) { // pins - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posx-cmd", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posx_cmd), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posx_cmd), + 0.0, "%s.xy2mod.%02d.posx-cmd", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.posx-cmd', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posy-cmd", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posy_cmd), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posy_cmd), + 0.0, "%s.xy2mod.%02d.posy-cmd", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.posy-cmd', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.velx-cmd", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.velx_cmd), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.velx_cmd), + 0.0, "%s.xy2mod.%02d.velx-cmd", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.velx-cmd', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.vely-cmd", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.vely_cmd), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.vely_cmd), + 0.0, "%s.xy2mod.%02d.vely-cmd", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.vely-cmd', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.accx-cmd", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.accx_cmd), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.accx_cmd), + 0.0, "%s.xy2mod.%02d.accx-cmd", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.accx-cmd', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.accy-cmd", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.accy_cmd), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.accy_cmd), + 0.0, "%s.xy2mod.%02d.accy-cmd", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.accy-cmd', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.velx-fb", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.velx_fb), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.velx_fb), + 0.0, "%s.xy2mod.%02d.velx-fb", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.velx-fb', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.vely-fb", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.vely_fb), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.vely_fb), + 0.0, "%s.xy2mod.%02d.vely-fb", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.vely-fb', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posx-fb", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posx_fb), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posx_fb), + 0.0, "%s.xy2mod.%02d.posx-fb", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.posx-fb', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posy-fb", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posy_fb), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posy_fb), + 0.0, "%s.xy2mod.%02d.posy-fb", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.posy-fb', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posx-scale", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posx_scale), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posx_scale), + 1.0, "%s.xy2mod.%02d.posx-scale", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.posx-scale', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posy-scale", hm2->llio->name, i); - r = hal_pin_float_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posy_scale), hm2->llio->comp_id); + r = hal_pin_new_real(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.posy_scale), + 1.0, "%s.xy2mod.%02d.posy-scale", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.posy-scale', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.enable", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.enable), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.enable), + 0, "%s.xy2mod.%02d.enable", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.enable', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.controlx", hm2->llio->name, i); - r = hal_pin_u32_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.controlx), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.controlx), + 1, "%s.xy2mod.%02d.controlx", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.controlx', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.controly", hm2->llio->name, i); - r = hal_pin_u32_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.controly), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.controly), + 1, "%s.xy2mod.%02d.controly", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.controly', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.commandx", hm2->llio->name, i); - r = hal_pin_u32_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.commandx), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.commandx), + 0, "%s.xy2mod.%02d.commandx", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.commandx', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.commandy", hm2->llio->name, i); - r = hal_pin_u32_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.commandy), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.commandy), + 0, "%s.xy2mod.%02d.commandy", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.commandy', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.18bitmodex", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.mode18bitx), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.mode18bitx), + 0, "%s.xy2mod.%02d.18bitmodex", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.18bitmodex', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.18bitmodey", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.mode18bity), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.mode18bity), + 0, "%s.xy2mod.%02d.18bitmodey", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.18bitmodey', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.commandmodex", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.commandmodex), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.commandmodex), + 0, "%s.xy2mod.%02d.commandmodex", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.commandmodex', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.commandmodey", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.commandmodey), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_IN, &(hm2->xy2mod.instance[i].hal.pin.commandmodey), + 0, "%s.xy2mod.%02d.commandmodey", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.commandmodey', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posx-overflow", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posx_overflow), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posx_overflow), + 0, "%s.xy2mod.%02d.posx-overflow", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.posx-overflow', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.posy-overflow", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posy_overflow), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.posy_overflow), + 0, "%s.xy2mod.%02d.posy-overflow", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.posy-overflow', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.velx-overflow", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.velx_overflow), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.velx_overflow), + 0, "%s.xy2mod.%02d.velx-overflow", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.velx-overflow', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.vely-overflow", hm2->llio->name, i); - r = hal_pin_bit_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.vely_overflow), hm2->llio->comp_id); + r = hal_pin_new_bool(hm2->llio->comp_id, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.vely_overflow), + 0, "%s.xy2mod.%02d.vely-overflow", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.vely-overflow', aborting\n", r, hm2->llio->name, i); goto fail0; } - rtapi_snprintf(name, sizeof(name), "%s.xy2mod.%02d.status", hm2->llio->name, i); - r = hal_pin_u32_new(name, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.status), hm2->llio->comp_id); + r = hal_pin_new_ui32(hm2->llio->comp_id, HAL_OUT, &(hm2->xy2mod.instance[i].hal.pin.status), + 0, "%s.xy2mod.%02d.status", hm2->llio->name, i); if (r < 0) { - HM2_ERR("error adding pin '%s', aborting\n", name); - r = -ENOMEM; + HM2_ERR("error %d adding pin '%s.xy2mod.%02d.status', aborting\n", r, hm2->llio->name, i); goto fail0; } - - - // init - *(hm2->xy2mod.instance[i].hal.pin.posx_cmd) = 0.0; - *(hm2->xy2mod.instance[i].hal.pin.posy_cmd) = 0.0; - *(hm2->xy2mod.instance[i].hal.pin.velx_cmd) = 0.0; - *(hm2->xy2mod.instance[i].hal.pin.vely_cmd) = 0.0; - *(hm2->xy2mod.instance[i].hal.pin.accx_cmd) = 0.0; - *(hm2->xy2mod.instance[i].hal.pin.accy_cmd) = 0.0; - *(hm2->xy2mod.instance[i].hal.pin.posx_fb) = 0.0; - *(hm2->xy2mod.instance[i].hal.pin.posy_fb) = 0.0; - *(hm2->xy2mod.instance[i].hal.pin.velx_fb) = 0.0; - *(hm2->xy2mod.instance[i].hal.pin.vely_fb) = 0.0; - *(hm2->xy2mod.instance[i].hal.pin.posx_scale) = 1.0; - *(hm2->xy2mod.instance[i].hal.pin.posy_scale) = 1.0; - *(hm2->xy2mod.instance[i].hal.pin.enable) = 0; - *(hm2->xy2mod.instance[i].hal.pin.controlx) = 1; - *(hm2->xy2mod.instance[i].hal.pin.controly) = 1; - *(hm2->xy2mod.instance[i].hal.pin.commandx) = 0; - *(hm2->xy2mod.instance[i].hal.pin.commandy) = 0; - *(hm2->xy2mod.instance[i].hal.pin.mode18bitx) = 0; - *(hm2->xy2mod.instance[i].hal.pin.mode18bity) = 0; - *(hm2->xy2mod.instance[i].hal.pin.commandmodex) = 0; - *(hm2->xy2mod.instance[i].hal.pin.commandmodey) = 0; - - } } @@ -810,7 +757,7 @@ void hm2_xy2mod_print_module(hostmot2_t *hm2) { HM2_PRINT(" status_addr: 0x%04X\n", hm2->xy2mod.status_addr); for (i = 0; i < hm2->xy2mod.num_instances; i ++) { HM2_PRINT(" instance %d:\n", i); - HM2_PRINT(" enable = %d\n", *hm2->xy2mod.instance[i].hal.pin.enable); + HM2_PRINT(" enable = %d\n", hal_get_bool(hm2->xy2mod.instance[i].hal.pin.enable)); HM2_PRINT(" hw:\n"); HM2_PRINT(" accx = 0x%08X\n", hm2->xy2mod.accx_reg[i]); HM2_PRINT(" accy = 0x%08X\n", hm2->xy2mod.accy_reg[i]); diff --git a/src/hal/hal.h b/src/hal/hal.h index 17372ccd3d1..f9b588f1f0c 100644 --- a/src/hal/hal.h +++ b/src/hal/hal.h @@ -58,6 +58,10 @@ information, go to www.linuxcnc.org. */ +#if defined(__HAL_LIBRARY_INTERNAL_ONLY) +#error "Including hal.h after hal_priv.h" +#endif + /*********************************************************************** * GENERAL NOTES AND DOCUMENTATION * ************************************************************************/ @@ -278,7 +282,7 @@ const char *hal_strerror(int err); /** hal_comp_name() returns the name of the given component, or NULL if comp_id is not a loaded component */ -extern char* hal_comp_name(int comp_id); +extern const char *hal_comp_name(int comp_id); /** hal_get_realtime_type() returns the type of the running real time */ @@ -396,15 +400,15 @@ static inline __HAL_ALWAYS_INLINE bool hal_pdir_is_neither(hal_pdir_t v) { // compiler. // ==> Remove when we get rid of old hal_*_t typedefs. <== typedef rtapi_real real_t; -typedef rtapi_u64 ireal_t __attribute__((aligned(8))); // integral type as wide as real_t / hal_float_t +typedef rtapi_u64 ireal_t __attribute__((aligned(8))) __attribute__((deprecated)); // integral type as wide as real_t / hal_float_t typedef volatile bool hal_bit_t; typedef volatile rtapi_u32 hal_u32_t; typedef volatile rtapi_s32 hal_s32_t; typedef volatile rtapi_u64 hal_u64_t; typedef volatile rtapi_s64 hal_s64_t; -typedef volatile real_t hal_float_t; -typedef volatile int hal_port_t; +typedef volatile rtapi_real hal_float_t; +typedef volatile rtapi_port hal_port_t; /** HAL "data union" structure ** This structure may hold any type of hal data @@ -889,12 +893,12 @@ extern int hal_param_new(const char *name, hal_type_t type, hal_param_dir_t dir, On success, the hal_param_xxx_set() functions return 0, and on failure they return a negative error code. */ -extern int hal_param_bit_set(const char *name, int value); -extern int hal_param_float_set(const char *name, double value); -extern int hal_param_u32_set(const char *name, unsigned long value); -extern int hal_param_s32_set(const char *name, signed long value); -extern int hal_param_u64_set(const char *name, unsigned long value); -extern int hal_param_s64_set(const char *name, signed long value); +int hal_param_bit_set(const char *name, int value) __attribute__((deprecated("Use hal_set_p()"))); +int hal_param_float_set(const char *name, double value) __attribute__((deprecated("Use hal_set_p()"))); +int hal_param_u32_set(const char *name, unsigned long value) __attribute__((deprecated("Use hal_set_p()"))); +int hal_param_s32_set(const char *name, signed long value) __attribute__((deprecated("Use hal_set_p()"))); +int hal_param_u64_set(const char *name, unsigned long value) __attribute__((deprecated("Use hal_set_p()"))); +int hal_param_s64_set(const char *name, signed long value) __attribute__((deprecated("Use hal_set_p()"))); /** 'hal_param_alias()' assigns an alternate name, aka an alias, to a parameter. Once assigned, the parameter can be referred to by @@ -918,7 +922,7 @@ extern int hal_param_alias(const char *pin_name, const char *alias); If successful, hal_param_set() returns 0. On failure it returns a negative error code. */ -extern int hal_param_set(const char *name, hal_type_t type, void *value_addr); +int hal_param_set(const char *name, hal_type_t type, void *value_addr) __attribute__((deprecated("Use hal_set_p()"))); /*********************************************************************** * PIN/SIG/PARAM GETTER FUNCTIONS * @@ -933,7 +937,7 @@ extern int hal_param_set(const char *name, hal_type_t type, void *value_addr); */ extern int hal_get_pin_value_by_name( - const char *name, hal_type_t *type, hal_data_u **data, bool *connected); + const char *name, hal_type_t *type, hal_data_u **data, bool *connected) __attribute__((deprecated("Use hal_get_p()"))); /** 'hal_get_signal_value_by_name()' returns the value of any arbitrary HAL * signal by signal name. @@ -944,7 +948,7 @@ extern int hal_get_pin_value_by_name( */ extern int hal_get_signal_value_by_name( - const char *name, hal_type_t *type, hal_data_u **data, bool *has_writers); + const char *name, hal_type_t *type, hal_data_u **data, bool *has_writers) __attribute__((deprecated("Use hal_get_s()"))); /** 'hal_get_param_value_by_name()' returns the value of any arbitrary HAL * parameter by parameter name. @@ -954,7 +958,7 @@ extern int hal_get_signal_value_by_name( */ extern int hal_get_param_value_by_name( - const char *name, hal_type_t *type, hal_data_u **data); + const char *name, hal_type_t *type, hal_data_u **data) __attribute__((deprecated("Use hal_get_p()"))); /*********************************************************************** diff --git a/src/hal/hal.hh b/src/hal/hal.hh deleted file mode 100644 index e4c9a40e637..00000000000 --- a/src/hal/hal.hh +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef HALXX_HH -#define HALXX_HH - -#include -#include -#include -#include "hal.h" - -#warning "Do not use hal.hh. It will be removed (and, eventually, replaced)." - -enum class hal_dir{ - IN = HAL_IN, - OUT = HAL_OUT, -}; - -#if 0 -// If this class is ever necessary, then it needs to be moved into a new -// header 'hal_priv.hh' because it uses internal access methods from -// 'hal_priv.h' that should not be available to the casual source file. - -#include "hal_priv.h" - -class hal{ - public: - static bool component_exists(const std::string& name){ - return halpr_find_comp_by_name(name.c_str()) != NULL; - } - static bool pin_has_writer(const std::string& name){ - hal_pin_t *pin = halpr_find_pin_by_name(name.c_str()); - if(!pin) {//pin does not exist - return false; - } - if(pin->signal) { - hal_sig_t *signal = (hal_sig_t*)SHMPTR(pin->signal); - return signal->writers > 0; - } - return false; - } - static bool component_is_ready(const std::string& name){ - // Bad form to assume comp name exists - stop crashing! - hal_comp_t *thecomp = halpr_find_comp_by_name(name.c_str()); - return thecomp && (thecomp->ready != 0); - } -}; -#endif - -template -class hal_pin{ - public: - volatile T** ptr; - T operator=(const T& value){ - **ptr = value; - return **ptr; - } - operator T(){ - return **ptr; - } -}; - -using pin_t = std::variant,hal_pin,hal_pin,hal_pin>; - -class hal_comp{ - int comp_id; - std::string comp_name; - std::map map; - int add_pin_(const std::string& name, hal_dir dir, hal_pin pin){ - return hal_pin_new(name.c_str(), HAL_BIT, static_cast(dir), (void **)(pin.ptr), comp_id); - } - int add_pin_(const std::string& name, hal_dir dir, hal_pin pin){ - return hal_pin_new(name.c_str(), HAL_S32, static_cast(dir), (void **)(pin.ptr), comp_id); - } - int add_pin_(const std::string& name, hal_dir dir, hal_pin pin){ - return hal_pin_new(name.c_str(), HAL_U32, static_cast(dir), (void **)(pin.ptr), comp_id); - } - int add_pin_(const std::string& name, hal_dir dir, hal_pin pin){ - return hal_pin_new(name.c_str(), HAL_FLOAT, static_cast(dir), (void **)(pin.ptr), comp_id); - } - public: - int error = 0; - hal_comp(const std::string& name){ - comp_id = hal_init(name.c_str()); - comp_name = name; - if(comp_id < 0){ - error -= 1; - rtapi_print_msg(RTAPI_MSG_ERR, "%s ERROR: hal_init() failed\n", comp_name.c_str()); - hal_exit(comp_id); - } - } - hal_comp() = delete; - - void newpin(const std::string& name, hal_type_t type, hal_dir dir){ - auto& pin = map[name]; - switch(type){ - case HAL_BIT: - pin = hal_pin(); - add_pin(name, dir, std::get>(pin)); - break; - case HAL_FLOAT: - pin = hal_pin(); - add_pin(name, dir, std::get>(pin)); - break; - case HAL_S32: - pin = hal_pin(); - add_pin(name, dir, std::get>(pin)); - break; - case HAL_U32: - pin = hal_pin(); - add_pin(name, dir, std::get>(pin)); - break; - [[fallthrough]]; - default: - break; - } - } - - std::variant getitem(const std::string& name){ - auto pin = map[name]; - if (auto* v = std::get_if>(&pin)) { - return *v; - } else if (auto* v = std::get_if>(&pin)) { - return *v; - } else if (auto* v = std::get_if>(&pin)) { - return *v; - } else if (auto* v = std::get_if>(&pin)) { - return *v; - } - return 0; - } - - template - void setitem(const std::string& name, T value){ - auto pin = map[name]; - if (auto* p = std::get_if>(&pin)) { - *p = value; - } else if (auto* p = std::get_if>(&pin)) { - *p = value; - } else if (auto* p = std::get_if>(&pin)) { - *p = value; - } else if (auto* p = std::get_if>(&pin)) { - *p = value; - } - } - - void ready(){ - hal_ready(comp_id); - } - - template - void add_pin(const std::string& pin_name, hal_dir dir, hal_pin &pin){ - pin.ptr = (volatile T**)hal_malloc(8); - if(!pin.ptr){ - error -= 1; - rtapi_print_msg(RTAPI_MSG_ERR, "%s ERROR: hal_malloc() failed\n", pin_name.c_str()); - hal_exit(comp_id); - } - error += add_pin_(comp_name + "." + pin_name, dir, pin); - if(error < 0){ - rtapi_print_msg(RTAPI_MSG_ERR, "%s ERROR: hal_pin_new() failed\n", pin_name.c_str()); - hal_exit(comp_id); - } - } - - ~hal_comp(){ - hal_exit(comp_id); - } -}; - -#endif diff --git a/src/hal/hal_lib.c b/src/hal/hal_lib.c index 9dffdc59c53..d35a52823c1 100644 --- a/src/hal/hal_lib.c +++ b/src/hal/hal_lib.c @@ -69,6 +69,7 @@ #include /* RTAPI realtime OS API */ #include "hal.h" /* HAL public API decls */ +#define __HAL_LIBRARY_INTERNAL_ONLY 1 #include "hal_priv.h" /* HAL private decls */ #include @@ -777,10 +778,10 @@ const char *hal_strerror(int err) } } -char *hal_comp_name(int comp_id) +const char *hal_comp_name(int comp_id) { hal_comp_t *comp; - char *result = NULL; + const char *result = NULL; halpr_mutex_acquire(); comp = halpr_find_comp_by_id(comp_id); if(comp) result = comp->name; @@ -2061,6 +2062,10 @@ int hal_param_new_fake(int compid, hal_refs_u *ref) /* wrapper functs for typed params - these call the generic funct below */ +// We don't want our library to emit the deprecation warning. +// We already know it and need to provide them until removed. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" int hal_param_bit_set(const char *name, int value) { return hal_param_set(name, HAL_BIT, &value); @@ -2090,6 +2095,7 @@ int hal_param_s64_set(const char *name, signed long value) { return hal_param_set(name, HAL_S64, &value); } +#pragma GCC diagnostic pop /* this is a generic function that does the majority of the work */ @@ -5221,6 +5227,8 @@ EXPORT_SYMBOL(hal_param_new_uint); EXPORT_SYMBOL(hal_param_new_real); EXPORT_SYMBOL(hal_param_new_fake); +// Parameter set functions have been deprecated. +// Use the generic hal_set_p() instead. EXPORT_SYMBOL(hal_param_bit_set); EXPORT_SYMBOL(hal_param_float_set); EXPORT_SYMBOL(hal_param_u32_set); @@ -5244,6 +5252,8 @@ EXPORT_SYMBOL(hal_del_funct_from_thread); EXPORT_SYMBOL(hal_start_threads); EXPORT_SYMBOL(hal_stop_threads); +// All HAL lib internals' access has bee deprecated. All function prefixed with +// halpr_ are only for private internal use. EXPORT_SYMBOL(hal_shmem_base); EXPORT_SYMBOL(halpr_find_comp_by_name); EXPORT_SYMBOL(halpr_find_pin_by_name); @@ -5262,7 +5272,7 @@ EXPORT_SYMBOL(halpr_find_pin_by_sig); EXPORT_SYMBOL(hal_pin_alias); EXPORT_SYMBOL(hal_param_alias); -EXPORT_SYMBOL(hal_port_alloc); +EXPORT_SYMBOL(hal_port_alloc); // Deprecated EXPORT_SYMBOL(hal_port_read); EXPORT_SYMBOL(hal_port_peek); EXPORT_SYMBOL(hal_port_peek_commit); diff --git a/src/hal/hal_lib_extra.c b/src/hal/hal_lib_extra.c index f8867ca9e76..8bd666611c0 100644 --- a/src/hal/hal_lib_extra.c +++ b/src/hal/hal_lib_extra.c @@ -16,6 +16,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "hal.h" +#define __HAL_LIBRARY_INTERNAL_ONLY 1 #include "hal_priv.h" // diff --git a/src/hal/hal_lib_query.c b/src/hal/hal_lib_query.c index 47ced24c0b6..909ca9afd92 100644 --- a/src/hal/hal_lib_query.c +++ b/src/hal/hal_lib_query.c @@ -16,6 +16,7 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "hal.h" +#define __HAL_LIBRARY_INTERNAL_ONLY 1 #include "hal_priv.h" //===================================================== diff --git a/src/hal/hal_priv.h b/src/hal/hal_priv.h index b34e9507d8d..9bc882aebd4 100644 --- a/src/hal/hal_priv.h +++ b/src/hal/hal_priv.h @@ -57,6 +57,10 @@ */ +#if !defined(__HAL_LIBRARY_INTERNAL_ONLY) +#warning "You should not be including HAL's private hal_priv.h. Please use the HAL query API." +#endif + /*********************************************************************** * GENERAL INFORMATION * ************************************************************************/ @@ -527,7 +531,7 @@ extern hal_pin_t *halpr_find_pin_by_sig(hal_sig_t * sig, hal_pin_t * start); should use hal_set_s() to allocate the port once the pins are connected to the signal. */ -extern int hal_port_alloc(unsigned size, hal_port_t *port); +int hal_port_alloc(unsigned size, hal_port_t *port) __attribute__((deprecated("Use hal_set_s()"))); int halpr_port_alloc(unsigned size, hal_port_t *port); // Recursive HAL mutex (replaces old mutex) diff --git a/src/hal/halquery.c b/src/hal/halquery.c new file mode 100644 index 00000000000..6ea99b29821 --- /dev/null +++ b/src/hal/halquery.c @@ -0,0 +1,620 @@ +// +// HAL Python query API +// +// Copyright (c) 2026 B.Stultiens +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +#include +#include + +#include "utils/setps_util.h" + +static PyObject *value_object(hal_type_t type, hal_refs_u u) +{ + switch(type) { + case HAL_BOOL: return PyBool_FromLong(hal_get_bool(u.b)); + case HAL_S32: return PyLong_FromLong(hal_get_si32(u.s)); + case HAL_SINT: return PyLong_FromLongLong(hal_get_sint(u.s)); + case HAL_U32: return PyLong_FromUnsignedLong(hal_get_ui32(u.u)); + case HAL_UINT: return PyLong_FromUnsignedLongLong(hal_get_uint(u.u)); + case HAL_REAL: return PyFloat_FromDouble(hal_get_real(u.r)); + case HAL_PORT: return PyLong_FromLong(0); // FIXME + default: Py_INCREF(Py_None); return Py_None; + } +} + +static PyObject *build_dict_comp(const hal_query_t *q) +{ + return Py_BuildValue("{s:s,s:s,s:i,s:i,s:i,s:p,s:s}", + "haltype", "component", + "name", q->name, + "type", q->comp.type, + "id", q->comp.comp_id, + "pid", q->comp.pid, + "ready", (int)q->comp.ready, + "insmod", q->comp.insmod); +} + +static PyObject *build_dict_pin_param(const hal_query_t *q, int ispin) +{ + return Py_BuildValue("{s:s,s:s,s:i,s:i,s:N,s:s,s:s,s:s,s:i}", + "haltype", ispin ? "pin" : "param", + "name", q->name, + "type", (int)q->pp.type, + "dir", (int)q->pp.dir, + "value", value_object(q->pp.type, q->pp.ref), + "alias", q->pp.alias, + "signal", q->pp.signal, + "comp", q->pp.comp, + "comp_id", q->pp.comp_id); +} + +static PyObject *build_dict_signal(const hal_query_t *q) +{ + return Py_BuildValue("{s:s,s:s,s:i,s:N,s:i,s:i,s:i}", + "haltype", "signal", + "name", q->name, + "type", (int)q->sig.type, + "value", value_object(q->sig.type, q->sig.ref), + "writers", q->sig.writers, + "readers", q->sig.readers, + "bidirs", q->sig.bidirs); +} + +static PyObject *build_dict_funct(const hal_query_t *q) +{ + return Py_BuildValue("{s:s,s:s,s:s,s:i,s:i,s:p}", + "haltype", "function", + "name", q->name, + "comp", q->funct.comp, + "comp_id", q->funct.comp_id, + "users", q->funct.users, + "reentrant", q->funct.reentrant); +} + +static PyObject *build_dict_threadfunct(const hal_query_t *q) +{ + return Py_BuildValue("{s:s,s:s,s:i,s:p}", + "haltype", "threadfunction", + "name", q->thread.funct, + "index", q->thread.functidx, + "is_init", (int)q->thread.is_init); +} + +static PyObject *build_dict_thread(const hal_query_t *q, PyObject *functs) +{ + return Py_BuildValue("{s:s,s:s,s:s,s:i,s:i,s:l,s:N}", + "haltype", "thread", + "name", q->name, + "comp", q->thread.comp, + "comp_id", q->thread.comp_id, + "priority", q->thread.priority, + "period", q->thread.period, + "functions", functs); +} + +// +// *** Get named component *** +// +static PyObject *get_comp(PyObject *self, PyObject *args) +{ + (void)self; + PyObject *obj = NULL; + if(!PyArg_ParseTuple(args, "O", &obj)) + return NULL; + + hal_query_t q = {}; + int rv; + if(PyUnicode_Check(obj)) { + rv = hal_comp_by_name(PyUnicode_AsUTF8(obj), &q); + } else if(PyLong_Check(obj)) { + rv = hal_comp_by_id((int)PyLong_AsLong(obj), &q); + } else { + PyErr_SetString(PyExc_TypeError, "component() expects a string or an integer as argument"); + return NULL; + } + switch(rv) { + case -ENOENT: Py_INCREF(Py_None); return Py_None; + case 0: return build_dict_comp(&q); + default: + PyErr_Format(PyExc_RuntimeError, "hal_comp_by_*: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; + } +} + +// +// *** Get named pin/param *** +// +static PyObject *get_pin_param(PyObject *args, int ispin) +{ + hal_query_t q = {}; + q.qtype = ispin ? HAL_QTYPE_PIN : HAL_QTYPE_PARAM; + + if(!PyArg_ParseTuple(args, "s", &q.name)) + return NULL; + + int rv = hal_getref_p(&q); + switch(rv) { + case -ENOENT: Py_INCREF(Py_None); return Py_None; + case 0: return build_dict_pin_param(&q, ispin); + default: + PyErr_Format(PyExc_RuntimeError, "hal_get_p: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; + } +} + +static PyObject *get_pin(PyObject *self, PyObject *args) +{ + (void)self; + return get_pin_param(args, 1); +} + +static PyObject *get_param(PyObject *self, PyObject *args) +{ + (void)self; + return get_pin_param(args, 0); +} + +// +// *** Get named signal *** +// +static PyObject *get_signal(PyObject *self, PyObject *args) +{ + (void)self; + hal_query_t q = {}; + + if(!PyArg_ParseTuple(args, "s", &q.name)) + return NULL; + + int rv = hal_getref_s(&q); + switch(rv) { + case -ENOENT: Py_INCREF(Py_None); return Py_None; + case 0: return build_dict_signal(&q); + default: + PyErr_Format(PyExc_RuntimeError, "hal_get_s: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; + } +} + +// +// *** Get named function *** +// +static int get_funct_cb(hal_query_t *q, void *arg) +{ + if(!strcmp(q->name, (const char *)arg)) + return 1; // Found it, break the loop without error + return 0; +} + +static PyObject *get_funct(PyObject *self, PyObject *args) +{ + (void)self; + const char *name; + if(!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + hal_query_t q = {}; + int rv = hal_list_funct(&q, get_funct_cb, (void *)name); + switch(rv) { + case 0: Py_INCREF(Py_None); return Py_None; + case 1: return build_dict_funct(&q); + default: + PyErr_Format(PyExc_RuntimeError, "hal_list_funct: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; + } +} + +// +// *** Get named thread *** +// +typedef struct { + const char *name; + PyObject *dict; + PyObject *functs; + hal_query_t qt; +} threadlist_t; + +static int get_thread_cb(hal_query_t *q, void *arg) +{ + threadlist_t *tlp = (threadlist_t *)arg; + if(!strcmp(tlp->name, q->name)) { + if(q->qtype == HAL_QTYPE_THREAD) { + // Thread construct + tlp->qt = *q; + tlp->functs = PyList_New(0); + if(!tlp->functs) + return -ENOMEM; + } else if(q->qtype == HAL_QTYPE_THREAD_FUNCT) { + // Attached function to thread + PyObject *obj = build_dict_threadfunct(q); + PyList_Append(tlp->functs, obj); + Py_DECREF(obj); + } else { + return -EINVAL; + } + } else if(tlp->dict) { + // We moved to the next thread name and caught the one we want + tlp->dict = build_dict_thread(&tlp->qt, tlp->functs); + tlp->functs = NULL; + return 1; + } + return 0; +} + +static PyObject *get_thread(PyObject *self, PyObject *args) +{ + (void)self; + const char *name; + if(!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + hal_query_t q = {}; + q.qtype = HAL_QTYPE_THREAD_FUNCT; + threadlist_t tl = { .name = name, .dict = NULL, .functs = NULL, .qt = {} }; + int rv = hal_list_thread(&q, get_thread_cb, &tl); + if(rv >= 0) { + // Return value can be zero if the last in the list was the one we + // wanted. Iteration stops by end-of-list and not by a name change. + if(tl.functs) { + // List created, but callback terminated without seeing a new + // thread object. This happens when the found thread is the last in + // the list. We need to create the thread dict here. + tl.dict = build_dict_thread(&tl.qt, tl.functs); + } + if(!tl.dict) { + // List not created means name not found + Py_INCREF(Py_None); + return Py_None; + } + return tl.dict; + } + PyErr_Format(PyExc_RuntimeError, "hal_list_thread: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; +} + +// +// *** Get all pins connected to a named signal *** +// +static int get_signalpins_cb(hal_query_t *q, void *arg) +{ + PyObject *obj = build_dict_pin_param(q, 1); + PyObject *str = PyUnicode_FromString(q->name); + PyDict_SetItem((PyObject *)arg, str, obj); + Py_DECREF(str); + Py_DECREF(obj); + return 0; +} + +static PyObject *get_signalpins(PyObject *self, PyObject *args) +{ + (void)self; + hal_query_t q = {}; + if(!PyArg_ParseTuple(args, "s", &q.name)) + return NULL; + + PyObject *dict = PyDict_New(); + if(!dict) { + PyErr_SetString(PyExc_RuntimeError, "get_signalpins: PyDict_New failed"); + return NULL; + } + int rv = hal_list_p_s(&q, get_signalpins_cb, (void *)dict); + if(!rv) + return dict; + if(-ENOENT == rv) { + Py_INCREF(Py_None); + return Py_None; + } + PyErr_Format(PyExc_RuntimeError, "hal_list_p_s: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; +} + +// +// *** Get all pins *** +// +static int get_pins_cb(hal_query_t *q, void *arg) +{ + PyObject *obj = build_dict_pin_param(q, 1); + PyObject *str = PyUnicode_FromString(q->name); + PyDict_SetItem((PyObject *)arg, str, obj); + Py_DECREF(str); + Py_DECREF(obj); + return 0; +} + +static PyObject *get_pins(PyObject *self, PyObject *args) +{ + (void)self; + (void)args; + PyObject *dict = PyDict_New(); + if(!dict) { + PyErr_SetString(PyExc_RuntimeError, "get_pins: PyDict_New failed"); + return NULL; + } + hal_query_t q = {}; + q.qtype = HAL_QTYPE_PIN; + int rv = hal_list_p(&q, get_pins_cb, (void *)dict); + if(!rv) + return dict; + PyErr_Format(PyExc_RuntimeError, "hal_list_p: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; +} + +// +// *** Get all params *** +// +static int get_params_cb(hal_query_t *q, void *arg) +{ + PyObject *obj = build_dict_pin_param(q, 0); + PyObject *str = PyUnicode_FromString(q->name); + PyDict_SetItem((PyObject *)arg, str, obj); + Py_DECREF(str); + Py_DECREF(obj); + return 0; +} + +static PyObject *get_params(PyObject *self, PyObject *args) +{ + (void)self; + (void)args; + PyObject *dict = PyDict_New(); + if(!dict) { + PyErr_SetString(PyExc_RuntimeError, "get_params: PyDict_New failed"); + return NULL; + } + hal_query_t q = {}; + q.qtype = HAL_QTYPE_PARAM; + int rv = hal_list_p(&q, get_params_cb, (void *)dict); + if(!rv) + return dict; + PyErr_Format(PyExc_RuntimeError, "hal_list_p: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; +} + +// +// *** Get all signals *** +// +static int get_signals_cb(hal_query_t *q, void *arg) +{ + PyObject *obj = build_dict_signal(q); + PyObject *str = PyUnicode_FromString(q->name); + PyDict_SetItem((PyObject *)arg, str, obj); + Py_DECREF(str); + Py_DECREF(obj); + return 0; +} + +static PyObject *get_signals(PyObject *self, PyObject *args) +{ + (void)self; + (void)args; + PyObject *dict = PyDict_New(); + if(!dict) { + PyErr_Format(PyExc_RuntimeError, "get_signals: PyDict_New failed"); + return NULL; + } + hal_query_t q = {}; + int rv = hal_list_s(&q, get_signals_cb, (void *)dict); + if(!rv) + return dict; + PyErr_Format(PyExc_RuntimeError, "hal_list_s: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; +} + +// +// *** Get all components *** +// +static int get_comps_cb(hal_query_t *q, void *arg) +{ + PyObject *obj = build_dict_comp(q); + PyObject *str = PyUnicode_FromString(q->name); + PyDict_SetItem((PyObject *)arg, str, obj); + Py_DECREF(str); + Py_DECREF(obj); + return 0; +} + +static PyObject *get_comps(PyObject *self, PyObject *args) +{ + (void)self; + (void)args; + PyObject *dict = PyDict_New(); + if(!dict) { + PyErr_Format(PyExc_RuntimeError, "get_comps: PyDict_New failed"); + return NULL; + } + hal_query_t q = {}; + int rv = hal_list_comp(&q, get_comps_cb, (void *)dict); + if(!rv) + return dict; + PyErr_Format(PyExc_RuntimeError, "hal_list_comp: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; +} + +// +// *** Get all functions *** +// +static int get_functs_cb(hal_query_t *q, void *arg) +{ + PyObject *obj = build_dict_funct(q); + PyObject *str = PyUnicode_FromString(q->name); + PyDict_SetItem((PyObject *)arg, str, obj); + Py_DECREF(str); + Py_DECREF(obj); + return 0; +} + +static PyObject *get_functs(PyObject *self, PyObject *args) +{ + (void)self; + (void)args; + PyObject *dict = PyDict_New(); + if(!dict) { + PyErr_Format(PyExc_RuntimeError, "get_functs: PyDict_New failed"); + return NULL; + } + hal_query_t q = {}; + int rv = hal_list_funct(&q, get_functs_cb, (void *)dict); + if(!rv) + return dict; + PyErr_Format(PyExc_RuntimeError, "hal_list_funct: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; +} + +// +// *** Get all threads *** +// +typedef struct { + hal_query_t qt; + PyObject *threads; + PyObject *functs; +} threadscb_t; +static int get_threads_cb(hal_query_t *q, void *arg) +{ + threadscb_t *tcb = (threadscb_t *)arg; + + if(HAL_QTYPE_THREAD == q->qtype) { + if(tcb->functs) { + // Seen functions from previous thread + PyObject *obj = build_dict_thread(&tcb->qt, tcb->functs); + PyObject *str = PyUnicode_FromString(tcb->qt.name); + PyDict_SetItem(tcb->threads, str, obj); + Py_DECREF(str); + Py_DECREF(obj); + tcb->functs = NULL; + } + tcb->qt = *q; // Save the current thread info + // Create a function dictionary + if(!(tcb->functs = PyList_New(0))) + return -ENOMEM; + } else if(HAL_QTYPE_THREAD_FUNCT == q->qtype) { + PyObject *obj = build_dict_threadfunct(q); + PyList_Append(tcb->functs, obj); + Py_DECREF(obj); + } else { + return -EINVAL; + } + return 0; +} + +static PyObject *get_threads(PyObject *self, PyObject *args) +{ + (void)self; + (void)args; + threadscb_t tc = {}; + tc.threads = PyDict_New(); + if(!tc.threads) { + PyErr_Format(PyExc_RuntimeError, "get_threads: PyDict_New failed"); + return NULL; + } + + hal_query_t q = {}; + q.qtype = HAL_QTYPE_THREAD_FUNCT; + int rv = hal_list_thread(&q, get_threads_cb, &tc); + if(rv >= 0) { + // Return value can be zero if the last in the list was the one we + // wanted. Iteration stops by end-of-list and not by a name change. + if(tc.functs) { + PyObject *obj = build_dict_thread(&tc.qt, tc.functs); + PyObject *str = PyUnicode_FromString(tc.qt.name); + PyDict_SetItem(tc.threads, str, obj); + Py_DECREF(str); + Py_DECREF(obj); + } + return tc.threads; + } + PyErr_Format(PyExc_RuntimeError, "hal_list_thread: error=%d (%s)", rv, hal_strerror(rv)); + return NULL; +} + +static PyMethodDef halquery_module_methods[] = { + {"pin", get_pin, METH_VARARGS, "pin(name:string)"}, + {"param", get_param, METH_VARARGS, "param(name:string)"}, + {"signal", get_signal, METH_VARARGS, "signal(name:string)"}, + {"comp", get_comp, METH_VARARGS, "comp(name:string|id:int)"}, + {"funct", get_funct, METH_VARARGS, "funct(name:string)"}, + {"thread", get_thread, METH_VARARGS, "thread(name:string)"}, + + {"signalpins", get_signalpins, METH_VARARGS, "signalpins(name:string)"}, + + {"pins", get_pins, METH_NOARGS, "pins()"}, + {"params", get_params, METH_NOARGS, "params()"}, + {"signals", get_signals, METH_NOARGS, "signals()"}, + {"comps", get_comps, METH_NOARGS, "comps()"}, + {"functs", get_functs, METH_NOARGS, "functs()"}, + {"threads", get_threads, METH_NOARGS, "threads()"}, + {}, +}; + +static const char halquery_module_doc[] = + "Query interface to LinuxCNC's HAL internals\n" + "\n" + "This module allows you to retrieve information about all HAL\n" + "internal constructs, such as:\n" + " - pins\n" + " - parameters\n" + " - signals\n" + " - components\n" + " - functions\n" + " - threads\n" + "\n" + "Typical usage:\n" + " import halquery\n" + " # print info on one component\n" + " print(\"Component xyz:\", halquery.component(\"xyz\"))\n" + "\n" + " # print info on all signals\n" + " print(\"Signals:\")\n" + " print(halquery.signals())\n" + ; + + +static int halquery_module_exec(PyObject *m) +{ + (void)m; + static int hq_init = 0; + if(hq_init) { + PyErr_SetString(PyExc_ImportError, "Cannot initialize halquery module more than once"); + return -1; + } + hq_init = 1; + + int rv; + if(0 != (rv = hal_lib_init())) { + PyErr_Format(PyExc_ImportError, "Initializing hal_lib returned error=%d", rv); + return -1; + } + Py_AtExit(hal_lib_exit); // Register to exit the HAL library when done + return 0; +} + +static PyModuleDef_Slot halquery_module_slots[] = { + {Py_mod_exec, (void *)halquery_module_exec}, + {0, NULL} +}; + +static struct PyModuleDef halquery_moduledef = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "halquery", + .m_doc = halquery_module_doc, + .m_methods = halquery_module_methods, + .m_slots = halquery_module_slots, +}; + +PyMODINIT_FUNC PyInit_halquery(void) +{ + return PyModuleDef_Init(&halquery_moduledef); +} +// vim: ts=4 sw=4 et diff --git a/src/hal/utils/Submakefile b/src/hal/utils/Submakefile index 69d17f766e1..3c980d256d1 100644 --- a/src/hal/utils/Submakefile +++ b/src/hal/utils/Submakefile @@ -27,12 +27,12 @@ TARGETS += ../tcl/hal.so $(Q)$(CXX) $(LDFLAGS) -o $@ $^ $(READLINE_LIBS) -lfmt TARGETS += ../bin/halcmd -HALRMTSRCS := hal/utils/halrmt.c +HALRMTSRCS := hal/utils/halrmt.cc hal/utils/setps_util.c USERSRCS += $(HALRMTSRCS) -../bin/halrmt: $(call TOOBJS, $(HALRMTSRCS)) ../lib/liblinuxcnchal.so.0 +../bin/halrmt: $(call TOOBJS, $(HALRMTSRCS)) ../lib/liblinuxcnchal.so.0 ../lib/liblinuxcncini.so.1 $(ECHO) Linking $(notdir $@) - $(Q)$(CC) $(LDFLAGS) -o $@ $^ -lpthread + $(Q)$(CXX) $(LDFLAGS) -o $@ $^ -lfmt TARGETS += ../bin/halrmt ifneq ($(GTK_VERSION),) diff --git a/src/hal/utils/halrmt.c b/src/hal/utils/halrmt.c deleted file mode 100644 index 6d9ad460dd8..00000000000 --- a/src/hal/utils/halrmt.c +++ /dev/null @@ -1,3593 +0,0 @@ -/******************************************************************** -* Description: halrmt.cc -* Simple telnet interface to LinuxCNC HAL commands (halcmd) -* -* Derived from work by jmkasunich -* -* Other contributors: -* Alex Joni -* -* Author: Eric H. Johnson -* License: GPL Version 2 -* System: Linux -* -* Copyright (c) 2006-2008 All rights reserved. -* -* Last change: -********************************************************************/ - -/******************************************************************* - Using halrmt: - - halrmt {-- --port --name --connectpw - --enablepw --sessions -ini } - - With -- --port Waits for socket connections (Telnet) on specified socket, without port - uses default port 5006. (note: linuxcncrsh uses 5007 as default) - With -- --name Sets the server name to specified name for Hello. - With -- --connectpw Sets the connection password to 'password'. Default EMC - With -- --enablepw Sets the enable password to 'password'. Default EMCTOO - With -- --sessions Sets the maximum number of simultaneous connextions - to max sessions. Default is no limit (-1). - With -- -ini , uses specified INI file instead of default emc.ini. - - There are six commands supported, Where the commands set and get contain HAL - specific sub-commands based on the commands supported by halcmd. Commands and - most parameters are not case sensitive. The exceptions are passwords, - file paths and text strings. - - The supported commands are as follows: - - ==> HELLO <== - - Hello - If a valid password was entered the server will respond with - - HELLO ACK - - Where server name and server version are looked up from the implementation. - if an invalid password or any other syntax error occurs then the server - responds with: - - HELLO NAK - - ==> Get <== - - The get command includes one of the hal sub-commands, described below and - zero or more additional parameters. - - ==> Set <== - - The set command inclides one of the hal sub-commands, described below and - one or more additional parameters. - - ==> Quit <== - - The quit command disconnects the associated socket connection. - - ==> Shutdown <== - - The shutdown command tells EMC to shutdown before quitting the connection. This - command may only be issued if the Hello has been successfully negotiated and the - connection has control of the CNC (see enable sub-command below). This command - has no parameters. - - ==> Help <== - - The help command will return help information in text format over the telnet - connection. If no parameters are specified, it will itemize the available commands. - If a command is specified, it will provide usage information for the specified - command. Help will respond regardless of whether a "Hello" has been - successfully negotiated. - - - HAL sub-commands: - - echo on | off - With get will return the current echo state, with set, sets the echo - state. When echo is on, all commands will be echoed upon receipt. This - state is local to each connection. - - verbose on | off - With get will return the current verbose state, with set, sets the - verbose state. When in verbose mode is on, all set commands return - positive acknowledgement in the form SET ACK. In addition, - text error messages will be issued when in verbose mode. This state - is local to each connection. - - enable | off - With get will return On or Off to indicate whether the current connection - is enabled to perform control functions. With set and a valid password, - the current connection is enabled for control functions. "OFF" may not - be used as a password and disables control functions for this connection. - - config [TBD] - - comm_mode ascii | binary - With get, will return the current communications mode. With set, will - set the communications mode to the specified mode. The binary protocol - is TBD. - - comm_prot - With get, returns the current protocol version used by the server, - with set, sets the server to use the specified protocol version, - provided it is lower than or equal to the highest version number - supported by the server implementation. - - Comps [] - - Get only, returns all components beginning with the specified substring. - If no substring is specified then it returns all components. - - Pins [] - - Get only, returns all information about all pins beginning with the - specified substring. If no substring is specified then it returns all pins. - - PinVals [] - - Get only, returns only value information about all pins beginning with the - specified substring. If no substring is specified then it returns all pins. - - Signals [] - - Get only, returns all information about all signals beginning with the - specified substring. If no substring is specified then it returns all signals. - - SigVals [] - - Get only, returns only value information about all signals beginning with the - specified substring. If no substring is specified then it returns all pins. - - Params [] - - Get only, returns all information about all parameters beginning with the - specified substring. If no substring is specified then it returns all - parameters. - - ParamVals [] - - Get only, returns only value information about all parameters beginning with the - specified substring. If no substring is specified then it returns all pins - parameters. - - Functs [] - - Get only, returns all information about all functions beginning with the - specified substring. If no substring is specified then it returns all - functions. - - Threads - - Get only, returns all information about all functions. - - Comp - - Get only, returns the component matching the specified name. - - Pin - - Get only, returns all information about the pin matching the specified - name. - - PinVal - - Get only, returns the value of the pin matching the specified name. - - Sig - - Get only, returns all information about the pin matching the specified - name. - - SigVal - - Get only, returns just the value of the signal matching the specified - name. - - Param - - Get only, returns all information about the parameter matching the - specified name. - - ParamVal - - Get only, returns just the value of the parameter matching the specified - name. - - Funct - - Get only, returns all information about the parameter matching the - specified name. - - Thread - - Get only, returns all information about the thread matching the - specified name. - - LoadRt - - Set only, loads the real time executable specified by name. - - Unload - - Set only, unloads the executable specified by name. - - LoadUsr - - Set only, loads the user executable specified by name. - - Linkps - - Set only, links the specified pin to the specified signal. - - Linksp - - Set only, links the specified signal to the specified pin. - - Linkpp - - Set only, links the pin specified by pin 1 with the pin specified by pin 2. - - Net - - Set only, nets the specified net list. - - Unlinkp - - Set only, unlinks the specified pins - - Lock - - Unlock - - NewSig - - Set only, creates the signal specified by name and of type specified by type. - - DelSig - - Set only, deletes the signal specified by name. - - SetP - - Set only, sets the parameter specified by name to the value specified by value. - - SetS - - Set only, sets the signal specified by name to the value specified by value. - - AddF [] - - Set only, adds the function specified by name, to the thread specified by - thread, with the optional parameters specified by parameters. - - DelF - - Set only, deletes the function specified by name. - - Save - - Start - - Stop - -****************************************************************************/ - -#include "config.h" - -#define _REENTRANT - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include // RTAPI realtime OS API -#include -#include // rtapi_strlcpy -#include // HAL public API decls -#include "../hal_priv.h" // private HAL decls - -/*********************************************************************** -* LOCAL FUNCTION DECLARATIONS * -************************************************************************/ - -/* These functions are used internally by this file. The code is at - the end of the file. */ - -#define MAX_TOK 20 -#define MAX_CMD_LEN 1024 -#define MAX_EXPECTED_SIGS 999 - -static int release_HAL_mutex(void); -static int do_help_cmd(char *command); -static int unloadrt_comp(char *mod_name); -static const char *data_type(int type); -static const char *pin_data_dir(int dir); -static const char *param_data_dir(int dir); -static const char *data_arrow1(int dir); -static const char *data_arrow2(int dir); -static char *data_value(int type, void *valptr); -static char *data_value2(int type, void *valptr); -static void save_comps(FILE *dst); -static void save_signals(FILE *dst); -static void save_links(FILE *dst, int arrows); -static void save_nets(FILE *dst, int arrows); -static void save_params(FILE *dst); -static void save_threads(FILE *dst); -static void print_help_general(int showR); - -/*********************************************************************** -* GLOBAL VARIABLES * -************************************************************************/ - -int comp_id = -1; /* -1 means hal_init() not called yet */ -int hal_flag = 0; /* used to indicate that halrmt might have the - hal mutex, so the sig handler can't just - exit, instead it must set 'done' */ -int done = 0; /* used to break out of processing loop */ -int linenumber=0; /* used to print linenumber on errors */ -int scriptmode = 0; /* used to make output "script friendly" (suppress headers) */ -int prompt_mode = 0; /* when getting input from stdin, print a prompt */ -char comp_name[HAL_NAME_LEN+1]; /* name for this instance of halrmt */ - -char pwd[16] = "EMC\0"; // Connect password -char enablePWD[16] = "EMCTOO\0"; // Enable password -char serverName[24] = "EMCNETSVR\0"; // Server name written in hello response -int sessions = 0; // Number of open sessions -int maxSessions = -1; // Maximum number of sessions to allow - -typedef struct { - int cliSock; - char hostName[80]; - char version[8]; - int linked; - int echo; - int verbose; - int enabled; - int commMode; - int commProt; - char inBuf[256]; - char outBuf[4096]; - char progName[256];} connectionRecType; - - -int port = 5006; -char errorStr[256]; - -int server_sockfd, client_sockfd; -socklen_t server_len, client_len; -struct sockaddr_in server_address; -struct sockaddr_in client_address; -int useSockets = 1; -int tokenIdx; -const char *delims = " \n\r\0"; -int connCount = -1; -int enabledConn = -1; - -typedef enum { - cmdHello, cmdSet, cmdGet, cmdQuit, cmdShutdown, cmdHelp, cmdUnknown} commandTokenType; - -typedef enum { - hcEcho, hcVerbose, hcEnable, hcConfig, hcCommMode, hcCommProt, - hcComps, hcPins, hcPinVals, hcSigs, hcSigVals, hcParams, hcParamVals, hcFuncts, hcThreads, - hcComp, hcPin, hcPinVal, hcSig, hcSigVal, hcParam, hcParamVal, hcFunct, hcThread, - hcLoadRt, hcUnload, hcLoadUsr, hcLinkps, hcLinksp, hcLinkpp, hcNet, hcUnlinkp, - hcLock, hcUnlock, hcNewSig, hcDelSig, hcSetP, hcSetS, hcAddF, hcDelF, - hcSave, hcStart, hcStop, hcUnknown - } halCommandType; - -typedef enum { - rtNoError, rtHandledNoError, rtStandardError, rtCustomError, rtCustomHandledError - } cmdResponseType; - -struct option longopts[] = { - {"port", 1, NULL, 'p'}, - {"name", 1, NULL, 'n'}, - {"sessions", 1, NULL, 's'}, - {"connectpw", 1, NULL, 'w'}, - {"enablepw", 1, NULL, 'e'}, - {NULL,0,NULL,0} -}; - -const char *commands[] = {"HELLO", "SET", "GET", "QUIT", "SHUTDOWN", "HELP", ""}; -const char *halCommands[] = { - "ECHO", "VERBOSE", "ENABLE", "CONFIG", "COMM_MODE", "COMM_PROT", - "COMPS", "PINS", "PINVALS", "SIGNALS", "SIGVALS", "PARAMS", "PARAMVALS", "FUNCTS", "THREADS", - "COMP", "PIN", "PINVAL", "SIGNAL", "SIGVAL", "PARAM", "PARAMVAL", "FUNCT", "THREAD", - "LOADRT", "UNLOAD", "LOADUSR", "LINKPS", "LINKSP", "LINKPP", "NET", "UNLINKP", - "LOCK", "UNLOCK", "NEWSIG", "DELSIG", "SETP", "SETS", "ADDF", "DELF", - "SAVE", "START", "STOP", ""}; - -#ifndef NO_INI - FILE *inifile = NULL; -#endif - - -/* signal handler */ -static void quit(int sig) -{ - (void)sig; - if ( hal_flag ) { - /* this process might have the hal mutex, so just set the - 'done' flag and return, exit after mutex work finishes */ - done = 1; - } else { - /* don't have to worry about the mutex, but if we just - return, we might return into the fgets() and wait - all day instead of exiting. So we exit from here. */ - if ( comp_id > 0 ) { - hal_exit(comp_id); - } - _exit(1); - } -} - -static void strupr(char *s) -{ - int i; - - for (i = 0; i < (int)strlen(s); i++) - if (s[i] > 96 && s[i] <= 'z') - s[i] -= 32; -} - -static int initSockets() -{ - int optval = 1; - - server_sockfd = socket(AF_INET, SOCK_STREAM, 0); - setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); - server_address.sin_family = AF_INET; - server_address.sin_addr.s_addr = htonl(INADDR_ANY); - server_address.sin_port = htons(port); - server_len = sizeof(server_address); - bind(server_sockfd, (struct sockaddr *)&server_address, server_len); - listen(server_sockfd, 5); - signal(SIGCHLD, SIG_IGN); - return 0; -} - -static int sockWrite(connectionRecType *context) -{ - rtapi_strxcat(context->outBuf, "\r\n"); - return write(context->cliSock, context->outBuf, strlen(context->outBuf)); -} - -static void sockWriteError(const char *nakStr, connectionRecType *context) -{ - if (context->verbose == 1) - snprintf(context->outBuf, sizeof(context->outBuf), "%s %s", nakStr, errorStr); - else - snprintf(context->outBuf, sizeof(context->outBuf), "%s", nakStr); - if(sockWrite(context) < 0) perror("sockWrite"); -} - -pid_t hal_systemv_nowait(char *const argv[], connectionRecType *context) { - pid_t pid; - int n; - const char *nakStr = "SET LOADRT NAK"; - - /* now we need to fork, and then exec .... */ - /* disconnect from the HAL shmem area before forking */ - hal_exit(comp_id); - comp_id = 0; - /* now the fork() */ - pid = fork(); - if ( pid < 0 ) { - /* fork failed */ -// halcmd_error("fork() failed\n"); - /* reconnect to the HAL shmem area */ - comp_id = hal_init(comp_name); - if (comp_id < 0) { - fprintf(stderr, "halcmd: hal_init() failed after fork: %d\n", - comp_id ); - exit(-1); - } - hal_ready(comp_id); - return -1; - } - if ( pid == 0 ) { - /* child process */ - /* print debugging info if "very verbose" (-V) */ - for(n=0; argv[n] != NULL; n++) { - rtapi_print_msg(RTAPI_MSG_DBG, "%s ", argv[n] ); - } - if (n == 0) { - snprintf(errorStr, sizeof(errorStr), "hal_systemv_nowait: empty argv array passed in\n"); - sockWriteError(nakStr, context); - exit(1); - } - rtapi_print_msg(RTAPI_MSG_DBG, "\n" ); - /* call execv() to invoke command */ - execvp(argv[0], argv); - /* should never get here */ -// halcmd_error("execv(%s) failed\n", argv[0] ); - snprintf(errorStr, sizeof(errorStr), "execv(%s) failed", argv[0]); - sockWriteError(nakStr, context); - exit(1); - } - /* parent process */ - /* reconnect to the HAL shmem area */ - comp_id = hal_init(comp_name); - - return pid; -} - -int hal_systemv(char *const argv[], connectionRecType *context) { - pid_t pid; - int status; - int retval; - const char *nakStr = "SET LOADRT NAK"; - - /* do the fork */ - pid = hal_systemv_nowait(argv, context); - /* this is the parent process, wait for child to end */ - retval = waitpid ( pid, &status, 0 ); - retval = 0; - if (comp_id < 0) { - fprintf(stderr, "halcmd: hal_init() failed after systemv: %d\n", comp_id ); - exit(-1); - } - hal_ready(comp_id); - /* check result of waitpid() */ - if ( retval < 0 ) { -// halcmd_error("waitpid(%d) failed: %s\n", pid, strerror(errno) ); - snprintf(errorStr, sizeof(errorStr), "waitpid(%d) failed: %s", pid, strerror(errno)); - sockWriteError(nakStr, context); - return -1; - } - if ( WIFEXITED(status) == 0 ) { -// halcmd_error("child did not exit normally\n"); - snprintf(errorStr, sizeof(errorStr), "child did not exit normally"); - sockWriteError(nakStr, context); - return -1; - } - retval = WEXITSTATUS(status); - if ( retval != 0 ) { -// halcmd_error("exit value: %d\n", retval ); - snprintf(errorStr, sizeof(errorStr), "exit value: %d", retval); - sockWriteError(nakStr, context); - return -1; - } - return 0; -} - - -/*********************************************************************** -* LOCAL FUNCTION DEFINITIONS * -************************************************************************/ - -/* release_HAL_mutex() unconditionally releases the hal_mutex - very useful after a program segfaults while holding the mutex -*/ -static int release_HAL_mutex(void) -{ - return hal_mutex_force_release() == 0 ? 0 : -EINVAL; -} - -static int doLock(char *command, connectionRecType *context) -{ - int retval = 0; - const char *nakStr = "SET LOCK NAK"; - - /* if command is blank, want to lock everything */ - if (*command == '\0') - retval = hal_set_lock(HAL_LOCK_ALL); - else if (strcmp(command, "none") == 0) - retval = hal_set_lock(HAL_LOCK_NONE); - else if (strcmp(command, "tune") == 0) - retval = hal_set_lock(HAL_LOCK_TUNE); - else if (strcmp(command, "all") == 0) - retval = hal_set_lock(HAL_LOCK_ALL); - - if (retval != 0) { - snprintf(errorStr, sizeof(errorStr), "HAL:%d: Locking failed", linenumber); - sockWriteError(nakStr, context); - } - return retval; -} - -static int doUnlock(char *command, connectionRecType *context) -{ - int retval=0; - const char *nakStr = "SET UNLOCK NAK"; - - /* if command is blank, want to unlock everything */ - if (*command == '\0') - retval = hal_set_lock(HAL_LOCK_NONE); - else if (strcmp(command, "none") == 0) - retval = hal_set_lock(HAL_LOCK_NONE); - else if (strcmp(command, "tune") == 0) - retval = hal_set_lock(hal_get_lock() & ~HAL_LOCK_TUNE); - else if (strcmp(command, "all") == 0) - retval = hal_set_lock(HAL_LOCK_NONE); - - if (retval != 0) { - snprintf(errorStr, sizeof(errorStr), "HAL:%d: Unlocking failed", linenumber); - sockWriteError(nakStr, context); - } - return retval; -} - -static int doLinkpp(char *first_pin_name, char *second_pin_name, connectionRecType *context) -{ - int retval; - hal_pin_t *first_pin, *second_pin; - const char *nakStr = "SET LINKPP NAK"; - - halpr_mutex_acquire(); - /* check if the pins are there */ - first_pin = halpr_find_pin_by_name(first_pin_name); - second_pin = halpr_find_pin_by_name(second_pin_name); - if (first_pin == NULL) { - /* first pin not found*/ - halpr_mutex_release(); - snprintf(errorStr, sizeof(errorStr), "HAL:%d: ERROR: pin '%s' not found\n", linenumber, first_pin_name); - sockWriteError(nakStr, context); - return -EINVAL; - } - else - if (second_pin == NULL) { - halpr_mutex_release(); - snprintf(errorStr, sizeof(errorStr), "HAL:%d: ERROR: pin '%s' not found", linenumber, second_pin_name); - sockWriteError(nakStr, context); - return -EINVAL; - } - - /* give the mutex, as the other functions use their own mutex */ - halpr_mutex_release(); - - /* check that both pins have the same type, - don't want to create a sig, which after that won't be useful */ - if (first_pin->type != second_pin->type) { - snprintf(errorStr, sizeof(errorStr), "HAL:%d: ERROR: pins '%s' and '%s' not of the same type", - linenumber, first_pin_name, second_pin_name); - sockWriteError(nakStr, context); - return -EINVAL; - } - - /* now create the signal */ - retval = hal_signal_new(first_pin_name, first_pin->type); - - if (retval == 0) { - /* if it worked, link the pins to it */ - retval = hal_link(first_pin_name, first_pin_name); - - if ( retval == 0 ) - /* if that worked, link the second pin to the new signal */ - retval = hal_link(second_pin_name, first_pin_name); - } - if (retval < 0) { - snprintf(errorStr, sizeof(errorStr), "HAL:%d: linkpp failed", linenumber); - sockWriteError(nakStr, context); - } - return retval; -} - -int doLinkPS(char *pin, char *sig, connectionRecType *context) -{ - int retval; - const char *nakStr = "SET NET NAK"; - - retval = hal_link(pin, sig); - if (retval == 0) { - /* print success message */ -// halcmd_info("Pin '%s' linked to signal '%s'\n", pin, sig); - snprintf(errorStr, sizeof(errorStr), "Pin '%s' linked to signal '%s'", pin, sig); - sockWriteError(nakStr, context); - } else { -// halcmd_error("link failed\n"); - snprintf(errorStr, sizeof(errorStr), "link failed"); - sockWriteError(nakStr, context); - } - return retval; -} - - -static int preflightNet(char *signal, hal_sig_t *sig, char *pins[], connectionRecType *context) -{ - int i, type=-1, writers=0, bidirs=0, pincnt=0; - const char *nakStr = "SET NET NAK"; - - /* if signal already exists, use its info */ - if (sig) { - type = sig->type; - writers = sig->writers; - bidirs = sig->bidirs; - } - - for(i=0; pins[i] && *pins[i]; i++) { - hal_pin_t *pin = NULL; - pin = halpr_find_pin_by_name(pins[i]); - if(!pin) { -// halcmd_error("pin '%s' does not exist\n", pins[i]); - snprintf(errorStr, sizeof(errorStr), "pin '%s' does not exist", pins[i]); - sockWriteError(nakStr, context); - return -ENOENT; - } - if(SHMPTR(pin->signal) == sig) { - /* Already on this signal */ - pincnt++; - continue; - } else if(pin->signal != 0) { -// halcmd_error("pin '%s' was already linked\n", pin->name); - snprintf(errorStr, sizeof(errorStr), "pin '%s' was already linked", pin->name); - sockWriteError(nakStr, context); - return -EINVAL; - } - if (type == -1) { - /* no pre-existing type, use this pin's type */ - type = pin->type; - } - if(type != pin->type) { -// halcmd_error("Type mismatch on pin '%s'\n", pin->name); - snprintf(errorStr, sizeof(errorStr), "Type mismatch on pin '%s'", pin->name); - sockWriteError(nakStr, context); - return -EINVAL; - } - if(pin->dir == HAL_OUT) { - if(writers || bidirs) { -// halcmd_error("Signal '%s' can not add OUT pin '%s'\n", signal, pin->name); - snprintf(errorStr, sizeof(errorStr), "Signal '%s' can not add OUT pin '%s'", signal, pin->name); - sockWriteError(nakStr, context); - return -EINVAL; - } - writers++; - } - if(pin->dir == HAL_IO) { - if(writers) { -// halcmd_error("Signal '%s' can not add I/O pin '%s'\n", signal, pin->name); - snprintf(errorStr, sizeof(errorStr), "Signal '%s' can not add I/O pin '%s'", signal, pin->name); - sockWriteError(nakStr, context); - return -EINVAL; - } - bidirs++; - } - pincnt++; - } - if(pincnt) - return 0; -// halcmd_error("'net' requires at least one pin, none given\n"); - snprintf(errorStr, sizeof(errorStr), "'net' requires at least one pin, none given"); - sockWriteError(nakStr, context); - return -EINVAL; -} - - -int doNet(char *signal, char *pins[], connectionRecType *context) -{ - hal_sig_t *sig; - int i, retval; - const char *nakStr = "SET NET NAK"; - - halpr_mutex_acquire(); - /* see if signal already exists */ - sig = halpr_find_sig_by_name(signal); - - /* verify that everything matches up (pin types, etc) */ - retval = preflightNet(signal, sig, pins, context); - if(retval < 0) { - halpr_mutex_release(); - return retval; - } - - { - hal_pin_t *pin = halpr_find_pin_by_name(signal); - if(pin) { -// halcmd_error("Signal name '%s' must not be the same as a pin.\n", signal); - snprintf(errorStr, sizeof(errorStr), "Signal name '%s' must not be the same as a pin.", signal); - sockWriteError(nakStr, context); - halpr_mutex_release(); - return -ENOENT; - } - } - if(!sig) { - /* Create the signal with the type of the first pin */ - hal_pin_t *pin = halpr_find_pin_by_name(pins[0]); - halpr_mutex_release(); - if(!pin) { - return -ENOENT; - } - retval = hal_signal_new(signal, pin->type); - } else { - /* signal already exists */ - halpr_mutex_release(); - } - /* add pins to signal */ - for(i=0; retval == 0 && pins[i] && *pins[i]; i++) { - retval = doLinkPS(pins[i], signal, context); - } - - return retval; -} - - -static int doLink(char *pin, char *sig, connectionRecType *context) -{ - int retval; - const char *nakStr = "SET LINKPS NAK"; - - /* if sig is blank, want to unlink pin */ - if (*sig == '\0') { - /* unlink the pin */ - retval = hal_unlink(pin); - } else { - /* make the link */ - retval = hal_link(pin, sig); - } - if (retval != 0) { - snprintf(errorStr, sizeof(errorStr), "HAL:%d: link failed", linenumber); - sockWriteError(nakStr, context); - } - return retval; -} - -static int doNewsig(char *name, char *type, connectionRecType *context) -{ - int retval; - const char *nakStr = "SET NEWSIG NAK"; - - if (strcasecmp(type, "bit") == 0) - retval = hal_signal_new(name, HAL_BIT); - else - if (strcasecmp(type, "float") == 0) - retval = hal_signal_new(name, HAL_FLOAT); - else - if (strcasecmp(type, "u16") == 0) - retval = hal_signal_new(name, HAL_U32); - else - if (strcasecmp(type, "s32") == 0) - retval = hal_signal_new(name, HAL_S32); - else { - snprintf(errorStr, sizeof(errorStr), "HAL:%d: Unknown signal type '%s'", - linenumber, type); - sockWriteError(nakStr, context); - retval = -EINVAL; - } - if (retval < 0) { - snprintf(errorStr, sizeof(errorStr), "HAL:%d: newsig failed", linenumber); - sockWriteError(nakStr, context); - } - return retval; -} - -static int set_common(hal_type_t type, void *d_ptr, char *value, connectionRecType *context) { - (void)context; - // This function assumes that the mutex is held - int retval = 0; - double fval; - long lval; - unsigned long ulval; - char *cp = value; - - switch (type) { - case HAL_BIT: - if ((strcmp("1", value) == 0) || (strcasecmp("TRUE", value) == 0)) { - *(hal_bit_t *) (d_ptr) = 1; - } else if ((strcmp("0", value) == 0) - || (strcasecmp("FALSE", value)) == 0) { - *(hal_bit_t *) (d_ptr) = 0; - } else { - retval = -EINVAL; - } - break; - case HAL_FLOAT: - fval = strtod ( value, &cp ); - if ((*cp != '\0') && (!isspace(*cp))) { - /* invalid character(s) in string */ - retval = -EINVAL; - } else { - *((hal_float_t *) (d_ptr)) = fval; - } - break; - case HAL_S32: - lval = strtol(value, &cp, 0); - if ((*cp != '\0') && (!isspace(*cp))) { - /* invalid chars in string */ - retval = -EINVAL; - } else { - *((hal_s32_t *) (d_ptr)) = lval; - } - break; - case HAL_U32: - ulval = strtoul(value, &cp, 0); - if ((*cp != '\0') && (!isspace(*cp))) { - /* invalid chars in string */ - retval = -EINVAL; - } else { - *((hal_u32_t *) (d_ptr)) = ulval; - } - break; - default: - /* Shouldn't get here, but just in case... */ - retval = -EINVAL; - } - return retval; -} - -static int doSetp(char *name, char *value, connectionRecType *context) -{ - const char *nakStr = "SET SETP NAK"; - int retval; - hal_param_t *param; - hal_pin_t *pin; - hal_type_t type; - void *d_ptr; - - /* get mutex before accessing shared data */ - halpr_mutex_acquire(); - /* search param list for name */ - param = halpr_find_param_by_name(name); - if (param == NULL) { - pin = halpr_find_pin_by_name(name); - if(pin == NULL) { - halpr_mutex_release(); - snprintf(errorStr, sizeof(errorStr), - "HAL:%d: ERROR: parameter or pin '%s' not found\n", linenumber, name); - sockWriteError(nakStr, context); - return -EINVAL; - } else { - /* found it */ - type = pin->type; - if(pin->dir == HAL_OUT) { - halpr_mutex_release(); - snprintf(errorStr, sizeof(errorStr), - "HAL:%d: ERROR: pin '%s' is not writable\n", linenumber, name); - sockWriteError(nakStr, context); - return -EINVAL; - } - if(pin->signal != 0) { - halpr_mutex_release(); - snprintf(errorStr, sizeof(errorStr), - "HAL:%d: ERROR: pin '%s' is connected to a signal\n", linenumber, name); - sockWriteError(nakStr, context); - return -EINVAL; - } - // d_ptr = (void*)SHMPTR(pin->dummysig); - d_ptr = (void*)&pin->dummysig; - } - } else { - /* found it */ - type = param->type; - /* is it read only? */ - if (param->dir == HAL_RO) { - halpr_mutex_release(); - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: param '%s' is not writable\n", linenumber, name); - return -EINVAL; - } - d_ptr = SHMPTR(param->data_ptr); - } - - retval = set_common(type, d_ptr, value, context); - - halpr_mutex_release(); - if (retval != 0) { - snprintf(errorStr, sizeof(errorStr), "HAL:%d: setp failed\n", linenumber); - sockWriteError(nakStr, context); - } - return retval; -} - -static int doSets(char *name, char *value, connectionRecType *context) -{ - const char *nakStr = "SET SETS NAK"; - int retval; - hal_sig_t *sig; - hal_type_t type; - void *d_ptr; - - /* get mutex before accessing shared data */ - halpr_mutex_acquire(); - /* search signal list for name */ - sig = halpr_find_sig_by_name(name); - if (sig == NULL) { - halpr_mutex_release(); - snprintf(errorStr, sizeof(errorStr), - "HAL:%d: ERROR: signal '%s' not found\n", linenumber, name); - sockWriteError(nakStr, context); - return -EINVAL; - } - /* found it - does it have a writer? */ - if (sig->writers > 0) { - halpr_mutex_release(); - snprintf(errorStr, sizeof(errorStr), - "HAL:%d: ERROR: signal '%s' already has writer(s)\n", linenumber, name); - sockWriteError(nakStr, context); - return -EINVAL; - } - /* no writer, so we can safely set it */ - type = sig->type; - d_ptr = SHMPTR(sig->data_ptr); - retval = set_common(type, d_ptr, value, context); - halpr_mutex_release(); - if (retval != 0) { - snprintf(errorStr, sizeof(errorStr), "HAL:%d: sets failed\n", linenumber); - sockWriteError(nakStr, context); - } - return retval; -} - -static int doAddf(char *name, char *thread, char *parm, connectionRecType *context) -{ - int retval; - const char *nakStr = "SET ADDF NAK"; - - if (parm[0] == '\0') - /* no - add function at end of thread */ - retval = hal_add_funct_to_thread(name, thread, -1); - else - retval = hal_add_funct_to_thread(name, thread, atoi(parm)); - if (retval != 0) { - /* print fail message */ - snprintf(errorStr, sizeof(errorStr), "HAL:%d: Unable to add function '%s' to thread '%s'", linenumber, name, thread); - sockWriteError(nakStr, context); - } - return retval; -} - -static int doDelf(char *name, char *thread, connectionRecType *context) -{ - int retval; - const char *nakStr = "SET DELF NAK"; - - retval = hal_del_funct_from_thread(name, thread); - if (retval != 0) { - /* print success message */ - snprintf(errorStr, sizeof(errorStr), "Failed to remove function '%s' from thread '%s'", name, thread); - sockWriteError(nakStr, context); - } - return retval; -} - -static int doStart(connectionRecType *context) -{ - int retval; - const char *nakStr = "SET START NAK"; - - retval = hal_start_threads(); - if (retval != 0) { - /* print success message */ - snprintf(errorStr, sizeof(errorStr), "Failed to start realtime threads"); - sockWriteError(nakStr, context); - } - return retval; -} - -static int doStop(connectionRecType *context) -{ - int retval; - const char *nakStr = "SET STOP NAK"; - - retval = hal_stop_threads(); - if (retval != 0) { - /* print success message */ - snprintf(errorStr, sizeof(errorStr), "Unable to stop realtime threads"); - sockWriteError(nakStr, context); - } - return retval; -} - -static int doLoadRt(char *mod_name, char *args[], connectionRecType *context) -{ - char arg_string[MAX_CMD_LEN+1]; - int n=0, retval=0; - hal_comp_t *comp; - char *cp1; - const char *nakStr = "SET LOADRT NAK"; - -#if defined(RTAPI_USPACE) -#if 0 - argv[m++] = "-Wn"; - argv[m++] = mod_name; - argv[m++] = EMC2_BIN_DIR "/rtapi_app"; - argv[m++] = "load"; - argv[m++] = mod_name; - /* loop thru remaining arguments */ - while ( args[n] && args[n][0] != '\0' ) { - argv[m++] = args[n++]; - } - argv[m++] = NULL; -// retval = do_loadusr_cmd(argv); -#endif -#else - int m=0; - char *argv[MAX_TOK+3]; - static char *rtmod_dir = EMC2_RTLIB_DIR; - struct stat stat_buf; - char mod_path[MAX_CMD_LEN+1]; - - if (hal_get_lock()&HAL_LOCK_LOAD) { - snprintf(errorStr, sizeof(errorStr), "HAL is locked, loading of modules is not permitted"); - sockWriteError(nakStr, context); - return -EPERM; - } - if ( (strlen(rtmod_dir)+strlen(mod_name)+5) > MAX_CMD_LEN ) { - snprintf(errorStr, sizeof(errorStr), "Module path too long"); - sockWriteError(nakStr, context); - return -1; - } - - /* make full module name '/.o' */ - rtapi_strxcpy (mod_path, rtmod_dir); - rtapi_strxcat (mod_path, "/"); - rtapi_strxcat (mod_path, mod_name); - rtapi_strxcat (mod_path, MODULE_EXT); - /* is there a file with that name? */ - if ( stat(mod_path, &stat_buf) != 0 ) { - /* can't find it */ - snprintf(errorStr, sizeof(errorStr), "Can't find module '%s' in %s", mod_name, rtmod_dir); - sockWriteError(nakStr, context); - return -1; - } - - // TODO - FIXME - remove test after 2.2.x when blocks isn't functional anymore - if (strncmp(mod_name, "blocks", 6) == 0) { - //using RTAPI_MSG_ERR as that is the default warning level for halcmd - snprintf(errorStr, sizeof(errorStr), "blocks is deprecated, use the subcomponents generated by 'comp' instead"); - sockWriteError(nakStr, context); - } - - argv[0] = EMC2_BIN_DIR "/linuxcnc_module_helper"; - argv[1] = "insert"; - argv[2] = mod_path; - /* loop thru remaining arguments */ - n = 0; - m = 3; - while ( args[n] && args[n][0] != '\0' ) { - argv[m++] = args[n++]; - } - /* add a NULL to terminate the argv array */ - argv[m] = NULL; -/* snprintf(context->outBuf, sizeof(context->outBuf), "Setup argv %s %s %s", argv[0], argv[1], argv[2]); - sockWrite(context); - return 0; */ - - - retval = hal_systemv(argv, context); -#endif - - if ( retval != 0 ) { - snprintf(errorStr, sizeof(errorStr), "insmod failed, returned %d", retval); - sockWriteError(nakStr, context); - return -1; - } - /* make the args that were passed to the module into a single string */ - n = 0; - arg_string[0] = '\0'; - while ( args[n] && args[n][0] != '\0' ) { - strncat(arg_string, args[n++], MAX_CMD_LEN); - strncat(arg_string, " ", MAX_CMD_LEN); - } - /* allocate HAL shmem for the string */ - cp1 = hal_malloc(strlen(arg_string)+1); - if ( cp1 == NULL ) { - snprintf(errorStr, sizeof(errorStr), "failed to allocate memory for module args"); - sockWriteError(nakStr, context); - return -1; - } - /* copy string to shmem */ - strcpy (cp1, arg_string); - /* get mutex before accessing shared data */ - halpr_mutex_acquire(); - /* search component list for the newly loaded component */ - comp = halpr_find_comp_by_name(mod_name); - if (comp == NULL) { - halpr_mutex_release(); - snprintf(errorStr, sizeof(errorStr), "module '%s' not loaded", mod_name); - sockWriteError(nakStr, context); - return -EINVAL; - } - /* link args to comp struct */ - comp->insmod_args = SHMOFF(cp1); - halpr_mutex_release(); - /* print success message */ -// halcmd_info("Realtime module '%s' loaded\n", mod_name); - return 0; -} - -static int doDelsig(char *mod_name, connectionRecType *context) -{ - int next, retval, retval1, n; - hal_sig_t *sig; - char sigs[MAX_EXPECTED_SIGS][HAL_NAME_LEN+1]; - const char *nakStr = "SET DELSIG NAK"; - - /* check for "all" */ - if ( strcmp(mod_name, "all" ) != 0 ) { - retval = hal_signal_delete(mod_name); - return retval; - } - else { - /* build a list of signal(s) to delete */ - n = 0; - halpr_mutex_acquire(); - - next = hal_data->sig_list_ptr; - while (next != 0) { - sig = SHMPTR(next); - /* we want to unload this signal, remember it's name */ - if (n < ( MAX_EXPECTED_SIGS - 1)) { - snprintf(sigs[n], sizeof(sigs[n]), "%s", sig->name); - n++; - } - next = sig->next_ptr; - } - halpr_mutex_release(); - sigs[n][0] = '\0'; - - if (sigs[0][0] == '\0') { - /* desired signals not found */ - snprintf(errorStr, sizeof(errorStr), "HAL:%d: ERROR: no signals found to be deleted", linenumber); - sockWriteError(nakStr, context); - return -1; - } - /* we now have a list of components, unload them */ - n = 0; - retval1 = 0; - while (sigs[n][0] != '\0') { - retval = hal_signal_delete(sigs[n]); - /* check for fatal error */ - if (retval < -1) - return retval; - /* check for other error */ - if (retval != 0) - retval1 = retval; - n++; - } - } - return retval1; -} - -static int doUnload(char *mod_name, connectionRecType *context) -{ - int next, retval, retval1, n, all; - hal_comp_t *comp; - char comps[64][HAL_NAME_LEN+1]; - const char *nakStr = "SET UNLOAD NAK"; - - /* check for "all" */ - if ( strcmp(mod_name, "all" ) == 0 ) { - all = 1; - } else { - all = 0; - } - /* build a list of component(s) to unload */ - n = 0; - halpr_mutex_acquire(); - next = hal_data->comp_list_ptr; - while (next != 0) { - comp = SHMPTR(next); - if ( comp->type == COMPONENT_TYPE_REALTIME ) { - /* found a realtime component */ - if ( all || ( strcmp(mod_name, comp->name) == 0 )) { - /* we want to unload this component, remember its name */ - if ( n < 63 ) { - snprintf(comps[n], sizeof(comps[n]), "%s", comp->name); - comps[n][HAL_NAME_LEN] = '\0'; - n++; - } - } - } - next = comp->next_ptr; - } - halpr_mutex_release(); - /* mark end of list */ - comps[n][0] = '\0'; - if ( !all && ( comps[0][0] == '\0' )) { - /* desired component not found */ -// halcmd_error("component '%s' is not loaded\n", mod_name); - snprintf(errorStr, sizeof(errorStr), "component '%s' is not loaded", mod_name); - sockWriteError(nakStr, context); - return -1; - } - /* we now have a list of components, unload them */ - n = 0; - retval1 = 0; - while ( comps[n][0] != '\0' ) { - retval = unloadrt_comp(comps[n++]); - /* check for fatal error */ - if ( retval < -1 ) { - return retval; - } - /* check for other error */ - if ( retval != 0 ) { - retval1 = retval; - } - } -/* if (retval1 < 0) { - snprintf(errorStr, sizeof(errorStr), "unloadrt failed"); - sockWriteError(nakStr, context); - } */ - return retval1; -} - -static int unloadrt_comp(char *mod_name) -{ - int retval, status; - char *argv[4]; - pid_t pid; - - /* now we need to fork, and then exec rmmod.... */ - /* disconnect from the HAL shmem area before forking */ - hal_exit(comp_id); - comp_id = 0; - /* now the fork() */ - pid = fork(); - if ( pid < 0 ) { - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: unloadrt fork() failed\n", linenumber); - /* reconnect to the HAL shmem area */ - comp_id = hal_init(comp_name); - if (comp_id < 0) { - fprintf(stderr, "halrmt: hal_init() failed after fork: %d\n", - comp_id); - exit(-1); - } - hal_ready(comp_id); - return -1; - } - if ( pid == 0 ) { - /* this is the child process - prepare to exec() rmmod */ - argv[0] = EMC2_BIN_DIR "/linuxcnc_module_helper"; - argv[1] = "remove"; - argv[2] = mod_name; - /* add a NULL to terminate the argv array */ - argv[3] = NULL; - /* print debugging info if "very verbose" (-V) */ - rtapi_print_msg(RTAPI_MSG_DBG, "%s %s %s\n", argv[0], argv[1], argv[2] ); - /* call execv() to invoke rmmod */ - execv(argv[0], argv); - /* should never get here */ - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: execv(%s) failed\n", linenumber, argv[0] ); - exit(1); - } - /* this is the parent process, wait for child to end */ - retval = waitpid ( pid, &status, 0 ); - /* reconnect to the HAL shmem area */ - comp_id = hal_init(comp_name); - if (comp_id < 0) { - fprintf(stderr, "halrmt: hal_init() failed after unloadrt: %d\n", - comp_id ); - exit(-1); - } - hal_ready(comp_id); - /* check result of waitpid() */ - if ( retval < 0 ) { - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: waitpid(%d) failed\n", linenumber, pid); - return -1; - } - if ( WIFEXITED(status) == 0 ) { - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: child did not exit normally\n", linenumber); - return -1; - } - retval = WEXITSTATUS(status); - if ( retval != 0 ) { - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: rmmod failed, returned %d\n", linenumber, retval); - return -1; - } - /* print success message */ - rtapi_print_msg(RTAPI_MSG_INFO, "Realtime module '%s' unloaded\n", - mod_name); - return 0; -} - -static int doLoadUsr(char *args[]) -{ - int wait_flag, wait_comp_flag, name_flag, ignore_flag; - char *prog_name, *new_comp_name; - char prog_path[MAX_CMD_LEN+1]; - char *cp1, *cp2, *envpath; - struct stat stat_buf; - char *argv[MAX_TOK+1]; - int n, m, retval, status; - pid_t pid; - - if (hal_get_lock()&HAL_LOCK_LOAD) { - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: HAL is locked, loading of programs is not permitted\n", linenumber); - return -EPERM; - } - /* check for options (-w, -i, and/or -r) */ - wait_flag = 0; - wait_comp_flag = 0; - name_flag = 0; - ignore_flag = 0; - prog_name = NULL; - while ( **args == '-' ) { - /* this argument contains option(s) */ - cp1 = *args; - cp1++; - while ( *cp1 != '\0' ) { - if ( *cp1 == 'w' ) { - wait_flag = 1; - } else if ( *cp1 == 'W' ) { - wait_comp_flag = 1; - } else if ( *cp1 == 'i' ) { - ignore_flag = 1; - } else if ( *cp1 == 'n' ) { - name_flag = 1; - } else { - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: unknown loadusr option '-%c'\n", linenumber, *cp1); - return -EINVAL; - } - cp1++; - } - /* move to next arg */ - args++; - } - /* get program and component name */ - if(name_flag) { - new_comp_name = *args++; - prog_name = *args++; - } else { - new_comp_name = prog_name = *args++; - } - /* need to find path to a program matching "prog_name" */ - prog_path[0] = '\0'; - if ( prog_path[0] == '\0' ) { - /* try the name by itself */ - rtapi_strlcpy(prog_path, prog_name, MAX_CMD_LEN); - rtapi_print_msg(RTAPI_MSG_DBG, "Trying '%s'\n", prog_path); - if ( stat(prog_path, &stat_buf) != 0 ) { - /* no luck, clear prog_path to indicate failure */ - prog_path[0] = '\0'; - } - } - if ( prog_path[0] == '\0' ) { - /* no luck yet, try the emc2/bin directory where - the halrmt executable is located */ - n = readlink("/proc/self/exe", prog_path, MAX_CMD_LEN-10); - if ( n > 0 ) { - prog_path[n] = '\0'; - /* have path to executabie, find last '/' */ - cp2 = ""; - cp1 = prog_path; - while ( *cp1 != '\0' ) { - if ( *cp1 == '/' ) { - cp2 = cp1; - } - cp1++; - } - if ( *cp2 == '/' ) { - /* chop "halrmt" from end of path */ - *(++cp2) = '\0'; - /* append the program name */ - strncat(prog_path, prog_name, MAX_CMD_LEN-strlen(prog_path)); - /* and try it */ - rtapi_print_msg(RTAPI_MSG_DBG, "Trying '%s'\n", prog_path); - if ( stat(prog_path, &stat_buf) != 0 ) { - /* no luck, clear prog_path to indicate failure */ - prog_path[0] = '\0'; - } - } - } - } - if ( prog_path[0] == '\0' ) { - /* no luck yet, try the user's PATH */ - envpath = getenv("PATH"); - if ( envpath != NULL ) { - while ( *envpath != '\0' ) { - /* copy a single directory from the PATH env variable */ - n = 0; - while ( (*envpath != ':') && (*envpath != '\0') && (n < MAX_CMD_LEN)) { - prog_path[n++] = *envpath++; - } - /* append '/' and program name */ - if ( n < MAX_CMD_LEN ) { - prog_path[n++] = '/'; - } - cp1 = prog_name; - while ((*cp1 != '\0') && ( n < MAX_CMD_LEN)) { - prog_path[n++] = *cp1++; - } - prog_path[n] = '\0'; - rtapi_print_msg(RTAPI_MSG_DBG, "Trying '%s'\n", prog_path); - if ( stat(prog_path, &stat_buf) != 0 ) { - /* no luck, clear prog_path to indicate failure */ - prog_path[0] = '\0'; - /* and get ready to try the next directory */ - if ( *envpath == ':' ) { - envpath++; - } - } else { - /* success, break out of loop */ - break; - } - } - } - } - if ( prog_path[0] == '\0' ) { - /* still can't find a program to run */ - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: Can't find program '%s'\n", linenumber, prog_name); - return -1; - } - - /* now we need to fork, and then exec the program.... */ - /* disconnect from the HAL shmem area before forking */ - hal_exit(comp_id); - comp_id = 0; - /* now the fork() */ - pid = fork(); - if ( pid < 0 ) { - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: loadusr fork() failed\n", linenumber); - /* reconnect to the HAL shmem area */ - comp_id = hal_init(comp_name); - if (comp_id < 0) { - fprintf(stderr, "halrmt: hal_init() failed after fork: %d\n", - comp_id); - exit(-1); - } - hal_ready(comp_id); - return -1; - } - if ( pid == 0 ) { - /* this is the child process - prepare to exec() the program */ - argv[0] = prog_name; - /* loop thru remaining arguments */ - n = 0; - m = 1; - while ( args[n][0] != '\0' ) { - argv[m++] = args[n++]; - } - /* add a NULL to terminate the argv array */ - argv[m] = NULL; - /* print debugging info if "very verbose" (-V) */ - rtapi_print_msg(RTAPI_MSG_DBG, "%s ", argv[0] ); - n = 1; - while ( argv[n] != NULL ) { - rtapi_print_msg(RTAPI_MSG_DBG, "%s ", argv[n++] ); - } - rtapi_print_msg(RTAPI_MSG_DBG, "\n" ); - /* call execv() to invoke the program */ - execv(prog_path, argv); - /* should never get here */ - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: execv(%s) failed: %s\n", linenumber, prog_name, - strerror(errno)); - exit(1); - } - /* this is the parent process, reconnect to the HAL shmem area */ - comp_id = hal_init(comp_name); - if (comp_id < 0) { - fprintf(stderr, "halrmt: hal_init() failed after loadusr: %d\n", - comp_id); - exit(-1); - } - hal_ready(comp_id); - if ( wait_comp_flag ) { - int ready = 0, count=0; - int next; - while(!ready) { - struct timespec ts = {0, 10 * 1000 * 1000}; // 10ms - nanosleep(&ts, NULL); - retval = waitpid( pid, &status, WNOHANG ); - if(retval != 0) goto wait_common; - - halpr_mutex_acquire(); - next = hal_data->comp_list_ptr; - while(next) { - hal_comp_t *comp = SHMPTR(next); - next = comp->next_ptr; - if(strcmp(comp->name, new_comp_name) == 0 && comp->ready) { - ready = 1; - break; - } - } - halpr_mutex_release(); - - count++; - if(count == 100) { - fprintf(stderr, "Waiting for component '%s' to become ready.", - new_comp_name); - fflush(stderr); - } else if(count > 100 && count % 10 == 0) { - fprintf(stderr, "."); - fflush(stderr); - } - } - if (count >= 100) { - fprintf(stderr, "\n"); - } - rtapi_print_msg(RTAPI_MSG_INFO, "Component '%s' ready\n", new_comp_name); - } - if ( wait_flag ) { - /* wait for child process to complete */ - retval = waitpid ( pid, &status, 0 ); - /* check result of waitpid() */ -wait_common: - if ( retval < 0 ) { - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: waitpid(%d) failed\n", linenumber, pid); - return -1; - } - if ( WIFEXITED(status) == 0 ) { - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: program '%s' did not exit normally\n", linenumber, prog_name ); - return -1; - } - if ( ignore_flag == 0 ) { - retval = WEXITSTATUS(status); - if ( retval != 0 ) { - rtapi_print_msg(RTAPI_MSG_ERR, - "HAL:%d: ERROR: program '%s' failed, returned %d\n", linenumber, prog_name, retval ); - return -1; - } - } - /* print success message */ - rtapi_print_msg(RTAPI_MSG_INFO, "Program '%s' finished\n", prog_name); - } else { - /* print success message */ - rtapi_print_msg(RTAPI_MSG_INFO, "Program '%s' started\n", prog_name); - } - return 0; -} - -static void getCompInfo(char *pattern, connectionRecType *context) -{ - int next, len; - hal_comp_t *comp; - - halpr_mutex_acquire(); - len = strlen(pattern); - next = hal_data->comp_list_ptr; - while (next != 0) { - comp = SHMPTR(next); - if (strncmp(pattern, comp->name, len) == 0) { - snprintf(context->outBuf, sizeof(context->outBuf), "COMP %s %02d %s", comp->name, comp->comp_id, (comp->type != COMPONENT_TYPE_USER) ? "RT " : "User"); - sockWrite(context); - } - next = comp->next_ptr; - } - halpr_mutex_release(); -} - - -static void getPinInfo(char *pattern, int valuesOnly, connectionRecType *context) -{ - int next, len; - hal_pin_t *pin; - hal_comp_t *comp; - hal_sig_t *sig; - void *dptr; - - halpr_mutex_acquire(); - len = strlen(pattern); - next = hal_data->pin_list_ptr; - while (next != 0) { - pin = SHMPTR(next); - if (strncmp(pattern, pin->name, len) == 0) { - comp = SHMPTR(pin->owner_ptr); - if (pin->signal != 0) { - sig = SHMPTR(pin->signal); - dptr = SHMPTR(sig->data_ptr); - } - else { - sig = NULL; - dptr = &(pin->dummysig); - } - if (valuesOnly == 0) - snprintf(context->outBuf, sizeof(context->outBuf), "PIN %s %s %02d %s %s", - pin->name, - data_value2((int) pin->type, dptr), - comp->comp_id, - data_type((int) pin->type), - pin_data_dir((int) pin->dir)); - else - snprintf(context->outBuf, sizeof(context->outBuf), "PINVAL %s %s", - pin->name, - data_value2((int) pin->type, dptr)); - sockWrite(context); - } - next = pin->next_ptr; - } - halpr_mutex_release(); -} - - -static void getSigInfo(char *pattern, int valuesOnly, connectionRecType *context) -{ - int next, len; - hal_sig_t *sig; - void *dptr; - - halpr_mutex_acquire(); - len = strlen(pattern); - next = hal_data->sig_list_ptr; - while (next != 0) { - sig = SHMPTR(next); - if (strncmp(pattern, sig->name, len) == 0) { - dptr = SHMPTR(sig->data_ptr); - if (valuesOnly == 0) - snprintf(context->outBuf, sizeof(context->outBuf), "SIGNAL %s %s %s", - sig->name, - data_value((int) sig->type, dptr), - data_type((int) sig->type)); - else - snprintf(context->outBuf, sizeof(context->outBuf), "SIGNALVAL %s %s", sig->name, data_value((int) sig->type, dptr)); - sockWrite(context); - } - next = sig->next_ptr; - } - halpr_mutex_release(); -} - -static void getParamInfo(char *pattern, int valuesOnly, connectionRecType *context) -{ - int next, len; - hal_param_t *param; - hal_comp_t *comp; - - halpr_mutex_acquire(); - len = strlen(pattern); - next = hal_data->param_list_ptr; - while (next != 0) { - param = SHMPTR(next); - if ( strncmp(pattern, param->name, len) == 0 ) { - comp = SHMPTR(param->owner_ptr); - if (valuesOnly == 0) - snprintf(context->outBuf, sizeof(context->outBuf), "PARAM %s %s %02d %s %s", - param->name, - data_value((int) param->type, SHMPTR(param->data_ptr)), - comp->comp_id, - data_type((int) param->type), - param_data_dir((int) param->dir)); - else - snprintf(context->outBuf, sizeof(context->outBuf), "PARAMVAL %s %s", - param->name, - data_value((int) param->type, SHMPTR(param->data_ptr))); - sockWrite(context); - } - next = param->next_ptr; - } - halpr_mutex_release(); -} - -static void getFunctInfo(char *pattern, connectionRecType *context) -{ - int next, len; - hal_funct_t *fptr; - hal_comp_t *comp; - - halpr_mutex_acquire(); - len = strlen(pattern); - next = hal_data->funct_list_ptr; - while (next != 0) { - fptr = SHMPTR(next); - if (strncmp(pattern, fptr->name, len) == 0) { - comp = SHMPTR(fptr->owner_ptr); - snprintf(context->outBuf, sizeof(context->outBuf), "FUNCT %s %02d %08lX %08lX %s %3d", - fptr->name, - comp->comp_id, - (unsigned long)fptr->funct, - (unsigned long)fptr->arg, - (fptr->uses_fp ? "YES" : "NO"), - fptr->users); - sockWrite(context); - } - next = fptr->next_ptr; - } - halpr_mutex_release(); -} - -static void getThreadInfo(char *pattern, connectionRecType *context) -{ - int next_thread, len, n; - hal_thread_t *tptr; - hal_list_t *list_root, *list_entry; - hal_funct_entry_t *fentry; - hal_funct_t *funct; - - halpr_mutex_acquire(); - len = strlen(pattern); - next_thread = hal_data->thread_list_ptr; - while (next_thread != 0) { - tptr = SHMPTR(next_thread); - if (strncmp(pattern, tptr->name, len) == 0) { - char name[HAL_NAME_LEN+1]; - hal_pin_t* pin; - hal_sig_t* sig; - void* dptr; - unsigned int runtime_pin_value; - - size_t ret = snprintf(name, sizeof(name), "%s.time",tptr->name); - if (ret >= sizeof(name)) { - rtapi_print_msg(RTAPI_MSG_ERR, - "unexpected: pin name too long for %s thread",tptr->name); - runtime_pin_value = 0; - } else { - pin = halpr_find_pin_by_name(name); - if (pin) { - if (pin->signal != 0) { - sig = SHMPTR(pin->signal); - dptr = SHMPTR(sig->data_ptr); - } else { - sig = NULL; - dptr = &(pin->dummysig); - } - runtime_pin_value = (int)*(int*)dptr; - } else { - runtime_pin_value = 0; - rtapi_print_msg(RTAPI_MSG_ERR, - "unexpected: cannot find time pin for %s thread",tptr->name); - } - } - - snprintf(context->outBuf, sizeof(context->outBuf), "THREAD %s %11u %s %u %u", - tptr->name, - (unsigned int)tptr->period, - (tptr->uses_fp ? "YES" : "NO "), - runtime_pin_value, - (unsigned int)hal_get_si32(tptr->maxtime)); - sockWrite(context); - list_root = &(tptr->funct_list); - list_entry = list_next(list_root); - n = 1; - while (list_entry != list_root) { - /* print the function info */ - fentry = (hal_funct_entry_t *) list_entry; - funct = SHMPTR(fentry->funct_ptr); - /* scriptmode only uses one line per thread, which contains: - thread period, FP flag, name, then all functs separated by spaces */ - snprintf(context->outBuf, sizeof(context->outBuf), "SUBTHREAD %s %2d", funct->name, n); - sockWrite(context); - n++; - list_entry = list_next(list_entry); - } - } - next_thread = tptr->next_ptr; - } - halpr_mutex_release(); -} - - -/* Switch function for pin/sig/param type for the print_*_list functions */ -static const char *data_type(int type) -{ - const char *type_str; - - switch (type) { - case HAL_BIT: - type_str = "bit "; - break; - case HAL_FLOAT: - type_str = "float"; - break; - case HAL_S32: - type_str = "s32 "; - break; - case HAL_U32: - type_str = "u32 "; - break; - default: - /* Shouldn't get here, but just in case... */ - type_str = "undef"; - } - return type_str; -} - -/* Switch function for pin direction for the print_*_list functions */ -static const char *pin_data_dir(int dir) -{ - const char *pin_dir; - - switch (dir) { - case HAL_IN: - pin_dir = "IN "; - break; - case HAL_OUT: - pin_dir = "OUT"; - break; - case HAL_IO: - pin_dir = "I/O"; - break; - default: - /* Shouldn't get here, but just in case... */ - pin_dir = "???"; - } - return pin_dir; -} - -/* Switch function for param direction for the print_*_list functions */ -static const char *param_data_dir(int dir) -{ - const char *param_dir; - - switch (dir) { - case HAL_RO: - param_dir = "RO"; - break; - case HAL_RW: - param_dir = "RW"; - break; - default: - /* Shouldn't get here, but just in case... */ - param_dir = "??"; - } - return param_dir; -} - -/* Switch function for arrow direction for the print_*_list functions */ -static const char *data_arrow1(int dir) -{ - const char *arrow; - - switch (dir) { - case HAL_IN: - arrow = "<=="; - break; - case HAL_OUT: - arrow = "==>"; - break; - case HAL_IO: - arrow = "<=>"; - break; - default: - /* Shouldn't get here, but just in case... */ - arrow = "???"; - } - return arrow; -} - -/* Switch function for arrow direction for the print_*_list functions */ -static const char *data_arrow2(int dir) -{ - const char *arrow; - - switch (dir) { - case HAL_IN: - arrow = "==>"; - break; - case HAL_OUT: - arrow = "<=="; - break; - case HAL_IO: - arrow = "<=>"; - break; - default: - /* Shouldn't get here, but just in case... */ - arrow = "???"; - } - return arrow; -} - -/* Switch function to return var value for the print_*_list functions */ -/* the value is printed in a fixed width field */ -static char *data_value(int type, void *valptr) -{ - char *value_str; - static char buf[15]; - - switch (type) { - case HAL_BIT: - if (*((char *) valptr) == 0) - value_str = " FALSE"; - else - value_str = " TRUE"; - break; - case HAL_FLOAT: - snprintf(buf, 14, "%12.7g", (double)*((hal_float_t *) valptr)); - value_str = buf; - break; - case HAL_S32: - snprintf(buf, 14, " %10ld", (long)*((hal_u32_t *) valptr)); - value_str = buf; - break; - case HAL_U32: - snprintf(buf, 14, " %08lX", (unsigned long)*((hal_u32_t *) valptr)); - value_str = buf; - break; - default: - /* Shouldn't get here, but just in case... */ - value_str = " undef "; - } - return value_str; -} - -/* Switch function to return var value in string form */ -/* the value is printed as a packed string (no whitespace */ -static char *data_value2(int type, void *valptr) -{ - char *value_str; - static char buf[15]; - - switch (type) { - case HAL_BIT: - if (*((char *) valptr) == 0) - value_str = "FALSE"; - else - value_str = "TRUE"; - break; - case HAL_FLOAT: - snprintf(buf, 14, "%.7g", (double)*((hal_float_t *) valptr)); - value_str = buf; - break; - case HAL_S32: - snprintf(buf, 14, "%ld", (long)*((hal_s32_t *) valptr)); - value_str = buf; - break; - case HAL_U32: - snprintf(buf, 14, "%lu", (unsigned long)*((hal_u32_t *) valptr)); - value_str = buf; - break; - default: - /* Shouldn't get here, but just in case... */ - value_str = "unknown_type"; - } - return value_str; -} - -static int doSave(char *type, char *filename, connectionRecType *context) -{ - FILE *dst; - const char *nakStr = "SET SAVE NAK"; - - if (rtapi_get_msg_level() == RTAPI_MSG_NONE) { - /* must be -Q, don't print anything */ - return 0; - } - if (*filename == '\0' ) - dst = stdout; - else { - dst = fopen(filename, "w" ); - if (dst == NULL) { - snprintf(errorStr, sizeof(errorStr), "HAL:%d: Can't open 'save' destination '%s'", linenumber, filename); - sockWriteError(nakStr, context); - return -1; - } - } - if (*type == '\0') - type = "all"; - if (strcmp(type, "all" ) == 0) { - /* save everything */ - save_comps(dst); - save_signals(dst); - save_links(dst, 0); - save_params(dst); - save_threads(dst); - } - else - if (strcmp(type, "comp") == 0) - save_comps(dst); - else - if (strcmp(type, "sig") == 0) - save_signals(dst); - else - if (strcmp(type, "link") == 0) - save_links(dst, 0); - else - if (strcmp(type, "linka") == 0) - save_links(dst, 1); - else - if (strcmp(type, "net") == 0) - save_nets(dst, 0); - else - if (strcmp(type, "neta") == 0) - save_nets(dst, 1); - else - if (strcmp(type, "param") == 0) - save_params(dst); - else - if (strcmp(type, "thread") == 0) - save_threads(dst); - else { - snprintf(errorStr, sizeof(errorStr), "HAL:%d: Unknown 'save' type '%s'", linenumber, type); - sockWriteError(nakStr, context); - fclose(dst); - return -1; - } - if (*filename != '\0' ) - fclose(dst); - return 0; -} - -static void save_comps(FILE *dst) -{ - int next; - hal_comp_t *comp; - - fprintf(dst, "# components\n"); - halpr_mutex_acquire(); - next = hal_data->comp_list_ptr; - while (next != 0) { - comp = SHMPTR(next); - if ( comp->type == COMPONENT_TYPE_REALTIME ) { - /* only print realtime components */ - if ( comp->insmod_args == 0 ) { - fprintf(dst, "#loadrt %s (not loaded by loadrt, no args saved)\n", comp->name); - } else { - fprintf(dst, "loadrt %s %s\n", comp->name, - (char *)SHMPTR(comp->insmod_args)); - } - } - next = comp->next_ptr; - } - halpr_mutex_release(); -} - -static void save_signals(FILE *dst) -{ - int next; - hal_sig_t *sig; - - fprintf(dst, "# signals\n"); - halpr_mutex_acquire(); - next = hal_data->sig_list_ptr; - while (next != 0) { - sig = SHMPTR(next); - fprintf(dst, "newsig %s %s\n", sig->name, data_type((int) sig->type)); - next = sig->next_ptr; - } - halpr_mutex_release(); -} - -static void save_links(FILE *dst, int arrow) -{ - int next; - hal_pin_t *pin; - hal_sig_t *sig; - const char *arrow_str; - - fprintf(dst, "# links\n"); - halpr_mutex_acquire(); - next = hal_data->pin_list_ptr; - while (next != 0) { - pin = SHMPTR(next); - if (pin->signal != 0) { - sig = SHMPTR(pin->signal); - if (arrow != 0) { - arrow_str = data_arrow1((int) pin->dir); - } else { - arrow_str = "\0"; - } - fprintf(dst, "linkps %s %s %s\n", pin->name, arrow_str, sig->name); - } - next = pin->next_ptr; - } - halpr_mutex_release(); -} - -static void save_nets(FILE *dst, int arrow) -{ - int next; - hal_pin_t *pin; - hal_sig_t *sig; - const char *arrow_str; - - fprintf(dst, "# nets\n"); - halpr_mutex_acquire(); - next = hal_data->sig_list_ptr; - while (next != 0) { - sig = SHMPTR(next); - fprintf(dst, "newsig %s %s\n", sig->name, data_type((int) sig->type)); - pin = halpr_find_pin_by_sig(sig, NULL); - while (pin != NULL) { - if (arrow != 0) { - arrow_str = data_arrow2((int) pin->dir); - } else { - arrow_str = "\0"; - } - fprintf(dst, "linksp %s %s %s\n", sig->name, arrow_str, pin->name); - pin = halpr_find_pin_by_sig(sig, pin); - } - next = sig->next_ptr; - } - halpr_mutex_release(); -} - -static void save_params(FILE *dst) -{ - int next; - hal_param_t *param; - - fprintf(dst, "# parameter values\n"); - halpr_mutex_acquire(); - next = hal_data->param_list_ptr; - while (next != 0) { - param = SHMPTR(next); - if (param->dir != HAL_RO) { - /* param is writable, save it's value */ - fprintf(dst, "setp %s %s\n", param->name, - data_value((int) param->type, SHMPTR(param->data_ptr))); - } - next = param->next_ptr; - } - halpr_mutex_release(); -} - -static void save_threads(FILE *dst) -{ - int next_thread; - hal_thread_t *tptr; - hal_list_t *list_root, *list_entry; - hal_funct_entry_t *fentry; - hal_funct_t *funct; - - fprintf(dst, "# realtime thread/function links\n"); - halpr_mutex_acquire(); - next_thread = hal_data->thread_list_ptr; - while (next_thread != 0) { - tptr = SHMPTR(next_thread); - list_root = &(tptr->funct_list); - list_entry = list_next(list_root); - while (list_entry != list_root) { - /* print the function info */ - fentry = (hal_funct_entry_t *) list_entry; - funct = SHMPTR(fentry->funct_ptr); - fprintf(dst, "addf %s %s\n", funct->name, tptr->name); - list_entry = list_next(list_entry); - } - next_thread = tptr->next_ptr; - } - halpr_mutex_release(); -} - -static int do_help_cmd(char *command) -{ - - if (strcmp(command, "help") == 0) { - printf("If you need help to use 'help', then I can't help you.\n"); - } else if (strcmp(command, "loadrt") == 0) { - printf("loadrt modname [modarg(s)]\n"); - printf(" Loads realtime HAL module 'modname', passing 'modargs'\n"); - printf(" to the module.\n"); - } else if (strcmp(command, "unloadrt") == 0) { - printf("unloadrt modname\n"); - printf(" Unloads realtime HAL module 'modname'. If 'modname'\n"); - printf(" is 'all', unloads all realtime modules.\n"); - } else if (strcmp(command, "loadusr") == 0) { - printf("loadusr [options] progname [progarg(s)]\n"); - printf(" Starts user space program 'progname', passing\n"); - printf(" 'progargs' to it. Options are:\n"); - printf(" -w wait for program to finish\n"); - printf(" -i ignore program return value (use with -w)\n"); - } else if ((strcmp(command, "linksp") == 0) || (strcmp(command,"linkps") == 0)) { - printf("linkps pinname [arrow] signame\n"); - printf("linksp signame [arrow] pinname\n"); - printf(" Links pin 'pinname' to signal 'signame'. Both forms do\n"); - printf(" the same thing. Use whichever makes sense. The optional\n"); - printf(" 'arrow' can be '==>', '<==', or '<=>' and is ignored. It\n"); - printf(" can be used in files to show the direction of data flow,\n"); - printf(" but don't use arrows on the command line.\n"); - } else if (strcmp(command, "linkpp") == 0) { - printf("linkpp firstpin secondpin\n"); - printf(" Creates a signal with the name of the first pin,\n"); printf(" then links both pins to the signal. \n"); - }else if (strcmp(command, "unlinkp") == 0) { - printf("unlinkp pinname\n"); - printf(" Unlinks pin 'pinname' if it is linked to any signal.\n"); - } else if (strcmp(command, "lock") == 0) { - printf("lock [all|tune|none]\n"); - printf(" Locks HAL to some degree.\n"); - printf(" none - no locking done.\n"); - printf(" tune - some tuning is possible (setp & such).\n"); - printf(" all - HAL completely locked.\n"); - } else if (strcmp(command, "unlock") == 0) { - printf("unlock [all|tune]\n"); - printf(" Unlocks HAL to some degree.\n"); - printf(" tune - some tuning is possible (setp & such).\n"); - printf(" all - HAL completely unlocked.\n"); - } else if (strcmp(command, "newsig") == 0) { - printf("newsig signame type\n"); - printf(" Creates a new signal called 'signame'. Type is 'bit',\n"); - printf(" 'float', 'u8', 's8', 'u16', 's16', 'u32', or 's32'.\n"); - } else if (strcmp(command, "delsig") == 0) { - printf("delsig signame\n"); - printf(" Deletes signal 'signame'. If 'signame is 'all',\n"); - printf(" deletes all signals\n"); - } else if (strcmp(command, "setp") == 0) { - printf("setp paramname value\n"); - printf("paramname = value\n"); - printf(" Sets parameter 'paramname' to 'value' (if writable).\n"); - printf(" 'setp' and '=' work the same, don't use '=' on the\n"); - printf(" command line. 'value' may be a constant such as 1.234\n"); - printf(" or TRUE, or a reference to an environment variable,\n"); -#ifdef NO_INI - printf(" using the syntax '$name'./n"); -#else - printf(" using the syntax '$name'. If option -i was given,\n"); - printf(" 'value' may also be a reference to an INI file entry\n"); - printf(" using the syntax '[section]name'.\n"); -#endif - } else if (strcmp(command, "sets") == 0) { - printf("sets signame value\n"); - printf(" Sets signal 'signame' to 'value' (if sig has no writers).\n"); - } else if (strcmp(command, "getp") == 0) { - printf("getp paramname\n"); - printf(" Gets the value of parameter 'paramname'.\n"); - } else if (strcmp(command, "gets") == 0) { - printf("gets signame\n"); - printf(" Gets the value of signal 'signame'.\n"); - } else if (strcmp(command, "addf") == 0) { - printf("addf functname threadname [position]\n"); - printf(" Adds function 'functname' to thread 'threadname'. If\n"); - printf(" 'position' is specified, adds the function to that spot\n"); - printf(" in the thread, otherwise adds it to the end. Negative\n"); - printf(" 'position' means position with respect to the end of the\n"); - printf(" thread. For example '1' is start of thread, '-1' is the\n"); - printf(" end of the thread, '-3' is third from the end.\n"); - } else if (strcmp(command, "delf") == 0) { - printf("delf functname threadname\n"); - printf(" Removes function 'functname' from thread 'threadname'.\n"); - } else if (strcmp(command, "show") == 0) { - printf("show [type] [pattern]\n"); - printf(" Prints info about HAL items of the specified type.\n"); - printf(" 'type' is 'comp', 'pin', 'sig', 'param', 'funct',\n"); - printf(" 'thread', or 'all'. If 'type' is omitted, it assumes\n"); - printf(" 'all' with no pattern. If 'pattern' is specified\n"); - printf(" it prints only those items whose names match the\n"); - printf(" pattern (no fancy regular expressions, just a simple\n"); - printf(" match: 'foo' matches 'foo', 'foobar' and 'foot' but\n"); - printf(" not 'fo' or 'frobz' or 'ffoo').\n"); - } else if (strcmp(command, "list") == 0) { - printf("list type [pattern]\n"); - printf(" Prints the names of HAL items of the specified type.\n"); - printf(" 'type' is 'comp', 'pin', 'sig', 'param', 'funct', or\n"); - printf(" 'thread'. If 'pattern' is specified it prints only\n"); - printf(" those names that match the pattern (no fancy regular\n"); - printf(" expressions, just a simple match: 'foo' matches 'foo',\n"); - printf(" 'foobar' and 'foot' but not 'fo' or 'frobz' or 'ffoo').\n"); - printf(" Names are printed on a single line, space separated.\n"); - } else if (strcmp(command, "status") == 0) { - printf("status [type]\n"); - printf(" Prints status info about HAL.\n"); - printf(" 'type' is 'lock', 'mem', or 'all'. \n"); - printf(" If 'type' is omitted, it assumes\n"); - printf(" 'all'.\n"); - } else if (strcmp(command, "save") == 0) { - printf("save [type] [filename]\n"); - printf(" Prints HAL state to 'filename' (or stdout), as a series\n"); - printf(" of HAL commands. State can later be restored by using\n"); - printf(" \"halrmt -f filename\".\n"); - printf(" Type can be 'comp', 'sig', 'link[a]', 'net[a]', 'param',\n"); - printf(" or 'thread'. ('linka' and 'neta' show arrows for pin\n"); - printf(" direction.) If 'type' is omitted or 'all', does the\n"); - printf(" equivalent of 'comp', 'sig', 'link', 'param', and 'thread'.\n"); - } else if (strcmp(command, "start") == 0) { - printf("start\n"); - printf(" Starts all realtime threads.\n"); - } else if (strcmp(command, "stop") == 0) { - printf("stop\n"); - printf(" Stops all realtime threads.\n"); - } else if (strcmp(command, "quit") == 0) { - printf("quit\n"); - printf(" Stop processing input and terminate halrmt (when\n"); - printf(" reading from a file or stdin).\n"); - } else if (strcmp(command, "exit") == 0) { - printf("exit\n"); - printf(" Stop processing input and terminate halrmt (when\n"); - printf(" reading from a file or stdin).\n"); - } else { - printf("No help for unknown command '%s'\n", command); - } - return 0; -} - -static void print_help_general(int showR) -{ - printf("\nUsage: halrmt [options] [cmd [args]]\n\n"); - printf("options:\n\n"); - printf(" -f [filename] Read commands from 'filename', not command\n"); - printf(" line. If no filename, read from stdin.\n"); -#ifndef NO_INI - printf(" -i filename Open INI file 'filename', allow commands\n"); - printf(" to get their values from INI file.\n"); -#endif - printf(" -q Quiet - print errors only (default).\n"); - printf(" -Q Very quiet - print nothing.\n"); - if (showR != 0) { - printf(" -R Release mutex (for crash recovery only).\n"); - } - printf(" -s Script friendly - don't print headers on output.\n"); - printf(" -v Verbose - print result of every command.\n"); - printf(" -V Very verbose - print lots of junk.\n"); - printf(" -h Help - print this help screen and exit.\n\n"); - printf("commands:\n\n"); - printf(" loadrt, unloadrt, loadusr, lock, unlock, linkps, linksp, linkpp,\n"); - printf(" unlinkp, newsig, delsig, setp, getp, sets, gets, addf, delf, show,\n"); - printf(" list, save, status, start, stop, quit, exit\n"); - printf(" help Lists all commands with short descriptions\n"); - printf(" help command Prints detailed help for 'command'\n\n"); -} - -static halCommandType lookupHalCommand(char *s) -{ - halCommandType i = hcEcho; - int temp; - - while (i < hcUnknown) { - if (strcmp(halCommands[i], s) == 0) return i; -// (int)i += 1; - temp = i; - temp++; - i = (halCommandType) temp; - } - return i; -} - - static int commandHello(connectionRecType *context) -{ - char *pch; -// const char *password = "EMC"; - - pch = strtok(NULL, delims); - if (pch == NULL) return -1; - if (strcmp(pch, pwd) != 0) return -1; - pch = strtok(NULL, delims); - if (pch == NULL) return -1; - rtapi_strxcpy(context->hostName, pch); - pch = strtok(NULL, delims); - if (pch == NULL) return -1; - context->linked = 1; - rtapi_strxcpy(context->version, pch); - printf("Connected to %s\n\r", context->hostName); - return 0; -} - -static cmdResponseType getEcho(char *s, connectionRecType *context) -{ - (void)s; - const char *pEchoStr = "ECHO %s"; - - if (context->echo == 1) snprintf(context->outBuf, sizeof(context->outBuf), pEchoStr, "ON"); - else snprintf(context->outBuf, sizeof(context->outBuf), pEchoStr, "OFF"); - return rtNoError; -} - -static cmdResponseType getVerbose(char *s, connectionRecType *context) -{ - (void)s; - const char *pVerboseStr = "VERBOSE %s"; - - if (context->verbose == 1) snprintf(context->outBuf, sizeof(context->outBuf), pVerboseStr, "ON"); - else snprintf(context->outBuf, sizeof(context->outBuf), pVerboseStr, "OFF"); - return rtNoError; -} - -static cmdResponseType getEnable(char *s, connectionRecType *context) -{ - (void)s; - const char *pEnableStr = "ENABLE %s"; - - if (context->cliSock == enabledConn) snprintf(context->outBuf, sizeof(context->outBuf), pEnableStr, "ON"); - else snprintf(context->outBuf, sizeof(context->outBuf), pEnableStr, "OFF"); - return rtNoError; -} - -static cmdResponseType getConfig(char *s, connectionRecType *context) -{ - (void)s; - const char *pConfigStr = "CONFIG"; - - rtapi_strxcpy(context->outBuf, pConfigStr); - return rtNoError; -} - -static cmdResponseType getCommMode(char *s, connectionRecType *context) -{ - (void)s; - const char *pCommModeStr = "COMM_MODE %s"; - - switch (context->commMode) { - case 0: snprintf(context->outBuf, sizeof(context->outBuf), pCommModeStr, "ASCII"); break; - case 1: snprintf(context->outBuf, sizeof(context->outBuf), pCommModeStr, "BINARY"); break; - } - return rtNoError; -} - -static cmdResponseType getCommProt(char *s, connectionRecType *context) -{ - (void)s; - const char *pCommProtStr = "COMM_PROT %s"; - - snprintf(context->outBuf, sizeof(context->outBuf), pCommProtStr, context->version); - return rtNoError; -} - -static cmdResponseType getComps(char *s, connectionRecType *context) -{ - if (s == NULL) - getCompInfo("", context); - else - getCompInfo(s, context); - return rtHandledNoError; -} - -static cmdResponseType getPins(char *s, connectionRecType *context) -{ - if (s == NULL) - getPinInfo("", 0, context); - else - getPinInfo(s, 0, context); - return rtHandledNoError; -} - -static cmdResponseType getPinVals(char *s, connectionRecType *context) - -{ - if (s == NULL) - getPinInfo("", 1, context); - else - getPinInfo(s, 1, context); - return rtHandledNoError; -} - -static cmdResponseType getSignals(char *s, connectionRecType *context) -{ - if (s == NULL) - getSigInfo("", 0, context); - else - getSigInfo(s, 0, context); - return rtHandledNoError; -} - -static cmdResponseType getSignalVals(char *s, connectionRecType *context) -{ - if (s == NULL) - getSigInfo("", 1, context); - else - getSigInfo(s, 1, context); - return rtHandledNoError; -} - -static cmdResponseType getParams(char *s, connectionRecType *context) -{ - if (s == NULL) - getParamInfo("", 0, context); - else - getParamInfo(s, 0, context); - return rtHandledNoError; -} - -static cmdResponseType getParamVals(char *s, connectionRecType *context) -{ - if (s == NULL) - getParamInfo("", 1, context); - else - getParamInfo(s, 1, context); - return rtHandledNoError; -} - -static cmdResponseType getFuncts(char *s, connectionRecType *context) -{ - if (s == NULL) - getFunctInfo("", context); - else - getFunctInfo(s, context); - return rtHandledNoError; -} - -static cmdResponseType getThreads(char *s, connectionRecType *context) -{ - if (s == NULL) - getThreadInfo("", context); - else - getThreadInfo(s, context); - return rtHandledNoError; -} - -static cmdResponseType getComp(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - getCompInfo(s, context); - return rtHandledNoError; -} - -static cmdResponseType getPin(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - getPinInfo(s, 0, context); - return rtHandledNoError; -} - -static cmdResponseType getPinVal(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - getPinInfo(s, 1, context); - return rtHandledNoError; -} - -static cmdResponseType getSignal(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - getSigInfo(s, 0, context); - return rtHandledNoError; -} - -static cmdResponseType getSignalVal(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - getSigInfo(s, 1, context); - return rtHandledNoError; -} - -static cmdResponseType getParam(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - getParamInfo(s, 0, context); - return rtHandledNoError; -} - -static cmdResponseType getParamVal(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - getParamInfo(s, 1, context); - return rtHandledNoError; -} - -static cmdResponseType getFunct(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - getFunctInfo(s, context); - return rtHandledNoError; -} - -static cmdResponseType getThread(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - getThreadInfo(s, context); - return rtHandledNoError; -} - -int commandGet(connectionRecType *context) -{ - static char *setNakStr = "GET NAK\r\n"; - static char *setCmdNakStr = "GET %s NAK\r\n"; - halCommandType cmd; - char *pch; - cmdResponseType ret = rtNoError; - - pch = strtok(NULL, delims); - if (pch == NULL) { - return write(context->cliSock, setNakStr, strlen(setNakStr)); - } - strupr(pch); - cmd = lookupHalCommand(pch); - switch (cmd) { - case hcEcho: ret = getEcho(pch, context); break; - case hcVerbose: ret = getVerbose(pch, context); break; - case hcEnable: ret = getEnable(pch, context); break; - case hcConfig: ret = getConfig(pch, context); break; - case hcCommMode: ret = getCommMode(pch, context); break; - case hcCommProt: ret = getCommProt(pch, context); break; - case hcComps: ret = getComps(strtok(NULL, delims), context); break; - case hcPins: ret = getPins(strtok(NULL, delims), context); break; - case hcPinVals: ret = getPinVals(pch, context); break; - case hcSigs: ret = getSignals(strtok(NULL, delims), context); break; - case hcSigVals: ret = getSignalVals(strtok(NULL, delims), context); break; - case hcParams: ret = getParams(strtok(NULL, delims), context); break; - case hcParamVals: ret = getParamVals(strtok(NULL, delims), context); break; - case hcFuncts: ret = getFuncts(strtok(NULL, delims), context); break; - case hcThreads: ret = getThreads(strtok(NULL, delims), context); break; - case hcComp: ret = getComp(strtok(NULL, delims), context); break; - case hcPin: ret = getPin(strtok(NULL, delims), context); break; - case hcPinVal: ret = getPinVal(strtok(NULL, delims), context); break; - case hcSig: ret = getSignal(strtok(NULL, delims), context); break; - case hcSigVal: ret = getSignalVal(strtok(NULL, delims), context); break; - case hcParam: ret = getParam(strtok(NULL, delims), context); break; - case hcParamVal: ret = getParamVal(strtok(NULL, delims), context); break; - case hcFunct: ret = getFunct(strtok(NULL, delims), context); break; - case hcThread: ret = getThread(strtok(NULL, delims), context); break; - case hcLoadRt: ; - case hcUnload: ; - case hcLoadUsr: ; - case hcLinkps: ; - case hcLinksp: ; - case hcLinkpp: ; - case hcNet: ; - case hcUnlinkp: ; - case hcLock: ; - case hcUnlock: ; - case hcNewSig: ; - case hcDelSig: ; - case hcSetP: ; - case hcSetS: ; - case hcAddF: ; - case hcDelF: ; - case hcSave: ; - case hcStart: ; - case hcStop: ; - case hcUnknown: ret = rtStandardError; - } - switch (ret) { - case rtNoError: // Standard ok response, just write value in buffer - sockWrite(context); - break; - case rtHandledNoError: // Custom ok response already handled, take no action - break; - case rtStandardError: // Standard error response - snprintf(context->outBuf, sizeof(context->outBuf), setCmdNakStr, pch); - sockWrite(context); - break; - case rtCustomError: // Custom error response entered in buffer - sockWrite(context); - break; - case rtCustomHandledError: ;// Custom error response handled, take no action - } - return 0; -} - -static int checkOnOff(char *s) -{ - static char *onStr = "ON"; - static char *offStr = "OFF"; - - if (s == NULL) return -1; - strupr(s); - if (strcmp(s, onStr) == 0) return 0; - if (strcmp(s, offStr) == 0) return 1; - return -1; -} - -static int checkBinaryASCII(char *s) -{ - static char *binaryStr = "BINARY"; - static char *ASCIIStr = "ASCII"; - - if (s == NULL) return -1; - strupr(s); - if (strcmp(s, ASCIIStr) == 0) return 0; - if (strcmp(s, binaryStr) == 0) return 1; - return -1; -} - -static cmdResponseType setEcho(char *s, connectionRecType *context) -{ - - switch (checkOnOff(s)) { - case -1: return rtStandardError; - case 0: context->echo = 1; break; - case 1: context->echo = 0; - } - return rtNoError; -} - -static cmdResponseType setVerbose(char *s, connectionRecType *context) -{ - - switch (checkOnOff(s)) { - case -1: return rtStandardError; - case 0: context->verbose = 1; break; - case 1: context->verbose = 0; - } - return rtNoError; -} - -static cmdResponseType setEnable(char *s, connectionRecType *context) -{ - if (strcmp(s, enablePWD) == 0) { - enabledConn = context->cliSock; - context->enabled = 1; - return rtNoError; - } - else - if (checkOnOff(s) == 1) { - context->enabled = 0; - enabledConn = -1; - return rtNoError; - } - else return rtStandardError; -} - -static cmdResponseType setConfig(char *s, connectionRecType *context) -{ - (void)s; - (void)context; - return rtNoError; -} - -static cmdResponseType setCommMode(char *s, connectionRecType *context) -{ - int ret; - - ret = checkBinaryASCII(s); - if (ret == -1) return rtStandardError; - context->commMode = ret; - return rtNoError; -} - -static cmdResponseType setCommProt(char *s, connectionRecType *context) -{ - (void)s; - char *pVersion; - - pVersion = strtok(NULL, delims); - if (pVersion == NULL) return rtStandardError; - rtapi_strxcpy(context->version, pVersion); - return rtNoError; -} - -static cmdResponseType setLoadRt(char *s, connectionRecType *context) -{ - char *pch; - char *args[MAX_TOK+3]; - int i; - - if (*s == '\0') return rtCustomHandledError; - i = 0; - pch = strtok(NULL, delims); - while (pch != NULL) { - args[i] = pch; - pch = strtok(NULL, delims); - i++; - } - args[i] = NULL; - if (doLoadRt(s, args, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setUnload(char *s, connectionRecType *context) -{ - if (doUnload(s, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setLoadUsr(char *s, connectionRecType *context) -{ - (void)context; - char *argv[MAX_TOK+1] = {NULL}; - - argv[0] = s; - argv[1] = "\0"; - if (doLoadUsr(argv) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setLinkps(char *p, char *s, connectionRecType *context) -{ - if ((p == NULL) || (s == NULL)) return rtStandardError; - if (doLink(p, s, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setLinksp(char *p, char *s, connectionRecType *context) -{ - if ((p == NULL) || (s == NULL)) return rtStandardError; - if (doLink(s, p, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setLinkpp(char *p1, char *p2, connectionRecType *context) -{ - if ((p1 == NULL) || (p2 == NULL)) return rtStandardError; - if (doLinkpp(p1, p2, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setNet(char *p1, connectionRecType *context) -{ - char *argv[MAX_TOK]; - int i; - char *pch; - - if (p1 == NULL) return rtStandardError; - i = 0; - - do { - pch = strtok(NULL, delims); - if (pch == NULL) break; - argv[i] = pch; - i++; - if (i >= MAX_TOK) return rtStandardError; // too many pins to link to the net - } while(1); - - if (i == 0) return rtStandardError; // no pins to link to the net - else - if (doNet(p1, argv, context) == 0) - return rtNoError; - else return rtCustomHandledError; -} - -static cmdResponseType setUnlink(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - if (doLink(s, "\0", context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setLock(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - if (doLock(s, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setUnlock(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - if (doUnlock(s, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setNewsig(char *s, char *t, connectionRecType *context) -{ - if ((s == NULL) || (t == NULL)) return rtStandardError; - if (doNewsig(s, t, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setDelsig(char *s, connectionRecType *context) -{ - if (s == NULL) return rtStandardError; - if (doDelsig(s, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setSetp(char *s, char *p, connectionRecType *context) -{ - if ((s == NULL) || (p == NULL)) return rtStandardError; - if (doSetp(s, p, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setSets(char *s, char *p, connectionRecType *context) -{ - if ((s == NULL) || (p == NULL)) return rtStandardError; - if (doSets(s, p, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setAddf(char *s, char *t, char *p, connectionRecType *context) -{ - if ((s == NULL) || (t == NULL)) return rtStandardError; - if (doAddf(s, t, p, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setDelf(char *s, char *t, connectionRecType *context) -{ - if ((s == NULL) || (t == NULL)) return rtStandardError; - if (doDelf(s, t, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setSave(char *type, char *fileName, connectionRecType *context) -{ - if (doSave(type, fileName, context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setStart(connectionRecType *context) -{ - if (doStart(context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -static cmdResponseType setStop(connectionRecType *context) -{ - if (doStop(context) == 0) - return rtNoError; - else - return rtCustomHandledError; -} - -#define MAX_TOKENS 5 - -int commandSet(connectionRecType *context) -{ - static char *setNakStr = "SET NAK\n\r"; - static char *setCmdNakStr = "SET %s NAK\n\r"; - static char *ackStr = "SET %s ACK\n\r"; - halCommandType cmd; - char *tokens[MAX_TOKENS]; - int i; - char *pch; - char *pcmd; - int retval = 0; - cmdResponseType ret = rtNoError; - - pcmd = strtok(NULL, delims); - if (pcmd == NULL) { - return write(context->cliSock, setNakStr, strlen(setNakStr)); - } - strupr(pcmd); - cmd = lookupHalCommand(pcmd); - if ((cmd >= hcCommProt) && (context->cliSock != enabledConn)) { - snprintf(context->outBuf, sizeof(context->outBuf), setCmdNakStr, pcmd); - return write(context->cliSock, context->outBuf, strlen(context->outBuf)); - } - pch = strtok(NULL, delims); - i = 0; - while (pch != NULL) { - tokens[i] = pch; - i++; - pch = strtok(NULL, delims); - } - switch (cmd) { - case hcEcho: ret = setEcho(tokens[0], context); break; - case hcVerbose: ret = setVerbose(tokens[0], context); break; - case hcEnable: ret = setEnable(tokens[0], context); break; - case hcConfig: ret = setConfig(tokens[0], context); break; - case hcCommMode: ret = setCommMode(tokens[0], context); break; - case hcCommProt: ret = setCommProt(tokens[0], context); break; - case hcComps: break; - case hcPins: break; - case hcPinVals: break; - case hcSigs: break; - case hcSigVals: break; - case hcParams: break; - case hcParamVals: break; - case hcFuncts: break; - case hcThreads: break; - case hcComp: break; - case hcPin: break; - case hcPinVal: break; - case hcSig: break; - case hcSigVal: break; - case hcParam: break; - case hcParamVal: break; - case hcFunct: break; - case hcThread: break; - case hcLoadRt: ret = setLoadRt(tokens[0], context); break; - case hcUnload: ret = setUnload(tokens[0], context); break; - case hcLoadUsr: ret = setLoadUsr(tokens[0], context); break; - case hcLinkps: setLinkps(tokens[0], tokens[1], context); break; - case hcLinksp: setLinksp(tokens[0], tokens[1], context); break; - case hcLinkpp: setLinkpp(tokens[0], tokens[1], context); break; - case hcNet: setNet(tokens[0], context); break; - case hcUnlinkp: setUnlink(tokens[0], context); break; - case hcLock: setLock(tokens[0], context); break; - case hcUnlock: setUnlock(tokens[0], context); break;; - case hcNewSig: setNewsig(tokens[0], tokens[1], context); break; - case hcDelSig: setDelsig(tokens[0], context); break; - case hcSetP: setSetp(tokens[0], tokens[1], context); break; - case hcSetS: setSets(tokens[0], tokens[1], context); break; - case hcAddF: setAddf(tokens[0], tokens[1], tokens[2], context); break; - case hcDelF: setDelf(tokens[0], tokens[1], context); break; - case hcSave: setSave(tokens[0], tokens[1], context); break; - case hcStart: setStart(context); break; - case hcStop: setStop(context); break; - case hcUnknown: ret = rtStandardError; - } - switch (ret) { - case rtNoError: - if (context->verbose) { - snprintf(context->outBuf, sizeof(context->outBuf), ackStr, pcmd); - retval = write(context->cliSock, context->outBuf, strlen(context->outBuf)); - } - break; - case rtHandledNoError: // Custom ok response already handled, take no action - break; - case rtStandardError: - snprintf(context->outBuf, sizeof(context->outBuf), setCmdNakStr, pcmd); - retval = write(context->cliSock, context->outBuf, strlen(context->outBuf)); - break; - case rtCustomError: // Custom error response entered in buffer - retval = write(context->cliSock, context->outBuf, strlen(context->outBuf)); - break; - case rtCustomHandledError: ;// Custom error response handled, take no action - } - return retval; -} - -int commandQuit(connectionRecType *context) -{ - printf("Closing connection with %s\n", context->hostName); - return -1; -} - -int commandShutdown(connectionRecType *context) -{ - if (context->cliSock == enabledConn) { - printf("Shutting down\n"); - hal_flag = 1; - hal_exit(comp_id); - exit(0); - return -1; - } - else - return 0; -} - -static int helpGeneral(connectionRecType *context) -{ - snprintf(context->outBuf, sizeof(context->outBuf), "Available commands:\n\r"); - rtapi_strxcat(context->outBuf, " Hello \n\r"); - rtapi_strxcat(context->outBuf, " Get \n\r"); - rtapi_strxcat(context->outBuf, " Set \n\r"); - rtapi_strxcat(context->outBuf, " Quit\n\r"); - rtapi_strxcat(context->outBuf, " Shutdown\n\r"); - rtapi_strxcat(context->outBuf, " Help \n\r"); - sockWrite(context); - return 0; -} - -static int helpHello(connectionRecType *context) -{ - snprintf(context->outBuf, sizeof(context->outBuf), "Usage:\n\r"); - rtapi_strxcat(context->outBuf, " Hello \n\rWhere:\n\r"); - rtapi_strxcat(context->outBuf, " Password is the connection password to allow communications with the CNC server.\n\r"); - rtapi_strxcat(context->outBuf, " Client Name is the name of client trying to connect, typically the network name of the client.\n\r"); - rtapi_strxcat(context->outBuf, " Protocol Version is the version of the protocol with which the client wishes to use.\n\r\n\r"); - rtapi_strxcat(context->outBuf, " With valid password, server responds with:\n\r"); - rtapi_strxcat(context->outBuf, " Hello Ack \n\rWhere:\n\r"); - rtapi_strxcat(context->outBuf, " Ack is acknowledging the connection has been made.\n\r"); - rtapi_strxcat(context->outBuf, " Server Name is the name of the EMC Server to which the client has connected.\n\r"); - rtapi_strxcat(context->outBuf, " Protocol Version is the client requested version or latest version support by server if"); - rtapi_strxcat(context->outBuf, " the client requests a version later than that supported by the server.\n\r\n\r"); - rtapi_strxcat(context->outBuf, " With invalid password, the server responds with:\n\r"); - rtapi_strxcat(context->outBuf, " Hello Nak\n\r"); - sockWrite(context); - return 0; -} - -static int helpGet(connectionRecType *context) -{ - snprintf(context->outBuf, sizeof(context->outBuf), "Usage:\n\rGet \n\r"); - rtapi_strxcat(context->outBuf, " Get commands require that a hello has been successfully negotiated.\n\r"); - rtapi_strxcat(context->outBuf, " Emc command may be one of:\n\r"); - rtapi_strxcat(context->outBuf, " Comm_mode\n\r"); - rtapi_strxcat(context->outBuf, " Comm_prot\n\r"); - rtapi_strxcat(context->outBuf, " Comp outBuf, " Comps\n\r"); - rtapi_strxcat(context->outBuf, " Echo\n\r"); - rtapi_strxcat(context->outBuf, " Enable\n\r"); - rtapi_strxcat(context->outBuf, " Funct \n\r"); - rtapi_strxcat(context->outBuf, " Functs\n\r"); - rtapi_strxcat(context->outBuf, " Param \n\r"); - rtapi_strxcat(context->outBuf, " Params\n\r"); - rtapi_strxcat(context->outBuf, " ParamVal \n\r"); - rtapi_strxcat(context->outBuf, " ParamVals\n\r"); - rtapi_strxcat(context->outBuf, " Pin \n\r"); - rtapi_strxcat(context->outBuf, " PinVal \n\r"); - rtapi_strxcat(context->outBuf, " Pins\n\r"); - rtapi_strxcat(context->outBuf, " PinVals\n\r"); - rtapi_strxcat(context->outBuf, " Signal \n\r"); - rtapi_strxcat(context->outBuf, " Signals\n\r"); - rtapi_strxcat(context->outBuf, " SigVal \n\r"); - rtapi_strxcat(context->outBuf, " SigVals\n\r"); - rtapi_strxcat(context->outBuf, " Thread \n\r"); - rtapi_strxcat(context->outBuf, " Threads\n\r"); - rtapi_strxcat(context->outBuf, " Verbose\n\r"); -// rtapi_strxcat(outBuf, "CONFIG\n\r"); - sockWrite(context); - return 0; -} - -static int helpSet(connectionRecType *context) -{ - snprintf(context->outBuf, sizeof(context->outBuf), "Usage:\n\r Set \n\r"); - rtapi_strxcat(context->outBuf, " Set commands require that a hello has been successfully negotiated,\n\r"); - rtapi_strxcat(context->outBuf, " in most instances requires that control be enabled by the connection.\n\r"); - rtapi_strxcat(context->outBuf, " The set commands not requiring control enabled are:\n\r"); - rtapi_strxcat(context->outBuf, " Comm_mode \n\r"); - rtapi_strxcat(context->outBuf, " Comm_prot \n\r"); - rtapi_strxcat(context->outBuf, " Echo \n\r"); - rtapi_strxcat(context->outBuf, " Enable \n\r"); - rtapi_strxcat(context->outBuf, " Verbose \n\r\n\r"); - rtapi_strxcat(context->outBuf, " The set commands requiring control enabled are:\n\r"); - rtapi_strxcat(context->outBuf, " Addf []\n\r"); - rtapi_strxcat(context->outBuf, " Delf \n\r"); - rtapi_strxcat(context->outBuf, " DelSig \n\r"); - rtapi_strxcat(context->outBuf, " Linkpp \n\r"); - rtapi_strxcat(context->outBuf, " Linkps \n\r"); - rtapi_strxcat(context->outBuf, " Linksp \n\r"); - rtapi_strxcat(context->outBuf, " Loadrt \n\r"); - rtapi_strxcat(context->outBuf, " Loadusr [ .. ]\n\r"); - rtapi_strxcat(context->outBuf, " Lock \n\r"); - rtapi_strxcat(context->outBuf, " Net [ .. \n\r"); - rtapi_strxcat(context->outBuf, " NewSig \n\r"); - rtapi_strxcat(context->outBuf, " Save [ []]\n\r"); - rtapi_strxcat(context->outBuf, " Setp \n\r"); - rtapi_strxcat(context->outBuf, " Sets \n\r"); - rtapi_strxcat(context->outBuf, " Start\n\r"); - rtapi_strxcat(context->outBuf, " Stop\n\r"); - rtapi_strxcat(context->outBuf, " Unlink \n\r"); - rtapi_strxcat(context->outBuf, " Unload \n\r"); - rtapi_strxcat(context->outBuf, " Unlock \n\r"); - - sockWrite(context); - return 0; -} - -static int helpQuit(connectionRecType *context) -{ - snprintf(context->outBuf, sizeof(context->outBuf), "Usage:\n\r"); - rtapi_strxcat(context->outBuf, " The quit command has the server initiate a disconnect from the client,\n\r"); - rtapi_strxcat(context->outBuf, " the command has no parameters and no requirements to have negotiated\n\r"); - rtapi_strxcat(context->outBuf, " a hello, or be in control."); - sockWrite(context); - return 0; -} - -static int helpShutdown(connectionRecType *context) -{ - snprintf(context->outBuf, sizeof(context->outBuf), "Usage:\n\r"); - rtapi_strxcat(context->outBuf, " The shutdown command terminates the connection with all clients,\n\r"); - rtapi_strxcat(context->outBuf, " and initiates a shutdown of EMC. The command has no parameters, and\n\r"); - rtapi_strxcat(context->outBuf, " can only be issued by the connection having control.\n\r"); - sockWrite(context); - return 0; -} - -static int helpHelp(connectionRecType *context) -{ - snprintf(context->outBuf, sizeof(context->outBuf), "If you need help on help, it is time to look into another line of work.\n\r"); - sockWrite(context); - return 0; -} - -int commandHelp(connectionRecType *context) -{ - char *pch; - - pch = strtok(NULL, delims); - if (pch == NULL) return (helpGeneral(context)); - strupr(pch); - printf("Command = %s", pch); - if (strcmp(pch, "HELLO") == 0) return (helpHello(context)); - if (strcmp(pch, "GET") == 0) return (helpGet(context)); - if (strcmp(pch, "SET") == 0) return (helpSet(context)); - if (strcmp(pch, "QUIT") == 0) return (helpQuit(context)); - if (strcmp(pch, "SHUTDOWN") == 0) return (helpShutdown(context)); - if (strcmp(pch, "HELP") == 0) return (helpHelp(context)); - snprintf(context->outBuf, sizeof(context->outBuf), "%s is not a valid command.", pch); - sockWrite(context); - return 0; -} - -commandTokenType lookupToken(char *s) -{ - commandTokenType i = cmdHello; - int temp; - - while (i < cmdUnknown) { - if (strcmp(commands[i], s) == 0) return i; -// (int)i += 1; - temp = i; - temp++; - i = (commandTokenType) temp; - } - return i; -} - -int parseCommand(connectionRecType *context) -{ - int ret = 0; - char *pch; - char s[64]; - static char *helloNakStr = "HELLO NAK\r\n"; - static char *helloAckStr = "HELLO ACK %s 1.1\r\n"; - static char *setNakStr = "SET NAK\r\n"; - - pch = strtok(context->inBuf, delims); - snprintf(s, sizeof(s), helloAckStr, serverName); - if (pch != NULL) { - strupr(pch); - switch (lookupToken(pch)) { - case cmdHello: - if (commandHello(context) == -1) - ret = write(context->cliSock, helloNakStr, strlen(helloNakStr)); - else - ret = write(context->cliSock, s, strlen(s)); - break; - case cmdGet: - ret = commandGet(context); - break; - case cmdSet: - if (context->linked == 0) - ret = write(context->cliSock, setNakStr, strlen(setNakStr)); - else ret = commandSet(context); - break; - case cmdQuit: - ret = commandQuit(context); - break; - case cmdShutdown: - ret = commandShutdown(context); - break; - case cmdHelp: - ret = commandHelp(context); - break; - case cmdUnknown: ret = -2; - } - } - return ret; -} - -void *readClient(void *arg) -{ - (void)arg; - char str[1600]; - char buf[1600]; - unsigned int i, j; - int len; - int ret; - connectionRecType *context; - - -// res = 1; - context = (connectionRecType *) malloc(sizeof(connectionRecType)); - if(NULL == context) { - perror("readClient():malloc"); - abort(); // There is no "clean" way. Ensure we make some noise. - } - context->cliSock = client_sockfd; - context->linked = 0; - context->echo = 1; - context->verbose = 0; - rtapi_strxcpy(context->version, "1.0"); - rtapi_strxcpy(context->hostName, "Default"); - connCount++; - context->commMode = 0; - context->commProt = 0; - context->inBuf[0] = 0; - buf[0] = 0; - - while (1) { - len = read(context->cliSock, &str, 1600); - if (len <= 0) goto finished; - str[len] = 0; - rtapi_strxcat(buf, str); - if (!memchr(str, 0x0d, strlen(str))) continue; - if ((context->echo == 1) && (context->linked == 1)) { - ret = write(context->cliSock, &buf, strlen(buf)); - if (ret < 0) { - goto finished; - } - } - i = 0; - j = 0; - while (i <= strlen(buf)) { - if ((buf[i] != '\n') && (buf[i] != '\r')) { - context->inBuf[j] = buf[i]; - j++; - } - else if (j > 0) - { - context->inBuf[j] = 0; - if (parseCommand(context) == -1) goto finished; - j = 0; - } - i++; - } - buf[0] = 0; - } - -finished: - close(context->cliSock); - free(context); - pthread_exit((void *)0); -} - -/*********************************************************************** -* MAIN PROGRAM * -************************************************************************/ - - /* main() is responsible for parsing command line options, and then - parsing either a single command from the command line or a series - of commands from a file or standard input. It breaks the command[s] - into tokens, and passes them to parse_cmd() which does the actual - work for each command. -*/ - -int sockMain() -{ - pthread_t thrd; - int res; - - while (1) { - - client_len = sizeof(client_address); - client_sockfd = accept(server_sockfd, - (struct sockaddr *)&client_address, &client_len); - if (client_sockfd < 0) exit(0); - res = pthread_create(&thrd, NULL, readClient, (void *)NULL); - if (res != 0) - close(client_sockfd); - } - return 0; -} - -int main(int argc, char **argv) -{ - int n, fd; - int errorcount; - int opt; - char *cp1, *filename = NULL; - FILE *srcfile = NULL; - - /* set default level of output - 'quiet' */ - rtapi_set_msg_level(RTAPI_MSG_ERR); - /* set default for other options */ - // process halrmt command line args - while((opt = getopt_long(argc, argv, "e:n:p:s:w:", longopts, NULL)) != -1) { - switch(opt) { - case 'e': snprintf(enablePWD, sizeof(enablePWD), "%s", optarg); break; - case 'n': snprintf(serverName, sizeof(serverName), "%s", optarg); break; - case 'p': sscanf(optarg, "%d", &port); break; - case 's': sscanf(optarg, "%d", &maxSessions); break; - case 'w': snprintf(pwd, sizeof(pwd), "%s", optarg); break; - } - } - - /* start parsing halcmd options */ - n = optind; - while ((n < argc) && (argv[n][0] == '-')) { - cp1 = argv[n++]; - /* loop to parse grouped options */ - while (*(++cp1) != '\0') { - switch (*cp1) { - case 'R': - /* force an unlock of the HAL mutex - to be used after a segfault in a hal program */ - if (release_HAL_mutex() < 0) { - printf("halrmt: Release Mutex failed!\n"); - return 1; - } - return 0; - break; - case 'h': - /* -h = help */ - if (argc > n) { /* there are more arguments, n has been incremented already */ - do_help_cmd(argv[n]); - } else - print_help_general(1); - return 0; - break; - case 'q': - /* -q = quiet (default) */ - rtapi_set_msg_level(RTAPI_MSG_ERR); - break; - case 'Q': - /* -Q = very quiet */ - rtapi_set_msg_level(RTAPI_MSG_NONE); - break; - case 's': - /* script friendly mode */ - scriptmode = 1; - break; - case 'v': - /* -v = verbose */ - rtapi_set_msg_level(RTAPI_MSG_INFO); - break; - case 'V': - /* -V = very verbose */ - rtapi_set_msg_level(RTAPI_MSG_ALL); - break; - case 'f': - /* -f = read from file (or stdin) */ - if (srcfile == NULL) { - /* it's the first -f (ignore repeats) */ - if ((n < argc) && (argv[n][0] != '-')) { - /* there is a following arg, and it's not an option */ - filename = argv[n++]; - srcfile = fopen(filename, "r"); - if (srcfile == NULL) { - fprintf(stderr, - "Could not open command file '%s'\n", - filename); - exit(-1); - } - /* make sure file is closed on exec() */ - fd = fileno(srcfile); - fcntl(fd, F_SETFD, FD_CLOEXEC); - } else { - /* no filename followed -f option, use stdin */ - srcfile = stdin; - prompt_mode = 1; - } - } - break; -#ifndef NO_INI - case 'i': - /* -i = allow reading 'setp' values from an INI file */ - if (inifile == NULL) { - /* it's the first -i (ignore repeats) */ - if ((n < argc) && (argv[n][0] != '-')) { - /* there is a following arg, and it's not an option */ - filename = argv[n++]; - inifile = fopen(filename, "r"); - if (inifile == NULL) { - fprintf(stderr, - "Could not open INI file '%s'\n", - filename); - exit(-1); - } - /* make sure file is closed on exec() */ - fd = fileno(inifile); - fcntl(fd, F_SETFD, FD_CLOEXEC); - } else { - /* no filename followed -i option, error */ - fprintf(stderr, - "No missing INI filename for -i option\n"); - exit(-1); - } - } - break; -#endif /* NO_INI */ - default: - /* unknown option */ - printf("Unknown option '-%c'\n", *cp1); - break; - } - } - } - signal(SIGINT, quit); - signal(SIGTERM, quit); - signal(SIGPIPE, SIG_IGN); - /* at this point all options are parsed, connect to HAL */ - /* create a unique module name, to allow for multiple halrmt's */ - snprintf(comp_name, HAL_NAME_LEN, "halrmt%d", getpid()); - /* tell the signal handler that we might have the mutex */ - hal_flag = 1; - /* connect to the HAL */ - comp_id = hal_init(comp_name); - /* done with mutex */ - hal_flag = 0; - /* check result */ - if (comp_id < 0) { - fprintf(stderr, "halrmt: hal_init() failed: %d\n", comp_id ); - fprintf(stderr, "NOTE: 'rtapi' kernel module must be loaded\n" ); - return 1; - } - hal_ready(comp_id); - errorcount = 0; - initSockets(); - /* HAL init is OK, let's process the command(s) */ - /* tell the signal handler we might have the mutex */ - sockMain(); - hal_flag = 1; - hal_exit(comp_id); - if ( errorcount > 0 ) { - return 1; - } else { - return 0; - } -} - diff --git a/src/hal/utils/halrmt.cc b/src/hal/utils/halrmt.cc new file mode 100644 index 00000000000..cabccb67e36 --- /dev/null +++ b/src/hal/utils/halrmt.cc @@ -0,0 +1,3089 @@ +/******************************************************************** +* Description: halrmt.cc +* Simple telnet interface to LinuxCNC HAL commands (halcmd) +* +* Derived from work by jmkasunich +* +* Other contributors: +* Alex Joni +* +* Author: Eric H. Johnson +* License: GPL Version 2 +* System: Linux +* +* Copyright (c) 2006-2008 All rights reserved. +* Copyright (c) 2026 B.Stultiens +* +* Last change: +* 2026 - Mostly rewritten +********************************************************************/ + +//****************************************************************** +// Using halrmt: see man halrmt(1) +//****************************************************************** + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "setps_util.h" + +using namespace linuxcnc; + +#define NELEM(x) (sizeof(x) / sizeof(*(x))) + +// To prevent excessive hostnames only +#define MAX_HOSTNAME_SIZE 80 + +static std::string helloPwd = "EMC"; // Connect password +static std::string enablePwd = "EMCTOO"; // Enable password +static std::string serverName = "EMCNETSVR"; // Server name written in hello response +static int port = 5006; +static std::string inifilename; +static volatile int quitloop = 0; // Signal to main loop to exit +static int quiet = 0; + +static unsigned maxSessions = 0; // Maximum number of sessions to allow + +typedef struct { + int sock; // Client socket + std::vector toks; // Tokenized command + std::string inbuf; // Input buffer, contains all data from read() + std::string outbuf; // Output buffer, contains all data to write() + std::string hostname; // Name of the client + std::string version; // Client's version + std::string inifilename; // Local ini filename for the connection + bool halfclosed; + bool linked; + bool enabled; + bool echo; // Echo input + bool verbose; // Show GET/SET xxx ACK on every command + bool timestamp; + bool timefmt; + bool expand; // Enable INI-file expansion + bool header; // Show a header with PIN{VAL}S, PARAM{VAL}S, SIGNAL{VAL}S, FUNCTS, THREADS +} connectionRecType; + +static std::vector clients; // Client connections + + +typedef enum { cmdUnknown, cmdHello, cmdSet, cmdGet, cmdQuit, cmdShutdown, cmdHelp } cmdType; + +typedef enum { + hcUnknown, + hcEcho, hcVerbose, hcEnable, hcExpand, hcHeader, + hcTime, hcTimestamp, + hcIni, hcIniFile, + hcSave, + hcPin, hcPinVal, hcPins, hcPinVals, + hcParam, hcParamVal, hcParams, hcParamVals, + hcSig, hcSigVal, hcSigs, hcSigVals, + hcComp, hcComps, + hcFunct, hcFuncts, + hcThread, hcThreads, + hcLoadRt, hcUnload, hcLoadUsr, + hcLinkPS, hcLinkSP, hcNet, hcUnlinkP, + // hcLinkPP, -- Deprecated and now no longer implemented + hcLock, hcUnlock, + hcNewSig, hcDelSig, + hcSetP, hcSetS, + hcAddF, hcDelF, + hcStart, hcStop +} subCmdType; + +typedef enum { + rtOk, + rtError +} cmdResponseType; + +typedef struct { + cmdType command; + unsigned nargs; // Minimum number of arguments + const char *name; +} commandListType; + +// Must be sorted on 'name' +static const commandListType commandList[] = { + {cmdGet, 1, "GET" }, + {cmdHello, 2, "HELLO" }, + {cmdHelp, 0, "HELP" }, + {cmdQuit, 0, "QUIT" }, + {cmdSet, 1, "SET" }, + {cmdShutdown, 0, "SHUTDOWN"}, +}; + +enum accessLevelType { + alNone, // No restrictions + alHello, // Must have issued successful HELLO + alEnable // Must have issued successful SET ENABLE +}; + +typedef struct { + subCmdType command; + const char *name; + unsigned nget; // Minimum getter arg count (token count = nget + 2) + unsigned nset; // minimum setter arg count (token count = nget + 2) + cmdResponseType (*getter)(connectionRecType &); + cmdResponseType (*setter)(connectionRecType &); + accessLevelType acclvl; // Access level + const char *gethelp; // Argument list for GET + const char *sethelp; // Argument list for SET +} getsetListType; + +static void info(const char *fmt, ...) __attribute__((format(printf, 1, 2))); +static void info(const char *fmt, ...) +{ + if(quiet > 0) + return; + va_list va; + va_start(va, fmt); + fprintf(stdout, "halrmt: "); + vfprintf(stdout, fmt, va); + fprintf(stdout, "\n"); + fflush(stdout); + va_end(va); +} + +static void error(const char *fmt, ...) __attribute__((format(printf, 1, 2))); +static void error(const char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + fprintf(stderr, "halrmt: "); + vfprintf(stderr, fmt, va); + fprintf(stderr, "\n"); + fflush(stderr); + va_end(va); +} + +static void xperror(const char *fmt, ...) __attribute__((format(printf, 1, 2))); +static void xperror(const char *fmt, ...) +{ + int en = errno; + va_list va; + va_start(va, fmt); + fprintf(stderr, "halrmt: "); + vfprintf(stderr, fmt, va); + fprintf(stderr, ": %s\n", strerror(en)); + fflush(stderr); + va_end(va); +} + +static void mysleep(double secs) +{ + struct timespec ts, rem; + ts.tv_sec = (time_t)secs; + ts.tv_nsec = 1000000000l * (secs - ts.tv_sec); +retry: + int err = nanosleep(&ts, &rem); + if(err < 0) { + if(EINTR == errno) { + ts = rem; + goto retry; + } + xperror("nanosleep"); + } +} + +static void flushall(void) +{ + // Try to write pending data to each socket + for(auto &c : clients) { + if(!c.outbuf.size()) + continue; + + ssize_t res = write(c.sock, c.outbuf.c_str(), c.outbuf.size()); + if (res < 0) { + if (errno != EINTR && errno != EAGAIN) { + xperror("flushall: client write()"); + // Make this connection to close/abort + c.halfclosed = true; + c.inbuf.clear(); + c.outbuf.clear(); + } + } else { + c.outbuf.erase(0, res); // Remove written data from buffer + } + } +} + +static void reply(connectionRecType &ctx, const std::string &s) +{ + if (ctx.timestamp) { + struct timeval tv; + gettimeofday(&tv, NULL); + if (ctx.timefmt) { + ctx.outbuf.append(fmt::format("{}.{:06d}: ", tv.tv_sec, tv.tv_usec)); + } else { + char tstr[32]; // Enough to hold 'yyyy-mm-dd hh:mm:ss.000000' + struct tm lt; + localtime_r(&tv.tv_sec, <); + strftime(tstr, sizeof(tstr), "%F %T", <); + ctx.outbuf.append(fmt::format("{}.{:06d}: ", tstr, tv.tv_usec)); + } + } + ctx.outbuf.append(s); +} + +static void replynl(connectionRecType &ctx, const std::string &s) +{ + reply(ctx, s + "\r\n"); +} + +static void errornl(connectionRecType &ctx, const std::string &s) +{ + reply(ctx, "error: " + s + "\r\n"); +} + +static void warnnl(connectionRecType &ctx, const std::string &s) +{ + reply(ctx, "warning: " + s + "\r\n"); +} + +static bool to_int(const std::string &s, int &i) +{ + try { + size_t pos; + i = std::stoi(s, &pos); + return pos == s.size(); + } catch (std::exception const &) { + return false; + } +} + + +static int compareNoCase(const std::string &a, const std::string &b) +{ + for (auto i = a.begin(), j = b.begin(); i != a.end() && j != b.end(); ++i, ++j) { + int d = std::toupper((unsigned char)*i) - std::toupper((unsigned char)*j); + if (d) + return d; // Trivial, difference in character sequence + } + // Until here, all characters are the same, but we may have broken out of + // the compare loop due to a difference in string length and both strings + // share the same prefix. + // Non-trivial compare, sizes differ on same string prefix: + // a=ABC + // b=ABC\0D + // We cannot use the difference between character ordinal because we have + // to account for embedded NUL characters. Therefore, we must use the sizes + // to determine rank. Using the difference of sizes also matches equal + // length, i.e. when the strings are equal. + return (int)((ssize_t)a.size() - (ssize_t)b.size()); +} + +// Support functions +static const char *data_type(hal_type_t type) +{ + switch (type) { + case HAL_BOOL: return "bool "; + case HAL_REAL: return "real "; + case HAL_S32: return "s32 "; + case HAL_U32: return "u32 "; + case HAL_SINT: return "sint "; + case HAL_UINT: return "uint "; + case HAL_PORT: return "port "; + default: return "undef"; // Shouldn't happen... + } +} + +/* Switch function for pin direction for the print_*_list functions */ +static const char *pin_data_dir(hal_pdir_t dir) +{ + switch (dir) { + case HAL_IN: return "IN "; + case HAL_OUT: return "OUT"; + case HAL_IO: return "I/O"; + default: return "???"; // Shouldn't happen... + } +} + +/* Switch function for param direction for the print_*_list functions */ +static const char *param_data_dir(hal_pdir_t dir) +{ + switch (dir) { + case HAL_RO: return "RO"; + case HAL_RW: return "RW"; + default: return "??"; // Shouldn't happen... + } +} + +/* Switch function for arrow direction for the print_*_list functions */ +static const char *data_arrow1(hal_pdir_t dir) +{ + switch (dir) { + case HAL_IN: return "<=="; + case HAL_OUT: return "==>"; + case HAL_IO: return "<=>"; + default: return "???"; // Shouldn't happen... + } +} + +/* Switch function for arrow direction for the print_*_list functions */ +static const char *data_arrow2(hal_pdir_t dir) +{ + switch (dir) { + case HAL_IN: return "==>"; + case HAL_OUT: return "<=="; + case HAL_IO: return "<=>"; + default: return "???"; // Shouldn't happen... + } +} + +static std::string data_value(hal_type_t type, hal_query_value_u val) +{ + switch (type) { + case HAL_BOOL: return val.b ? " TRUE" : " FALSE"; + case HAL_REAL: return fmt::format("{:12.7g}", val.r); + case HAL_PORT: // FIXME + case HAL_S32: + case HAL_SINT: return fmt::format(" {:10d}", val.s); + case HAL_U32: + case HAL_UINT: return fmt::format(" {:08X}", val.u); + default: return " undef "; + } +} + +static std::string data_value2(hal_type_t type, hal_query_value_u val) +{ + switch (type) { + case HAL_BOOL: return val.b ? "TRUE" : "FALSE"; + case HAL_REAL: return fmt::format("{:.7g}", val.r); + case HAL_PORT: // FIXME + case HAL_S32: + case HAL_SINT: return fmt::format("{}", val.s); + case HAL_U32: + case HAL_UINT: return fmt::format("{}", val.u); + default: return "unknown_type"; + } +} + +static std::optional getIniVar(connectionRecType &ctx, const std::string &var, const std::string §ion) +{ + if(ctx.inifilename.empty()) { + return std::nullopt; + } + + IniFile inifile(ctx.inifilename); + if(!inifile) { + return std::nullopt; + } + + return inifile.findString(var, section); +} + +static inline bool isEnabled(const connectionRecType &ctx) +{ + return ctx.enabled; +} + +static inline bool doDisable(connectionRecType &ctx) +{ + if (!isEnabled(ctx)) { + return false; + } + ctx.enabled = false; + info("Disabled '%s' (%d)", ctx.hostname.c_str(), ctx.sock); + return true; +} + +static inline bool doEnable(connectionRecType &ctx) +{ + if (isEnabled(ctx)) { + return false; + } + ctx.enabled = true; + info("Enabled '%s' (%d)", ctx.hostname.c_str(), ctx.sock); + return true; +} + +static inline bool doUnlink(connectionRecType &ctx) +{ + if (!ctx.linked) { + return false; + } + ctx.linked = false; + info("Unlinked '%s' (%d)", ctx.hostname.c_str(), ctx.sock); + return true; +} + +static inline bool doLink(connectionRecType &ctx) +{ + if (ctx.linked) { + return false; + } + ctx.linked = true; + info("Linked '%s' (%d)", ctx.hostname.c_str(), ctx.sock); + return true; +} + +typedef struct { + int value; + const char *keyword; +} keywordValueType; + +// Command argument keyword enum +enum { + kwOn, kwOff, + kwAll, kwLoad, kwConfig, kwParams, kwRun, kwTune, kwNone, +}; + +static int checkKeywords(const std::string &s, const keywordValueType *kv, size_t n) +{ + // Going through the list linearly is O(n), but the lists are no longer + // than 8 so binary search does not really make sense. + for (size_t i = 0; i < n; i++) { + if (!compareNoCase(kv[i].keyword, s)) + return kv[i].value; + } + return -1; +} + +static int checkOnOff(const std::string &s) +{ + static const keywordValueType kv[] = { + {kwOn, "ON" }, + {kwOff, "OFF" }, + {kwOn, "1" }, // Be tolerant + {kwOff, "0" }, + {kwOn, "TRUE" }, // Be very tolerant + {kwOff, "FALSE"}, + {kwOn, "YES" }, // Be extremely tolerant + {kwOff, "NO" }, + }; + return checkKeywords(s, kv, NELEM(kv)); +} + +static int checkLock(const std::string &s) +{ + static const keywordValueType kv[] = { + {kwAll, "ALL" }, + {kwLoad, "LOAD" }, + {kwConfig, "CONFIG"}, + {kwParams, "PARAMS"}, + {kwRun, "RUN" }, + {kwTune, "TUNE" }, + {kwNone, "NONE" }, + }; + return checkKeywords(s, kv, NELEM(kv)); +} + +static inline const char *onOff(bool b) +{ + return b ? "ON" : "OFF"; +} + +static std::string onOffString(const std::string &s, bool b) +{ + return fmt::format("{} {}", s, onOff(b)); +} + + +// Signal handler cannot call exit. +// Any exit in the signal handler would leave shared memory segments behind. +static void quitSig(int sig) +{ + (void)sig; + quitloop = 1; +} + +static pid_t halrmt_systemv_nowait(connectionRecType &ctx, const std::vector &argv) +{ + // Need program name and a NULL + if(argv.size() < 2) { + errornl(ctx, "halrmt_systemv_nowait: no program or arguments"); + return -1; + } + if(NULL != argv[argv.size()-1]) { + errornl(ctx, "halrmt_systemv_nowait: argument list not NULL terminated"); + return -1; + } + + // disconnect from the HAL shmem area before forking + hal_lib_exit(); + + int err; + pid_t pid = fork(); + switch(pid) { + case -1: // Error + err = errno; + hal_lib_init(); // Reconnect + errornl(ctx, fmt::format("halrmt_systemv_nowait: Fork failed: errno={} ({})", err, strerror(err))); + return -1; + case 0: // Child + // Restore signals to default before exec + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGPIPE, SIG_DFL); + execvp(argv[0], (char * const *)argv.data()); + fprintf(stderr, "halrmt: Child execvp(%s,...) failed: %s\n", argv[0], strerror(errno)); + _exit(1); + break; + default: // Parent + hal_lib_init(); // Reconnect + break; + } + return pid; +} + +static int halrmt_systemv(connectionRecType &ctx, const std::vector &argv) +{ + int status; + + pid_t pid = halrmt_systemv_nowait(ctx, argv); + + do { +retry_wait: + int err = waitpid(pid, &status, 0); // Wait for the child to finish + if(err < 0) { + if(EINTR == errno) { + goto retry_wait; + } + errornl(ctx, fmt::format("halrmt_systemv: waitpid({}) failed, errno={} ({})", pid, errno, strerror(errno))); + return -1; + } + } while(!WIFEXITED(status) && !WIFSIGNALED(status)); + + int rv = WEXITSTATUS(status); + if(0 != rv) { + errornl(ctx, fmt::format("{}: exit value: {}", argv[0], rv)); + return -1; + } + return 0; +} + +/*********************************************************************** +* LOCAL FUNCTION DEFINITIONS * +************************************************************************/ + +static int unloadrt_cb(hal_query_t *q, void *arg) +{ + std::vector *comps = reinterpret_cast *>(arg); + if(HAL_COMP_TYPE_REALTIME == q->comp.type) { + comps->push_back(q->name); + } + return 0; +} + +static int unloadrt_comp(connectionRecType &ctx, const std::string &mod_name) +{ + std::vector argv; + +#if defined(RTAPI_USPACE) + argv.push_back(EMC2_BIN_DIR "/rtapi_app"); + argv.push_back("unload"); +#else + argv.push_back(EMC2_BIN_DIR "/linuxcnc_module_helper"); + argv.push_back("remove"); +#endif + argv.push_back(mod_name.c_str()); + argv.push_back(NULL); + + return halrmt_systemv(ctx, argv); +} + +// +// It turns out that it is not portable to reset the state of getopt, so that a +// different argv list can be parsed. +// https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=192834 +// +// (though that thread ends with the bug being closed as fixed in lenny, it is +// not fixed or has regressed by debian jessie) +// +static void reset_getopt_state() +{ +#ifdef __GNU_LIBRARY__ + optind = 0; +#else + optind = 1; +#endif +#ifdef HAVE_OPTRESET + optreset = 1; +#endif +} + +static std::string guess_comp_name(const std::string &prog_name) +{ + std::string name; + size_t pos = prog_name.find_last_of('/'); + if(std::string::npos != pos) { + name = prog_name.substr(pos + 1); + } else { + name = prog_name; + } + pos = name.find_last_of('.'); + if(std::string::npos != pos) { + name.erase(pos); + } + return name; +} + +static int get_all_comp_names_cb(hal_query_t *q, void *arg) +{ + std::set *comps = reinterpret_cast *>(arg); + comps->insert(q->name); + return 0; +} + +static std::set get_all_comp_names() { + std::set result; + hal_query_t q = {}; + hal_list_comp(&q, get_all_comp_names_cb, &result); + return result; +} + +static void warn_newly_loaded_comps(connectionRecType &ctx, std::set &names, const std::string &newname) +{ + auto new_names = get_all_comp_names(); + for(const auto &name : new_names) { + if(name == newname) continue; + if(names.find(name) == names.end()) { + errornl(ctx, fmt::format("While waiting for '{}', component '{}' loaded.\r\n" + "Did you specify the correct name via 'loadusr -Wn'?", + newname, name)); + flushall(); + } + } + std::swap(new_names, names); +} + +// +// FIXME: The loadUsr code will stall the entire process. We need to do this +// in a coroutine style for other connections to be served. +// +static int doLoadUsr(connectionRecType &ctx, const std::vector &args) +{ + int status; + + if(args.size() < 2) { + errornl(ctx, fmt::format("LoadUsr: Not enough arguments")); + return -EINVAL; + } + if(NULL != args[args.size() - 1]) { + errornl(ctx, fmt::format("LoadUsr: Argument list not NULL terminated")); + return -EINVAL; + } + + if(hal_get_lock() & HAL_LOCK_LOAD) { + errornl(ctx, "LoadUsr: HAL is locked, loading of programs is not permitted"); + return -EPERM; + } + + int wait_flag = 0; + int wait_comp_flag = 0; + int ignore_flag = 0; + std::string new_comp_name; + + /* check for options (-w, -i, and/or -r) */ + reset_getopt_state(); + int optc; + int argc = args.size() - 1; + while (-1 != (optc = getopt(argc, (char * const *)args.data(), "+wWin:"))) { + switch(optc) { + case 'w': wait_flag = 1; break; + case 'W': wait_comp_flag = 1; break; + case 'i': ignore_flag = 1; break; + case 'n': new_comp_name = optarg; break; + default: + errornl(ctx, fmt::format("LoadUsr: Invalid option '-{}'", isprint(optc) ? optc : '?')); + return -EINVAL; + } + } + std::vector argv; + for(unsigned i = optind; i < args.size(); i++) { + argv.push_back(args[i]); + } + // Double check argument list + if(argv.size() < 2) { + errornl(ctx, fmt::format("LoadUsr: Not enough arguments for halcmd_systemv")); + return -EINVAL; + } + if(NULL != argv[argv.size() - 1]) { + errornl(ctx, fmt::format("LoadUsr: Argument list not NULL terminated for halcmd_systemv")); + return -EINVAL; + } + + // Get component name + if(new_comp_name.empty()) { + new_comp_name = guess_comp_name(argv[0]); + } + + // Component status quo + std::set comp_names_pre = get_all_comp_names(); + + // Create the new user process + pid_t pid = halrmt_systemv_nowait(ctx, argv); + if(pid < 0) { + int err = errno; + errornl(ctx, fmt::format("LoadUsr: Failed to execute '{}'", argv[0])); + return -err; + } + + bool exited = false; + int err; + if(wait_comp_flag) { + bool ready = false; + int count = 0; + int retval = 0; + while(!ready && !exited) { + mysleep(0.01); + // Program done? + errno = 0; + retval = waitpid(pid, &status, WNOHANG); + err = errno; + if (retval != 0) { + if(EINTR == err) { + continue; + } + exited = true; + ready = false; + errornl(ctx, fmt::format("LoadUsr: waitpid failed '{}' ('{}') errno={}", argv[0], new_comp_name, err)); + break; + } + if(WIFEXITED(status)) { + errornl(ctx, fmt::format("LoadUsr: program '{}' terminated with code {}", argv[0], (int)WEXITSTATUS(status))); + exited = true; + ready = false; + break; + } + /* check for program becoming ready */ + hal_query_t q = {}; + int rv = hal_comp_by_name(new_comp_name.c_str(), &q); + if(!rv && q.comp.ready) { + ready = true; + break; + } + /* pacify the user */ + count++; + if(count >= 300 && 0 == (count % 200)) { + replynl(ctx, fmt::format("\nWaiting for component '{}' to become ready.", new_comp_name)); + warn_newly_loaded_comps(ctx, comp_names_pre, new_comp_name); + flushall(); + } else if(count > 200 && count % 10 == 0) { + reply(ctx, "."); + warn_newly_loaded_comps(ctx, comp_names_pre, new_comp_name); + flushall(); + } + } + if (count > 200) { + // terminate the ... pacifier + replynl(ctx, ""); + flushall(); + } + // did it work? + if (!ready) { + if (retval < 0) { + errornl(ctx, fmt::format("LoadUsr: waitpid({}) failed errno={} ({})", pid, err, strerror(err))); + } else { + errornl(ctx, fmt::format("LoadUsr: {} exited without becoming ready", argv[0])); + } + return -err; + } + } + + if (wait_flag) { + while(!exited) { + int rv = waitpid(pid, &status, 0); + err = errno; + if (rv < 0) { + if(EINTR == err) { + continue; + } + errornl(ctx, fmt::format("LoadUsr: waitpid({}) failed, errno={} ({})", pid, err, strerror(err))); + return -err; + } + if(WIFEXITED(status)) { + // Done... + break; + } + if(WIFSIGNALED(status)) { + errornl(ctx, fmt::format("LoadUsr: program '{}' did exit on signal {}", argv[0], WTERMSIG(status))); + return -ESRCH; + } + } + if (!ignore_flag) { + int rv = WEXITSTATUS(status); + if (0 != rv) { + errornl(ctx, fmt::format("LoadUsr: program '{}' failed, returned {}", argv[0], rv)); + return -ESRCH; + } + } + } + return 0; +} + +static int doLoadRt(connectionRecType &ctx, const std::vector &args) +{ + int retval; + std::vector argv; + +#if defined(RTAPI_USPACE) + argv.push_back("-W"); + argv.push_back("-n"); + argv.push_back(args[0].c_str()); + argv.push_back(EMC2_BIN_DIR "/rtapi_app"); + argv.push_back("load"); + for(unsigned i = 0; i < args.size(); i++) { + argv.push_back(args[i].c_str()); + } + argv.push_back(NULL); + retval = doLoadUsr(ctx, argv); +#else + if (hal_get_lock() & HAL_LOCK_LOAD) { + errornl(ctx, "LoadRt: HAL is locked, loading of modules is not permitted"); + return -EPERM; + } + + // Make full module name '/.o' + std::string mod_path = fmt::format("{}/{}{}", EMC2_RTLIB_DIR, args[0], MODULE_EXT); + + // Does the module exist? + struct stat stat_buf; + if (stat(mod_path.c_str(), &stat_buf) != 0 ) { + errornl(ctx, fmt::format("LoadRt: Can't find module '{}' in '{}'", args[0], EMC2_RTLIB_DIR)); + return -ENOENT; + } + + argv.push_back(EMC2_BIN_DIR "/linuxcnc_module_helper"); + argv.push_back("insert"); + for(unsigned i = 0; i < args.size(); i++) { + argv.push_back(args[i].c_str()); + } + argv.push_back(NULL); + + retval = halrmt_systemv(ctx, argv); +#endif + + if (0 != retval) { + errornl(ctx, fmt::format("LoadRt: insmod '{}' failed, returned {}", args[0], retval)); + return retval; + } + // Join the module arguments into a single string + std::string insmod = args[0]; + for(unsigned i = 1; i < args.size(); i++) { + insmod += ' '; + insmod += args[i]; + } + // Module argument string needs to go into hal memory + char *cptr = (char *)hal_malloc(insmod.size() + 1); + if (!cptr) { + errornl(ctx, "LoadRt: Failed to allocate HAL memory"); + return -ENOMEM; + } + strcpy(cptr, insmod.c_str()); + int rv = hal_comp_insmod_args(args[0].c_str(), cptr); + if(rv) { + errornl(ctx, fmt::format("LoadRt: module '{}' not loaded", args[0])); + return -EINVAL; + } + return 0; +} + +static int getCompInfo_cb(hal_query_t *q, void *arg) +{ + connectionRecType *ctx = reinterpret_cast(arg); + const std::string *pattern = reinterpret_cast(q->callerdata.cpval); + if(pattern->empty() || !fnmatch(pattern->c_str(), q->name, FNM_NOESCAPE|FNM_CASEFOLD)) { + replynl(*ctx, fmt::format("COMP {:12s} {:3d} {}", + q->name, q->comp.comp_id, q->comp.type == HAL_COMP_TYPE_REALTIME ? "RT " : "User")); + } + return 0; +} + +static int getCompInfo(connectionRecType &ctx, const std::string &pattern) +{ + hal_query_t q = {}; + q.callerdata.cpval = &pattern; + if(ctx.header) { + replynl(ctx, fmt::format("COMP Name Id Type")); + } + return hal_list_comp(&q, getCompInfo_cb, &ctx); +} + +typedef struct { + connectionRecType *ctx; + const std::string *pattern; + int count; + bool valuesOnly; +} getXinfo_t; + +static int getPinInfo_cb(hal_query_t *q, void *arg) +{ + getXinfo_t *gpi = reinterpret_cast(arg); + if(gpi->pattern->empty() || !fnmatch(gpi->pattern->c_str(), q->name, FNM_NOESCAPE|FNM_CASEFOLD)) { + gpi->count++; + if(gpi->valuesOnly) { + replynl(*gpi->ctx, fmt::format("PINVAL {:30s} {}", + q->name, data_value2(q->pp.type, q->pp.value))); + } else { + replynl(*gpi->ctx, fmt::format("PIN {:30s} {:11s} {:12s}({:3d}) {} {}", + q->name, data_value2(q->pp.type, q->pp.value), + q->pp.comp, q->pp.comp_id, data_type(q->pp.type), pin_data_dir(q->pp.dir))); + } + } + return 0; +} + +static std::pair getPinInfo(connectionRecType &ctx, const std::string &pattern, bool valuesOnly) +{ + getXinfo_t gpi = { &ctx, &pattern, 0, valuesOnly }; + hal_query_t q = {}; + q.qtype = HAL_QTYPE_PIN; + if(ctx.header) { + if(valuesOnly) + replynl(ctx, fmt::format("PINVAL Name Value")); + else + replynl(ctx, fmt::format("PIN Name Value Component ( id) Type Dir")); + } + return {hal_list_p(&q, getPinInfo_cb, &gpi), gpi.count}; +} + +static int getSigInfo_cb(hal_query_t *q, void *arg) +{ + getXinfo_t *gpi = reinterpret_cast(arg); + if(gpi->pattern->empty() || !fnmatch(gpi->pattern->c_str(), q->name, FNM_NOESCAPE|FNM_CASEFOLD)) { + gpi->count++; + if(gpi->valuesOnly) { + replynl(*gpi->ctx, fmt::format("SIGNALVAL {:30s} {}", + q->name, data_value2(q->sig.type, q->sig.value))); + } else { + replynl(*gpi->ctx, fmt::format("SIGNAL {:30s} {:11s} {}", + q->name, data_value2(q->sig.type, q->sig.value), data_type(q->sig.type))); + } + } + return 0; +} + +static std::pair getSigInfo(connectionRecType &ctx, const std::string &pattern, bool valuesOnly) +{ + getXinfo_t gpi = { &ctx, &pattern, 0, valuesOnly }; + hal_query_t q = {}; + if(ctx.header) { + if(valuesOnly) + replynl(ctx, fmt::format("SIGNALVAL Name Value")); + else + replynl(ctx, fmt::format("SIGNAL Name Value Type")); + } + return {hal_list_s(&q, getSigInfo_cb, &gpi), gpi.count}; +} + +static int getParamInfo_cb(hal_query_t *q, void *arg) +{ + getXinfo_t *gpi = reinterpret_cast(arg); + if(gpi->pattern->empty() || !fnmatch(gpi->pattern->c_str(), q->name, FNM_NOESCAPE|FNM_CASEFOLD)) { + gpi->count++; + if(gpi->valuesOnly) { + replynl(*gpi->ctx, fmt::format("PARAMVAL {:30s} {}", + q->name, data_value2(q->pp.type, q->pp.value))); + } else { + replynl(*gpi->ctx, fmt::format("PARAM {:30s} {:11s} {:12s}({:3d}) {} {}", + q->name, data_value2(q->pp.type, q->pp.value), + q->pp.comp, q->pp.comp_id, data_type(q->pp.type), param_data_dir(q->pp.dir))); + } + } + return 0; +} + +static std::pair getParamInfo(connectionRecType &ctx, const std::string &pattern, bool valuesOnly) +{ + getXinfo_t gpi = { &ctx, &pattern, 0, valuesOnly }; + hal_query_t q = {}; + q.qtype = HAL_QTYPE_PARAM; + if(ctx.header) { + if(valuesOnly) + replynl(ctx, fmt::format("PARAMVAL Name Value")); + else + replynl(ctx, fmt::format("PARAM Name Value Component ( id) Type Dir")); + } + return {hal_list_p(&q, getParamInfo_cb, &gpi), gpi.count}; +} + +static int getFunctInfo_cb(hal_query_t *q, void *arg) +{ + connectionRecType *ctx = reinterpret_cast(arg); + const std::string *pattern = reinterpret_cast(q->callerdata.cpval); + if(pattern->empty() || !fnmatch(pattern->c_str(), q->name, FNM_NOESCAPE|FNM_CASEFOLD)) { + replynl(*ctx, fmt::format("FUNCT {:16s} {:12s}({:3d}) {:3d}", + q->name, q->funct.comp, q->funct.comp_id, q->funct.users)); + } + return 0; +} + +static int getFunctInfo(connectionRecType &ctx, const std::string &pattern) +{ + hal_query_t q = {}; + q.callerdata.cpval = reinterpret_cast(&pattern); + if(ctx.header) { + replynl(ctx, "FUNCT Name Component ( id) Users"); + } + return hal_list_funct(&q, getFunctInfo_cb, &ctx); +} + +static rtapi_sint getpin_sint(connectionRecType &ctx, const std::string &name) +{ + hal_query_t q = {}; + q.name = name.c_str(); + int rv = hal_get_p(&q, NULL, NULL); + if(0 != rv) { + errornl(ctx, fmt::format("Cannot find thread's pin '{}', error={}", name, rv)); + return 0; + } + return q.pp.value.s; +} +static int getThreadInfo_cb(hal_query_t *q, void *arg) +{ + connectionRecType *ctx = reinterpret_cast(arg); + const std::string *pattern = reinterpret_cast(q->callerdata.cpval); + if(HAL_QTYPE_THREAD == q->qtype) { + // The thread reference + if(pattern->empty() || !fnmatch(pattern->c_str(), q->name, FNM_NOESCAPE|FNM_CASEFOLD)) { + rtapi_sint tp = getpin_sint(*ctx, fmt::format("{}.time", q->name)); + rtapi_sint tm = getpin_sint(*ctx, fmt::format("{}.tmax", q->name)); + replynl(*ctx, fmt::format("THREAD {:12s} {:11d} {} {}", q->name, q->thread.period, tp, tm)); + } + } else { + // The thread's function reference + replynl(*ctx, fmt::format("THREADFUNCT {:16s} {:2d}", q->thread.funct, q->thread.functidx + 1)); + } + return 0; +} + +static int getThreadInfo(connectionRecType &ctx, const std::string &pattern) +{ + hal_query_t q = {}; + q.qtype = HAL_QTYPE_THREAD_FUNCT; + q.callerdata.cpval = reinterpret_cast(&pattern); + if(ctx.header) { + replynl(ctx, "THREAD Name Period time tmax"); + } + return hal_list_thread(&q, getThreadInfo_cb, &ctx); +} + +static int save_comps_cb(hal_query_t *q, void *arg) +{ + std::string *str = reinterpret_cast(arg); + if(strstr(q->name, HAL_PSEUDO_COMP_PREFIX) == q->name) { + // Those starting with '__' are fake components + return 0; + } + if(HAL_COMP_TYPE_REALTIME == q->comp.type) { + // Realtime components only + if(!q->comp.insmod) { + *str += fmt::format("# loadrt {} (not loaded by loadrt, no args saved)\n", q->name); + } else { + *str += fmt::format("loadrt {} {}\n", q->name, q->comp.insmod); + } + } + return 0; +} + +static void save_comps(std::string &dst) +{ + dst += "# components\n"; + hal_query_t q = {}; + hal_list_comp(&q, save_comps_cb, &dst); +} + +static int save_signals_cb(hal_query_t *q, void *arg) +{ + std::string *str = reinterpret_cast(arg); + *str += fmt::format("newsig {} {}\n", q->name, data_type(q->sig.type)); + return 0; +} + +static void save_signals(std::string &dst) +{ + dst += "# signals\n"; + hal_query_t q = {}; + hal_list_s(&q, save_signals_cb, &dst); +} + +static int save_links_cb(hal_query_t *q, void *arg) +{ + if(q->pp.signal) { + std::string *str = reinterpret_cast(arg); + const char *arrow_str = q->callerdata.sival ? data_arrow1(q->pp.dir) : ""; + *str += fmt::format("linkps {} {} {}\n", q->name, arrow_str, q->pp.signal); + } + return 0; +} + +static void save_links(std::string &dst, int arrow) +{ + dst += "# links\n"; + hal_query_t q = {}; + q.qtype = HAL_QTYPE_PIN; + q.callerdata.sival = arrow; + hal_list_p(&q, save_links_cb, &dst); +} + +static int save_nets_pins_cb(hal_query_t *q, void *arg) +{ + std::string *str = reinterpret_cast(arg); + const char *arrow_str = q->callerdata.sival ? data_arrow2(q->pp.dir) : ""; + *str += fmt::format("linksp {} {} {}\n", q->pp.signal, arrow_str, q->name); + return 0; +} + +static int save_nets_cb(hal_query_t *q, void *arg) +{ + std::string *str = reinterpret_cast(arg); + *str += fmt::format("newsig {} {}\n", q->name, data_type(q->sig.type)); + hal_query_t qp = {}; + qp.name = q->name; + qp.callerdata.sival = q->callerdata.sival; + return hal_list_p_s(&qp, save_nets_pins_cb, arg); +} +static void save_nets(std::string &dst, int arrow) +{ + dst += "# nets\n"; + hal_query_t q = {}; + q.callerdata.sival = arrow; + hal_list_s(&q, save_nets_cb, &dst); +} + +static int save_params_cb(hal_query_t *q, void *arg) +{ + std::string *str = reinterpret_cast(arg); + *str += fmt::format("setp {} {}\n", q->name, data_value(q->pp.type, q->pp.value).c_str()); + return 0; +} + +static void save_params(std::string &dst) +{ + dst += "# parameter values\n"; + hal_query_t q = {}; + q.qtype = HAL_QTYPE_PARAM; + hal_list_p(&q, save_params_cb, &dst); +} + +static int save_threads_cb(hal_query_t *q, void *arg) +{ + if(HAL_QTYPE_THREAD_FUNCT == q->qtype) { + std::string *str = reinterpret_cast(arg); + *str += fmt::format("addf {} {}\n", q->thread.funct, q->name); + } + return 0; +} + +static void save_threads(std::string &dst) +{ + dst += "# realtime thread/function links\n"; + hal_query_t q = {}; + q.qtype = HAL_QTYPE_THREAD_FUNCT; + hal_list_thread(&q, save_threads_cb, &dst); +} + +// initiate session +static int commandHello(connectionRecType &ctx) +{ + // HELLO [] + + if (ctx.toks[2].size() > MAX_HOSTNAME_SIZE) { + errornl(ctx, fmt::format("Hostname too long. Max length allowed is {}", MAX_HOSTNAME_SIZE)); + replynl(ctx, "HELLO NAK"); + return -1; + } + + // Repeating a HELLO means we disable and unlink. + // Linking needs to be reestablished + doDisable(ctx); + doUnlink(ctx); + + // On password errors, don't say too much. + if (ctx.toks[1] != helloPwd) { + replynl(ctx, "HELLO NAK"); + return -1; + } + + std::string version = "1.1"; + if (auto inistring = getIniVar(ctx, "VERSION", "EMC")) + version = *inistring; + + ctx.hostname = ctx.toks[2]; + + // ctx.version defaults to "1.1" when the context is created + if (ctx.toks.size() > 3) + ctx.version = ctx.toks[3]; + + if (ctx.version > version) { + warnnl(ctx, fmt::format("Requested version '{}' is newer than '{}' from [EMC]VERSION", ctx.version, version)); + } + + doLink(ctx); + replynl(ctx, fmt::format("HELLO ACK {} {}", serverName, version)); + return 0; +} + +int commandQuit(connectionRecType &ctx) +{ + doDisable(ctx); + ctx.halfclosed = true; + ctx.inbuf.clear(); // Zap any remaining input + info("Closing connection '%s' (%d)", ctx.hostname.c_str(), ctx.sock); + replynl(ctx, "QUIT ACK"); + return 0; +} + +int commandShutdown(connectionRecType &ctx) +{ + if (isEnabled(ctx)) { + // A shutdown will disconnect all clients from halrmt + info("Shutdown initiated by '%s' (%d)", ctx.hostname.c_str(), ctx.sock); + doDisable(ctx); + // Shutdown is not actually performed... + // It cannot work because there is no infrastructure in place to do a + // remote shutdown. + replynl(ctx, "SHUTDOWN ACK"); + return 0; + } + + errornl(ctx, "SHUTDOWN failed, not enabled"); + replynl(ctx, "SHUTDOWN NAK"); + return -1; +} + +static cmdResponseType getEcho(connectionRecType &ctx) +{ + // GET ECHO + replynl(ctx, onOffString("ECHO", ctx.echo)); + return rtOk; +} + +static cmdResponseType getVerbose(connectionRecType &ctx) +{ + // GET VERBOSE + replynl(ctx, onOffString("VERBOSE", ctx.verbose)); + return rtOk; +} + +static cmdResponseType getHeader(connectionRecType &ctx) +{ + // GET HEADER + replynl(ctx, onOffString("HEADER", ctx.header)); + return rtOk; +} + +static cmdResponseType getEnable(connectionRecType &ctx) +{ + // GET ENABLE + replynl(ctx, onOffString("ENABLE", isEnabled(ctx))); + return rtOk; +} + +static cmdResponseType getExpand(connectionRecType &ctx) +{ + // GET EXPAND + replynl(ctx, onOffString("EXPAND", ctx.expand)); + return rtOk; +} + +static cmdResponseType getComps(connectionRecType &ctx) +{ + // GET COMPS [prefix] + int rv; + if(ctx.toks.size() > 2) + rv = getCompInfo(ctx, ctx.toks[2].c_str()); + else + rv = getCompInfo(ctx, ""); + return 0 == rv ? rtOk : rtError; +} + +static cmdResponseType getPins(connectionRecType &ctx) +{ + // GET PINS [prefix] + std::pair rv; + if(ctx.toks.size() > 2) { + rv = getPinInfo(ctx, ctx.toks[2], false); + } else { + rv = getPinInfo(ctx, "", false); + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getPinVals(connectionRecType &ctx) +{ + // GET PINVALS [prefix] + std::pair rv; + if(ctx.toks.size() > 2) { + rv = getPinInfo(ctx, ctx.toks[2], true); + } else { + rv = getPinInfo(ctx, "", true); + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getSigs(connectionRecType &ctx) +{ + // GET SIGS [prefix] + std::pair rv; + if(ctx.toks.size() > 2) { + rv = getSigInfo(ctx, ctx.toks[2], false); + } else { + rv = getSigInfo(ctx, "", false); + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getSigVals(connectionRecType &ctx) +{ + // GET SIGVALS [prefix] + std::pair rv; + if(ctx.toks.size() > 2) { + rv = getSigInfo(ctx, ctx.toks[2], true); + } else { + rv = getSigInfo(ctx, "", true); + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getParams(connectionRecType &ctx) +{ + // GET PARAMS [prefix] + std::pair rv; + if(ctx.toks.size() > 2) { + rv = getParamInfo(ctx, ctx.toks[2], false); + } else { + rv = getParamInfo(ctx, "", false); + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getParamVals(connectionRecType &ctx) +{ + // GET PARAMVALS [prefix] + std::pair rv; + if(ctx.toks.size() > 2) { + rv = getParamInfo(ctx, ctx.toks[2], true); + } else { + rv = getParamInfo(ctx, "", true); + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getFuncts(connectionRecType &ctx) +{ + // GET FUNCTS [prefix] + int rv; + if(ctx.toks.size() > 2) { + rv = getFunctInfo(ctx, ctx.toks[2]); + } else { + rv = getFunctInfo(ctx, ""); + } + return 0 == rv ? rtOk : rtError; +} + +static cmdResponseType getIni(connectionRecType &ctx) +{ + // GET INI
+ auto inistring = getIniVar(ctx, ctx.toks[2], ctx.toks[3]); + if (inistring) { + replynl(ctx, fmt::format("INI [{}]{}={}", ctx.toks[3], ctx.toks[2], *inistring)); + return rtOk; + } else { + errornl(ctx, fmt::format("INI file entry '[{}]{}' not found", ctx.toks[3], ctx.toks[2])); + return rtError; + } +} + +static cmdResponseType getIniFile(connectionRecType &ctx) +{ + // GET INIFILE + replynl(ctx, fmt::format("INIFILE {}", ctx.inifilename)); + return rtOk; +} + +static cmdResponseType getThreads(connectionRecType &ctx) +{ + // GET THREADS [prefix] + int rv; + if(ctx.toks.size() > 2) { + rv = getThreadInfo(ctx, ctx.toks[2]); + } else { + rv = getThreadInfo(ctx, ""); + } + return 0 == rv ? rtOk : rtError; +} + +static cmdResponseType getComp(connectionRecType &ctx) +{ + // GET COMP + return 0 == getCompInfo(ctx, ctx.toks[2]) ? rtOk : rtError; +} + +static cmdResponseType getPin(connectionRecType &ctx) +{ + // GET PIN + std::pair rv = getPinInfo(ctx, ctx.toks[2], false); + if(0 == rv.first && 0 == rv.second) { + errornl(ctx, fmt::format("Pin '{}' not found", ctx.toks[2])); + return rtError; + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getPinVal(connectionRecType &ctx) +{ + // GET PINVAL + std::pair rv = getPinInfo(ctx, ctx.toks[2], true); + if(0 == rv.first && 0 == rv.second) { + errornl(ctx, fmt::format("Pin '{}' not found", ctx.toks[2])); + return rtError; + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getSig(connectionRecType &ctx) +{ + // GET SIGNAL + std::pair rv = getSigInfo(ctx, ctx.toks[2], false); + if(0 == rv.first && 0 == rv.second) { + errornl(ctx, fmt::format("Signal '{}' not found", ctx.toks[2])); + return rtError; + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getSigVal(connectionRecType &ctx) +{ + // GET SIGNALVAL + std::pair rv = getSigInfo(ctx, ctx.toks[2], true); + if(0 == rv.first && 0 == rv.second) { + errornl(ctx, fmt::format("Signal '{}' not found", ctx.toks[2])); + return rtError; + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getParam(connectionRecType &ctx) +{ + // GET PARAM + std::pair rv = getParamInfo(ctx, ctx.toks[2], false); + if(0 == rv.first && 0 == rv.second) { + errornl(ctx, fmt::format("Parameter '{}' not found", ctx.toks[2])); + return rtError; + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getParamVal(connectionRecType &ctx) +{ + // GET PARAMVAL + std::pair rv = getParamInfo(ctx, ctx.toks[2], true); + if(0 == rv.first && 0 == rv.second) { + errornl(ctx, fmt::format("Parameter '{}' not found", ctx.toks[2])); + return rtError; + } + return 0 == rv.first ? rtOk : rtError; +} + +static cmdResponseType getFunct(connectionRecType &ctx) +{ + // GET FUNCT + return 0 == getFunctInfo(ctx, ctx.toks[2]) ? rtOk : rtError; +} + +static cmdResponseType getThread(connectionRecType &ctx) +{ + // GET THREAD + return 0 == getThreadInfo(ctx, ctx.toks[2]) ? rtOk : rtError; +} + +static cmdResponseType getLock(connectionRecType &ctx) +{ + // GET LOCK + unsigned char lck = hal_get_lock(); + if(HAL_LOCK_NONE == lck) { + replynl(ctx, "LOCK none"); + } else if(HAL_LOCK_ALL == lck) { + replynl(ctx, "LOCK all"); + } else { +#define LOCK_ANY (HAL_LOCK_LOAD | HAL_LOCK_CONFIG | HAL_LOCK_PARAMS | HAL_LOCK_RUN) + std::string l; + if(lck & HAL_LOCK_LOAD) l += " load"; + if(lck & HAL_LOCK_CONFIG) l += " config"; + if(lck & HAL_LOCK_PARAMS) l += " params"; + if(lck & HAL_LOCK_RUN) l += " run"; + if(0 != (lck & ~LOCK_ANY)) { + l += fmt::format(" (unknown values: lock=0x{:02x})", lck); + } + replynl(ctx, fmt::format("LOCK{}", l)); +#undef LOCK_ANY + } + return rtOk; +} + +static int getNet_cb(hal_query_t *q, void *arg) +{ + connectionRecType *ctx = reinterpret_cast(arg); + replynl(*ctx, fmt::format("{} {} {}", q->pp.signal, data_arrow1(q->pp.dir), q->name)); + return 0; +} + +static cmdResponseType getNet(connectionRecType &ctx) +{ + // GET NET + hal_query_t q = {}; + q.name = ctx.toks[2].c_str(); + int rv = hal_list_p_s(&q, getNet_cb, &ctx); + if(0 == rv) { + return rtOk; + } else if(-ENOENT == rv) { + errornl(ctx, fmt::format("Signal '{}' not found", ctx.toks[2])); + return rtError; + } else { + errornl(ctx, fmt::format("Signal '{}' resulted in error={} ({})", ctx.toks[2], rv, hal_strerror(rv))); + return rtError; + } +} + +static cmdResponseType getTimestamp(connectionRecType &ctx) +{ + // GET TIMESTAMP + replynl(ctx, fmt::format("TIMESTAMP {} {}", onOff(ctx.timestamp), onOff(ctx.timefmt))); + return rtOk; +} + +static cmdResponseType getTime(connectionRecType &ctx) +{ + // GET TIME + struct timeval tv; + gettimeofday(&tv, NULL); + double t = (double)tv.tv_sec + tv.tv_usec * 1e-6; + replynl(ctx, fmt::format("TIME {}", t)); + return rtOk; +} + +static cmdResponseType setEcho(connectionRecType &ctx) +{ + // SET ECHO + switch (checkOnOff(ctx.toks[2])) { + default: errornl(ctx, fmt::format("Invalid argument '{}', must be {{on,off}}", ctx.toks[2])); return rtError; + case kwOn: ctx.echo = true; break; + case kwOff: ctx.echo = false; break; + } + return rtOk; +} + +static cmdResponseType setVerbose(connectionRecType &ctx) +{ + // SET VERBOSE + switch (checkOnOff(ctx.toks[2])) { + default: errornl(ctx, fmt::format("Invalid argument '{}', must be {{on,off}}", ctx.toks[2])); return rtError; + case kwOn: ctx.verbose = true; break; + case kwOff: ctx.verbose = false; break; + } + return rtOk; +} + +static cmdResponseType setHeader(connectionRecType &ctx) +{ + // SET HEADER + switch (checkOnOff(ctx.toks[2])) { + default: errornl(ctx, fmt::format("Invalid argument '{}', must be {{on,off}}", ctx.toks[2])); return rtError; + case kwOn: ctx.header = true; break; + case kwOff: ctx.header = false; break; + } + return rtOk; +} + +static cmdResponseType setEnable(connectionRecType &ctx) +{ + // SET ENABLE + if (ctx.toks[2] == enablePwd) { + doEnable(ctx); + return rtOk; + } + + if (!compareNoCase(ctx.toks[2], "OFF")) { + if (!isEnabled(ctx)) { + errornl(ctx, "Trying to set enable to off on a non-enabled link"); + return rtError; + } + doDisable(ctx); + return rtOk; + } + return rtError; +} + +static cmdResponseType setExpand(connectionRecType &ctx) +{ + // SET EXPAND + switch (checkOnOff(ctx.toks[2])) { + default: errornl(ctx, fmt::format("Invalid argument '{}', must be {{on,off}}", ctx.toks[2])); return rtError; + case kwOn: ctx.expand = true; break; + case kwOff: ctx.expand = false; break; + } + return rtOk; +} + +static cmdResponseType setLoadRt(connectionRecType &ctx) +{ + // SET LOADRT [args...] + if(REALTIME_TYPE_UNINITIALIZED == hal_get_realtime_type()) { + errornl(ctx, "Realtime has not been initialized."); + return rtError; + } + + std::vector args; + + for(unsigned i = 2; i < ctx.toks.size(); i++) { + args.push_back(ctx.toks[i]); + } + int rv = doLoadRt(ctx, args); + return 0 == rv ? rtOk : rtError; +} + +static cmdResponseType setUnload(connectionRecType &ctx) +{ + // SET UNLOAD |all + if(REALTIME_TYPE_UNINITIALIZED == hal_get_realtime_type()) { + errornl(ctx, "Realtime has not been initialized."); + return rtError; + } + + std::vector comps; + + if("all" == ctx.toks[2]) { + // Unload all components + // Gather all RT components + hal_query_t q = {}; + int rv = hal_list_comp(&q, unloadrt_cb, &comps); + if(0 != rv) { + errornl(ctx, fmt::format("Failed to gather component list, error={} ({})", + ctx.toks[2], rv, hal_strerror(rv))); + return rtError; + } + } else { + // Unload one specific component + hal_query_t q = {}; + int rv = hal_comp_by_name(ctx.toks[2].c_str(), &q); + if(0 != rv) { + errornl(ctx, fmt::format("Component '{}' is not loaded, error={} ({})", + ctx.toks[2], rv, hal_strerror(rv))); + return rtError; + } + if(HAL_COMP_TYPE_REALTIME != q.comp.type) { + errornl(ctx, fmt::format("Component '{}' is not a real-time component", ctx.toks[2])); + return rtError; + } + comps.push_back(ctx.toks[2]); + } + + // Now unload the lot + for(const auto &comp : comps) { + int rv = unloadrt_comp(ctx, comp); + if(0 != rv) { + errornl(ctx, fmt::format("Component '{}' failed to unload, error={} ({})", + ctx.toks[2], rv, hal_strerror(rv))); + return rtError; + } + } + return rtOk; +} + +static cmdResponseType setLoadUsr(connectionRecType &ctx) +{ + // SET LOADUSR [arg [arg...]] + std::vector argv; + for(unsigned i = 2; i < ctx.toks.size(); i++) { + argv.push_back(ctx.toks[i].c_str()); + } + argv.push_back(NULL); + int rv = doLoadUsr(ctx, argv); + return 0 == rv ? rtOk : rtError; +} + +static cmdResponseType linkPS(connectionRecType &ctx, const std::string &pin, const std::string &sig) +{ + if(sig.empty()) { + int rv = hal_unlink(pin.c_str()); + if(0 != rv) { + errornl(ctx, fmt::format("Failed to unlink '{}'", pin)); + return rtError; + } + } else { + int rv = hal_link(pin.c_str(), sig.c_str()); + if(0 != rv) { + errornl(ctx, fmt::format("Failed to link pin '{}' to signal '{}'", pin, sig)); + return rtError; + } + } + return rtOk; +} + +static cmdResponseType setLinkPS(connectionRecType &ctx) +{ + // SET LINKPS [] + if(ctx.toks.size() > 3) + return linkPS(ctx, ctx.toks[2], ctx.toks[3]); + else + return linkPS(ctx, ctx.toks[2], ""); +} + +static cmdResponseType setLinkSP(connectionRecType &ctx) +{ + // SET LINKSP + return linkPS(ctx, ctx.toks[3], ctx.toks[2]); +} + +#if 0 +// This has been deprecated in halcmd for quite some time. +// No need to continue it. +static cmdResponseType setLinkPP(connectionRecType &ctx) +{ + // SET LINKPP + hal_query_t p1 = {}; + hal_query_t p2 = {}; + p1.qtype = HAL_QTYPE_PIN; + p1.name = ctx.toks[2].c_str(); + p2.qtype = HAL_QTYPE_PIN; + p2.name = ctx.toks[3].c_str(); + int pin1 = hal_getref_p(&p1); + int pin2 = hal_getref_p(&p2); + // Check if both pins exist + if (0 != pin1 || 0 != pin2) { + errornl(ctx, fmt::format("Pin '{}' not found", 0 != pin1 ? ctx.toks[2] : ctx.toks[3])); + return rtError; + } + + // Check that both pins have the same type + if (p1.pp.type != p2.pp.type) { + errornl(ctx, fmt::format("Pins '{}' and '{}' are not of same type ({} != {})", + ctx.toks[2], ctx.toks[3], (int)p1.pp.type, (int)p2.pp.type)); + return rtError; + } + + // Create the signal + int rv = hal_signal_new(ctx.toks[2].c_str(), p1.pp.type); + + if (0 == rv) { + // Link pin 1 to signal + rv = hal_link(ctx.toks[2].c_str(), ctx.toks[2].c_str()); + + if (0 == rv) { + // Link pin 2 to signal + rv = hal_link(ctx.toks[2].c_str(), ctx.toks[2].c_str()); + if(0 != rv) { + errornl(ctx, fmt::format("Failed to link pin '{}' to signal '{}'", ctx.toks[3], ctx.toks[2])); + return rtError; + } + } else { + errornl(ctx, fmt::format("Failed to link pin '{}' to signal '{}'", ctx.toks[2], ctx.toks[2])); + return rtError; + } + } else { + errornl(ctx, fmt::format("Failed to create signal '{}'", ctx.toks[2])); + return rtError; + } + return rtOk; +} +#endif + +static cmdResponseType setNet(connectionRecType &ctx) +{ + // SET NET [pin [..]] + + hal_query_t qs = {}; + qs.name = ctx.toks[2].c_str(); + int havesig = hal_getref_s(&qs); + if(0 != havesig && -ENOENT != havesig) { + errornl(ctx, fmt::format("Failed to retrieve signal info for '{}' error={} ({})", + ctx.toks[2], havesig, hal_strerror(havesig))); + return rtError; + } + + // The type of the signal (to be) + hal_type_t ts = 0 == havesig ? qs.sig.type : HAL_TYPE_UNINITIALIZED; + + for(unsigned i = 3; i < ctx.toks.size(); i++) { + hal_query_t qp = {}; + qp.qtype = HAL_QTYPE_PIN; + qp.name = ctx.toks[i].c_str(); + int rv = hal_getref_p(&qp); + if(0 != rv) { + errornl(ctx, fmt::format("Failed to retrieve pin info for '{}', error={} ({})", + ctx.toks[i], rv, hal_strerror(rv))); + return rtError; + } + if(HAL_TYPE_UNINITIALIZED == ts) { + ts = qp.pp.type; + } else if(ts != qp.pp.type) { + errornl(ctx, fmt::format("Type mismatch {} != {} ({}!={})", + data_type(ts), data_type(qp.pp.type), (int)ts, (int)qp.pp.type)); + return rtError; + } + if(HAL_OUT == qp.pp.dir && (qs.sig.writers > 0 || qs.sig.bidirs > 0)) { + if(qs.sig.writers > 0) + errornl(ctx, fmt::format("Cannot add OUT pin '{}', signal '{}' already has a writer", qp.name, qs.name)); + else + errornl(ctx, fmt::format("Cannot add OUT pin '{}', signal '{}' already has bidirs", qp.name, qs.name)); + return rtError; + } else if(HAL_IO == qp.pp.dir) { + qs.sig.bidirs++; + if(qs.sig.writers > 0) { + errornl(ctx, fmt::format("Cannot add IO pin '{}', signal '{}' already has a writer", qp.name, qs.name)); + return rtError; + } + } + } + + // Create the signal if it does not yet exist + if(-ENOENT == havesig) { + hal_query_t qp = {}; + qp.name = ctx.toks[2].c_str(); + int rv = hal_getref_p(&qp); + if(0 == rv) { + errornl(ctx, fmt::format("Signal name '{}' is already in use as a {} name", + ctx.toks[2], HAL_QTYPE_PIN == qp.qtype ? "pin" : "param")); + return rtError; + } + if(0 != (rv = hal_signal_new(ctx.toks[2].c_str(), ts))) { + errornl(ctx, fmt::format("Failed to create signal '{}', error={}", ctx.toks[2], rv)); + return rtError; + } + } + + // Link up all the pins + for(unsigned i = 3; i < ctx.toks.size(); i++) { + int rv = hal_link(ctx.toks[i].c_str(), ctx.toks[2].c_str()); + if(0 != rv) { + errornl(ctx, fmt::format("Failed to add pin '{}' to signal '{}', error={}", ctx.toks[i], ctx.toks[2], rv)); + return rtError; + } + } + return rtOk; +} + +static cmdResponseType setUnlinkP(connectionRecType &ctx) +{ + // SET UNLINK + return linkPS(ctx, ctx.toks[2], ""); +} + +static cmdResponseType setLock(connectionRecType &ctx) +{ + // SET LOCK {all|load|config|params|run|tune|none} + int lck; + if((lck = checkLock(ctx.toks[2].c_str())) < 0) { + errornl(ctx, fmt::format("Invalid lock argument '{}'", ctx.toks[2])); + return rtError; + } + unsigned char old = hal_get_lock(); + int rv; + switch(lck) { + case kwAll: rv = hal_set_lock(HAL_LOCK_ALL); break; + case kwLoad: rv = hal_set_lock(old | HAL_LOCK_LOAD); break; + case kwConfig: rv = hal_set_lock(old | HAL_LOCK_CONFIG); break; + case kwParams: rv = hal_set_lock(old | HAL_LOCK_PARAMS); break; + case kwRun: rv = hal_set_lock(old | HAL_LOCK_RUN); break; + case kwTune: rv = hal_set_lock(HAL_LOCK_TUNE); break; + case kwNone: rv = hal_set_lock(HAL_LOCK_NONE); break; + default: + errornl(ctx, fmt::format("internal: Invalid lock key '{}'", lck)); + return rtError; + } + return 0 == rv ? rtOk : rtError; +} + +static cmdResponseType setUnlock(connectionRecType &ctx) +{ + // SET UNLOCK {all|load|config|params|run|tune|none} + int lck; + if((lck = checkLock(ctx.toks[2].c_str())) < 0) { + errornl(ctx, fmt::format("Invalid lock argument '{}'", ctx.toks[2])); + return rtError; + } + unsigned char old = hal_get_lock(); + int rv; + switch(lck) { + case kwAll: rv = hal_set_lock(HAL_LOCK_NONE); break; + case kwLoad: rv = hal_set_lock(old & ~HAL_LOCK_LOAD); break; + case kwConfig: rv = hal_set_lock(old & ~HAL_LOCK_CONFIG); break; + case kwParams: rv = hal_set_lock(old & ~HAL_LOCK_PARAMS); break; + case kwRun: rv = hal_set_lock(old & ~HAL_LOCK_RUN); break; + case kwTune: rv = hal_set_lock(old & ~HAL_LOCK_TUNE); break; + case kwNone: rv = 0; break; + default: + errornl(ctx, fmt::format("internal: Invalid lock key '{}'", lck)); + return rtError; + } + return 0 == rv ? rtOk : rtError; +} + +static hal_type_t haltype_from_str(const std::string &str) +{ + static const struct { + const char *name; + hal_type_t type; + } types[] = { + { "bit", HAL_BOOL }, + { "bool", HAL_BOOL }, + { "float", HAL_REAL }, + { "real", HAL_REAL }, + { "s32", HAL_S32 }, + { "s64", HAL_SINT }, + { "sint", HAL_SINT }, + { "u32", HAL_U32 }, + { "u64", HAL_UINT }, + { "uint", HAL_UINT }, + }; + for(unsigned i = 0; i < NELEM(types); i++) { + if(str == types[i].name) + return types[i].type; + } + return HAL_TYPE_UNSPECIFIED; +} + +static cmdResponseType setNewSig(connectionRecType &ctx) +{ + // SET NEWSIG + hal_type_t type = haltype_from_str(ctx.toks[3]); + if(type <= 0) { + errornl(ctx, fmt::format("Invalid type '{}'", ctx.toks[3])); + return rtError; + } + int rv = hal_signal_new(ctx.toks[2].c_str(), type); + if(0 != rv) { + errornl(ctx, fmt::format("Cannot create signal '{}' with type '{}', error={}", ctx.toks[2], ctx.toks[3], rv)); + return rtError; + } + return rtOk; +} + +static int setDelSig_cb(hal_query_t *q, void *arg) +{ + std::vector *sigs = reinterpret_cast *>(arg); + sigs->push_back(q->name); + return 0; +} + +static cmdResponseType setDelSig(connectionRecType &ctx) +{ + // SET DELSIG + if(ctx.toks[2] == "all") { + std::vector sigs; + hal_query_t q = {}; + int rv = hal_list_s(&q, setDelSig_cb, &sigs); + if(0 != rv) { + errornl(ctx, fmt::format("Failed to gather all signal names, error={}", rv)); + return rtError; + } + bool fail = false; + for(const auto &sig : sigs) { + rv = hal_signal_delete(sig.c_str()); + if(0 != rv) { + errornl(ctx, fmt::format("Cannot delete signal '{}', error={}", sig, rv)); + fail = true; + } + } + if(fail) { + return rtError; + } + } else { + int rv = hal_signal_delete(ctx.toks[2].c_str()); + if(0 != rv) { + errornl(ctx, fmt::format("Cannot delete signal '{}', error={}", ctx.toks[2], rv)); + return rtError; + } + } + return rtOk; +} + +static cmdResponseType setSetP(connectionRecType &ctx) +{ + // SET SETP + hal_query_t query = {}; + query.name = ctx.toks[2].c_str(); + int rv = hal_set_p(&query, setps_common_cb, ctx.toks[3].data()); + if(0 != rv) { + errornl(ctx, fmt::format("Cannot setp '{}' to '{}', error={}", ctx.toks[2], ctx.toks[3], rv)); + return rtError; + } + return rtOk; +} + +static cmdResponseType setSetS(connectionRecType &ctx) +{ + // SET SETS + hal_query_t query = {}; + query.name = ctx.toks[2].c_str(); + int rv = hal_set_s(&query, setps_common_cb, ctx.toks[3].data()); + if(0 != rv) { + errornl(ctx, fmt::format("Cannot sets '{}' to '{}', error={}", ctx.toks[2], ctx.toks[3], rv)); + return rtError; + } + return rtOk; +} + +static cmdResponseType setAddf(connectionRecType &ctx) +{ + // SET ADDF [arg] + int cl = -1; + if (ctx.toks.size() > 4 && !to_int(ctx.toks[4], cl)) { + errornl(ctx, fmt::format("Invalid argument '{}', must be integer", ctx.toks[4])); + return rtError; + } + if(cl < -1) { + errornl(ctx, fmt::format("Invalid argument '{}', must be >= -1", ctx.toks[4])); + return rtError; + } + int rv = hal_add_funct_to_thread(ctx.toks[2].c_str(), ctx.toks[3].c_str(), cl); + if(0 != rv) { + errornl(ctx, fmt::format("Failed to add fucntion '{}' to thread '{}', error={}", ctx.toks[2], ctx.toks[3], rv)); + return rtError; + } + return rtOk; +} + +static cmdResponseType setDelF(connectionRecType &ctx) +{ + // SET DELF + int rv = hal_del_funct_from_thread(ctx.toks[2].c_str(), ctx.toks[3].c_str()); + if(0 != rv) { + errornl(ctx, fmt::format("Failed to remove function '{}' from thread '{}'", ctx.toks[2], ctx.toks[3])); + return rtError; + } + return rtOk; +} + +static cmdResponseType setSave(connectionRecType &ctx) +{ + // SET SAVE {all,comp,sig,link,linka,net,neta,param,thread} [filename] + static std::set keys = {"all","comp","sig","link","linka","net","neta","param","thread"}; + + if(keys.end() == keys.find(ctx.toks[2])) { + errornl(ctx, fmt::format("Invalid save type '{}'", ctx.toks[2])); + return rtError; + } + std::string out; + if("all" == ctx.toks[2]) { + save_comps(out); + save_signals(out); + save_links(out, 0); + save_params(out); + save_threads(out); + } else if("comp" == ctx.toks[2]) { + save_comps(out); + } else if("sig" == ctx.toks[2]) { + save_signals(out); + } else if("link" == ctx.toks[2]) { + save_links(out, 0); + } else if("linka" == ctx.toks[2]) { + save_links(out, 1); + } else if("net" == ctx.toks[2]) { + save_nets(out, 0); + } else if("neta" == ctx.toks[2]) { + save_nets(out, 1); + } else if("param" == ctx.toks[2]) { + save_params(out); + } else if("thread" == ctx.toks[2]) { + save_threads(out); + } else { + errornl(ctx, fmt::format("internal: failed to match key '{}'", ctx.toks[2])); + return rtError; + } + if(ctx.toks.size() > 3) { + // Filename was specified + int fd = creat(ctx.toks[3].c_str(), 0644); + if(!fd) { + errornl(ctx, fmt::format("Cannot open '{}' for write ({})", ctx.toks[2], strerror(errno))); + return rtError; + } + size_t done = 0; + while(done < out.size()) { + ssize_t err = write(fd, out.c_str() + done, out.size() - done); + int e = errno; + if(err < 0) { + if(EINTR == e) + continue; + close(fd); + errornl(ctx, fmt::format("Write to '{}' failed written={} != size={} errno={} ({})", + ctx.toks[2], done, out.size(), e, strerror(e))); + return rtError; + } + done += err; + } + close(fd); + } else { + replynl(ctx, out); + } + return rtOk; +} + +static cmdResponseType setStart(connectionRecType &ctx) +{ + // SET START + if(REALTIME_TYPE_UNINITIALIZED == hal_get_realtime_type()) { + errornl(ctx, "Realtime has not been initialized."); + return rtError; + } + + int rv = hal_start_threads(); + if (rv != 0) { + errornl(ctx, fmt::format("Failed to start realtime threads, error={}", rv)); + } + return 0 == rv ? rtOk : rtError; +} + +static cmdResponseType setStop(connectionRecType &ctx) +{ + // SET STOP + if(REALTIME_TYPE_UNINITIALIZED == hal_get_realtime_type()) { + errornl(ctx, "Realtime has not been initialized."); + return rtError; + } + + int rv = hal_stop_threads(); + if (rv != 0) { + errornl(ctx, fmt::format("Unable to stop realtime threads, error={}", rv)); + } + return 0 == rv ? rtOk : rtError; +} + +static cmdResponseType setTimestamp(connectionRecType &ctx) +{ + // SET TIMESTAMP [ON|OFF] + switch (checkOnOff(ctx.toks[2])) { + default: errornl(ctx, fmt::format("Invalid argument '{}', must be {{on,off}}", ctx.toks[2])); return rtError; + case kwOn: ctx.timestamp = true; break; + case kwOff: ctx.timestamp = false; break; + } + + ctx.timefmt = ctx.toks.size() > 3 && kwOn == checkOnOff(ctx.toks[3]); + return rtOk; +} + +static cmdResponseType setIniFile(connectionRecType &ctx) +{ + // SET INIFILE + IniFile ini(ctx.toks[2]); // Try to open and parse + if(!ini) { + errornl(ctx, fmt::format("Invalid INI-file '{}'", ctx.toks[2])); + return rtError; + } + ctx.inifilename = ctx.toks[2]; + return rtOk; +} + +static cmdResponseType gsNotImpl(connectionRecType &) +{ + return rtError; +} + +static const getsetListType getsetList[] = { + { hcAddF, "ADDF", 0, 2, gsNotImpl, setAddf, alEnable, "", " [order]" }, + { hcComp, "COMP", 1, 0, getComp, gsNotImpl, alEnable, "", "" }, + { hcComps, "COMPS", 0, 0, getComps, gsNotImpl, alEnable, "[pattern]", "" }, + { hcDelF, "DELF", 0, 2, gsNotImpl, setDelF, alEnable, "", " " }, + { hcDelSig, "DELSIG", 0, 1, gsNotImpl, setDelSig, alEnable, "", "" }, + { hcEcho, "ECHO", 0, 1, getEcho, setEcho, alNone, "", "{on|off}" }, + { hcEnable, "ENABLE", 0, 1, getEnable, setEnable, alHello, "", "|{off}" }, + { hcExpand, "EXPAND", 0, 1, getExpand, setExpand, alHello, "", "{on|off}" }, + { hcFunct, "FUNCT", 1, 0, getFunct, gsNotImpl, alEnable, "", "" }, + { hcFuncts, "FUNCTS", 0, 0, getFuncts, gsNotImpl, alEnable, "[pattern]", "" }, + { hcHeader, "HEADER", 0, 1, getHeader, setHeader, alNone, "", "{on|off}" }, + { hcIni, "INI", 2, 0, getIni, gsNotImpl, alHello, "
", "" }, + { hcIniFile, "INIFILE", 0, 1, getIniFile, setIniFile, alHello, "", "" }, +// { hcLinkPP, "LINKPP", 0, 2, gsNotImpl, setLinkPP, alEnable, "", " " }, + { hcLinkPS, "LINKPS", 0, 1, gsNotImpl, setLinkPS, alEnable, "", " []" }, + { hcLinkSP, "LINKSP", 0, 2, gsNotImpl, setLinkSP, alEnable, "", " " }, + { hcLoadRt, "LOADRT", 0, 1, gsNotImpl, setLoadRt, alEnable, "", "" }, + { hcLock, "LOCK", 0, 1, getLock, setLock, alEnable, "", "{all|load|config|params|run|tune|none}" }, + { hcNet, "NET", 1, 2, getNet, setNet, alHello, "", " [pin [...]]" }, + { hcNewSig, "NEWSIG", 0, 2, gsNotImpl, setNewSig, alEnable, "", " " }, + { hcParam, "PARAM", 1, 0, getParam, gsNotImpl, alEnable, "", "" }, + { hcParams, "PARAMS", 0, 0, getParams, gsNotImpl, alEnable, "[pattern]", "" }, + { hcParamVal, "PARAMVAL", 1, 0, getParamVal, gsNotImpl, alEnable, "", "" }, + { hcParamVals, "PARAMVALS", 0, 0, getParamVals, gsNotImpl, alEnable, "[pattern]", "" }, + { hcPin, "PIN", 1, 0, getPin, gsNotImpl, alEnable, "", "" }, + { hcPins, "PINS", 0, 0, getPins, gsNotImpl, alEnable, "[pattern]", "" }, + { hcPinVal, "PINVAL", 1, 0, getPinVal, gsNotImpl, alEnable, "", "" }, + { hcPinVals, "PINVALS", 0, 0, getPinVals, gsNotImpl, alEnable, "[pattern]", "" }, + { hcSave, "SAVE", 0, 1, gsNotImpl, setSave, alEnable, + "", "{all,comp,sig,link,linka,net,neta,param,thread} [filename]" }, + { hcSetP, "SETP", 0, 2, gsNotImpl, setSetP, alEnable, "", " " }, + { hcSetS, "SETS", 0, 2, gsNotImpl, setSetS, alEnable, "", " " }, + { hcSig, "SIGNAL", 1, 0, getSig, gsNotImpl, alEnable, "", "" }, + { hcSigs, "SIGNALS", 0, 0, getSigs, gsNotImpl, alEnable, "[pattern]", "" }, + { hcSigVal, "SIGVAL", 1, 0, getSigVal, gsNotImpl, alEnable, "", "" }, + { hcSigVals, "SIGVALS", 0, 0, getSigVals, gsNotImpl, alEnable, "[pattern]", "" }, + { hcStart, "START", 0, 0, gsNotImpl, setStart, alEnable, "", "" }, + { hcStop, "STOP", 0, 0, gsNotImpl, setStop, alEnable, "", "" }, + { hcThread, "THREAD", 1, 0, getThread, gsNotImpl, alEnable, "", "" }, + { hcThreads, "THREADS", 0, 0, getThreads, gsNotImpl, alEnable, "[pattern]", "" }, + { hcTime, "TIME", 0, 0, getTime, gsNotImpl, alNone, "", "" }, + { hcTimestamp, "TIMESTAMP", 0, 1, getTimestamp, setTimestamp, alNone, "", "{on|off} [{on|off}]" }, + { hcUnlinkP, "UNLINKP", 0, 1, gsNotImpl, setUnlinkP, alEnable, "", "" }, + { hcUnload, "UNLOAD", 0, 1, gsNotImpl, setUnload, alEnable, "", "|" }, + { hcUnlock, "UNLOCK", 0, 1, gsNotImpl, setUnlock, alEnable, "", "{all|load|config|params|run|tune|none}" }, + { hcVerbose, "VERBOSE", 0, 1, getVerbose, setVerbose, alHello, "", "{on|off}" }, +}; + +static int cmpGSList(const void *a, const void *b) +{ + return compareNoCase(static_cast(a)->name, static_cast(b)->name); +} + +int commandGetSet(connectionRecType &ctx, cmdType getset) +{ + const char *sg = getset == cmdSet ? "SET" : "GET"; + if (ctx.toks.size() < 2) { + // Missing missing parameter + errornl(ctx, fmt::format("Must specify subcommand for {}", sg)); + replynl(ctx, fmt::format("{} NAK", sg)); + return -1; + } + + // Find the command in the list + getsetListType v = {}; + v.name = ctx.toks[1].c_str(); + void *_tag = bsearch(&v, getsetList, NELEM(getsetList), sizeof(getsetList[0]), cmpGSList); + const getsetListType *tag = static_cast(_tag); + if (!tag) { + errornl(ctx, fmt::format("Subcommand not found: {} {}", sg, ctx.toks[1])); + replynl(ctx, fmt::format("{} NAK", sg)); + return -1; + } + + if (getset == cmdGet) { + // GET X command + // Check for enough arguments + if (tag->nget + 2 > ctx.toks.size()) { + errornl(ctx, fmt::format("Too few arguments to GET {}, have {}, need {} or more", + tag->name, ctx.toks.size() - 2, tag->nget)); + replynl(ctx, fmt::format("GET {} NAK", tag->name)); + return -1; + } + cmdResponseType res = tag->getter(ctx); + switch (res) { + case rtOk: + if (ctx.verbose) { + replynl(ctx, fmt::format("GET {} ACK", tag->name)); + } + break; + case rtError: // Standard error response + replynl(ctx, fmt::format("GET {} NAK", tag->name)); + break; + default: replynl(ctx, fmt::format("internal: GET {} returned unknown value '{}'", tag->name, (int)res)); break; + } + } else { + // SET X command + // Check for enough arguments + if (tag->nset + 2 > ctx.toks.size()) { + errornl(ctx, fmt::format("Too few arguments to SET {}, have {}, need {} or more", + tag->name, ctx.toks.size() - 2, tag->nset)); + replynl(ctx, fmt::format("GET {} NAK", tag->name)); + return -1; + } + + if (tag->acclvl >= alHello && !ctx.linked) { + errornl(ctx, fmt::format("A HELLO must be successfully negotiated for SET {}", tag->name)); + replynl(ctx, fmt::format("SET {} NAK", tag->name)); + return -1; + } + + if (tag->acclvl >= alEnable && !isEnabled(ctx)) { + errornl(ctx, fmt::format("Connection must be enabled for SET {}", tag->name)); + replynl(ctx, fmt::format("SET {} NAK", tag->name)); + return -1; + } + + cmdResponseType res = tag->setter(ctx); + switch (res) { + case rtOk: + if (ctx.verbose) { + replynl(ctx, fmt::format("SET {} ACK", tag->name)); + } + break; + case rtError: // Standard error response + replynl(ctx, fmt::format("SET {} NAK", tag->name)); + break; + default: + replynl(ctx, fmt::format("internal: SET {} returned unknown value '{}'", tag->name, (int)res)); + break; + } + } + return 0; +} + +static int helpGeneral(connectionRecType &ctx) +{ + replynl(ctx, + "Available commands:\r\n" + " HELLO \r\n" + " GET [parameters...]\r\n" + " SET [parameters...]\r\n" + " SHUTDOWN\r\n" + " HELP \r\n"); + return 0; +} + +static int helpHello(connectionRecType &ctx) +{ + replynl(ctx, + "Usage: HELLO []\r\n" + " Where:\r\n" + " - password: the connection password to allow communications with the server.\r\n" + " - clientname: the name of the client trying to connect.\r\n" + " - protover: the version of the protocol which the client wishes to use.\r\n" + " With valid password, server responds with:\r\n" + " HELLO ACK \r\n" + " Where:\r\n" + " - ACK: acknowledging the connection has been made.\r\n" + " - servername: the name of the LinuxCNC Server to which the client has connected.\r\n" + " - protover: the client requested version or latest version support by server if\r\n" + " the client requests a version later than that supported by the server.\r\n" + " With invalid password, the server responds with:\r\n" + " HELLO NAK\r\n"); + return 0; +} + +static int helpGet(connectionRecType &ctx) +{ + replynl(ctx, + "Usage: GET [parameters...]\r\n" + " All get commands require that a HELLO has been successfully negotiated.\r\n" + " Command may be one of:"); + for (unsigned i = 0; i < NELEM(getsetList); i++) { + const getsetListType *gsl = &getsetList[i]; + if (gsl->getter == gsNotImpl) + continue; + replynl(ctx, fmt::format(" {} {}", gsl->name, gsl->gethelp)); + } + reply(ctx, "\r\n"); + return 0; +} + +static int helpSet(connectionRecType &ctx) +{ + replynl(ctx, + "Usage: SET [parameters...]\r\n" + " All set commands require that a HELLO has been successfully negotiated.\r\n" + " Most set commands require exclusive control over the connection to\r\n" + " LinuxCNC by having successfully executed 'SET ENABLE '.\r\n" + " Set commands not requiring any access level control:"); + for (unsigned i = 0; i < NELEM(getsetList); i++) { + const getsetListType *gsl = &getsetList[i]; + if (gsl->setter == gsNotImpl || gsl->acclvl != alNone) + continue; + replynl(ctx, fmt::format(" {} {}", gsl->name, gsl->sethelp)); + } + reply(ctx, " Set commands requiring HELLO level control:"); + reply(ctx, "\r\n"); + for (unsigned i = 0; i < NELEM(getsetList); i++) { + const getsetListType *gsl = &getsetList[i]; + if (gsl->setter == gsNotImpl || gsl->acclvl != alHello) + continue; + replynl(ctx, fmt::format(" {} {}", gsl->name, gsl->sethelp)); + } + reply(ctx, "\r\n"); + replynl(ctx, " Set commands requiring control enabled:"); + for (unsigned i = 0; i < NELEM(getsetList); i++) { + const getsetListType *gsl = &getsetList[i]; + if (gsl->setter == gsNotImpl || gsl->acclvl != alEnable) + continue; + replynl(ctx, fmt::format(" {} {}", gsl->name, gsl->sethelp)); + } + reply(ctx, "\r\n"); + return 0; +} + +static int helpQuit(connectionRecType &ctx) +{ + replynl(ctx, + "Usage: QUIT\r\n" + " The quit command disconnects the client from the server.\r\n" + " the command has no parameters and no requirements to have negotiated\r\n" + " a hello, or be in control.\r\n"); + return 0; +} + +static int helpShutdown(connectionRecType &ctx) +{ + replynl(ctx, + "Usage: SHUTDOWN\r\n" + " The shutdown command terminates the connections with all clients.\r\n" + " No shutdown of LinuxCNC is performed or attempted. It is not possible\r\n" + " for halrmt to perform any clean shudown procedure.\r\n" + " The command has no parameters, and can only be issued on the connection\r\n" + " that has enable control.\r\n"); + return 0; +} + +static int helpHelp(connectionRecType &ctx) +{ + replynl(ctx, + "Usage: HELP HELP\r\n" + " You need help if you need help on help to help you with help.\r\n" + " It may be time to look into another line of work where computers are\r\n" + " no requirement. Computers will only remind you of the necessary evil\r\n" + " they represent and cause severe helplessness for those requesting help.\r\n"); + return 0; +} + +static int commandHelp(connectionRecType &ctx) +{ + if (ctx.toks.size() < 2) + return helpGeneral(ctx); + std::string s = ctx.toks[1]; + std::transform(s.begin(), s.end(), s.begin(), [](char c) { return std::toupper((unsigned char)c); }); + if (s == "HELLO") return helpHello(ctx); + if (s == "GET") return helpGet(ctx); + if (s == "SET") return helpSet(ctx); + if (s == "QUIT") return helpQuit(ctx); + if (s == "SHUTDOWN") return helpShutdown(ctx); + if (s == "HELP") return helpHelp(ctx); + errornl(ctx, fmt::format("{} is not a valid command. ({})", ctx.toks[1], s)); + return 0; +} + +static int cmpCmdList(const void *a, const void *b) +{ + return compareNoCase(static_cast(a)->name, static_cast(b)->name); +} + +static inline bool isidchar(int ch) +{ + return (::isascii(ch & 0xff) && ::isalnum(ch & 0xff)) || '_' == ch; +} + +static std::string resolveIni(connectionRecType &ctx, const std::string §ion, const std::string &variable) +{ + if(ctx.inifilename.empty()) + return ""; + + IniFile ini(ctx.inifilename); + if(!ini) + return ""; + + if(auto str = ini.findString(variable, section)) + return *str; + return ""; +} + +static void iniExpand(connectionRecType &ctx, std::string &line) +{ + if(!ctx.expand) + return; + std::string newline; + std::string section; + std::string variable; + enum { ST_START, ST_BOPEN, ST_BCLOSE, ST_POPEN, ST_VAR } state = ST_START; + for(const auto &ch : line) { + switch(state) { + default: + case ST_START: + if('[' == ch) { + state = ST_BOPEN; + } else { + newline += ch; + } + break; + case ST_BOPEN: // Seen '[' + if(']' == ch) { + state = ST_BCLOSE; + } else { + if(!isidchar(ch)) { + // Invalid char in section name. + newline += '[' + section + ch; + section.clear(); + state = ST_START; + } else { + section += ch; + } + } + break; + case ST_BCLOSE: // Seen '[section]' + if('(' == ch) { + state = ST_POPEN; + } else { + if(!isidchar(ch)) { + // Invalid char starting variable + newline += '[' + section + ']' + ch; + variable.clear(); + section.clear(); + state = ST_START; + } else { + state = ST_VAR; + variable += ch; + } + } + break; + case ST_VAR: // Seen '[section]x' + if(!isidchar(ch)) { + if(isspace(ch & 0xff)) { + // Have '[section]variable' --> resolve + newline += resolveIni(ctx, section, variable); + } else { + // Invalid termination --> restore + newline += '[' + section + ']' + variable; + } + newline += ch; + section.clear(); + variable.clear(); + state = ST_START; + } else { + variable += ch; + } + break; + case ST_POPEN: // Seen '[section](' + if(!isidchar(ch)) { + if(')' == ch) { + // Have '[section](variable)' --> resolve + newline += resolveIni(ctx, section, variable); + } else { + // Invalid termination --> restore + newline += '[' + section + "](" + variable + ch; + } + section.clear(); + variable.clear(); + state = ST_START; + } else { + variable += ch; + } + break; + } + } + + // We can terminate on end-of-string in any state + // Repair any intermediate + switch(state) { + default: + case ST_START: break; + case ST_BOPEN: newline += '[' + section; break; + case ST_BCLOSE: newline += '[' + section + ']'; break; + case ST_POPEN: newline += '[' + section + "](" + variable; break; + case ST_VAR: newline += resolveIni(ctx, section, variable); break; + } + line = newline; +} + +static int parseCommand(connectionRecType &ctx, std::string &line) +{ + static const char toksep[] = " \t\n\r"; + + size_t pos = 0; + ctx.toks.clear(); // Clear any previous commands/tokens + iniExpand(ctx, line); + while (pos < line.size()) { + // trim left + size_t lft = line.find_first_not_of(toksep, pos); + if (lft == std::string::npos) { + // No non-whitespace characters found to delimit the start + pos = line.size(); // All white-space until end + continue; + } + // Now have: + // arbitrary string with spaces + // ^ + // lft + size_t rgt = line.find_first_of(toksep, lft); + if (rgt == std::string::npos) { + // No whitespace characters found to delimit the end + // The current range [lft,size()) has the token + rgt = line.size(); + } + // Now have: + // arbitrary string with spaces + // ^ ^ + // lft rgt + ctx.toks.push_back(line.substr(lft, rgt - lft)); + pos = rgt; + } + + if (ctx.toks.size() < 1) + return 0; + + // Find the command in the list + commandListType v = {cmdUnknown, 0, ctx.toks[0].c_str()}; + void *_tag = bsearch(&v, commandList, NELEM(commandList), sizeof(commandList[0]), cmpCmdList); + const commandListType *tag = static_cast(_tag); + if (!tag) { + errornl(ctx, fmt::format("Command '{}' not found", ctx.toks[0])); + return 0; + } + + if (ctx.toks.size() < tag->nargs + 1) { + errornl(ctx, fmt::format("Too few arguments for '{}' command", ctx.toks[0])); + return 0; + } + + // Only echo when on, linked and never on HELLO commands + if (ctx.echo && ctx.linked && tag->command != cmdHello) + replynl(ctx, line); + + switch (tag->command) { + case cmdHello: commandHello(ctx); break; + case cmdSet: + case cmdGet: commandGetSet(ctx, tag->command); break; + case cmdQuit: commandQuit(ctx); break; + case cmdHelp: commandHelp(ctx); break; + case cmdShutdown: + if (!commandShutdown(ctx)) { + return -1; + } + break; + default: + replynl(ctx, fmt::format("internal: Invalid command ID '{}' on name='{}'", (int)tag->command, tag->name)); + break; + } + return 0; +} + +/*********************************************************************** +* MAIN PROGRAM * +************************************************************************/ + +static int initSocket() +{ + int optval = 1; + int err; + int sockfd; + struct sockaddr_in6 address = {}; + + sockfd = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); + if (sockfd < 0) { + xperror("socket()"); + return -1; + } + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + // Using AF_INET6 will also allow IPv4 to connect (v4-mapped-on-v6) + address.sin6_family = AF_INET6; + address.sin6_addr = IN6ADDR_ANY_INIT; + address.sin6_port = htons(port); + err = bind(sockfd, reinterpret_cast(&address), sizeof(address)); + if (err) { + close(sockfd); + xperror("bind()"); + return -1; + } + + err = listen(sockfd, 5); + if (err) { + close(sockfd); + xperror("listen()"); + return -1; + } + + return sockfd; +} + +static void closeClient(connectionRecType &ctx) +{ + if (ctx.sock < 0) + return; + info("Connection terminated '%s' (%d)", ctx.hostname.c_str(), ctx.sock); + close(ctx.sock); + ctx.sock = -1; +} + +static int sockMain(int svrfd) +{ + std::vector rdbuf(1600); // Declare at top, no need to realloc each round in the loop + std::vector pfds(2); + bool shutdown = false; + + while (!quitloop && (clients.size() || !shutdown)) { + // Make sure we have room for clients and server socket + pfds.resize(clients.size() + 1); + + // Setup poll data for all sockets + pfds[0].fd = svrfd; + pfds[0].events = POLLIN; + pfds[0].revents = 0; + int pto = -1; // Default to infinite poll timeout + if (shutdown) + pto = 0; // Immediate return in shutdown mode + + for (size_t i = 0; i < clients.size(); i++) { + // Close connection when about to shutdown and all is flushed. All + // clients should already have halfclosed set and the input buffer + // cleared. + if (!clients[i].outbuf.size() && shutdown) { + closeClient(clients[i]); + // poll will ignore this entry + } + pfds[i + 1].fd = clients[i].sock; + pfds[i + 1].events = POLLPRI | (!clients[i].halfclosed ? POLLIN : 0) | (clients[i].outbuf.size() ? POLLOUT : 0); + pfds[i + 1].revents = 0; + + // If there is still a full line of data in an input buffer then + // make poll return asap. It will still check the descriptors for + // I/O activity. + if (clients[i].inbuf.find_first_of("\r\n") != std::string::npos) + pto = 0; + } + + // Wait until something happens + int err = poll(pfds.data(), pfds.size(), pto); + if (err < 0) { + if (EINTR == errno) { + continue; + } else { + error("poll() returned errno=%d (%s), quiting", errno, strerror(errno)); + return EXIT_FAILURE; + } + } + + // Check server socket first + if (pfds[0].revents & POLLERR) { + // This should never happen...famous...last...words... + error("Server socket received an error on poll, quiting"); + return EXIT_FAILURE; + } else if (pfds[0].revents & POLLIN) { + // POLLIN on a listen socket means new connection available + int cfd; + struct sockaddr_in6 csa; + socklen_t csal = sizeof(csa); + cfd = accept4(svrfd, reinterpret_cast(&csa), &csal, SOCK_CLOEXEC | SOCK_NONBLOCK); + if (cfd < 0) { + switch (errno) { + // The usual errors that should make us retry: + case EAGAIN: + case ECONNABORTED: + break; + // Network related errors should be treated as EAGAIN according + // to accept(2) manual + case ENETDOWN: + case EPROTO: + case ENOPROTOOPT: + case EHOSTDOWN: + case ENONET: + case EHOSTUNREACH: + case EOPNOTSUPP: + case ENETUNREACH: + mysleep(1.0); // Don't busy loop waiting for the net to be up again + break; + // Various restartable errors + case ETIMEDOUT: // Linux kernel thingy, apparently + case ERESTART: // During trace (in accept(2) manual named ERESTARTSYS) + break; + default: + // Any other error will be fatal + xperror("accept()"); + return EXIT_FAILURE; + } + } else { + if (!maxSessions || clients.size() < maxSessions) { + // The accept has set non-blocking and close-on-exec. + // Disable Nagle's algo + int nd = 1; + setsockopt(cfd, IPPROTO_TCP, TCP_NODELAY, &nd, sizeof(nd)); + connectionRecType cr = {}; + cr.sock = cfd; + cr.hostname = fmt::format("Default-{}", cfd); + cr.version = "1.1"; + cr.echo = true; + cr.inifilename = inifilename; // Inherit global default + clients.push_back(cr); + char addr[INET6_ADDRSTRLEN] = {}; + inet_ntop(AF_INET6, &csa.sin6_addr, addr, sizeof(addr)); + info("New connection from %s:%d", addr, ntohs(csa.sin6_port)); + } else { + close(cfd); + } + } + } + + // Note that we can have one extra client already added but it does not + // have a pfds entry. That happens when we accept a new connection + // above. However, we still need to check all other clients for + // read/write. + for (size_t i = 0; i < clients.size() && i < pfds.size() - 1; i++) { + if (pfds[i + 1].revents & POLLERR) { + // An error on a socket means we make it to close/abort + clients[i].halfclosed = true; + clients[i].inbuf.clear(); + clients[i].outbuf.clear(); + } + + if (pfds[i + 1].revents & POLLPRI) { + ssize_t res = recv(clients[i].sock, rdbuf.data(), rdbuf.size(), MSG_OOB); + if (res < 0) { + if (errno != EINTR && errno != EAGAIN) { + xperror("recv() OOB data"); + } + } else { + info("Received %zd bytes of OOB data (using telnet?), ignoring", res); + } + } + + if (pfds[i + 1].revents & POLLOUT) { + // Writable... + ssize_t res = write(clients[i].sock, clients[i].outbuf.c_str(), clients[i].outbuf.size()); + if (res < 0) { + if (errno != EINTR && errno != EAGAIN) { + xperror("client write()"); + // Make this connection to close/abort + clients[i].halfclosed = true; + clients[i].inbuf.clear(); + clients[i].outbuf.clear(); + } + } else { + clients[i].outbuf.erase(0, res); // Remove written data from buffer + } + } + + if (pfds[i + 1].revents & POLLIN) { + // Readable... + ssize_t len = read(clients[i].sock, rdbuf.data(), rdbuf.size()); + if (len < 0) { + if (errno != EAGAIN && errno != EINTR) { + xperror("client read()"); + // Make this connection to close but still try flush output + clients[i].halfclosed = true; + clients[i].inbuf.clear(); + } + } else if (0 == len) { + // Socket closed + info("Read close '%s' (%d)", clients[i].hostname.c_str(), clients[i].sock); + clients[i].halfclosed = true; + } else { + // Append the read data + clients[i].inbuf.append(rdbuf.data(), len); + } + } + + if (clients[i].halfclosed && !clients[i].inbuf.size() && !clients[i].outbuf.size()) { + // The input is closed and no more data to handle or write. + // Terminate the connection. + closeClient(clients[i]); + } + } + + // Remove fully closed clients + for (auto i = clients.begin(); i != clients.end();) { + if (-1 == i->sock) { + i = clients.erase(i); + } else { + ++i; + } + } + + // Handle input, one line at a time for each client (round robin) + for (auto i = clients.begin(); i != clients.end(); ++i) { + // Split into lines and send to parser + size_t nl = i->inbuf.find_first_of("\r\n"); + if (nl != std::string::npos) { + // Isolate the line and remove from input buffer + std::string line = i->inbuf.substr(0, nl); + // and remove any trailing \r\n too + size_t enl = i->inbuf.find_first_not_of("\r\n", nl); + i->inbuf.erase(0, enl); + if (line.size()) { + // Parse the line if there is something on it + // It returns non-zero when the shutdown has been executed + if (parseCommand(*i, line)) { + // We may still have data in the outbuf that needs to + // be flushed. Any remaining output will still be sent + // and then the client will be fully closed and removed. + shutdown = true; + // Halfclose all clients and zap remaining input. + for (auto c = clients.begin(); c != clients.end(); ++c) { + c->halfclosed = true; + c->inbuf.clear(); + } + } + } + } + // Else: Not a finished line, must wait for rest + } + } + + return 0; +} + +static void usage(void) +{ + static const char usage_str[] = + "Usage: halrmt [options]\n" + "Options:\n" + " -h,--help This help\n" + " -p,--port Listen on port 'num' (default=%d)\n" + " -n,--name Set this server's name to 'str' (default=%s)\n" + " -w,--connectpw Set connect/hello password to 'pwd' (default=%s)\n" + " -e,--enablepw Set enable password to 'pwd' (default=%s)\n" + " -s,--sessions Restrict number of session to 'num' (default=%u) (0 for no limit)\n" + " -i,--ini Use 'file' as inifile (default=env[INI_FILE_NAME])\n" + " -q,--quiet Don't print informational messages\n" + "\n" + "Session commands: Connect and use 'help', 'help get' and 'help set' for details.\n" + ; + printf(usage_str, port, serverName.c_str(), helloPwd.c_str(), enablePwd.c_str(), maxSessions); +} + +static bool check_white(const std::string &s) +{ + for (const char &c : s) { + if (std::iscntrl((unsigned char)c) || std::isspace((unsigned char)c)) + return true; + } + return false; +} + +static struct option longopts[] = { + {"help", 0, NULL, 'h'}, + {"name", 1, NULL, 'n'}, + {"port", 1, NULL, 'p'}, + {"connectpw", 1, NULL, 'w'}, + {"enablepw", 1, NULL, 'e'}, + {"sessions", 1, NULL, 's'}, + {"ini", 1, NULL, 'i'}, + {"quiet", 0, NULL, 'q'}, + {} +}; + +int main(int argc, char **argv) +{ + int optc; + int lose = 0; + char *eptr; + + /* set default level of output - 'quiet' */ + rtapi_set_msg_level(RTAPI_MSG_ERR); + /* set default for other options */ + // process halrmt command line args + while(-1 != (optc = getopt_long(argc, argv, "e:hi:n:p:qs:w:", longopts, NULL))) { + switch(optc) { + case 'h': + usage(); + return EXIT_FAILURE; + + case 'e': + enablePwd = optarg; + if (!compareNoCase(enablePwd, "OFF")) { + error("Invalid enable password. You cannot use 'OFF' as enable password"); + lose++; + } else { + if (check_white(enablePwd)) { + error("You cannot have control or space characters in the enable password"); + lose++; + } + } + break; + case 'i': { + inifilename = optarg; + IniFile ini(inifilename); // Parse file to see it alright (and cache it) + if(!ini) + lose++; + break; } + case 'q': + quiet++; + break; + case 'n': + serverName = optarg; + if (check_white(serverName)) { + error("You cannot have control or space characters in the server name"); + lose++; + } + break; + case 'w': + helloPwd = optarg; + if (check_white(helloPwd)) { + error("You cannot have control or space characters in the password"); + lose++; + } + break; + case 's': + maxSessions = strtoul(optarg, &eptr, 0); + if (eptr == optarg || *eptr) { + error("Invalid maxSessions '%s', must be integer in range [0,...)", optarg); + lose++; + } + break; + case 'p': + port = strtol(optarg, &eptr, 0); + if (eptr == optarg || *eptr || port <= 0 || port >= 65535) { + error("Invalid port '%s', must be integer in range [1,65534]", optarg); + lose++; + } + break; + + default: + lose++; + break; + } + } + + if(inifilename.empty()) { + const char *cptr = getenv("INI_FILE_NAME"); + if(!cptr) { + info("No inifile available"); + } else { + inifilename = cptr; + IniFile ini(inifilename); + if(!ini) + lose++; + } + } + + if(lose) + return EXIT_FAILURE; + + // Initialize the listen socket + int sockfd = initSocket(); + if (sockfd < 0) { + return EXIT_FAILURE; + } + + // Get us access to HAL + int rv = hal_lib_init(); + if(0 != rv) { + close(sockfd); + return EXIT_FAILURE; + } + + // Make sure we quit when requested + signal(SIGINT, quitSig); + signal(SIGQUIT, quitSig); + signal(SIGTERM, quitSig); + signal(SIGHUP, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + + rv = sockMain(sockfd); + + // Disconnect from HAL shared memory + hal_lib_exit(); + + return rv; +} +// vim: ts=4 sw=4 et