diff --git a/docs/Code_Overview.md b/docs/Code_Overview.md index abc60403..bfff4021 100644 --- a/docs/Code_Overview.md +++ b/docs/Code_Overview.md @@ -17,7 +17,7 @@ host architectures. The build arranges for includes of src/generic/somefile.h). 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 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 command-line arguments, opens the printer config file, instantiates the main printer objects, and starts the serial connection. The main -execution of gcode commands is in the process_commands() method in -**klippy/gcode.py**. This code translates the gcode commands into +execution of G-code commands is in the process_commands() method in +**klippy/gcode.py**. This code translates the G-code commands into printer object calls, which frequently translate the actions to commands to be executed on the micro-controller (as declared via the DECL_COMMAND macro in the micro-controller code). diff --git a/docs/Debugging.md b/docs/Debugging.md index eaac6748..51f1ac53 100644 --- a/docs/Debugging.md +++ b/docs/Debugging.md @@ -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 -firmware commands associated with a gcode file. Inspecting these -low-level firmware commands is useful when trying to understand the +micro-controller commands associated with a gcode file. Inspecting +these low-level commands is useful when trying to understand the 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 generate the firmware "data dictionary". This is done by compiling -the firmware code to obtain the **out/klipper.dict** file: +to generate the micro-controller "data dictionary". This is done by +compiling the micro-controller code to obtain the **out/klipper.dict** +file: ``` 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 -firmware commands. +micro-controller commands. The batch mode disables certain response / request commands in order to function. As a result, there will be some differences between -actual firmware commands and the above output. The generated data is -useful for testing and inspection; it is not useful for sending to a -real micro-controller. +actual commands and the above output. The generated data is useful for +testing and inspection; it is not useful for sending to a real +micro-controller. Testing with simulavr ===================== @@ -74,9 +75,10 @@ cd /patch/to/klipper make menuconfig ``` -and compile the firmware for an AVR atmega644p, disable the AVR -watchdog timer, and set the MCU frequency to 20000000. Then one can -compile Klipper (run `make`) and then start the simulation with: +and compile the micro-controller software for an AVR atmega644p, +disable the AVR watchdog timer, and set the MCU frequency +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 diff --git a/docs/Features.md b/docs/Features.md index 2857e9bd..dbc28ca4 100644 --- a/docs/Features.md +++ b/docs/Features.md @@ -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 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. * Simpler code. Klipper uses a very high level language (Python) for - most code. The kinematics algorithms, the gcode parsing, the heating - and thermistor algorithms, etc. are all written in Python. This - makes it easier to develop new functionality. + most code. The kinematics algorithms, the G-code parsing, the + heating and thermistor algorithms, etc. are all written in + Python. This makes it easier to develop new functionality. * Advanced features: * 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 decelerate back to a standstill. -* "Lookahead" support. The incoming stream of G-Code movement commands - are queued and analyzed - the acceleration between movements in a - similar direction will be optimized to reduce print stalls and - improve overall print time. +* "Look-ahead" support. The incoming stream of G-Code movement + commands are queued and analyzed - the acceleration between + movements in a similar direction will be optimized to reduce print + stalls and improve overall print time. * Support for cartesian, delta, and corexy style printers. diff --git a/docs/Firmware_Commands.md b/docs/Firmware_Commands.md deleted file mode 100644 index 6678b3c6..00000000 --- a/docs/Firmware_Commands.md +++ /dev/null @@ -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. diff --git a/docs/MCU_Commands.md b/docs/MCU_Commands.md new file mode 100644 index 00000000..c1544d2a --- /dev/null +++ b/docs/MCU_Commands.md @@ -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. diff --git a/docs/Overview.md b/docs/Overview.md index da72f5f0..813cff6a 100644 --- a/docs/Overview.md +++ b/docs/Overview.md @@ -15,9 +15,9 @@ See [code overview](Code_Overview.md) for information on the structure and layout of the Klipper code. See [protocol](Protocol.md) for information on the messaging protocol -between host and firmware. See also -[firmware commands](Firmware_Commands.md) for a high-level description -of common commands implemented in the firmware. +between host and micro-controller. See also +[MCU commands](MCU_Commands.md) for a description of low-level +commands implemented in the micro-controller software. See [debugging](Debugging.md) for information on how to test and debug Klipper. diff --git a/docs/Protocol.md b/docs/Protocol.md index 39b81a8a..fab5b5a5 100644 --- a/docs/Protocol.md +++ b/docs/Protocol.md @@ -1,8 +1,9 @@ -The Klipper transmission protocol can be thought of, at a high level, -as a series of command and response strings that are compressed, -transmitted over a serial line, and then processed at the receiving -side. An example series of commands in uncompressed human-readable -format might look like: +The Klipper messaging protocol is used for low-level communication +between the Klipper host software and the Klipper micro-controller +software. At a high level the protocol can be thought of as a series +of command and response strings that are compressed, transmitted, and +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 @@ -12,34 +13,35 @@ queue_step oid=7 interval=7458 count=10 add=331 queue_step oid=7 interval=11717 count=4 add=1281 ``` -See the [firmware commands](Firmware_Commands.md) document for -information on available commands. See the [debugging](Debugging.md) -document for information on how to translate a G-Code file into its -corresponding human-readable firmware commands. +See the [mcu commands](MCU_Commands.md) document for information on +available commands. See the [debugging](Debugging.md) document for +information on how to translate a G-Code file into its corresponding +human-readable micro-controller commands. -This page provides a high-level description of the Klipper -transmission protocol itself. It describes how messages are declared, -encoded in binary format (the "compression" scheme), and transmitted. +This page provides a high-level description of the Klipper messaging +protocol itself. It describes how messages are declared, encoded in +binary format (the "compression" scheme), and transmitted. The goal of the protocol is to enable an error-free communication -channel between the host and firmware that is low-latency, -low-bandwidth, and low-complexity for the firmware. +channel between the host and micro-controller that is low-latency, +low-bandwidth, and low-complexity for the micro-controller. -Firmware Interface -================== +Micro-controller Interface +========================== The Klipper transmission protocol can be thought of as a [RPC](https://en.wikipedia.org/wiki/Remote_procedure_call) mechanism -between firmware and host. The firmware declares the commands that the -host may invoke along with the response messages that it can -generate. The host uses that information to command the firmware to -perform actions and to interpret the results. +between micro-controller and host. The micro-controller software +declares the commands that the host may invoke along with the response +messages that it can generate. The host uses that information to +command the micro-controller to perform actions and to interpret the +results. Declaring commands ------------------ -The firmware declares a "command" by using the DECL_COMMAND() macro in -the C code. For example: +The micro-controller software declares a "command" by using the +DECL_COMMAND() macro in the C code. For example: ``` 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 host to "invoke" this command which would cause the command_set_digital_out() C function to be executed in the -firmware. The above also indicates that the command takes two integer -parameters. When the command_set_digital_out() C code is executed, it -will be passed an array containing these two integers - the first -corresponding to the 'pin' and the second corresponding to the -'value'. +micro-controller. The above also indicates that the command takes two +integer parameters. When the command_set_digital_out() C code is +executed, it will be passed an array containing these two integers - +the first corresponding to the 'pin' and the second corresponding to +the 'value'. In general, the parameters are described with printf() style syntax (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 integer size does not impact the parsing or encoding). -At firmware compile time, the build will collect all commands declared -with DECL_COMMAND(), determine their parameters, and arrange for them -to be callable. +The micro-controller build will collect all commands declared with +DECL_COMMAND(), determine their parameters, and arrange for them to be +callable. Declaring responses ------------------- -To send information from the firmware to the host a "response" is -generated. These are both declared and transmitted using the sendf() C -macro. For example: +To send information from the micro-controller to the host a "response" +is generated. These are both declared and transmitted using the +sendf() C macro. For example: ``` sendf("status clock=%u status=%c", sched_read_time(), sched_is_shutdown()); ``` The above transmits a "status" response message that contains two -integer parameters ("clock" and "status"). At firmware compile time -the build automatically finds all sendf() calls and generates encoders -for them. The first parameter of the sendf() function describes the +integer parameters ("clock" and "status"). The micro-controller build +automatically finds all sendf() calls and generates encoders for +them. The first parameter of the sendf() function describes the response and it is in the same format as command declarations. The host can arrange to register a callback function for each 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 -host. +in the micro-controller and responses allow the micro-controller +software to invoke code in the host. -The firmware should only invoke sendf() from command or task handlers, -and it should not be invoked from interrupts or timers. The firmware -does not need to issue a sendf() in response to a received command, it -is not limited in the number of times sendf() may be invoked, and it -may invoke sendf() at any time from a task handler. +The sendf() macro should only be invoked from command or task +handlers, and it should not be invoked from interrupts or timers. The +code does not need to issue a sendf() in response to a received +command, it is not limited in the number of times sendf() may be +invoked, and it may invoke sendf() at any time from a task handler. ### Output responses -To simplify debugging, the firmware also has an output() C -function. For example: +To simplify debugging, there is also has an output() C function. For +example: ``` 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 ------------------- -The firmware can also define constants to be exported. For example, -the following: +Constants can also be exported. For example, the following: ``` DECL_CONSTANT(SERIAL_BAUD, 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 ========================== @@ -130,9 +131,9 @@ the transmission system. Message Blocks -------------- -All data sent from host to firmware and vice-versa are contained in -"message blocks". A message block has a two byte header and a three -byte trailer. The format of a message block is: +All data sent from host to micro-controller and vice-versa are +contained in "message blocks". A message block has a two byte header +and a three byte trailer. The format of a message block is: ``` <1 byte length><1 byte sequence><2 byte crc><1 byte sync> @@ -160,11 +161,11 @@ present in the message block content. Message Block Contents ---------------------- -Each message block sent from host to firmware contains a series of -zero or more message commands in its contents. Each command starts -with a [Variable Length Quantity](#variable-length-quantities) (VLQ) -encoded integer command-id followed by zero or more VLQ parameters for -the given command. +Each message block sent from host to micro-controller contains a +series of zero or more message commands in its contents. Each command +starts with a [Variable Length Quantity](#variable-length-quantities) +(VLQ) encoded integer command-id followed by zero or more VLQ +parameters for the given command. As an example, the following four commands might be placed in a single 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 -firmware must agree on the command ids and the number of parameters -each command has. So, in the above example, both the host and firmware -would know that "id_set_digital_out" is always followed by two -parameters, and "id_get_config" and "id_get_status" have zero -parameters. The host and firmware share a "data dictionary" that maps -the command descriptions (eg, "set_digital_out pin=%u value=%c") to -their integer command-ids. When processing the data, the parser will -know to expect a specific number of VLQ encoded parameters following a -given command id. +micro-controller must agree on the command ids and the number of +parameters each command has. So, in the above example, both the host +and micro-controller would know that "id_set_digital_out" is always +followed by two parameters, and "id_get_config" and "id_get_status" +have zero parameters. The host and micro-controller share a "data +dictionary" that maps the command descriptions (eg, "set_digital_out +pin=%u value=%c") to their integer command-ids. When processing the +data, the parser will know to expect a specific number of VLQ encoded +parameters following a given command id. -The message contents for blocks sent from firmware to host follow the -same format. The identifiers in these messages are "response ids", but -they serve the same purpose and follow the same encoding rules. In -practice, message blocks sent from the firmware to the host never -contain more than one response in the message block contents. +The message contents for blocks sent from micro-controller to host +follow the same format. The identifiers in these messages are +"response ids", but they serve the same purpose and follow the same +encoding rules. In practice, message blocks sent from the +micro-controller to the host never contain more than one response in +the message block contents. ### 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 -host and firmware to know which command parameters use simple VLQ -encoding and which parameters use string encoding. +host and micro-controller to know which command parameters use simple +VLQ encoding and which parameters use string encoding. Data Dictionary =============== In order for meaningful communications to be established between -firmware and host, both sides must agree on a "data dictionary". This -data dictionary contains the integer identifiers for commands and -responses along with their descriptions. +micro-controller and host, both sides must agree on a "data +dictionary". This data dictionary contains the integer identifiers for +commands and responses along with their descriptions. -At compile time the firmware build uses the contents of DECL_COMMAND() -and sendf() macros to generate the data dictionary. The build +The micro-controller build uses the contents of DECL_COMMAND() and +sendf() macros to generate the data dictionary. The build automatically assigns unique identifiers to each command and -response. This system allows both the host and firmware code to -seamlessly use descriptive human-readable names while still using +response. This system allows both the host and micro-controller code +to seamlessly use descriptive human-readable names while still using minimal bandwidth. The host queries the data dictionary when it first connects to the -firmware. Once the host downloads the data dictionary from the -firmware, it uses that data dictionary to encode all commands and to -parse all responses from the firmware. The host must therefore handle -a dynamic data dictionary. However, to keep the firmware simple, the -firmware always uses its static (compiled in) data dictionary. +micro-controller. Once the host downloads the data dictionary from the +micro-controller, it uses that data dictionary to encode all commands +and to parse all responses from the micro-controller. The host must +therefore handle a dynamic data dictionary. However, to keep the +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 -firmware. The firmware will respond to each identify command with an -"identify_response" message. Since these two commands are needed prior -to obtaining the data dictionary, their integer ids and parameter -types are hard-coded in both the firmware and the host. The -"identify_response" response id is 0, the "identify" command id -is 1. Other than having hard-coded ids the identify command and its -response are declared and transmitted the same way as other commands -and responses. No other command or response is hard-coded. +micro-controller. The micro-controller will respond to each identify +command with an "identify_response" message. Since these two commands +are needed prior to obtaining the data dictionary, their integer ids +and parameter types are hard-coded in both the micro-controller and +the host. The "identify_response" response id is 0, the "identify" +command id is 1. Other than having hard-coded ids the identify command +and its response are declared and transmitted the same way as other +commands and responses. No other command or response is hard-coded. The format of the transmitted data dictionary itself is a zlib -compressed JSON string. The firmware compile process generates the -string, compresses it, and stores it in the text section of the -firmware. The data dictionary can be much larger than the maximum -message block size - the host downloads it by sending multiple -identify commands requesting progressive chunks of the data +compressed JSON string. The micro-controller build process generates +the string, compresses it, and stores it in the text section of the +micro-controller flash. The data dictionary can be much larger than +the maximum message block size - the host downloads it by sending +multiple identify commands requesting progressive chunks of the data dictionary. Once all chunks are obtained the host will assemble the chunks, uncompress the data, and parse the contents. In addition to information on the communication protocol, the data -dictionary also contains firmware version, constants (as defined by -DECL_CONSTANT), and static strings. +dictionary also contains the software version, constants (as defined +by DECL_CONSTANT), and static strings. Static Strings -------------- To reduce bandwidth the data dictionary also contains a set of static -strings known to the firmware. This is useful when sending messages -from firmware to host. For example, if the firmware were to run: +strings known to the micro-controller. This is useful when sending +messages from micro-controller to host. For example, if the +micro-controller were to run: ``` shutdown("Unable to handle command"); @@ -295,22 +299,22 @@ to their associated human-readable strings. Message flow ============ -Message commands sent from host to firmware are intended to be -error-free. The firmware will check the CRC and sequence numbers in -each message block to ensure the commands are accurate and -in-order. The firmware always processes message blocks in-order - -should it receive a block out-of-order it will discard it and any -other out-of-order blocks until it receives blocks with the correct -sequencing. +Message commands sent from host to micro-controller are intended to be +error-free. The micro-controller will check the CRC and sequence +numbers in each message block to ensure the commands are accurate and +in-order. The micro-controller always processes message blocks +in-order - should it receive a block out-of-order it will discard it +and any other out-of-order blocks until it receives blocks with the +correct sequencing. The low-level host code implements an automatic retransmission system -for lost and corrupt message blocks sent to the firmware. To -facilitate this, the firmware transmits an "ack message block" after -each successfully received message block. The host schedules a timeout -after sending each block and it will retransmit should the timeout -expire without receiving a corresponding "ack". In addition, if the -firmware detects a corrupt or out-of-order block it may transmit a -"nak message block" to facilitate fast retransmission. +for lost and corrupt message blocks sent to the micro-controller. To +facilitate this, the micro-controller transmits an "ack message block" +after each successfully received message block. The host schedules a +timeout after sending each block and it will retransmit should the +timeout expire without receiving a corresponding "ack". In addition, +if the micro-controller detects a corrupt or out-of-order block it may +transmit a "nak message block" to facilitate fast retransmission. 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 @@ -325,15 +329,15 @@ in the event of transmission latency. The timeout, retransmit, windowing, and ack mechanism are inspired by similar mechanisms in [TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol). -In the other direction, message blocks sent from firmware to host are -designed to be error-free, but they do not have assured +In the other direction, message blocks sent from micro-controller to +host are designed to be error-free, but they do not have assured transmission. (Responses should not be corrupt, but they may go -missing.) This is done to keep the implementation in the firmware -simple. There is no automatic retransmission system for responses - -the high-level code is expected to be capable of handling an -occasional missing response (usually by re-requesting the content or -setting up a recurring schedule of response transmission). The -sequence number field in message blocks sent to the host is always one -greater than the last received sequence number of message blocks -received from the host. It is not used to track sequences of response -message blocks. +missing.) This is done to keep the implementation in the +micro-controller simple. There is no automatic retransmission system +for responses - the high-level code is expected to be capable of +handling an occasional missing response (usually by re-requesting the +content or setting up a recurring schedule of response +transmission). The sequence number field in message blocks sent to the +host is always one greater than the last received sequence number of +message blocks received from the host. It is not used to track +sequences of response message blocks. diff --git a/docs/Todo.md b/docs/Todo.md index f953c29f..69878ee8 100644 --- a/docs/Todo.md +++ b/docs/Todo.md @@ -31,12 +31,12 @@ Host user interaction Safety features =============== -* Support loading a valid step range into the firmware after - homing. This would provide a sanity check in the firmware that would - reduce the risk of the host commanding a stepper motor past its - valid step range. To maintain high efficiency in the firmware, the - firmware would only need to check periodically (eg, every 100ms) - that the stepper is in range. +* Support loading a valid step range into the micro-controller + software after homing. This would provide a sanity check in the + micro-controller that would reduce the risk of the host commanding a + stepper motor past its valid step range. To maintain high + efficiency, the micro-controller would only need to check + periodically (eg, every 100ms) that the stepper is in range. * Possibly support periodically querying the endstop switches and use 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 - firmware for a "host simulator", but that simulator doesn't do - anything currently. It would be useful to expand the code to support - more error checks, kinematic simulations, and improved logging. + micro-controller for a "host simulator", but that simulator doesn't + do anything currently. It would be useful to expand the code to + support more error checks, kinematic simulations, and improved + logging. Documentation ============= @@ -67,7 +68,7 @@ Documentation Hardware features ================= -* Port firmware to more architectures: +* Port to additional micro-controller architectures: * Beagle Bone Black PRU * Smoothieboard / NXP LPC1769 (ARM cortex-M3) * Unix based scheduling; Unix based real-time scheduling