https://reprap.org/mediawiki/api.php?action=feedcontributions&user=Colinrgodsey&feedformat=atomRepRap - User contributions [en]2024-03-29T14:26:07ZUser contributionsMediaWiki 1.30.0https://reprap.org/mediawiki/index.php?title=Direct_Stepping&diff=187835Direct Stepping2020-05-08T18:23:01Z<p>Colinrgodsey: </p>
<hr />
<div>{{warning|Work in progress!}}<br />
<br />
Direct Stepping allows a host device to issue direct stepper movements that are defined in a binary format that is written ahead of time by the host device to a page in the device RAM. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
== Page Management ==<br />
<br />
The transfer of the binary data from host to device could be done several different ways, and falls under the general category of "page management". The reference implementation (for 8-bit AVR devices) for Marlin includes a binary protocol that can run parallel to the g-code stream over the single USB UART. This allows the host to buffer these pages as fast as possible without having to wait on g-codes that may be stuck pending due to g-code or planning buffers being filled. <br />
<br />
Page management can be done several other ways depending on the device, given that the only requirement is that binary data can be reliably buffered in the devices RAM.<br />
<br />
== Formats ==<br />
<br />
There are several formats that be used for the pages, with the option of creating more as desired for certain devices. The formats are largely broken into two categories: directional and non-directional. Directional formats encode the axes direction in the binary data and can be used to facilitate very quick direction changes, potentially up to thousands of times per second. Non-directional formats rely on the direction being provided in the g-code, with the binary data only providing the steps. Non-directional formats introduce more non-determinism when it comes to performance, as each direction change needs to be done with the g-code, and can place more strain on the page management, planning, and g-code subsystems.<br />
<br />
Compression can also be employed in the page formats, allowing for a higher step rate that could normally not be achieved with "per-bit" step accuracy. The segment-based compression still provides total geometric accuracy, but breaks the motion into tiny line segments for the sake of page size. The compressed segment value is then used in a lookup table to produce the actual steps the device will take over the segment timeframe. This type of compression shares some characteristics with the traditional method of using Bresenham lines with step-rate modulation for acceleration, in that motion accuracy may be sacrificed for slow axis movements. The main difference is that the compressed direct stepping data offers a hard guarantee on how much accuracy is sacrificed, while maintaining a constantly high step-rate that can satisfy both fast and slow axis motion at the same time.<br />
<br />
Using an 8 step compression at 60k steps/s will result in motion accuracy tolerance within 133 μs. Compressed formats also work well when micro-stepping is used as they generally fit the compressed segments within 8 steps or less, as the physical accuracy is generally at the whim of the micro-stepping characteristics.<br />
<br />
The naming scheme for the formats follow this general pattern: <nowiki>SP_<axes>_<compression ratio><'D' if directional>_<number of segments></nowiki><br />
<br />
Here is an example of 3 general purpose formats provided with Marlin that share the same total page size:<br />
<br />
* '''SP_4x4D_128''' - 4 axes, 4x compression, direction is binary encoded, 128 segments, 1024 steps and 256 bytes per page.<br />
* '''SP_4x2_256''' - 4 axes, 2x compression, no binary direction, 256 segments, 1024 steps and 256 bytes per page.<br />
* '''SP_4x1_512''' - 4 axes, no compression, no binary direction, 512 segments, 512 steps and 256 bytes per page.<br />
<br />
'''SP_4x4D_128''' is a good format for movements which may be very quick and change direction often (multiple times per 1024 steps). '''SP_4x2_256''' is a good general purpose format that seems optimal for 3d printing. '''SP_4x1_512''' may not be able to reach the same step rate as the other two, but provides absolute motion accuracy.<br />
<br />
== G6 Code ==<br />
<br />
Once a page is written to the device, it can be triggered using the G6 g-code which references the page index that should be used for that move. Depending on the page format, direction arguments may need to be provided in the G6 code.<br />
<br />
'''Arguments:'''<br />
<br />
* '''I''' - ''Page index''<br />
* '''S''' - ''Number of steps to take. Defaults to max steps for the page format.''<br />
* '''R''' - ''Step rate per second. Last value is cached for future invocations.''<br />
* '''X, Y, Z, E''' - ''Direction: 1 for positive, 0 for negative. Last value is cached for future invocations. Not used for directional formats.''<br />
<br />
== Serial Page Manager Protocol ==<br />
<br />
== Formats (Old) ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/17853 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Direct_Stepping&diff=187834Direct Stepping2020-05-08T18:21:38Z<p>Colinrgodsey: /* G6 Code */</p>
<hr />
<div>{{warning|Work in progress!}}<br />
<br />
Direct Stepping allows a host device to issue direct stepper movements that are defined in a binary format that is written ahead of time by the host device to a page in the device RAM. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
== Page Management ==<br />
<br />
The transfer of the binary data from host to device could be done several different ways, and falls under the general category of "page management". The reference implementation (for 8-bit AVR devices) for Marlin includes a binary protocol that can run parallel to the g-code stream over the single USB UART. This allows the host to buffer these pages as fast as possible without having to wait on g-codes that may be stuck pending due to g-code or planning buffers being filled. <br />
<br />
Page management can be done several other ways depending on the device, given that the only requirement is that binary data can be reliably buffered in the devices RAM.<br />
<br />
== Formats ==<br />
<br />
There are several formats that be used for the pages, with the option of creating more as desired for certain devices. The formats are largely broken into two categories: directional and non-directional. Directional formats encode the axes direction in the binary data and can be used to facilitate very quick direction changes, potentially up to thousands of times per second. Non-directional formats rely on the direction being provided in the g-code, with the binary data only providing the steps. Non-directional formats introduce more non-determinism when it comes to performance, as each direction change needs to be done with the g-code, and can place more strain on the page management, planning, and g-code subsystems.<br />
<br />
Compression can also be employed in the page formats, allowing for a higher step rate that could normally not be achieved with "per-bit" step accuracy. The segment-based compression still provides total geometric accuracy, but breaks the motion into tiny line segments for the sake of page size. The compressed segment value is then used in a lookup table to produce the actual steps the device will take over the segment timeframe. This type of compression shares some characteristics with the traditional method of using Bresenham lines with step-rate modulation for acceleration, in that motion accuracy may be sacrificed for slow axis movements. The main difference is that the compressed direct stepping data offers a hard guarantee on how much accuracy is sacrificed, while maintaining a constantly high step-rate that can satisfy both fast and slow axis motion at the same time.<br />
<br />
Using an 8 step compression at 60k steps/s will result in motion accuracy tolerance within 133 μs. Compressed formats also work well when micro-stepping is used as they generally fit the compressed segments within 8 steps or less, as the physical accuracy is generally at the whim of the micro-stepping characteristics.<br />
<br />
The naming scheme for the formats follow this general pattern: <nowiki>SP_<axes>_<compression ratio><'D' if directional>_<number of segments></nowiki><br />
<br />
Here is an example of 3 general purpose formats provided with Marlin that share the same total page size:<br />
<br />
* '''SP_4x4D_128''' - 4 axes, 4x compression, direction is binary encoded, 128 segments, 1024 steps and 256 bytes per page.<br />
* '''SP_4x2_256''' - 4 axes, 2x compression, no binary direction, 256 segments, 1024 steps and 256 bytes per page.<br />
* '''SP_4x1_512''' - 4 axes, no compression, no binary direction, 512 segments, 512 steps and 256 bytes per page.<br />
<br />
'''SP_4x4D_128''' is a good format for movements which may be very quick and change direction often (multiple times per 1024 steps). '''SP_4x2_256''' is a good general purpose format that seems optimal for 3d printing. '''SP_4x1_512''' may not be able to reach the same step rate as the other two, but provides absolute motion accuracy.<br />
<br />
== G6 Code ==<br />
<br />
Once a page is written to the device, it can be triggered using the G6 g-code which references the page index that should be used for that move. Depending on the page format, direction arguments may need to be provided in the G6 code.<br />
<br />
'''Arguments:'''<br />
<br />
* '''I''' - ''Page index''<br />
* '''S''' - ''Number of steps to take. Defaults to max steps for the page format.''<br />
* '''R''' - ''Step rate per second. Last value is cached for future invocations.''<br />
* '''X, Y, Z, E''' - ''Direction: 1 for positive, 0 for negative. Last value is cached for future invocations. Not used for directional formats.''<br />
<br />
== Serial Page Manager Protocol ==<br />
<br />
== Formats (Old) ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
};<br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'', ''"!fail"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Direct_Stepping&diff=187833Direct Stepping2020-05-08T18:21:05Z<p>Colinrgodsey: /* Formats */</p>
<hr />
<div>{{warning|Work in progress!}}<br />
<br />
Direct Stepping allows a host device to issue direct stepper movements that are defined in a binary format that is written ahead of time by the host device to a page in the device RAM. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
== Page Management ==<br />
<br />
The transfer of the binary data from host to device could be done several different ways, and falls under the general category of "page management". The reference implementation (for 8-bit AVR devices) for Marlin includes a binary protocol that can run parallel to the g-code stream over the single USB UART. This allows the host to buffer these pages as fast as possible without having to wait on g-codes that may be stuck pending due to g-code or planning buffers being filled. <br />
<br />
Page management can be done several other ways depending on the device, given that the only requirement is that binary data can be reliably buffered in the devices RAM.<br />
<br />
== Formats ==<br />
<br />
There are several formats that be used for the pages, with the option of creating more as desired for certain devices. The formats are largely broken into two categories: directional and non-directional. Directional formats encode the axes direction in the binary data and can be used to facilitate very quick direction changes, potentially up to thousands of times per second. Non-directional formats rely on the direction being provided in the g-code, with the binary data only providing the steps. Non-directional formats introduce more non-determinism when it comes to performance, as each direction change needs to be done with the g-code, and can place more strain on the page management, planning, and g-code subsystems.<br />
<br />
Compression can also be employed in the page formats, allowing for a higher step rate that could normally not be achieved with "per-bit" step accuracy. The segment-based compression still provides total geometric accuracy, but breaks the motion into tiny line segments for the sake of page size. The compressed segment value is then used in a lookup table to produce the actual steps the device will take over the segment timeframe. This type of compression shares some characteristics with the traditional method of using Bresenham lines with step-rate modulation for acceleration, in that motion accuracy may be sacrificed for slow axis movements. The main difference is that the compressed direct stepping data offers a hard guarantee on how much accuracy is sacrificed, while maintaining a constantly high step-rate that can satisfy both fast and slow axis motion at the same time.<br />
<br />
Using an 8 step compression at 60k steps/s will result in motion accuracy tolerance within 133 μs. Compressed formats also work well when micro-stepping is used as they generally fit the compressed segments within 8 steps or less, as the physical accuracy is generally at the whim of the micro-stepping characteristics.<br />
<br />
The naming scheme for the formats follow this general pattern: <nowiki>SP_<axes>_<compression ratio><'D' if directional>_<number of segments></nowiki><br />
<br />
Here is an example of 3 general purpose formats provided with Marlin that share the same total page size:<br />
<br />
* '''SP_4x4D_128''' - 4 axes, 4x compression, direction is binary encoded, 128 segments, 1024 steps and 256 bytes per page.<br />
* '''SP_4x2_256''' - 4 axes, 2x compression, no binary direction, 256 segments, 1024 steps and 256 bytes per page.<br />
* '''SP_4x1_512''' - 4 axes, no compression, no binary direction, 512 segments, 512 steps and 256 bytes per page.<br />
<br />
'''SP_4x4D_128''' is a good format for movements which may be very quick and change direction often (multiple times per 1024 steps). '''SP_4x2_256''' is a good general purpose format that seems optimal for 3d printing. '''SP_4x1_512''' may not be able to reach the same step rate as the other two, but provides absolute motion accuracy.<br />
<br />
== G6 Code ==<br />
<br />
Once a page is written to the device, it can be triggered using the G6 g-code which references the page index that should be used for that move. Depending on the page format, direction arguments may need to be provided in the G6 code.<br />
<br />
'''Arguments:'''<br />
<br />
'''I''' - ''Page index''<br />
<br />
'''S''' - ''Number of steps to take. Defaults to max steps for the page format.''<br />
<br />
'''R''' - ''Step rate per second. Last value is cached for future invocations.''<br />
<br />
'''X, Y, Z, E''' - ''Direction: 1 for positive, 0 for negative. Last value is cached for future invocations. Not used for directional formats.''<br />
<br />
== Serial Page Manager Protocol ==<br />
<br />
== Formats (Old) ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
};<br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'', ''"!fail"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Direct_Stepping&diff=187832Direct Stepping2020-05-08T18:12:16Z<p>Colinrgodsey: /* Formats */</p>
<hr />
<div>{{warning|Work in progress!}}<br />
<br />
Direct Stepping allows a host device to issue direct stepper movements that are defined in a binary format that is written ahead of time by the host device to a page in the device RAM. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
== Page Management ==<br />
<br />
The transfer of the binary data from host to device could be done several different ways, and falls under the general category of "page management". The reference implementation (for 8-bit AVR devices) for Marlin includes a binary protocol that can run parallel to the g-code stream over the single USB UART. This allows the host to buffer these pages as fast as possible without having to wait on g-codes that may be stuck pending due to g-code or planning buffers being filled. <br />
<br />
Page management can be done several other ways depending on the device, given that the only requirement is that binary data can be reliably buffered in the devices RAM.<br />
<br />
== Formats ==<br />
<br />
There are several formats that be used for the pages, with the option of creating more as desired for certain devices. The formats are largely broken into two categories: directional and non-directional. Directional formats encode the axes direction in the binary data and can be used to facilitate very quick direction changes, potentially up to thousands of times per second. Non-directional formats rely on the direction being provided in the g-code, with the binary data only providing the steps. Non-directional formats introduce more non-determinism when it comes to performance, as each direction change needs to be done with the g-code, and can place more strain on the page management, planning, and g-code subsystems.<br />
<br />
Compression can also be employed in the page formats, allowing for a higher step rate that could normally not be achieved with "per-bit" step accuracy. The segment-based compression still provides total geometric accuracy, but breaks the motion into tiny line segments for the sake of page size. The compressed segment value is then used in a lookup table to produce the actual steps the device will take over the segment timeframe. This type of compression shares some characteristics with the traditional method of using Bresenham lines with step-rate modulation for acceleration, in that motion accuracy may be sacrificed for slow axis movements. The main difference is that the compressed direct stepping data offers a hard guarantee on how much accuracy is sacrificed, while maintaining a constantly high step-rate that can satisfy both fast and slow axis motion at the same time.<br />
<br />
Using an 8 step compression at 60k steps/s will result in motion accuracy tolerance within 133 μs. Compressed formats also work well when micro-stepping is used as they generally fit the compressed segments within 8 steps or less, and the physical accuracy is generally at the whim of the micro-stepping characteristics.<br />
<br />
== G6 Code ==<br />
<br />
Once a page is written to the device, it can be triggered using the G6 g-code which references the page index that should be used for that move. Depending on the page format, direction arguments may need to be provided in the G6 code.<br />
<br />
'''Arguments:'''<br />
<br />
'''I''' - ''Page index''<br />
<br />
'''S''' - ''Number of steps to take. Defaults to max steps for the page format.''<br />
<br />
'''R''' - ''Step rate per second. Last value is cached for future invocations.''<br />
<br />
'''X, Y, Z, E''' - ''Direction: 1 for positive, 0 for negative. Last value is cached for future invocations. Not used for directional formats.''<br />
<br />
== Serial Page Manager Protocol ==<br />
<br />
== Formats (Old) ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
};<br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'', ''"!fail"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Direct_Stepping&diff=187831Direct Stepping2020-05-08T18:06:29Z<p>Colinrgodsey: /* Formats */</p>
<hr />
<div>{{warning|Work in progress!}}<br />
<br />
Direct Stepping allows a host device to issue direct stepper movements that are defined in a binary format that is written ahead of time by the host device to a page in the device RAM. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
== Page Management ==<br />
<br />
The transfer of the binary data from host to device could be done several different ways, and falls under the general category of "page management". The reference implementation (for 8-bit AVR devices) for Marlin includes a binary protocol that can run parallel to the g-code stream over the single USB UART. This allows the host to buffer these pages as fast as possible without having to wait on g-codes that may be stuck pending due to g-code or planning buffers being filled. <br />
<br />
Page management can be done several other ways depending on the device, given that the only requirement is that binary data can be reliably buffered in the devices RAM.<br />
<br />
== Formats ==<br />
<br />
There are several formats that be used for the pages, with the option of creating more as desired for certain devices. The formats are largely broken into two categories: directional and non-directional. Directional formats encode the axes direction in the binary data and can be used to facilitate very quick direction changes, up to hundreds or thousands of changes per second. Non-directional formats rely on the direction being provided in the g-code, with the binary data only provided the steps. Non-directional formats introduce more non-determinism when it comes to performance, as each direction change needs to be done with the g-code, and can place more strain on the page management subsystem.<br />
<br />
Compression can also be employed in the page formats, allowing for a higher step rate that could normally not be achieved with "per-bit" step accuracy. The segment-based compression still provides total geometric accuracy, but breaks the motion into tiny line segments for the sake of page size. The compressed segment value is then used in a lookup table to produce the actual steps the device will take over the segment timeframe. This type of compression shares some characteristics with the traditional method of using Bresenham lines with step-rate modulation for acceleration, in that motion accuracy may be sacrificed for slow axis movements. The main difference is that the compressed direct stepping data offers a hard guarantee on how much accuracy is sacrificed, while maintaining a constantly high step-rate that can satisfy both fast and slow axis motion at the same time.<br />
<br />
Using an 8x (8 step) compression at 60k steps/s will result in motion accuracy tolerance within 133 μs. Compressed formats also work well when micro-stepping is used as they generally fit the compressed segments within 8 steps or less, and the physical accuracy is generally at the whim of the micro-stepping characteristics.<br />
<br />
== G6 Code ==<br />
<br />
Once a page is written to the device, it can be triggered using the G6 g-code which references the page index that should be used for that move. Depending on the page format, direction arguments may need to be provided in the G6 code.<br />
<br />
'''Arguments:'''<br />
<br />
'''I''' - ''Page index''<br />
<br />
'''S''' - ''Number of steps to take. Defaults to max steps for the page format.''<br />
<br />
'''R''' - ''Step rate per second. Last value is cached for future invocations.''<br />
<br />
'''X, Y, Z, E''' - ''Direction: 1 for positive, 0 for negative. Last value is cached for future invocations. Not used for directional formats.''<br />
<br />
== Serial Page Manager Protocol ==<br />
<br />
== Formats (Old) ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
};<br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'', ''"!fail"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Direct_Stepping&diff=187830Direct Stepping2020-05-08T17:42:43Z<p>Colinrgodsey: /* G6 Code */</p>
<hr />
<div>{{warning|Work in progress!}}<br />
<br />
Direct Stepping allows a host device to issue direct stepper movements that are defined in a binary format that is written ahead of time by the host device to a page in the device RAM. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
== Page Management ==<br />
<br />
The transfer of the binary data from host to device could be done several different ways, and falls under the general category of "page management". The reference implementation (for 8-bit AVR devices) for Marlin includes a binary protocol that can run parallel to the g-code stream over the single USB UART. This allows the host to buffer these pages as fast as possible without having to wait on g-codes that may be stuck pending due to g-code or planning buffers being filled. <br />
<br />
Page management can be done several other ways depending on the device, given that the only requirement is that binary data can be reliably buffered in the devices RAM.<br />
<br />
== Formats ==<br />
<br />
There are several formats that be used for the pages, with the option of creating more as desired for certain devices. The formats are largely broken into two categories: directional and non-directional. Directional formats encode the axes direction in the binary data and can be used to facilitate very quick direction changes, up to hundreds or thousands of changes per second. Non-directional formats rely on the direction being provided in the g-code, with the binary data only provided the steps. Non-directional formats introduce more non-determinism when it comes to performance, as each direction change needs to be done with the g-code, and can place more strain on the page management subsystem. <br />
<br />
== G6 Code ==<br />
<br />
Once a page is written to the device, it can be triggered using the G6 g-code which references the page index that should be used for that move. Depending on the page format, direction arguments may need to be provided in the G6 code.<br />
<br />
'''Arguments:'''<br />
<br />
'''I''' - ''Page index''<br />
<br />
'''S''' - ''Number of steps to take. Defaults to max steps for the page format.''<br />
<br />
'''R''' - ''Step rate per second. Last value is cached for future invocations.''<br />
<br />
'''X, Y, Z, E''' - ''Direction: 1 for positive, 0 for negative. Last value is cached for future invocations. Not used for directional formats.''<br />
<br />
== Serial Page Manager Protocol ==<br />
<br />
== Formats (Old) ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
};<br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'', ''"!fail"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Direct_Stepping&diff=187829Direct Stepping2020-05-08T17:42:01Z<p>Colinrgodsey: /* G6 Code */</p>
<hr />
<div>{{warning|Work in progress!}}<br />
<br />
Direct Stepping allows a host device to issue direct stepper movements that are defined in a binary format that is written ahead of time by the host device to a page in the device RAM. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
== Page Management ==<br />
<br />
The transfer of the binary data from host to device could be done several different ways, and falls under the general category of "page management". The reference implementation (for 8-bit AVR devices) for Marlin includes a binary protocol that can run parallel to the g-code stream over the single USB UART. This allows the host to buffer these pages as fast as possible without having to wait on g-codes that may be stuck pending due to g-code or planning buffers being filled. <br />
<br />
Page management can be done several other ways depending on the device, given that the only requirement is that binary data can be reliably buffered in the devices RAM.<br />
<br />
== Formats ==<br />
<br />
There are several formats that be used for the pages, with the option of creating more as desired for certain devices. The formats are largely broken into two categories: directional and non-directional. Directional formats encode the axes direction in the binary data and can be used to facilitate very quick direction changes, up to hundreds or thousands of changes per second. Non-directional formats rely on the direction being provided in the g-code, with the binary data only provided the steps. Non-directional formats introduce more non-determinism when it comes to performance, as each direction change needs to be done with the g-code, and can place more strain on the page management subsystem. <br />
<br />
== G6 Code ==<br />
<br />
Once a page is written to the device, it can be triggered using the G6 g-code which references the page index that should be used for that move. Depending on the page format, direction arguments may need to be provided in the G6 code.<br />
<br />
'''Arguments:'''<br />
<br />
'''I''' - ''Page index''<br />
<br />
'''S''' - ''Number of steps to take. Defaults to max steps for the page format.''<br />
<br />
'''R''' - ''Step rate per second. Last value is cached for future invocations.''<br />
<br />
'''X, Y, Z, E''' - ''Direction: 1 for positive, 0 for negative. Last <br />
value is cached for future invocations. Not used for <br />
directional formats.''<br />
<br />
== Serial Page Manager Protocol ==<br />
<br />
== Formats (Old) ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
};<br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'', ''"!fail"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Direct_Stepping&diff=187828Direct Stepping2020-05-08T17:41:21Z<p>Colinrgodsey: </p>
<hr />
<div>{{warning|Work in progress!}}<br />
<br />
Direct Stepping allows a host device to issue direct stepper movements that are defined in a binary format that is written ahead of time by the host device to a page in the device RAM. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
== Page Management ==<br />
<br />
The transfer of the binary data from host to device could be done several different ways, and falls under the general category of "page management". The reference implementation (for 8-bit AVR devices) for Marlin includes a binary protocol that can run parallel to the g-code stream over the single USB UART. This allows the host to buffer these pages as fast as possible without having to wait on g-codes that may be stuck pending due to g-code or planning buffers being filled. <br />
<br />
Page management can be done several other ways depending on the device, given that the only requirement is that binary data can be reliably buffered in the devices RAM.<br />
<br />
== Formats ==<br />
<br />
There are several formats that be used for the pages, with the option of creating more as desired for certain devices. The formats are largely broken into two categories: directional and non-directional. Directional formats encode the axes direction in the binary data and can be used to facilitate very quick direction changes, up to hundreds or thousands of changes per second. Non-directional formats rely on the direction being provided in the g-code, with the binary data only provided the steps. Non-directional formats introduce more non-determinism when it comes to performance, as each direction change needs to be done with the g-code, and can place more strain on the page management subsystem. <br />
<br />
== G6 Code ==<br />
<br />
Once a page is written to the device, it can be triggered using the G6 g-code which references the page index that should be used for that move. Depending on the page format, direction arguments may need to be provided in the G6 code.<br />
<br />
'''Arguments:'''<br />
<br />
'''I''' - Page index<br />
<br />
'''S''' - Number of steps to take. Defaults to max steps for the page format.<br />
<br />
'''R''' - Step rate per second. Last value is cached for future invocations. <br />
<br />
'''X, Y, Z, E''' - Direction: 1 for positive, 0 for negative. Last <br />
value is cached for future invocations. Not used for <br />
directional formats. <br />
<br />
== Serial Page Manager Protocol ==<br />
<br />
== Formats (Old) ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
};<br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'', ''"!fail"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Talk:Direct_Stepping&diff=187827Talk:Direct Stepping2020-05-08T17:34:50Z<p>Colinrgodsey: Created page with "'''5-8-20 - Colin Godsey:''' The current Marlin PR can be found here: https://github.com/MarlinFirmware/Marlin/pull/17853"</p>
<hr />
<div>'''5-8-20 - Colin Godsey:'''<br />
<br />
The current Marlin PR can be found here: https://github.com/MarlinFirmware/Marlin/pull/17853</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Direct_Stepping&diff=187826Direct Stepping2020-05-08T17:32:52Z<p>Colinrgodsey: more work</p>
<hr />
<div>{{warning|Work in progress!}}<br />
<br />
Direct stepper page support is a feature that allows device firmware to process stepper movement buffers (pages) directly from a host device. This is done with a binary protocol that allows the host to buffer stepper pages to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
== Page Management ==<br />
<br />
The transfer of the binary data from host to device could be done several different ways, and falls under the general category of "page management". The reference implementation (for 8-bit AVR devices) for Marlin includes a binary protocol that can run parallel to the g-code stream over the single USB UART. This allows the host to buffer these pages as fast as possible without having to wait on g-codes that may be stuck pending due to g-code or planning buffers being filled. <br />
<br />
Page management can be done several other ways depending on the device, given that the only requirement is that binary data can be reliably buffered in the devices RAM.<br />
<br />
== Formats ==<br />
<br />
There are several formats that be used for the pages, with the option of creating more as desired for certain devices. The formats are largely broken into two categories: directional and non-directional. Directional formats encode the axes direction in the binary data and can be used to facilitate very quick direction changes, up to hundreds or thousands of changes per second. Non-directional formats rely on the direction being provided in the g-code, with the binary data only provided the steps. Non-directional formats introduce more non-determinism when it comes to performance, as each direction change needs to be done with the g-code, and can place more strain on the page management subsystem. <br />
<br />
== G6 Code ==<br />
<br />
Once a page is written to the device, it can be triggered using the G6 g-code which references the page index that should be used for that move. Depending on the page format, direction arguments may need to be provided in the G6 code.<br />
<br />
== Serial Page Manager Protocol ==<br />
<br />
== Formats (Old) ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
};<br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'', ''"!fail"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Direct_Stepping&diff=187677Direct Stepping2020-04-18T15:27:30Z<p>Colinrgodsey: /* Segment/Wave Table */</p>
<hr />
<div>{{warning|Work in progress!}}<br />
<br />
Direct stepper page support is a feature that allows device firmware to process stepper movement buffers (pages) directly from a host device. This is done with a binary protocol that allows the host to buffer stepper pages to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
<br />
== Formats ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
};<br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'', ''"!fail"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=187675Stepper Chunks2020-04-16T17:09:45Z<p>Colinrgodsey: Redirected page to Direct Stepping</p>
<hr />
<div>#REDIRECT [[Direct Stepping]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=187674Stepper Chunks2020-04-16T17:06:38Z<p>Colinrgodsey: </p>
<hr />
<div>{{Deprecated|Direct Stepping}}</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Direct_Stepping&diff=187673Direct Stepping2020-04-16T17:02:16Z<p>Colinrgodsey: Created page with "{{warning|Work in progress!}} Direct stepper page support is a feature that allows device firmware to process stepper movement buffers (pages) directly from a host device. Th..."</p>
<hr />
<div>{{warning|Work in progress!}}<br />
<br />
Direct stepper page support is a feature that allows device firmware to process stepper movement buffers (pages) directly from a host device. This is done with a binary protocol that allows the host to buffer stepper pages to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
<br />
== Formats ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
}; <br />
</span><br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'', ''"!fail"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=187672Stepper Chunks2020-04-16T16:59:37Z<p>Colinrgodsey: moving to new page</p>
<hr />
<div>= Outdated =<br />
Please see the new page at [[Direct Stepping]].</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=181741Stepper Chunks2018-02-14T13:49:38Z<p>Colinrgodsey: /* Protocol */ adding other chunk response token</p>
<hr />
<div>Direct stepper chunk support is a feature that allows device firmware to process stepper movement buffers (chunks) directly from a host device. This is done with a binary protocol that allows the host to buffer chunks to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
<br />
== Formats ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
}; <br />
</span><br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'', ''"!fail"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]<br />
<br />
[[Category:Firmware]]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=179857Stepper Chunks2017-07-11T01:32:18Z<p>Colinrgodsey: /* Protocol */ formatting</p>
<hr />
<div>Direct stepper chunk support is a feature that allows device firmware to process stepper movement buffers (chunks) directly from a host device. This is done with a binary protocol that allows the host to buffer chunks to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
<br />
== Formats ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
}; <br />
</span><br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent '''['!'][CHUNK_SIZE bytes][checksum]'''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger.<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=179856Stepper Chunks2017-07-11T01:31:23Z<p>Colinrgodsey: Draft protocol</p>
<hr />
<div>Direct stepper chunk support is a feature that allows device firmware to process stepper movement buffers (chunks) directly from a host device. This is done with a binary protocol that allows the host to buffer chunks to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
<br />
== Formats ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
}; <br />
</span><br />
<br />
== Protocol ==<br />
<br />
The chunk transmission protocol is a simple data transfer process that returns with an index if the data was stored successfully. Sequential chunks can be gathered into a full range of data that can be triggered for execution. <br />
<br />
To transfer a chunk, the device must be sent ''['!'][CHUNK_SIZE bytes][checksum]''. The device should be able to store this data very quickly and directly. <br />
<br />
During data transfer, the device will either respond with ''"!ok <idx>"'' or ''"!busy"''. If the device is busy, the transfer must be attempted again. <br />
<br />
To trigger the stepper chunks, the device must be sent '''[TRIGGER_CODE?][idx][n]''' where ''idx'' is the first chunk index, and ''n'' specifies the number of sequential chunks to trigger. <br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=179855Stepper Chunks2017-07-11T01:08:40Z<p>Colinrgodsey: /* Segment/Wave Table */ changing wording</p>
<hr />
<div>Direct stepper chunk support is a feature that allows device firmware to process stepper movement buffers (chunks) directly from a host device. This is done with a binary protocol that allows the host to buffer chunks to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
<br />
== Formats ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that use segments larger than 1 step may use a segment lookup table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
}; <br />
</span><br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=179854Stepper Chunks2017-07-11T01:04:53Z<p>Colinrgodsey: /* Formats */ describe precision loss of format</p>
<hr />
<div>Direct stepper chunk support is a feature that allows device firmware to process stepper movement buffers (chunks) directly from a host device. This is done with a binary protocol that allows the host to buffer chunks to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
<br />
== Formats ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement change (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. <br />
<br />
The 8-step segment resolution could suffer from some precision loss on non-linear moves, but only at high speeds that would already suffer precision loss due to jerk. The overall effect is that you have more precision at slower speeds for non-linear moves. At 30k tick/s rate, you would achieve full accuracy at speeds of 3.8k step/s or less on any axis for non-linear moves. For an axis with 80 step/mm, this would be about 50 mm/s. As long as jerk does not exceed this value, it will have no noticeable visual impact. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that include segments larger than 1 step generally requires a wave table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
}; <br />
</span><br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=179853Stepper Chunks2017-07-11T00:28:22Z<p>Colinrgodsey: /* Formats */ another segment example</p>
<hr />
<div>Direct stepper chunk support is a feature that allows device firmware to process stepper movement buffers (chunks) directly from a host device. This is done with a binary protocol that allows the host to buffer chunks to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
<br />
== Formats ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement delta (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks, a value of 10 would be a movement of +3 steps over 8 ticks, etc. The 8-step segment resolution could technically suffer from some precision loss, but only at high speeds that would already suffer precision loss due to momentum. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that include segments larger than 1 step generally requires a wave table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
}; <br />
</span><br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=179852Stepper Chunks2017-07-11T00:10:11Z<p>Colinrgodsey: /* Segment/Wave Table */</p>
<hr />
<div>Direct stepper chunk support is a feature that allows device firmware to process stepper movement buffers (chunks) directly from a host device. This is done with a binary protocol that allows the host to buffer chunks to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
<br />
== Formats ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement delta (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks. The 8-step segment resolution could technically suffer from some precision loss, but only at high speeds that would already suffer precision loss due to momentum. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that include segments larger than 1 step generally requires a wave table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for '''CH-4x4-128''':<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
}; <br />
</span><br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=179851Stepper Chunks2017-07-11T00:08:20Z<p>Colinrgodsey: adding links to marlin PR and step daemon</p>
<hr />
<div>Direct stepper chunk support is a feature that allows device firmware to process stepper movement buffers (chunks) directly from a host device. This is done with a binary protocol that allows the host to buffer chunks to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
<br />
== Formats ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement delta (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks. The 8-step segment resolution could technically suffer from some precision loss, but only at high speeds that would already suffer precision loss due to momentum. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that include segments larger than 1 step generally requires a wave table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for CH-4x4-128:<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
}; <br />
</span><br />
<br />
<br />
== External Links ==<br />
<br />
[https://github.com/MarlinFirmware/Marlin/pull/7047 Current proposal for Marlin]<br />
<br />
[https://github.com/colinrgodsey/step-daemon Step Daemon]</div>Colinrgodseyhttps://reprap.org/mediawiki/index.php?title=Stepper_Chunks&diff=179850Stepper Chunks2017-07-11T00:05:46Z<p>Colinrgodsey: Initial update</p>
<hr />
<div>Direct stepper chunk support is a feature that allows device firmware to process stepper movement buffers (chunks) directly from a host device. This is done with a binary protocol that allows the host to buffer chunks to the device, and trigger them using the trigger command. This allows the firmware to free up processing cycles that can be used to achieve higher step rates, while allowing more advanced processing to be done on the external device. <br />
<br />
The general flow involves the external host software taking on the role of "g-code consumer" and acts as a man-in-the-middle between the g-code source and the target device.<br />
<br />
<br />
== Formats ==<br />
<br />
'''CH-4x4-128'''<br />
<br />
This is the first proposed general format. It encodes 4 motors each with a 4-bit/8-step segment that produces 4x128 segments, a total chunk size of 256 bytes, spanning 1024 ticks total. This format is ideal for 8-bit processors as it requires very little unpacking and most iterators and indexes can be used as 8-bit values. Each 4-bit segment value is the movement delta (in steps) + 7, over 8 ticks. So a segment value of 8 would be a movement of +1 steps over 8 ticks. The 8-step segment resolution could technically suffer from some precision loss, but only at high speeds that would already suffer precision loss due to momentum. <br />
<br />
Bit format (2 bytes per segment):<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
|----segment----|<br /><br />
XXXXYYYY ZZZZEEEE XXXXYYYY ZZZZEEEE<br />
</span><br />
<br />
<br />
== Segment/Wave Table ==<br />
<br />
<br />
Any formats that include segments larger than 1 step generally requires a wave table to produce the actual step sequence for each segment. Other methods can be used, like Bresenham lines, but low-bit chunk formats work just fine with a simple segment sequence lookup table. <br />
<br />
Example table for CH-4x4-128:<br />
<br />
<span style="margin-bottom:0px;font-family: 'Courier New', Courier, monospace"><br />
uint8_t segment_moves[16][8] = { <br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 0 = -7<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 1 = -6<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 2 = -5<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 3 = -4<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 4 = -3<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 5 = -2<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1<br />
{ 0, 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0<br />
{ 0, 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1<br />
{ 0, 0, 1, 0, 0, 0, 1, 0 }, // 9 = 2<br />
{ 0, 1, 0, 0, 1, 0, 0, 1 }, // 10 = 3<br />
{ 0, 1, 0, 1, 0, 1, 0, 1 }, // 11 = 4<br />
{ 0, 1, 1, 0, 1, 0, 1, 1 }, // 12 = 5<br />
{ 1, 1, 1, 0, 1, 1, 1, 0 }, // 13 = 6<br />
{ 1, 1, 1, 1, 1, 1, 1, 0 }, // 14 = 7<br />
{ 0 }<br />
}; <br />
</span></div>Colinrgodsey