Nikolay-Kha / PyCNC

Python CNC machine controller for Raspberry Pi and other ARM Linux boards
MIT License
582 stars 187 forks source link

porting board guide #26

Open mhanuel26 opened 6 years ago

mhanuel26 commented 6 years ago

Hello,

Really nice project,

I would like to port to an FPGA board that runs Linux, I am studying the code so far. A few questions I have

1) I understand you send to PWM controller the motor direction and pulse as well as DMA delay (using PWM peripheral right?). The pulse will means a microstep and delay will be the time to wait until next microstep. The section of code that does it is (hal.py)

        if direction:  # set up directions
            pins_to_set = 0
            pins_to_clear = 0
            if tx > 0:
                pins_to_clear |= 1 << STEPPER_DIR_PIN_X
            elif tx < 0:
                pins_to_set |= 1 << STEPPER_DIR_PIN_X
            if ty > 0:
                pins_to_clear |= 1 << STEPPER_DIR_PIN_Y
            elif ty < 0:
                pins_to_set |= 1 << STEPPER_DIR_PIN_Y
            if tz > 0:
                pins_to_clear |= 1 << STEPPER_DIR_PIN_Z
            elif tz < 0:
                pins_to_set |= 1 << STEPPER_DIR_PIN_Z
            if te > 0:
                pins_to_clear |= 1 << STEPPER_DIR_PIN_E
            elif te < 0:
                pins_to_set |= 1 << STEPPER_DIR_PIN_E
            dma.add_set_clear(pins_to_set, pins_to_clear)
            continue
        pins = 0
        m = None
        for i in (tx, ty, tz, te):
            if i is not None and (m is None or i < m):
                m = i
        k = int(round(m * US_IN_SECONDS))
        if tx is not None:
            pins |= STEP_PIN_MASK_X
        if ty is not None:
            pins |= STEP_PIN_MASK_Y
        if tz is not None:
            pins |= STEP_PIN_MASK_Z
        if te is not None:
            pins |= STEP_PIN_MASK_E
        if k - prev > 0:
            dma.add_delay(k - prev)
        dma.add_pulse(pins, STEPPER_PULSE_LENGTH_US)
        # TODO not a precise way! pulses will set in queue, instead of crossing
        # if next pulse start during pulse length. Though it almost doesn't
        # matter for pulses with 1-2us length.
        prev = k + STEPPER_PULSE_LENGTH_US

I understand pins has information for all axis, such as which axi produces or not a STEP, pins_to clear and pins_to_clear control direction, so far so good, and add delay produces the timing between current and next pulses, but this delay affects all axis right? I understand that you gather the minimum delay of new movements (among all axis) to compare with previous delay in order to add a new delay, if no delay needed (I am not sure how this can become) you don't add_delay but you still add the pulse. Does it means DMA will not wait to send new sample to PWM controller?

Would you mind to give me some words here that help me understand the logic please.

2) If I want to start with some basic test (after I complete some porting code), how can I directly run some command to test with? I know there is a test folder but could you please let me know how to use them, is that only for gcode or can I manually send some axi movements to steppers?

I will appreciate your comments,

mhanuel26 commented 6 years ago

Hi Nikolay,

After studying more the code it's more clear how it works, still I have some doubts,

Under raspberry hal, move method, I would like to understand better this

        for i in (tx, ty, tz, te):
            if i is not None and (m is None or i < m):
                m = i

I was thinking on this because after looking at the iterator PulseGenerator object, I notice you set only the "motors" with minimum time, so there can be present if they has the same time right?

That is, under pulses.py

        # convert to real time
        m = None
        for i in (tx, ty, tz, te):
            if i is not None and (m is None or i < m):
                m = i
        am = self._to_accelerated_time(m)
        # sort pulses in time
        if tx is not None:
            if tx > m:
                tx = None
            else:
                tx = am
                self._iteration_x += 1
        if ty is not None:
            if ty > m:
                ty = None
            else:
                ty = am
                self._iteration_y += 1
        if tz is not None:
            if tz > m:
                tz = None
            else:
                tz = am
                self._iteration_z += 1
        if te is not None:
            if te > m:
                te = None
            else:
                te = am
                self._iteration_e += 1

        return False, tx, ty, tz, te

If they are present, it means you advance the iterator for that axi, but under raspberry hal, it seems you apply the minimum, but I cannot see how those values can differ if all are been set to accelerated time, such as

tx = am

Will appreciate your comments,