Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions docs/src/modules/stepgen.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ and velocity mode during operations.
position to veloctiy, you can keep your current setup when you explicitly set te pin ``velocity-mode``
to TRUE.

.. note::
At this moment the timings can be set for each stepgen channel. At start up these timings are
aggregated to a single timing which is applied to the whole stepgen. This means that the slowest
drive will determine the maximum speed of the machine. In future release of LitexCNC this behavior
will be changed and timings will be applied independently.

Step types
==========

Expand Down Expand Up @@ -63,6 +57,7 @@ The code-block belows gives an example for the configuration of ``StepGen`` for
"step_pin": "j9:0",
"dir_pin": "j9:1"
},
"max_frequency": 400000,
"soft_stop": true
},
...
Expand All @@ -89,6 +84,7 @@ The code-block belows gives an example for the configuration of ``StepGen`` for
"dir_pos_pin": "j9:2",
"dir_neg_pin": "j9:4"
},
"max_frequency": 400000
"soft_stop": true
},
...
Expand All @@ -98,6 +94,17 @@ The code-block belows gives an example for the configuration of ``StepGen`` for
]
...

.. info::
The maximum frequency in the configuration is the guaranteed maximum frequency the
stepgen can reach. The actual maximum frequency depends on the clock speed of the
FPGA and the scaling of this clock powers with a power of 2.

The maximum frequency should be chosen to be as close as possible to the maximum
frequency supported by the drive. Setting this value to a high value would lead
to reduction in resolution of the speed of the stepgen.

The field ``max_frequency`` is optional. When not set, it will default to 400 kHz.

HAL
===

Expand Down Expand Up @@ -191,6 +198,11 @@ The relevant parameters which are exported to the HAL are:
<board-name>.stepgen.<index/name>.dir-setup-time (FLOAT)
The minimum setup time from direction to step, in nanoseconds periods. Measured from
change of direction to rising edge of step.
<board-name>.stepgen.<index/name>.max_frequency (FLOAT)
The maximum frequency the FPGA can generate pulses. This maximum frequency is determined
based on the ``steplen`` and ``stepspace`` parameters and the fixed point math in the
FPGA (i.e. protection against rollovers). This frequency can be higher then the maximum
frequency requested in the JSON configuration file.

Timing parameters - up/down
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
36 changes: 34 additions & 2 deletions src/litexcnc/config/modules/stepgen.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Imports for creating a json-definition
import math
import os
try:
from typing import ClassVar, List, Literal, Union
Expand Down Expand Up @@ -128,6 +129,14 @@ class StepgenInstanceConfig(BaseModel):
...,
description="The configuration of the stepper type and pin-out."
)
max_frequency: bool = Field(
400e3,
description="The guaranteed maximum frequency the stepgen can generate in Hz. "
"The actual value can be larger then this value, as this is dependent on "
"the clock-frequency and scaling. Choosing a smaller value, close to the "
"limits of your drivers, gives a higher resolution in the velocity. Default "
"value is 400,000 Hz (400 kHz)."
)
soft_stop: bool = Field(
False,
description="When False, the stepgen will directly stop when the stepgen is "
Expand Down Expand Up @@ -158,6 +167,13 @@ class StepgenInstanceConfig(BaseModel):
'dir-hold-time',
]

def calculate_shift(self, mmio):
clock_frequency = mmio.clock_frequency.status.reset.value
shift = 0
while (clock_frequency / (1 << (shift+2)) > self.max_frequency):
shift += 1
return shift


class StepgenModuleConfig(ModuleBaseModel):
"""
Expand Down Expand Up @@ -197,14 +213,30 @@ def add_mmio_read_registers(self, mmio):

@property
def config_size(self):
return 4
"""Calculates the number DWORDS required to store the shift data
of the stepgen instances. The first byte is the number of instances,
followed by the shifts required for each instance to get the desired
maximum frequency.
"""
return math.ceil((1 + len(self.instances)) / 4) * 4

def store_config(self, mmio):
"""Calculates the shift for each instance and stores them in the
MMIO. To calculate the shift, the clock-frequency is required. This
is taken from the MMIO register, not to break with current design
of this module.
"""
# Deferred imports to prevent importing Litex while installing the driver
from litex.soc.interconnect.csr import CSRStatus
# - store the number of instances
config = len(self.instances) << (self.config_size * 8 - 8)
# - calculate and store the shift for each instance
clock_frequency = mmio.clock_frequency.status.reset.value
for index, instance in enumerate(self.instances):
config += instance.calculate_shift(mmio) << (self.config_size * 8 - (2 + index) * 8)
mmio.stepgen_config_data = CSRStatus(
size=self.config_size*8,
reset=len(self.instances),
reset=config,
description=f"The config of the Stepgen module."
)

Loading