The Smell of Molten Projects in the Morning

Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.

Category: Software

General-purpose computers doing something specific

  • Kicad-to-HAL: Naming Nets

    Kicad-to-HAL: Naming Nets

    Nets connecting Kicad components get their names in three different ways, each treated slightly differently by Kicad-to-HAL.

    The simplest case happens with a Global Label attached to the net, as with the All-home signal on the right, which can be referenced anywhere in the schematic :

    Home switches input - schematic
    Home switches input – schematic

    The XML file carries the Global Label text as the net name:

    <net code="154" name="All-home">
        <node ref="joint.3.100" pin="20"/>
        <node ref="joint.2.100" pin="20"/>
        <node ref="joint.0.100" pin="20"/>
        <node ref="joint.1.100" pin="20"/>
        <node ref="dbounce.100" pin="2"/>
    </net>
    

    The order of the nodes within the net depends on which one Kicad encounters first, so Kicad-to-HAL sorts the destination references in ascending order:

    net All-home <= dbounce.0.out => joint.0.home-sw-in joint.1.home-sw-in joint.2.home-sw-in joint.3.home-sw-in		# dbounce.100
    

    The ASCII-art arrows around the HAL source reference set it off from the rest of the clutter, with the comment (off-screen right for you) giving the original Kicad source component reference.

    Kicad generates a name for anonymous nets, like the one between the 5I25 GPIO pin and the debouncer, from the first component it encounters:

        <net code="617" name="Net-(dbounce.100-Pad1)">
          <node ref="hm2_5i25.0.gpio.013.100" pin="2"/>
          <node ref="dbounce.100" pin="1"/>
        </net>
    

    Kicad-to-HAL replaces those names with a less noisy one in an ascending sequence:

    net N_159 <= hm2_5i25.0.gpio.013.in_not => dbounce.0.in		# hm2_5i25.0.gpio.013.100
    

    The anonymous Kicad net between the parameter setting the debounce delay starts with a similar name:

    <net code="127" name="Net-(mux2.100-Pad1)">
        <node ref="parameter.106" pin="1"/>
        <node ref="mux2.100" pin="1"/>
    </net>
    

    Kicad-to-HAL extracts the source and destination nodes from the net to produce a HAL setp command for each destination:

    setp dbounce.0.delay 3		# parameter.111
    

    Kicad nets can get a name from a Local Label accessible only on that particular schematic sheet:

    Jog Speed conversion - schematic
    Jog Speed conversion – schematic

    Those Kicad net names include the sheet name as a prefix:

    <net code="130" name="/Jog Speed/Angular-Motion">
        <node ref="mux2.100" pin="3"/>
        <node ref="or2.112" pin="3"/>
    </net>
    <net code="132" name="/Jog Speed/Vel-Per-Second">
        <node ref="scale.104" pin="1"/>
        <node ref="mux2.100" pin="4"/>
    </net>
    <net code="138" name="/Jog Speed/Vel-Per-Minute">
        <node ref="scale.101" pin="1"/>
        <node ref="scale.104" pin="4"/>
        <node ref="scale.100" pin="1"/>
    </net>
    

    It’s not clear which characters HAL regards as valid, so KIcad-to-HAL smashes the Kicad name flat:

    net _Jog_Speed_Angular-Motion <= or2.12.out => mux2.0.sel		# or2.112
    net _Jog_Speed_Vel-Per-Minute <= scale.4.out => scale.0.in scale.1.in		# scale.104
    net _Jog_Speed_Vel-Per-Second <= mux2.0.out => scale.4.in		# mux2.100
    

    Kicad-to-HAL sorts the HAL net list by name to make a specific net easier to find.

    The XML netlist file contains a zillion single-node nets, one for each unconnected pin in the schematic. If the Kicad net name doesn’t start with Net-, KIcad-to-HAL will include a note in the HAL file:

    #* Named net with single pin: hm2_5i25.0.100 read_gpio
    

    Prefix the pin name (when you create the symbol) with an asterisk to suppress that message. This will be most useful for HAL function pins intended for an optional thread connection:

    Kicad Symbol Properties - HM2_5I25
    Kicad Symbol Properties – HM2_5I25

    Kicad-to-HAL does not generate HAL nets for Kicad nets with -thread in their names, as those generate addf commands.

  • Kicad-to-HAL: Charge Pump Driver

    Kicad-to-HAL: Charge Pump Driver

    Just to see if all the conversion machinery hung together, I added the PWM component for the Mesa 5I25 card to the Kicad-to-HAL library:

    PWM Charge Pump driver - schematic
    PWM Charge Pump driver – schematic

    The top symbol provides the reference stem for the per-group frequency controls and the second provides the stem for the per-PWM controls.

    It requires conjuring one PWM in the FPGA:

    PWM Charge Pump driver - LoadRT config
    PWM Charge Pump driver – LoadRT config

    The corresponding lines in the HAl file:

    setp hm2_5i25.0.pwmgen.00.output-type 1		# parameter.116
    setp hm2_5i25.0.pwmgen.00.value 0.5		# parameter.115
    setp hm2_5i25.0.pwmgen.pwm_frequency 10000		# parameter.114
    
    … snippage …
    
    net Machine-Is-On <= halui.machine.is-on => and2.13.in1 hm2_5i25.0.pwmgen.00.enable
    

    And then it just worked:

    Mesa 5I25 10 kHz PWM output waveform
    Mesa 5I25 10 kHz PWM output waveform

    It’s not useful with the Sherline driver box, but I find it much easier to contemplate simple schematics than to puzzle out HAL code.

  • Kicad-to-HAL: Mesa Electronics 5I25 FPGA Card

    Kicad-to-HAL: Mesa Electronics 5I25 FPGA Card

    The Mesa Electronics 5I25 FPGA card can implement a vast number of hardware I/O controllers, but I’ve only set up the few Kicad symbols required for my simple Sherline mill. The LinuxCNC hostmot2 doc gives the details.

    The hm2_5i25.0 component (upper right) carries the pins and functions pertaining to the card itself:

    Servo Thread Hookup schematic
    Servo Thread Hookup schematic

    If you have two such cards, you’ll also have an hm2_5i25.1 component. Kicad will annotate both with a zero, which Kicad-to-HAL then strips off before attaching the pin names.

    The read and write functions must attach to the first and last positions of the servo-thread component, respectively, to make the thing work correctly.

    The read_gpio and write_gpio functions are normally not connected; the * prefix suppresses a Kicad-to-HAL message about unconnected named pins. The code will strip the asterisk before connecting the pins, but that part is … lightly tested.

    Similarly, the schematic shows the watchdog output connected to one of the on-card LEDs. I’m not sure how to test that and wouldn’t see it inside the PC case; it might work as described.

    A hm2_5i25.0.gpio.000 Kicad symbol (middle) collects all of the HAL pins related to a single 5I25 GPIO pin; edit the three-digit pin identifier to match the hardware pin. Although the out and in names look backwards, they indicate the hardware direction: you write to the out pin and read from the in pin.

    The Sherline uses four stepgen blocks, so that’s the only other Kicad symbol on offer:

    X Axis Joint PID Stepgen schematic
    X Axis Joint PID Stepgen schematic

    The nets connecting those three components come directly from the LinuxCNC pncconf configuration utility. Fancier machines surely require more attention to the coefficient details.

    Connecting a true parameter to the step.invert_output and direction.invert_output pins flips the polarity of those signals. The pins are aliases of the corresponding GPIO invert_output pin, with the key advantage of not requiring you to figure out which GPIO pin corresponds to the FPGA’s output pin for each axis.

    The 5I25 card requires a pair of loadrt components to load the drivers and configure the FPGA:

    Kicad-to-HAL Demo Schematic
    Kicad-to-HAL Demo Schematic

    The one-page demo schematic uses the same 5I25 configuration as the Sherline, with the LEDs driven by gamepad buttons to provide something to look at:

    Mesa 5I25 card - LED activity
    Mesa 5I25 card – LED activity

    I should force-fit an LED into the Sherline driver box just to have something easier to see.

  • Kicad-to-HAL: HALUI Components

    Kicad-to-HAL: HALUI Components

    The LinuxCNC HALUI “component” has so many pins that I divided them among about 18 Kicad symbols, each collecting the pins related to one function:

    Gamepad Button logic - HALUI components
    Gamepad Button logic – HALUI components

    The Kicad references (halui.mode.100) use periods as separators, not dashes, because HALUI runs automagically and has no thread functions.

    The symbol name (HALUI_MODE) serves as a unique identifier that should match the reference stem. I used underscores just for pretty, but it doesn’t make any difference.

    All of the Kicad symbols include the StripAnno field to remove the Kicad annotation, as described earlier. The Kicad annotations now start from 100, because I’m in the midst of tinkering an automagic way to produce the proper start-from-zero HAL numbering with everything properly sorted; this is very much a work in progress.

    So the full name of the resume pin on the HALUI_PROGRAM component sporting Kicad reference halui.program.100 is just:

    halui.program.resume

    This corresponds to the description of that pin in the HALUI doc, without a numeric identifier: there is only one HALUI.

    The net connecting the gamepad button to that pin:

    net _Gamepad_Buttons_Program-Resume <= input.0.btn-base4 => halui.program.resume
    

    A few more examples from the nets near the AND2 gate:

    net _Gamepad_Buttons_E-Stop-A <= input.0.btn-top2 => and2.0.in0
    net _Gamepad_Buttons_E-Stop-B <= input.0.btn-base => and2.0.in1
    net _Gamepad_Buttons_E-Stop-Reset <= input.0.btn-base2 => halui.estop.reset
    net _Gamepad_Buttons_Machine-On <= input.0.btn-pinkie => halui.machine.on
    net _Gamepad_Buttons_Manual-Mode <= input.0.btn-base3 => halui.mode.manual
    
    

    Some HALUI component references include numbers and letters identifying specific joints / axes / spindles, all of which you must edit as needed and none of which should be subjected to Kicad’s renumbering whims:

    X Axis jogging schematic
    X Axis jogging schematic

    The HAL commands producing the nets connecting the AND2 gates to the HALUI pins:

    net N_065 <= and2.14.out => halui.axis.x.minus halui.joint.0.minus
    net N_066 <= and2.15.out => halui.axis.x.plus halui.joint.0.plus
    

    The nets lack any specific name, so Kicad-to-HAL replaces Kicad’s default gibberish with the next integer from an ascending series. If your HAL configuration requires more than three digits worth of anonymous nets, feel free to tweak the format string.

  • Kicad-to-HAL: LoadUsr

    Kicad-to-HAL: LoadUsr

    The Kicad LOADUSR symbol puts its text directly into a HAL loadusr command:

    Kicad symbol - LOADUSR
    Kicad symbol – LOADUSR

    Putting the same text in the LoadUsr field of a Kicad component may be tidier when there’s only one:

    Kicad Symbol Properties - Logitech gamepad
    Kicad Symbol Properties – Logitech gamepad

    The gamepad symbol in a schematic:

    Kicad-to-HAL Demo Schematic
    Kicad-to-HAL Demo Schematic

    Which produces this loadusr command in the HAL file:

    loadusr -W hal_input -KA Dual		# input.0.0
    

    You can edit the text after placing the Kicad component, so the symbol can contain placeholder text.

  • Kicad-to-HAL: Annotation Stripping

    Kicad-to-HAL: Annotation Stripping

    Kicad insists on annotating every component with a numeric suffix that can change depending on the sequence of components encountered during the annotation process. HAL, on the other hand, identifies multiple components using a numeric value as a suffix or embedded within the reference. HAL also has singleton components without a numeric value.

    A Moby Hack™ merges the two systems: Kicad will annotate each of its components, then Kicad-to-HAL can strip the annotation from the reference to form the HAL identifier.

    A Kicad component with a StripAnno field containing a “1” will trigger the stripping:

    Kicad Symbol Properties - HM2_5I25
    Kicad Symbol Properties – HM2_5I25

    The StripAnno digit (generally) appears to the right of the component name. A Kicad component without a StripAnno field or with the field containing anything other than “1” will pass its reference field directly into the HAL component.

    The Kicad reference for the HM2_5I25 component (center right) is hm2_5i25.0.0 and its stripped HAL reference is hm2_5i25.0:

    addf hm2_5i25.0.read		servo-thread
    

    The THREAD component (center bottom) is a singleton, because there will be only one component with a given thread name:

    Kicad symbol - THREAD
    Kicad symbol – THREAD

    The Kicad reference appends a zero to make servo-thread.0:

    Kicad-to-HAL Demo Schematic
    Kicad-to-HAL Demo Schematic

    The stripped HAL reference, as used in addf statements, is just servo-thread:

    addf and2.0		servo-thread
    addf constant.0		servo-thread
    addf constant.1		servo-thread
    addf not.0		servo-thread
    addf timedelay.0		servo-thread
    addf toggle.0		servo-thread
    

    Every Kicad symbol must have a reference ending with a period so Kicad-to-HAL can strip the trailing annotation value.

  • Kicad-to-HAL: Parameters and Constants

    Kicad-to-HAL: Parameters and Constants

    Kicad PARAMETER symbols (center, left of the upper TOGGLE) provide the value for HAL setp commands:

    Kicad-to-HAL Demo Schematic
    Kicad-to-HAL Demo Schematic

    Which becomes this line in the HAL file:

    setp toggle.0.debounce 5	# parameter.0
    

    Parameter pins use the Inverted graphic style decorating them with a small circle to distinguish parameters from ordinary data pins, but the data value is not inverted. Parameter components can also connect to ordinary HAL input pins without the Inverted style.

    PARAMETER symbols have an invisible reference value (parameter.0 in the example) that you don’t care about:

    Kicad symbol - PARAMETER
    Kicad symbol – PARAMETER

    Edit the value inside the symbol to whatever you need.

    Kicad CONSTANT symbols (lower center, left of the TIMEDELAY symbol) generate HAL CONSTANT modules, set their values, and connect them to a thread. The resulting HAL commands look like this:

    addf constant.0		servo-thread
    addf constant.1		servo-thread
    
    … snippage …
    
    setp constant.0.value [BLINKY]ON
    setp constant.1.value [BLINKY]OFF
    
    … snippage …
    
    net N_001 <= constant.1.out => timedelay.0.off-delay
    net N_002 <= constant.0.out => timedelay.0.on-delay
    

    The thread connections works the same way as for other HAL components with the automagic net connection to “_”:

    Kicad symbol - CONSTANT
    Kicad symbol – CONSTANT

    The (invisible) + in the middle tells Kicad-to-HAL to put the total number of CONSTANT components into the addf command.

    As with Parameters, edit the CONSTANT inside the symbol as needed.

    Both Parameters and Constants can use text values defined in the INI file:

    [BLINKY]
    ON = 0.2
    OFF = 2.0

    Both Parameters and Constants can connect to nets going to multiple input pins, but it’s probably not worth cluttering a schematic with off-page connectors just to reuse a single instance. When you copy-n-paste an otherwise identical symbol somewhere else, it will get a different reference number and generate additional HAL commands, which may offend your sense of neatness.