mirror of https://github.com/Desuuuu/klipper.git
docs: Avoid using "firmware" in the documentation
The term "firmware" is ambiguous - it could refer to the entire project (host and micro-controller software) or to just the micro-controller software. Avoid the term in the documentation. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
d7a1111955
commit
c1c0b2dd38
|
@ -17,7 +17,7 @@ host architectures. The build arranges for includes of
|
||||||
src/generic/somefile.h).
|
src/generic/somefile.h).
|
||||||
|
|
||||||
The **klippy/** directory contains the C and Python source for the
|
The **klippy/** directory contains the C and Python source for the
|
||||||
host part of the firmware.
|
host part of the software.
|
||||||
|
|
||||||
The **lib/** directory contains external 3rd-party library code that
|
The **lib/** directory contains external 3rd-party library code that
|
||||||
is necessary to build some targets.
|
is necessary to build some targets.
|
||||||
|
@ -92,8 +92,8 @@ some functionality in C code.
|
||||||
Initial execution starts in **klippy/klippy.py**. This reads the
|
Initial execution starts in **klippy/klippy.py**. This reads the
|
||||||
command-line arguments, opens the printer config file, instantiates
|
command-line arguments, opens the printer config file, instantiates
|
||||||
the main printer objects, and starts the serial connection. The main
|
the main printer objects, and starts the serial connection. The main
|
||||||
execution of gcode commands is in the process_commands() method in
|
execution of G-code commands is in the process_commands() method in
|
||||||
**klippy/gcode.py**. This code translates the gcode commands into
|
**klippy/gcode.py**. This code translates the G-code commands into
|
||||||
printer object calls, which frequently translate the actions to
|
printer object calls, which frequently translate the actions to
|
||||||
commands to be executed on the micro-controller (as declared via the
|
commands to be executed on the micro-controller (as declared via the
|
||||||
DECL_COMMAND macro in the micro-controller code).
|
DECL_COMMAND macro in the micro-controller code).
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
The Klippy host code has some tools to help in debugging the firmware.
|
The Klippy host code has some tools to help in debugging.
|
||||||
|
|
||||||
Translating gcode files to firmware commands
|
Translating gcode files to micro-controller commands
|
||||||
============================================
|
====================================================
|
||||||
|
|
||||||
The Klippy host code can run in a batch mode to produce the low-level
|
The Klippy host code can run in a batch mode to produce the low-level
|
||||||
firmware commands associated with a gcode file. Inspecting these
|
micro-controller commands associated with a gcode file. Inspecting
|
||||||
low-level firmware commands is useful when trying to understand the
|
these low-level commands is useful when trying to understand the
|
||||||
actions of the low-level hardware. It can also be useful to compare
|
actions of the low-level hardware. It can also be useful to compare
|
||||||
the difference in firmware commands after a code change.
|
the difference in micro-controller commands after a code change.
|
||||||
|
|
||||||
To run Klippy in this batch mode, there is a one time step necessary
|
To run Klippy in this batch mode, there is a one time step necessary
|
||||||
to generate the firmware "data dictionary". This is done by compiling
|
to generate the micro-controller "data dictionary". This is done by
|
||||||
the firmware code to obtain the **out/klipper.dict** file:
|
compiling the micro-controller code to obtain the **out/klipper.dict**
|
||||||
|
file:
|
||||||
|
|
||||||
```
|
```
|
||||||
make menuconfig
|
make menuconfig
|
||||||
|
@ -34,13 +35,13 @@ output. This output can be translated to readable text with:
|
||||||
```
|
```
|
||||||
|
|
||||||
The resulting file **test.txt** contains a human readable list of
|
The resulting file **test.txt** contains a human readable list of
|
||||||
firmware commands.
|
micro-controller commands.
|
||||||
|
|
||||||
The batch mode disables certain response / request commands in order
|
The batch mode disables certain response / request commands in order
|
||||||
to function. As a result, there will be some differences between
|
to function. As a result, there will be some differences between
|
||||||
actual firmware commands and the above output. The generated data is
|
actual commands and the above output. The generated data is useful for
|
||||||
useful for testing and inspection; it is not useful for sending to a
|
testing and inspection; it is not useful for sending to a real
|
||||||
real micro-controller.
|
micro-controller.
|
||||||
|
|
||||||
Testing with simulavr
|
Testing with simulavr
|
||||||
=====================
|
=====================
|
||||||
|
@ -74,9 +75,10 @@ cd /patch/to/klipper
|
||||||
make menuconfig
|
make menuconfig
|
||||||
```
|
```
|
||||||
|
|
||||||
and compile the firmware for an AVR atmega644p, disable the AVR
|
and compile the micro-controller software for an AVR atmega644p,
|
||||||
watchdog timer, and set the MCU frequency to 20000000. Then one can
|
disable the AVR watchdog timer, and set the MCU frequency
|
||||||
compile Klipper (run `make`) and then start the simulation with:
|
to 20000000. Then one can compile Klipper (run `make`) and then start
|
||||||
|
the simulation with:
|
||||||
|
|
||||||
```
|
```
|
||||||
PYTHONPATH=/path/to/simulavr/src/python/ ./scripts/avrsim.py -m atmega644 -s 20000000 -b 250000 out/klipper.elf
|
PYTHONPATH=/path/to/simulavr/src/python/ ./scripts/avrsim.py -m atmega644 -s 20000000 -b 250000 out/klipper.elf
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Klipper is a 3d printer firmware with several compelling features:
|
Klipper has several compelling features:
|
||||||
|
|
||||||
* High precision stepper movement. Klipper utilizes an application
|
* High precision stepper movement. Klipper utilizes an application
|
||||||
processor (such as a low-cost Raspberry Pi) when calculating printer
|
processor (such as a low-cost Raspberry Pi) when calculating printer
|
||||||
|
@ -32,9 +32,9 @@ Klipper is a 3d printer firmware with several compelling features:
|
||||||
micro-controller architectures as well.
|
micro-controller architectures as well.
|
||||||
|
|
||||||
* Simpler code. Klipper uses a very high level language (Python) for
|
* Simpler code. Klipper uses a very high level language (Python) for
|
||||||
most code. The kinematics algorithms, the gcode parsing, the heating
|
most code. The kinematics algorithms, the G-code parsing, the
|
||||||
and thermistor algorithms, etc. are all written in Python. This
|
heating and thermistor algorithms, etc. are all written in
|
||||||
makes it easier to develop new functionality.
|
Python. This makes it easier to develop new functionality.
|
||||||
|
|
||||||
* Advanced features:
|
* Advanced features:
|
||||||
* Klipper implements the "pressure advance" algorithm for
|
* Klipper implements the "pressure advance" algorithm for
|
||||||
|
@ -68,10 +68,10 @@ Klipper supports many standard 3d printer features:
|
||||||
gradually accelerate from standstill to cruising speed and then
|
gradually accelerate from standstill to cruising speed and then
|
||||||
decelerate back to a standstill.
|
decelerate back to a standstill.
|
||||||
|
|
||||||
* "Lookahead" support. The incoming stream of G-Code movement commands
|
* "Look-ahead" support. The incoming stream of G-Code movement
|
||||||
are queued and analyzed - the acceleration between movements in a
|
commands are queued and analyzed - the acceleration between
|
||||||
similar direction will be optimized to reduce print stalls and
|
movements in a similar direction will be optimized to reduce print
|
||||||
improve overall print time.
|
stalls and improve overall print time.
|
||||||
|
|
||||||
* Support for cartesian, delta, and corexy style printers.
|
* Support for cartesian, delta, and corexy style printers.
|
||||||
|
|
||||||
|
|
|
@ -1,290 +0,0 @@
|
||||||
This document provides high-level information on common firmware
|
|
||||||
commands. It is not an authoritative reference for these commands, nor
|
|
||||||
is it an exclusive list of all available firmware commands.
|
|
||||||
|
|
||||||
This document may be useful for users needing to configure a set of
|
|
||||||
hardware actions that their printer may require at startup (via the
|
|
||||||
"custom" field in the printer config file), and it may be useful for
|
|
||||||
developers wishing to obtain a high-level feel for available firmware
|
|
||||||
commands.
|
|
||||||
|
|
||||||
See the [protocol](Protocol.md) document for more information on the
|
|
||||||
format of commands and their low-level transmission. The commands here
|
|
||||||
are described using their "printf" style syntax - for those unfamiliar
|
|
||||||
with that format, just note that where a '%...' sequence is seen it
|
|
||||||
should be replaced with an actual integer. For example, a description
|
|
||||||
with "count=%c" could be replaced with the text "count=10".
|
|
||||||
|
|
||||||
Startup Commands
|
|
||||||
================
|
|
||||||
|
|
||||||
It may be necessary to take certain one-time actions to configure the
|
|
||||||
micro-controller and its peripherals. This section lists common
|
|
||||||
commands available for that purpose. Unlike other firmware commands,
|
|
||||||
these commands run as soon as they are received by the firmware and
|
|
||||||
they do not require any particular setup.
|
|
||||||
|
|
||||||
These commands are most useful in the "custom" block of the "mcu"
|
|
||||||
section of the printer configuration file. This feature is typically
|
|
||||||
used to configure the initial settings of LEDs, to configure
|
|
||||||
micro-stepping pins, to configure a digipot, etc.
|
|
||||||
|
|
||||||
Several of these commands will take a "pin=%u" parameter. The
|
|
||||||
low-level firmware uses integer encodings of the hardware pin numbers,
|
|
||||||
but to make things more readable the host will translate human
|
|
||||||
readable pin names (eg, "PA3") to their equivalent integer
|
|
||||||
encodings. By convention, any parameter named "pin" or that has a
|
|
||||||
"_pin" suffix will use pin name translation by the host. Similarly,
|
|
||||||
several commands take time parameters specified in clock ticks. One
|
|
||||||
can specify a value for these parameters in seconds using the
|
|
||||||
"TICKS()" macro - for example "cycle_ticks=TICKS(0.001)" would result
|
|
||||||
in "cycle_ticks=16000" on a micro-controller with a 16Mhz clock.
|
|
||||||
|
|
||||||
Common startup commands:
|
|
||||||
|
|
||||||
* `set_digital_out pin=%u value=%c` : This command immediately
|
|
||||||
configures the given pin as a digital out GPIO and it sets it to
|
|
||||||
either a low level (value=0) or a high level (value=1). This command
|
|
||||||
may be useful for configuring the initial value of LEDs and for
|
|
||||||
configuring the initial value of stepper driver micro-stepping pins.
|
|
||||||
|
|
||||||
* `set_pwm_out pin=%u cycle_ticks=%u value=%c` : This command will
|
|
||||||
immediately configure the given pin to use hardware based
|
|
||||||
pulse-width-modulation (PWM) with the given number of
|
|
||||||
cycle_ticks. The "cycle_ticks" is the number of MCU clock ticks each
|
|
||||||
power on and power off cycle should last. A cycle_ticks value of 1
|
|
||||||
can be used to request the fastest possible cycle time. The "value"
|
|
||||||
parameter is between 0 and 255 with 0 indicating a full off state
|
|
||||||
and 255 indicating a full on state. This command may be useful for
|
|
||||||
enabling CPU and nozzle cooling fans.
|
|
||||||
|
|
||||||
* `send_spi_message pin=%u msg=%*s` : This command can be used to
|
|
||||||
transmit messages to a serial-peripheral-interface (SPI) component
|
|
||||||
connected to the micro-controller. It has been used to configure the
|
|
||||||
startup settings of AD5206 digipots. The 'pin' parameter specifies
|
|
||||||
the chip select line to use during the transmission. The 'msg'
|
|
||||||
indicates the binary message to transmit to the given chip.
|
|
||||||
|
|
||||||
Firmware configuration
|
|
||||||
======================
|
|
||||||
|
|
||||||
Most commands in the firmware require an initial setup before they can
|
|
||||||
be successfully invoked. This section provides a high-level overview
|
|
||||||
of the micro-controller configuration process. This section and the
|
|
||||||
following sections are likely only of interest to developers
|
|
||||||
interested in the internal details of Klipper.
|
|
||||||
|
|
||||||
When the host first connects to the firmware it always starts by
|
|
||||||
obtaining the firmware's data dictionary (see [protocol](Protocol.md)
|
|
||||||
for more information). After the data dictionary is obtained the host
|
|
||||||
will check if the firmware is in a "configured" state and configure it
|
|
||||||
if not. Configuration involves the following phases:
|
|
||||||
|
|
||||||
* `get_config` : The host starts by checking if the firmware is already
|
|
||||||
configured. The firmware responds to this command with a "config"
|
|
||||||
response message. At micro-controller power-on the firmware always
|
|
||||||
starts in an unconfigured state. It remains in this state until the
|
|
||||||
host completes the configuration processes (by issuing a
|
|
||||||
finalize_config command). If the firmware is already configured (and
|
|
||||||
is configured with the desired settings) from a previous
|
|
||||||
host/firmware session then no further action is needed by the host
|
|
||||||
and the configuration process ends successfully.
|
|
||||||
|
|
||||||
* `allocate_oids count=%c` : This command is issued to inform the
|
|
||||||
firmware the maximum number of object-ids (oid) that the host
|
|
||||||
requires. It is only valid to issue this command once. An oid is an
|
|
||||||
integer identifier allocated to each stepper, each endstop, and each
|
|
||||||
schedulable gpio pin. The host determines in advance the number of
|
|
||||||
oids it will require to operate the hardware and passes this to the
|
|
||||||
firmware so that the firmware may allocate sufficient memory to
|
|
||||||
store a mapping from oid to internal firmware object.
|
|
||||||
|
|
||||||
* `config_XXX oid=%c ...` : By convention any command starting with
|
|
||||||
the "config_" prefix creates a new firmware object and assigns the
|
|
||||||
given oid to it. For example, the config_digital_out command will
|
|
||||||
configure the specified pin as a digital output GPIO and create an
|
|
||||||
internal object that the host can use to schedule changes to the
|
|
||||||
given GPIO. The oid parameter passed into the config command is
|
|
||||||
selected by the host and must be between zero and the maximum count
|
|
||||||
supplied in the allocate_oids command. The config commands may only
|
|
||||||
be run when the firmware is not in a configured state (ie, prior to
|
|
||||||
the host sending finalize_config) and after the allocate_oids
|
|
||||||
command has been sent.
|
|
||||||
|
|
||||||
* `finalize_config crc=%u` : The finalize_config command transitions
|
|
||||||
the firmware from an unconfigured state to a configured state. The
|
|
||||||
crc parameter passed to the firmware is stored in the firmware and
|
|
||||||
provided back to the host in "config" response messages. By
|
|
||||||
convention, the host takes a 32bit CRC of the firmware configuration
|
|
||||||
it will request and at the start of subsequent host/firmware
|
|
||||||
communication sessions it checks that the CRC stored in the firmware
|
|
||||||
exactly matches its desired CRC. If the CRC does not match then the
|
|
||||||
host knows the firmware has not been configured in the state desired
|
|
||||||
by the host.
|
|
||||||
|
|
||||||
Common firmware objects
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
This section lists some commonly used config commands.
|
|
||||||
|
|
||||||
* `config_digital_out oid=%c pin=%u default_value=%c
|
|
||||||
max_duration=%u` : This command creates an internal firmware object
|
|
||||||
for the given GPIO 'pin'. The pin will be configured in digital
|
|
||||||
output mode and set to an initial value as specified by
|
|
||||||
'default_value' (0 for low, 1 for high). Creating a digital_out
|
|
||||||
object allows the host to schedule GPIO updates for the given pin at
|
|
||||||
specified times (see the schedule_digital_out command described
|
|
||||||
below). Should the firmware go into shutdown mode then all
|
|
||||||
configured digital_out objects will be set back to their default
|
|
||||||
values. The 'max_duration' parameter is used to implement a safety
|
|
||||||
check - if it is non-zero then it is the maximum number of clock
|
|
||||||
ticks that the host may set the given GPIO to a non-default value
|
|
||||||
without further updates. For example, if the default_value is zero
|
|
||||||
and the max_duration is 16000 then if the host sets the gpio to a
|
|
||||||
value of one then it must schedule another update to the gpio pin
|
|
||||||
(to either zero or one) within 16000 clock ticks. This safety
|
|
||||||
feature can be used with heater pins to ensure the host does not set
|
|
||||||
the heater to a value of one and then go off-line.
|
|
||||||
|
|
||||||
* `config_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c
|
|
||||||
max_duration=%u` : This command creates an internal object for
|
|
||||||
hardware based PWM pins that the host may schedule updates for. Its
|
|
||||||
usage is analogous to config_digital_out - see the description of
|
|
||||||
the 'set_pwm_out' and 'config_digital_out' commands for parameter
|
|
||||||
description.
|
|
||||||
|
|
||||||
* `config_soft_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c
|
|
||||||
max_duration=%u` : This command creates an internal firmware object
|
|
||||||
for software implemented PWM. Unlike hardware pwm pins, a software
|
|
||||||
pwm object does not require any special hardware support (other than
|
|
||||||
the ability to configure the pin as a digital output GPIO). Because
|
|
||||||
the output switching is implemented in the software of the firmware,
|
|
||||||
it is recommended that the cycle_ticks parameter correspond to a
|
|
||||||
time of 10ms or greater. See the description of the 'set_pwm_out'
|
|
||||||
and 'config_digital_out' commands for parameter description.
|
|
||||||
|
|
||||||
* `config_analog_in oid=%c pin=%u` : This command is used to configure
|
|
||||||
a pin in analog input sampling mode. Once configured, the pin can be
|
|
||||||
sampled at regular interval using the query_analog_in command (see
|
|
||||||
below).
|
|
||||||
|
|
||||||
* `config_stepper oid=%c step_pin=%c dir_pin=%c min_stop_interval=%u
|
|
||||||
invert_step=%c` : This command creates an internal stepper
|
|
||||||
object. The 'step_pin' and 'dir_pin' parameters specify the step and
|
|
||||||
direction pins respectively; this command will configure them in
|
|
||||||
digital output mode. The 'invert_step' parameter specifies whether a
|
|
||||||
step occurs on a rising edge (invert_step=0) or falling edge
|
|
||||||
(invert_step=1). The 'min_stop_interval' implements a safety
|
|
||||||
feature - it is checked when the firmware finishes all moves for a
|
|
||||||
stepper - if it is non-zero it specifies the minimum number of clock
|
|
||||||
ticks since the last step. It is used as a check on the maximum
|
|
||||||
stepper velocity that a stepper may have before stopping.
|
|
||||||
|
|
||||||
* `config_end_stop oid=%c pin=%c pull_up=%c stepper_count=%c` : This
|
|
||||||
command creates an internal "endstop" object. It is used to specify
|
|
||||||
the endstop pins and to enable "homing" operations (see the
|
|
||||||
end_stop_home command below). The command will configure the
|
|
||||||
specified pin in digital input mode. The 'pull_up' parameter
|
|
||||||
determines whether hardware provided pullup resistors for the pin
|
|
||||||
(if available) will be enabled. The 'stepper_count' parameter
|
|
||||||
specifies the maximum number of steppers that this endstop may need
|
|
||||||
to halt during a homing operation (see end_stop_home below).
|
|
||||||
|
|
||||||
Common commands
|
|
||||||
===============
|
|
||||||
|
|
||||||
This section lists some commonly used run-time commands. It is likely
|
|
||||||
only of interest to developers looking to gain insight into Klippy.
|
|
||||||
|
|
||||||
* `schedule_digital_out oid=%c clock=%u value=%c` : This command will
|
|
||||||
schedule a change to a digital output GPIO pin at the given clock
|
|
||||||
time. To use this command a 'config_digital_out' command with the
|
|
||||||
same 'oid' parameter must have been issued during firmware
|
|
||||||
configuration.
|
|
||||||
|
|
||||||
* `schedule_pwm_out oid=%c clock=%u value=%c` : Schedules a change to
|
|
||||||
a hardware PWM output pin. See the 'schedule_digital_out' and
|
|
||||||
'config_pwm_out' commands for more info.
|
|
||||||
|
|
||||||
* `schedule_soft_pwm_out oid=%c clock=%u value=%c` : Schedules a
|
|
||||||
change to a software PWM output pin. See the 'schedule_digital_out'
|
|
||||||
and 'config_soft_pwm_out' commands for more info.
|
|
||||||
|
|
||||||
* `query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c
|
|
||||||
rest_ticks=%u min_value=%hu max_value=%hu` : This command sets up a
|
|
||||||
recurring schedule of analog input samples. To use this command a
|
|
||||||
'config_analog_in' command with the same 'oid' parameter must have
|
|
||||||
been issued during firmware configuration. The samples will start as
|
|
||||||
of 'clock' time, it will report on the obtained value every
|
|
||||||
'rest_ticks' clock ticks, it will over-sample 'sample_count' number
|
|
||||||
of times, and it will pause 'sample_ticks' number of clock ticks
|
|
||||||
between over-sample samples. The 'min_value' and 'max_value'
|
|
||||||
parameters implement a safety feature - the firmware will verify the
|
|
||||||
sampled value (after any oversampling) is always between the
|
|
||||||
supplied range. This is intended for use with pins attached to
|
|
||||||
thermistors controlling heaters - it can be used to check that a
|
|
||||||
heater is within a temperature range.
|
|
||||||
|
|
||||||
* `get_status` : This command causes the firmware to generate a
|
|
||||||
"status" response message. The host sends this command once a second
|
|
||||||
to obtain the value of the micro-controller clock and to estimate
|
|
||||||
the drift between host and micro-controller clocks. It enables the
|
|
||||||
host to accurately estimate the micro-controller clock.
|
|
||||||
|
|
||||||
Stepper commands
|
|
||||||
----------------
|
|
||||||
|
|
||||||
* `queue_step oid=%c interval=%u count=%hu add=%hi` : This command
|
|
||||||
schedules 'count' number of steps for the given stepper, with
|
|
||||||
'interval' number of clock ticks between each step. The first step
|
|
||||||
will be 'interval' number of clock ticks since the last scheduled
|
|
||||||
step for the given stepper. If 'add' is non-zero then the interval
|
|
||||||
will be adjusted by 'add' amount after each step. This command
|
|
||||||
appends the given interval/count/add sequence to a per-stepper
|
|
||||||
queue. There may be hundreds of these sequences queued during normal
|
|
||||||
operation. New sequence are appended to the end of the queue and as
|
|
||||||
each sequence completes its 'count' number of steps it is popped
|
|
||||||
from the front of the queue. This system allows the firmware to
|
|
||||||
queue potentially hundreds of thousands of steps - all with reliable
|
|
||||||
and predictable schedule times.
|
|
||||||
|
|
||||||
* `set_next_step_dir oid=%c dir=%c` : This command specifies the value
|
|
||||||
of the dir_pin that the next queue_step command will use.
|
|
||||||
|
|
||||||
* `reset_step_clock oid=%c clock=%u` : Normally, step timing is
|
|
||||||
relative to the last step for a given stepper. This command resets
|
|
||||||
the clock so that the next step is relative to the supplied 'clock'
|
|
||||||
time. The host usually only sends this command at the start of a
|
|
||||||
print.
|
|
||||||
|
|
||||||
* `stepper_get_position oid=%c` : This command causes the firmware to
|
|
||||||
generate a "stepper_position" response message with the stepper's
|
|
||||||
current position. The position is the total number of steps
|
|
||||||
generated with dir=1 minus the total number of steps generated with
|
|
||||||
dir=0.
|
|
||||||
|
|
||||||
* `end_stop_home oid=%c clock=%u rest_ticks=%u pin_value=%c` : This
|
|
||||||
command is used during stepper "homing" operations. To use this
|
|
||||||
command a 'config_end_stop' command with the same 'oid' parameter
|
|
||||||
must have been issued during firmware configuration. When invoked,
|
|
||||||
the firmware will sample the endstop pin every 'rest_ticks' clock
|
|
||||||
ticks and check if it has a value equal to 'pin_value'. If the value
|
|
||||||
matches then the movement queue for the associated stepper will be
|
|
||||||
cleared and the stepper will come to an immediate halt. The host
|
|
||||||
uses this command to implement homing - the host instructs the
|
|
||||||
endstop to sample for the endstop trigger and then it issues a
|
|
||||||
series of queue_step commands to the stepper to move it towards the
|
|
||||||
endstop. Once the stepper hits the endstop, the trigger will be
|
|
||||||
detected, the movement halted, and the host notified.
|
|
||||||
|
|
||||||
### Move queue
|
|
||||||
|
|
||||||
Each queue_step command utilizes an entry in the firmware "move
|
|
||||||
queue". The firmware allocates this queue when it receives the
|
|
||||||
"finalize_config" command, and it reports the number of available
|
|
||||||
queue entries in "config" response messages.
|
|
||||||
|
|
||||||
It is the responsibility of the host to ensure that there is available
|
|
||||||
space in the queue before sending a queue_step command. The host does
|
|
||||||
this by calculating when each queue_step command completes and
|
|
||||||
scheduling new queue_step commands accordingly.
|
|
|
@ -0,0 +1,294 @@
|
||||||
|
This document provides information on the low-level micro-controller
|
||||||
|
commands that are sent from the Klipper "host" software and processed
|
||||||
|
by the Klipper micro-controller software. This document is not an
|
||||||
|
authoritative reference for these commands, nor is it an exclusive
|
||||||
|
list of all available commands.
|
||||||
|
|
||||||
|
This document may be useful for users needing to configure a set of
|
||||||
|
hardware actions that their printer may require at startup (via the
|
||||||
|
"custom" field in the printer config file), and it may be useful for
|
||||||
|
developers wishing to obtain a high-level feel for low-level commands.
|
||||||
|
|
||||||
|
See the [protocol](Protocol.md) document for more information on the
|
||||||
|
format of commands and their transmission. The commands here are
|
||||||
|
described using their "printf" style syntax - for those unfamiliar
|
||||||
|
with that format, just note that where a '%...' sequence is seen it
|
||||||
|
should be replaced with an actual integer. For example, a description
|
||||||
|
with "count=%c" could be replaced with the text "count=10".
|
||||||
|
|
||||||
|
Startup Commands
|
||||||
|
================
|
||||||
|
|
||||||
|
It may be necessary to take certain one-time actions to configure the
|
||||||
|
micro-controller and its peripherals. This section lists common
|
||||||
|
commands available for that purpose. Unlike most micro-controller
|
||||||
|
commands, these commands run as soon as they are received and they do
|
||||||
|
not require any particular setup.
|
||||||
|
|
||||||
|
These commands are most useful in the "custom" block of the "mcu"
|
||||||
|
section of the printer configuration file. This feature is typically
|
||||||
|
used to configure the initial settings of LEDs, to configure
|
||||||
|
micro-stepping pins, to configure a digipot, etc.
|
||||||
|
|
||||||
|
Several of these commands will take a "pin=%u" parameter. The
|
||||||
|
low-level micro-controller software uses integer encodings of the
|
||||||
|
hardware pin numbers, but to make things more readable the host will
|
||||||
|
translate human readable pin names (eg, "PA3") to their equivalent
|
||||||
|
integer encodings. By convention, any parameter named "pin" or that
|
||||||
|
has a "_pin" suffix will use pin name translation by the
|
||||||
|
host. Similarly, several commands take time parameters specified in
|
||||||
|
clock ticks. One can specify a value for these parameters in seconds
|
||||||
|
using the "TICKS()" macro - for example "cycle_ticks=TICKS(0.001)"
|
||||||
|
would result in "cycle_ticks=16000" on a micro-controller with a 16Mhz
|
||||||
|
clock.
|
||||||
|
|
||||||
|
Common startup commands:
|
||||||
|
|
||||||
|
* `set_digital_out pin=%u value=%c` : This command immediately
|
||||||
|
configures the given pin as a digital out GPIO and it sets it to
|
||||||
|
either a low level (value=0) or a high level (value=1). This command
|
||||||
|
may be useful for configuring the initial value of LEDs and for
|
||||||
|
configuring the initial value of stepper driver micro-stepping pins.
|
||||||
|
|
||||||
|
* `set_pwm_out pin=%u cycle_ticks=%u value=%c` : This command will
|
||||||
|
immediately configure the given pin to use hardware based
|
||||||
|
pulse-width-modulation (PWM) with the given number of
|
||||||
|
cycle_ticks. The "cycle_ticks" is the number of MCU clock ticks each
|
||||||
|
power on and power off cycle should last. A cycle_ticks value of 1
|
||||||
|
can be used to request the fastest possible cycle time. The "value"
|
||||||
|
parameter is between 0 and 255 with 0 indicating a full off state
|
||||||
|
and 255 indicating a full on state. This command may be useful for
|
||||||
|
enabling CPU and nozzle cooling fans.
|
||||||
|
|
||||||
|
* `send_spi_message pin=%u msg=%*s` : This command can be used to
|
||||||
|
transmit messages to a serial-peripheral-interface (SPI) component
|
||||||
|
connected to the micro-controller. It has been used to configure the
|
||||||
|
startup settings of AD5206 digipots. The 'pin' parameter specifies
|
||||||
|
the chip select line to use during the transmission. The 'msg'
|
||||||
|
indicates the binary message to transmit to the given chip.
|
||||||
|
|
||||||
|
Low-level micro-controller configuration
|
||||||
|
========================================
|
||||||
|
|
||||||
|
Most commands in the micro-controller require an initial setup before
|
||||||
|
they can be successfully invoked. This section provides an overview of
|
||||||
|
the configuration process. This section and the following sections are
|
||||||
|
likely only of interest to developers interested in the internal
|
||||||
|
details of Klipper.
|
||||||
|
|
||||||
|
When the host first connects to the micro-controller it always starts
|
||||||
|
by obtaining a data dictionary (see [protocol](Protocol.md) for more
|
||||||
|
information). After the data dictionary is obtained the host will
|
||||||
|
check if the micro-controller is in a "configured" state and configure
|
||||||
|
it if not. Configuration involves the following phases:
|
||||||
|
|
||||||
|
* `get_config` : The host starts by checking if the micro-controller
|
||||||
|
is already configured. The micro-controller responds to this command
|
||||||
|
with a "config" response message. The micro-controller software
|
||||||
|
always starts in an unconfigured state at power-on. It remains in
|
||||||
|
this state until the host completes the configuration processes (by
|
||||||
|
issuing a finalize_config command). If the micro-controller is
|
||||||
|
already configured from a previous session (and is configured with
|
||||||
|
the desired settings) then no further action is needed by the host
|
||||||
|
and the configuration process ends successfully.
|
||||||
|
|
||||||
|
* `allocate_oids count=%c` : This command is issued to inform the
|
||||||
|
micro-controller of the maximum number of object-ids (oid) that the
|
||||||
|
host requires. It is only valid to issue this command once. An oid
|
||||||
|
is an integer identifier allocated to each stepper, each endstop,
|
||||||
|
and each schedulable gpio pin. The host determines in advance the
|
||||||
|
number of oids it will require to operate the hardware and passes
|
||||||
|
this to the micro-controller so that it may allocate sufficient
|
||||||
|
memory to store a mapping from oid to internal object.
|
||||||
|
|
||||||
|
* `config_XXX oid=%c ...` : By convention any command starting with
|
||||||
|
the "config_" prefix creates a new micro-controller object and
|
||||||
|
assigns the given oid to it. For example, the config_digital_out
|
||||||
|
command will configure the specified pin as a digital output GPIO
|
||||||
|
and create an internal object that the host can use to schedule
|
||||||
|
changes to the given GPIO. The oid parameter passed into the config
|
||||||
|
command is selected by the host and must be between zero and the
|
||||||
|
maximum count supplied in the allocate_oids command. The config
|
||||||
|
commands may only be run when the micro-controller is not in a
|
||||||
|
configured state (ie, prior to the host sending finalize_config) and
|
||||||
|
after the allocate_oids command has been sent.
|
||||||
|
|
||||||
|
* `finalize_config crc=%u` : The finalize_config command transitions
|
||||||
|
the micro-controller from an unconfigured state to a configured
|
||||||
|
state. The crc parameter passed to the micro-controller is stored
|
||||||
|
and provided back to the host in "config" response messages. By
|
||||||
|
convention, the host takes a 32bit CRC of the configuration it will
|
||||||
|
request and at the start of subsequent communication sessions it
|
||||||
|
checks that the CRC stored in the micro-controller exactly matches
|
||||||
|
its desired CRC. If the CRC does not match then the host knows the
|
||||||
|
micro-controller has not been configured in the state desired by the
|
||||||
|
host.
|
||||||
|
|
||||||
|
Common micro-controller objects
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
This section lists some commonly used config commands.
|
||||||
|
|
||||||
|
* `config_digital_out oid=%c pin=%u default_value=%c
|
||||||
|
max_duration=%u` : This command creates an internal micro-controller
|
||||||
|
object for the given GPIO 'pin'. The pin will be configured in
|
||||||
|
digital output mode and set to an initial value as specified by
|
||||||
|
'default_value' (0 for low, 1 for high). Creating a digital_out
|
||||||
|
object allows the host to schedule GPIO updates for the given pin at
|
||||||
|
specified times (see the schedule_digital_out command described
|
||||||
|
below). Should the micro-controller software go into shutdown mode
|
||||||
|
then all configured digital_out objects will be set back to their
|
||||||
|
default values. The 'max_duration' parameter is used to implement a
|
||||||
|
safety check - if it is non-zero then it is the maximum number of
|
||||||
|
clock ticks that the host may set the given GPIO to a non-default
|
||||||
|
value without further updates. For example, if the default_value is
|
||||||
|
zero and the max_duration is 16000 then if the host sets the gpio to
|
||||||
|
a value of one then it must schedule another update to the gpio pin
|
||||||
|
(to either zero or one) within 16000 clock ticks. This safety
|
||||||
|
feature can be used with heater pins to ensure the host does not
|
||||||
|
enable the heater and then go off-line.
|
||||||
|
|
||||||
|
* `config_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c
|
||||||
|
max_duration=%u` : This command creates an internal object for
|
||||||
|
hardware based PWM pins that the host may schedule updates for. Its
|
||||||
|
usage is analogous to config_digital_out - see the description of
|
||||||
|
the 'set_pwm_out' and 'config_digital_out' commands for parameter
|
||||||
|
description.
|
||||||
|
|
||||||
|
* `config_soft_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c
|
||||||
|
max_duration=%u` : This command creates an internal micro-controller
|
||||||
|
object for software implemented PWM. Unlike hardware pwm pins, a
|
||||||
|
software pwm object does not require any special hardware support
|
||||||
|
(other than the ability to configure the pin as a digital output
|
||||||
|
GPIO). Because the output switching is implemented in the
|
||||||
|
micro-controller software, it is recommended that the cycle_ticks
|
||||||
|
parameter correspond to a time of 10ms or greater. See the
|
||||||
|
description of the 'set_pwm_out' and 'config_digital_out' commands
|
||||||
|
for parameter description.
|
||||||
|
|
||||||
|
* `config_analog_in oid=%c pin=%u` : This command is used to configure
|
||||||
|
a pin in analog input sampling mode. Once configured, the pin can be
|
||||||
|
sampled at regular interval using the query_analog_in command (see
|
||||||
|
below).
|
||||||
|
|
||||||
|
* `config_stepper oid=%c step_pin=%c dir_pin=%c min_stop_interval=%u
|
||||||
|
invert_step=%c` : This command creates an internal stepper
|
||||||
|
object. The 'step_pin' and 'dir_pin' parameters specify the step and
|
||||||
|
direction pins respectively; this command will configure them in
|
||||||
|
digital output mode. The 'invert_step' parameter specifies whether a
|
||||||
|
step occurs on a rising edge (invert_step=0) or falling edge
|
||||||
|
(invert_step=1). The 'min_stop_interval' implements a safety
|
||||||
|
feature - it is checked when the micro-controller finishes all moves
|
||||||
|
for a stepper - if it is non-zero it specifies the minimum number of
|
||||||
|
clock ticks since the last step. It is used as a check on the
|
||||||
|
maximum stepper velocity that a stepper may have before stopping.
|
||||||
|
|
||||||
|
* `config_end_stop oid=%c pin=%c pull_up=%c stepper_count=%c` : This
|
||||||
|
command creates an internal "endstop" object. It is used to specify
|
||||||
|
the endstop pins and to enable "homing" operations (see the
|
||||||
|
end_stop_home command below). The command will configure the
|
||||||
|
specified pin in digital input mode. The 'pull_up' parameter
|
||||||
|
determines whether hardware provided pullup resistors for the pin
|
||||||
|
(if available) will be enabled. The 'stepper_count' parameter
|
||||||
|
specifies the maximum number of steppers that this endstop may need
|
||||||
|
to halt during a homing operation (see end_stop_home below).
|
||||||
|
|
||||||
|
Common commands
|
||||||
|
===============
|
||||||
|
|
||||||
|
This section lists some commonly used run-time commands. It is likely
|
||||||
|
only of interest to developers looking to gain insight into Klipper.
|
||||||
|
|
||||||
|
* `schedule_digital_out oid=%c clock=%u value=%c` : This command will
|
||||||
|
schedule a change to a digital output GPIO pin at the given clock
|
||||||
|
time. To use this command a 'config_digital_out' command with the
|
||||||
|
same 'oid' parameter must have been issued during micro-controller
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
* `schedule_pwm_out oid=%c clock=%u value=%c` : Schedules a change to
|
||||||
|
a hardware PWM output pin. See the 'schedule_digital_out' and
|
||||||
|
'config_pwm_out' commands for more info.
|
||||||
|
|
||||||
|
* `schedule_soft_pwm_out oid=%c clock=%u value=%c` : Schedules a
|
||||||
|
change to a software PWM output pin. See the 'schedule_digital_out'
|
||||||
|
and 'config_soft_pwm_out' commands for more info.
|
||||||
|
|
||||||
|
* `query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c
|
||||||
|
rest_ticks=%u min_value=%hu max_value=%hu` : This command sets up a
|
||||||
|
recurring schedule of analog input samples. To use this command a
|
||||||
|
'config_analog_in' command with the same 'oid' parameter must have
|
||||||
|
been issued during micro-controller configuration. The samples will
|
||||||
|
start as of 'clock' time, it will report on the obtained value every
|
||||||
|
'rest_ticks' clock ticks, it will over-sample 'sample_count' number
|
||||||
|
of times, and it will pause 'sample_ticks' number of clock ticks
|
||||||
|
between over-sample samples. The 'min_value' and 'max_value'
|
||||||
|
parameters implement a safety feature - the micro-controller
|
||||||
|
software will verify the sampled value (after any oversampling) is
|
||||||
|
always between the supplied range. This is intended for use with
|
||||||
|
pins attached to thermistors controlling heaters - it can be used to
|
||||||
|
check that a heater is within a temperature range.
|
||||||
|
|
||||||
|
* `get_status` : This command causes the micro-controller to generate
|
||||||
|
a "status" response message. The host sends this command once a
|
||||||
|
second to obtain the value of the micro-controller clock and to
|
||||||
|
estimate the drift between host and micro-controller clocks. It
|
||||||
|
enables the host to accurately estimate the micro-controller clock.
|
||||||
|
|
||||||
|
Stepper commands
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* `queue_step oid=%c interval=%u count=%hu add=%hi` : This command
|
||||||
|
schedules 'count' number of steps for the given stepper, with
|
||||||
|
'interval' number of clock ticks between each step. The first step
|
||||||
|
will be 'interval' number of clock ticks since the last scheduled
|
||||||
|
step for the given stepper. If 'add' is non-zero then the interval
|
||||||
|
will be adjusted by 'add' amount after each step. This command
|
||||||
|
appends the given interval/count/add sequence to a per-stepper
|
||||||
|
queue. There may be hundreds of these sequences queued during normal
|
||||||
|
operation. New sequence are appended to the end of the queue and as
|
||||||
|
each sequence completes its 'count' number of steps it is popped
|
||||||
|
from the front of the queue. This system allows the micro-controller
|
||||||
|
to queue potentially hundreds of thousands of steps - all with
|
||||||
|
reliable and predictable schedule times.
|
||||||
|
|
||||||
|
* `set_next_step_dir oid=%c dir=%c` : This command specifies the value
|
||||||
|
of the dir_pin that the next queue_step command will use.
|
||||||
|
|
||||||
|
* `reset_step_clock oid=%c clock=%u` : Normally, step timing is
|
||||||
|
relative to the last step for a given stepper. This command resets
|
||||||
|
the clock so that the next step is relative to the supplied 'clock'
|
||||||
|
time. The host usually only sends this command at the start of a
|
||||||
|
print.
|
||||||
|
|
||||||
|
* `stepper_get_position oid=%c` : This command causes the
|
||||||
|
micro-controller to generate a "stepper_position" response message
|
||||||
|
with the stepper's current position. The position is the total
|
||||||
|
number of steps generated with dir=1 minus the total number of steps
|
||||||
|
generated with dir=0.
|
||||||
|
|
||||||
|
* `end_stop_home oid=%c clock=%u rest_ticks=%u pin_value=%c` : This
|
||||||
|
command is used during stepper "homing" operations. To use this
|
||||||
|
command a 'config_end_stop' command with the same 'oid' parameter
|
||||||
|
must have been issued during micro-controller configuration. When
|
||||||
|
this command is invoked, the micro-controller will sample the
|
||||||
|
endstop pin every 'rest_ticks' clock ticks and check if it has a
|
||||||
|
value equal to 'pin_value'. If the value matches then the movement
|
||||||
|
queue for the associated stepper will be cleared and the stepper
|
||||||
|
will come to an immediate halt. The host uses this command to
|
||||||
|
implement homing - the host instructs the endstop to sample for the
|
||||||
|
endstop trigger and then it issues a series of queue_step commands
|
||||||
|
to move a stepper towards the endstop. Once the stepper hits the
|
||||||
|
endstop, the trigger will be detected, the movement halted, and the
|
||||||
|
host notified.
|
||||||
|
|
||||||
|
### Move queue
|
||||||
|
|
||||||
|
Each queue_step command utilizes an entry in the micro-controller
|
||||||
|
"move queue". This queue is allocated when it receives the
|
||||||
|
"finalize_config" command, and it reports the number of available
|
||||||
|
queue entries in "config" response messages.
|
||||||
|
|
||||||
|
It is the responsibility of the host to ensure that there is available
|
||||||
|
space in the queue before sending a queue_step command. The host does
|
||||||
|
this by calculating when each queue_step command completes and
|
||||||
|
scheduling new queue_step commands accordingly.
|
|
@ -15,9 +15,9 @@ See [code overview](Code_Overview.md) for information on the structure
|
||||||
and layout of the Klipper code.
|
and layout of the Klipper code.
|
||||||
|
|
||||||
See [protocol](Protocol.md) for information on the messaging protocol
|
See [protocol](Protocol.md) for information on the messaging protocol
|
||||||
between host and firmware. See also
|
between host and micro-controller. See also
|
||||||
[firmware commands](Firmware_Commands.md) for a high-level description
|
[MCU commands](MCU_Commands.md) for a description of low-level
|
||||||
of common commands implemented in the firmware.
|
commands implemented in the micro-controller software.
|
||||||
|
|
||||||
See [debugging](Debugging.md) for information on how to test and debug
|
See [debugging](Debugging.md) for information on how to test and debug
|
||||||
Klipper.
|
Klipper.
|
||||||
|
|
256
docs/Protocol.md
256
docs/Protocol.md
|
@ -1,8 +1,9 @@
|
||||||
The Klipper transmission protocol can be thought of, at a high level,
|
The Klipper messaging protocol is used for low-level communication
|
||||||
as a series of command and response strings that are compressed,
|
between the Klipper host software and the Klipper micro-controller
|
||||||
transmitted over a serial line, and then processed at the receiving
|
software. At a high level the protocol can be thought of as a series
|
||||||
side. An example series of commands in uncompressed human-readable
|
of command and response strings that are compressed, transmitted, and
|
||||||
format might look like:
|
then processed at the receiving side. An example series of commands in
|
||||||
|
uncompressed human-readable format might look like:
|
||||||
|
|
||||||
```
|
```
|
||||||
set_digital_out pin=86 value=1
|
set_digital_out pin=86 value=1
|
||||||
|
@ -12,34 +13,35 @@ queue_step oid=7 interval=7458 count=10 add=331
|
||||||
queue_step oid=7 interval=11717 count=4 add=1281
|
queue_step oid=7 interval=11717 count=4 add=1281
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [firmware commands](Firmware_Commands.md) document for
|
See the [mcu commands](MCU_Commands.md) document for information on
|
||||||
information on available commands. See the [debugging](Debugging.md)
|
available commands. See the [debugging](Debugging.md) document for
|
||||||
document for information on how to translate a G-Code file into its
|
information on how to translate a G-Code file into its corresponding
|
||||||
corresponding human-readable firmware commands.
|
human-readable micro-controller commands.
|
||||||
|
|
||||||
This page provides a high-level description of the Klipper
|
This page provides a high-level description of the Klipper messaging
|
||||||
transmission protocol itself. It describes how messages are declared,
|
protocol itself. It describes how messages are declared, encoded in
|
||||||
encoded in binary format (the "compression" scheme), and transmitted.
|
binary format (the "compression" scheme), and transmitted.
|
||||||
|
|
||||||
The goal of the protocol is to enable an error-free communication
|
The goal of the protocol is to enable an error-free communication
|
||||||
channel between the host and firmware that is low-latency,
|
channel between the host and micro-controller that is low-latency,
|
||||||
low-bandwidth, and low-complexity for the firmware.
|
low-bandwidth, and low-complexity for the micro-controller.
|
||||||
|
|
||||||
Firmware Interface
|
Micro-controller Interface
|
||||||
==================
|
==========================
|
||||||
|
|
||||||
The Klipper transmission protocol can be thought of as a
|
The Klipper transmission protocol can be thought of as a
|
||||||
[RPC](https://en.wikipedia.org/wiki/Remote_procedure_call) mechanism
|
[RPC](https://en.wikipedia.org/wiki/Remote_procedure_call) mechanism
|
||||||
between firmware and host. The firmware declares the commands that the
|
between micro-controller and host. The micro-controller software
|
||||||
host may invoke along with the response messages that it can
|
declares the commands that the host may invoke along with the response
|
||||||
generate. The host uses that information to command the firmware to
|
messages that it can generate. The host uses that information to
|
||||||
perform actions and to interpret the results.
|
command the micro-controller to perform actions and to interpret the
|
||||||
|
results.
|
||||||
|
|
||||||
Declaring commands
|
Declaring commands
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
The firmware declares a "command" by using the DECL_COMMAND() macro in
|
The micro-controller software declares a "command" by using the
|
||||||
the C code. For example:
|
DECL_COMMAND() macro in the C code. For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
DECL_COMMAND(command_set_digital_out, "set_digital_out pin=%u value=%c");
|
DECL_COMMAND(command_set_digital_out, "set_digital_out pin=%u value=%c");
|
||||||
|
@ -48,11 +50,11 @@ DECL_COMMAND(command_set_digital_out, "set_digital_out pin=%u value=%c");
|
||||||
The above declares a command named "set_digital_out". This allows the
|
The above declares a command named "set_digital_out". This allows the
|
||||||
host to "invoke" this command which would cause the
|
host to "invoke" this command which would cause the
|
||||||
command_set_digital_out() C function to be executed in the
|
command_set_digital_out() C function to be executed in the
|
||||||
firmware. The above also indicates that the command takes two integer
|
micro-controller. The above also indicates that the command takes two
|
||||||
parameters. When the command_set_digital_out() C code is executed, it
|
integer parameters. When the command_set_digital_out() C code is
|
||||||
will be passed an array containing these two integers - the first
|
executed, it will be passed an array containing these two integers -
|
||||||
corresponding to the 'pin' and the second corresponding to the
|
the first corresponding to the 'pin' and the second corresponding to
|
||||||
'value'.
|
the 'value'.
|
||||||
|
|
||||||
In general, the parameters are described with printf() style syntax
|
In general, the parameters are described with printf() style syntax
|
||||||
(eg, "%u"). The formatting directly corresponds to the human-readable
|
(eg, "%u"). The formatting directly corresponds to the human-readable
|
||||||
|
@ -63,42 +65,42 @@ documentation. In this example, the "%c" is also used as documentation
|
||||||
to indicate the expected integer is 1 byte in size (the declared
|
to indicate the expected integer is 1 byte in size (the declared
|
||||||
integer size does not impact the parsing or encoding).
|
integer size does not impact the parsing or encoding).
|
||||||
|
|
||||||
At firmware compile time, the build will collect all commands declared
|
The micro-controller build will collect all commands declared with
|
||||||
with DECL_COMMAND(), determine their parameters, and arrange for them
|
DECL_COMMAND(), determine their parameters, and arrange for them to be
|
||||||
to be callable.
|
callable.
|
||||||
|
|
||||||
Declaring responses
|
Declaring responses
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
To send information from the firmware to the host a "response" is
|
To send information from the micro-controller to the host a "response"
|
||||||
generated. These are both declared and transmitted using the sendf() C
|
is generated. These are both declared and transmitted using the
|
||||||
macro. For example:
|
sendf() C macro. For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
sendf("status clock=%u status=%c", sched_read_time(), sched_is_shutdown());
|
sendf("status clock=%u status=%c", sched_read_time(), sched_is_shutdown());
|
||||||
```
|
```
|
||||||
|
|
||||||
The above transmits a "status" response message that contains two
|
The above transmits a "status" response message that contains two
|
||||||
integer parameters ("clock" and "status"). At firmware compile time
|
integer parameters ("clock" and "status"). The micro-controller build
|
||||||
the build automatically finds all sendf() calls and generates encoders
|
automatically finds all sendf() calls and generates encoders for
|
||||||
for them. The first parameter of the sendf() function describes the
|
them. The first parameter of the sendf() function describes the
|
||||||
response and it is in the same format as command declarations.
|
response and it is in the same format as command declarations.
|
||||||
|
|
||||||
The host can arrange to register a callback function for each
|
The host can arrange to register a callback function for each
|
||||||
response. So, in effect, commands allow the host to invoke C functions
|
response. So, in effect, commands allow the host to invoke C functions
|
||||||
in the firmware and responses allow the firmware to invoke code in the
|
in the micro-controller and responses allow the micro-controller
|
||||||
host.
|
software to invoke code in the host.
|
||||||
|
|
||||||
The firmware should only invoke sendf() from command or task handlers,
|
The sendf() macro should only be invoked from command or task
|
||||||
and it should not be invoked from interrupts or timers. The firmware
|
handlers, and it should not be invoked from interrupts or timers. The
|
||||||
does not need to issue a sendf() in response to a received command, it
|
code does not need to issue a sendf() in response to a received
|
||||||
is not limited in the number of times sendf() may be invoked, and it
|
command, it is not limited in the number of times sendf() may be
|
||||||
may invoke sendf() at any time from a task handler.
|
invoked, and it may invoke sendf() at any time from a task handler.
|
||||||
|
|
||||||
### Output responses
|
### Output responses
|
||||||
|
|
||||||
To simplify debugging, the firmware also has an output() C
|
To simplify debugging, there is also has an output() C function. For
|
||||||
function. For example:
|
example:
|
||||||
|
|
||||||
```
|
```
|
||||||
output("The value of %u is %s with size %u.", x, buf, buf_len);
|
output("The value of %u is %s with size %u.", x, buf, buf_len);
|
||||||
|
@ -110,15 +112,14 @@ to generate and format arbitrary messages for human consumption.
|
||||||
Declaring constants
|
Declaring constants
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
The firmware can also define constants to be exported. For example,
|
Constants can also be exported. For example, the following:
|
||||||
the following:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
DECL_CONSTANT(SERIAL_BAUD, 250000);
|
DECL_CONSTANT(SERIAL_BAUD, 250000);
|
||||||
```
|
```
|
||||||
|
|
||||||
would export a constant named "SERIAL_BAUD" with a value of 250000
|
would export a constant named "SERIAL_BAUD" with a value of 250000
|
||||||
from the firmware to the host.
|
from the micro-controller to the host.
|
||||||
|
|
||||||
Low-level message encoding
|
Low-level message encoding
|
||||||
==========================
|
==========================
|
||||||
|
@ -130,9 +131,9 @@ the transmission system.
|
||||||
Message Blocks
|
Message Blocks
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
All data sent from host to firmware and vice-versa are contained in
|
All data sent from host to micro-controller and vice-versa are
|
||||||
"message blocks". A message block has a two byte header and a three
|
contained in "message blocks". A message block has a two byte header
|
||||||
byte trailer. The format of a message block is:
|
and a three byte trailer. The format of a message block is:
|
||||||
|
|
||||||
```
|
```
|
||||||
<1 byte length><1 byte sequence><n-byte content><2 byte crc><1 byte sync>
|
<1 byte length><1 byte sequence><n-byte content><2 byte crc><1 byte sync>
|
||||||
|
@ -160,11 +161,11 @@ present in the message block content.
|
||||||
Message Block Contents
|
Message Block Contents
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
Each message block sent from host to firmware contains a series of
|
Each message block sent from host to micro-controller contains a
|
||||||
zero or more message commands in its contents. Each command starts
|
series of zero or more message commands in its contents. Each command
|
||||||
with a [Variable Length Quantity](#variable-length-quantities) (VLQ)
|
starts with a [Variable Length Quantity](#variable-length-quantities)
|
||||||
encoded integer command-id followed by zero or more VLQ parameters for
|
(VLQ) encoded integer command-id followed by zero or more VLQ
|
||||||
the given command.
|
parameters for the given command.
|
||||||
|
|
||||||
As an example, the following four commands might be placed in a single
|
As an example, the following four commands might be placed in a single
|
||||||
message block:
|
message block:
|
||||||
|
@ -183,21 +184,22 @@ and encoded into the following eight VLQ integers:
|
||||||
```
|
```
|
||||||
|
|
||||||
In order to encode and parse the message contents, both the host and
|
In order to encode and parse the message contents, both the host and
|
||||||
firmware must agree on the command ids and the number of parameters
|
micro-controller must agree on the command ids and the number of
|
||||||
each command has. So, in the above example, both the host and firmware
|
parameters each command has. So, in the above example, both the host
|
||||||
would know that "id_set_digital_out" is always followed by two
|
and micro-controller would know that "id_set_digital_out" is always
|
||||||
parameters, and "id_get_config" and "id_get_status" have zero
|
followed by two parameters, and "id_get_config" and "id_get_status"
|
||||||
parameters. The host and firmware share a "data dictionary" that maps
|
have zero parameters. The host and micro-controller share a "data
|
||||||
the command descriptions (eg, "set_digital_out pin=%u value=%c") to
|
dictionary" that maps the command descriptions (eg, "set_digital_out
|
||||||
their integer command-ids. When processing the data, the parser will
|
pin=%u value=%c") to their integer command-ids. When processing the
|
||||||
know to expect a specific number of VLQ encoded parameters following a
|
data, the parser will know to expect a specific number of VLQ encoded
|
||||||
given command id.
|
parameters following a given command id.
|
||||||
|
|
||||||
The message contents for blocks sent from firmware to host follow the
|
The message contents for blocks sent from micro-controller to host
|
||||||
same format. The identifiers in these messages are "response ids", but
|
follow the same format. The identifiers in these messages are
|
||||||
they serve the same purpose and follow the same encoding rules. In
|
"response ids", but they serve the same purpose and follow the same
|
||||||
practice, message blocks sent from the firmware to the host never
|
encoding rules. In practice, message blocks sent from the
|
||||||
contain more than one response in the message block contents.
|
micro-controller to the host never contain more than one response in
|
||||||
|
the message block contents.
|
||||||
|
|
||||||
### Variable Length Quantities
|
### Variable Length Quantities
|
||||||
|
|
||||||
|
@ -229,60 +231,62 @@ the length as a VLQ encoded integer followed by the contents itself:
|
||||||
```
|
```
|
||||||
|
|
||||||
The command descriptions found in the data dictionary allow both the
|
The command descriptions found in the data dictionary allow both the
|
||||||
host and firmware to know which command parameters use simple VLQ
|
host and micro-controller to know which command parameters use simple
|
||||||
encoding and which parameters use string encoding.
|
VLQ encoding and which parameters use string encoding.
|
||||||
|
|
||||||
Data Dictionary
|
Data Dictionary
|
||||||
===============
|
===============
|
||||||
|
|
||||||
In order for meaningful communications to be established between
|
In order for meaningful communications to be established between
|
||||||
firmware and host, both sides must agree on a "data dictionary". This
|
micro-controller and host, both sides must agree on a "data
|
||||||
data dictionary contains the integer identifiers for commands and
|
dictionary". This data dictionary contains the integer identifiers for
|
||||||
responses along with their descriptions.
|
commands and responses along with their descriptions.
|
||||||
|
|
||||||
At compile time the firmware build uses the contents of DECL_COMMAND()
|
The micro-controller build uses the contents of DECL_COMMAND() and
|
||||||
and sendf() macros to generate the data dictionary. The build
|
sendf() macros to generate the data dictionary. The build
|
||||||
automatically assigns unique identifiers to each command and
|
automatically assigns unique identifiers to each command and
|
||||||
response. This system allows both the host and firmware code to
|
response. This system allows both the host and micro-controller code
|
||||||
seamlessly use descriptive human-readable names while still using
|
to seamlessly use descriptive human-readable names while still using
|
||||||
minimal bandwidth.
|
minimal bandwidth.
|
||||||
|
|
||||||
The host queries the data dictionary when it first connects to the
|
The host queries the data dictionary when it first connects to the
|
||||||
firmware. Once the host downloads the data dictionary from the
|
micro-controller. Once the host downloads the data dictionary from the
|
||||||
firmware, it uses that data dictionary to encode all commands and to
|
micro-controller, it uses that data dictionary to encode all commands
|
||||||
parse all responses from the firmware. The host must therefore handle
|
and to parse all responses from the micro-controller. The host must
|
||||||
a dynamic data dictionary. However, to keep the firmware simple, the
|
therefore handle a dynamic data dictionary. However, to keep the
|
||||||
firmware always uses its static (compiled in) data dictionary.
|
micro-controller software simple, the micro-controller always uses its
|
||||||
|
static (compiled in) data dictionary.
|
||||||
|
|
||||||
The data dictionary is queried by sending "identify" commands to the
|
The data dictionary is queried by sending "identify" commands to the
|
||||||
firmware. The firmware will respond to each identify command with an
|
micro-controller. The micro-controller will respond to each identify
|
||||||
"identify_response" message. Since these two commands are needed prior
|
command with an "identify_response" message. Since these two commands
|
||||||
to obtaining the data dictionary, their integer ids and parameter
|
are needed prior to obtaining the data dictionary, their integer ids
|
||||||
types are hard-coded in both the firmware and the host. The
|
and parameter types are hard-coded in both the micro-controller and
|
||||||
"identify_response" response id is 0, the "identify" command id
|
the host. The "identify_response" response id is 0, the "identify"
|
||||||
is 1. Other than having hard-coded ids the identify command and its
|
command id is 1. Other than having hard-coded ids the identify command
|
||||||
response are declared and transmitted the same way as other commands
|
and its response are declared and transmitted the same way as other
|
||||||
and responses. No other command or response is hard-coded.
|
commands and responses. No other command or response is hard-coded.
|
||||||
|
|
||||||
The format of the transmitted data dictionary itself is a zlib
|
The format of the transmitted data dictionary itself is a zlib
|
||||||
compressed JSON string. The firmware compile process generates the
|
compressed JSON string. The micro-controller build process generates
|
||||||
string, compresses it, and stores it in the text section of the
|
the string, compresses it, and stores it in the text section of the
|
||||||
firmware. The data dictionary can be much larger than the maximum
|
micro-controller flash. The data dictionary can be much larger than
|
||||||
message block size - the host downloads it by sending multiple
|
the maximum message block size - the host downloads it by sending
|
||||||
identify commands requesting progressive chunks of the data
|
multiple identify commands requesting progressive chunks of the data
|
||||||
dictionary. Once all chunks are obtained the host will assemble the
|
dictionary. Once all chunks are obtained the host will assemble the
|
||||||
chunks, uncompress the data, and parse the contents.
|
chunks, uncompress the data, and parse the contents.
|
||||||
|
|
||||||
In addition to information on the communication protocol, the data
|
In addition to information on the communication protocol, the data
|
||||||
dictionary also contains firmware version, constants (as defined by
|
dictionary also contains the software version, constants (as defined
|
||||||
DECL_CONSTANT), and static strings.
|
by DECL_CONSTANT), and static strings.
|
||||||
|
|
||||||
Static Strings
|
Static Strings
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
To reduce bandwidth the data dictionary also contains a set of static
|
To reduce bandwidth the data dictionary also contains a set of static
|
||||||
strings known to the firmware. This is useful when sending messages
|
strings known to the micro-controller. This is useful when sending
|
||||||
from firmware to host. For example, if the firmware were to run:
|
messages from micro-controller to host. For example, if the
|
||||||
|
micro-controller were to run:
|
||||||
|
|
||||||
```
|
```
|
||||||
shutdown("Unable to handle command");
|
shutdown("Unable to handle command");
|
||||||
|
@ -295,22 +299,22 @@ to their associated human-readable strings.
|
||||||
Message flow
|
Message flow
|
||||||
============
|
============
|
||||||
|
|
||||||
Message commands sent from host to firmware are intended to be
|
Message commands sent from host to micro-controller are intended to be
|
||||||
error-free. The firmware will check the CRC and sequence numbers in
|
error-free. The micro-controller will check the CRC and sequence
|
||||||
each message block to ensure the commands are accurate and
|
numbers in each message block to ensure the commands are accurate and
|
||||||
in-order. The firmware always processes message blocks in-order -
|
in-order. The micro-controller always processes message blocks
|
||||||
should it receive a block out-of-order it will discard it and any
|
in-order - should it receive a block out-of-order it will discard it
|
||||||
other out-of-order blocks until it receives blocks with the correct
|
and any other out-of-order blocks until it receives blocks with the
|
||||||
sequencing.
|
correct sequencing.
|
||||||
|
|
||||||
The low-level host code implements an automatic retransmission system
|
The low-level host code implements an automatic retransmission system
|
||||||
for lost and corrupt message blocks sent to the firmware. To
|
for lost and corrupt message blocks sent to the micro-controller. To
|
||||||
facilitate this, the firmware transmits an "ack message block" after
|
facilitate this, the micro-controller transmits an "ack message block"
|
||||||
each successfully received message block. The host schedules a timeout
|
after each successfully received message block. The host schedules a
|
||||||
after sending each block and it will retransmit should the timeout
|
timeout after sending each block and it will retransmit should the
|
||||||
expire without receiving a corresponding "ack". In addition, if the
|
timeout expire without receiving a corresponding "ack". In addition,
|
||||||
firmware detects a corrupt or out-of-order block it may transmit a
|
if the micro-controller detects a corrupt or out-of-order block it may
|
||||||
"nak message block" to facilitate fast retransmission.
|
transmit a "nak message block" to facilitate fast retransmission.
|
||||||
|
|
||||||
An "ack" is a message block with empty content (ie, a 5 byte message
|
An "ack" is a message block with empty content (ie, a 5 byte message
|
||||||
block) and a sequence number greater than the last received host
|
block) and a sequence number greater than the last received host
|
||||||
|
@ -325,15 +329,15 @@ in the event of transmission latency. The timeout, retransmit,
|
||||||
windowing, and ack mechanism are inspired by similar mechanisms in
|
windowing, and ack mechanism are inspired by similar mechanisms in
|
||||||
[TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol).
|
[TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol).
|
||||||
|
|
||||||
In the other direction, message blocks sent from firmware to host are
|
In the other direction, message blocks sent from micro-controller to
|
||||||
designed to be error-free, but they do not have assured
|
host are designed to be error-free, but they do not have assured
|
||||||
transmission. (Responses should not be corrupt, but they may go
|
transmission. (Responses should not be corrupt, but they may go
|
||||||
missing.) This is done to keep the implementation in the firmware
|
missing.) This is done to keep the implementation in the
|
||||||
simple. There is no automatic retransmission system for responses -
|
micro-controller simple. There is no automatic retransmission system
|
||||||
the high-level code is expected to be capable of handling an
|
for responses - the high-level code is expected to be capable of
|
||||||
occasional missing response (usually by re-requesting the content or
|
handling an occasional missing response (usually by re-requesting the
|
||||||
setting up a recurring schedule of response transmission). The
|
content or setting up a recurring schedule of response
|
||||||
sequence number field in message blocks sent to the host is always one
|
transmission). The sequence number field in message blocks sent to the
|
||||||
greater than the last received sequence number of message blocks
|
host is always one greater than the last received sequence number of
|
||||||
received from the host. It is not used to track sequences of response
|
message blocks received from the host. It is not used to track
|
||||||
message blocks.
|
sequences of response message blocks.
|
||||||
|
|
21
docs/Todo.md
21
docs/Todo.md
|
@ -31,12 +31,12 @@ Host user interaction
|
||||||
Safety features
|
Safety features
|
||||||
===============
|
===============
|
||||||
|
|
||||||
* Support loading a valid step range into the firmware after
|
* Support loading a valid step range into the micro-controller
|
||||||
homing. This would provide a sanity check in the firmware that would
|
software after homing. This would provide a sanity check in the
|
||||||
reduce the risk of the host commanding a stepper motor past its
|
micro-controller that would reduce the risk of the host commanding a
|
||||||
valid step range. To maintain high efficiency in the firmware, the
|
stepper motor past its valid step range. To maintain high
|
||||||
firmware would only need to check periodically (eg, every 100ms)
|
efficiency, the micro-controller would only need to check
|
||||||
that the stepper is in range.
|
periodically (eg, every 100ms) that the stepper is in range.
|
||||||
|
|
||||||
* Possibly support periodically querying the endstop switches and use
|
* Possibly support periodically querying the endstop switches and use
|
||||||
multiple step ranges depending on the switch state. This would
|
multiple step ranges depending on the switch state. This would
|
||||||
|
@ -52,9 +52,10 @@ Testing features
|
||||||
================
|
================
|
||||||
|
|
||||||
* Complete the host based simulator. It's possible to compile the
|
* Complete the host based simulator. It's possible to compile the
|
||||||
firmware for a "host simulator", but that simulator doesn't do
|
micro-controller for a "host simulator", but that simulator doesn't
|
||||||
anything currently. It would be useful to expand the code to support
|
do anything currently. It would be useful to expand the code to
|
||||||
more error checks, kinematic simulations, and improved logging.
|
support more error checks, kinematic simulations, and improved
|
||||||
|
logging.
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
=============
|
=============
|
||||||
|
@ -67,7 +68,7 @@ Documentation
|
||||||
Hardware features
|
Hardware features
|
||||||
=================
|
=================
|
||||||
|
|
||||||
* Port firmware to more architectures:
|
* Port to additional micro-controller architectures:
|
||||||
* Beagle Bone Black PRU
|
* Beagle Bone Black PRU
|
||||||
* Smoothieboard / NXP LPC1769 (ARM cortex-M3)
|
* Smoothieboard / NXP LPC1769 (ARM cortex-M3)
|
||||||
* Unix based scheduling; Unix based real-time scheduling
|
* Unix based scheduling; Unix based real-time scheduling
|
||||||
|
|
Loading…
Reference in New Issue