<p>It is actually difficult to answer this question as the code is written to handle likely over a hundred different types of hardware, and multiple types of stepper hardware.</p>
<p>Starting from where the pins are actually defined up to the code that drives them, here's a quick breakdown.</p>
<p>The header files in <code>src/pins/pins_*.h</code> define the actual pins that are talking to the hardware. E.g. these files contain lots of <code>#define</code> preprocessor directive such as this <code>#define</code> that defines what pin on a certain processor controls the direction of the Z stepper motor;</p>
<pre><code>#define Z_DIR_PIN 10
</code></pre>
<p>The header file <code>indirection.h</code> defines &quot;higher level&quot; #define's. Building on the above example, this macro is defined in <code>indirection.h</code> used to actually set the stepper motor direction.</p>
<pre><code>#define Z_DIR_WRITE(STATE) WRITE(Z_DIR_PIN,INVERT_DIR(Z, STATE))
</code></pre>
<p>Finally, <code>stepper.cpp</code> will use the above macros to actually write to the hardware. As noted above the bulk of this code is <code>#if</code>/<code>#else</code>/<code>#define</code> preprocessor directives to support all of the many hardware/processor configurations. <code>Stepper.h</code> does have some even higher level macros, e.g.,</p>
<pre><code>      #define Z_APPLY_DIR(FWD,Q) do{ \
        Z_DIR_WRITE(FWD); Z2_DIR_WRITE(INVERT_DIR(Z2_VS_Z, FWD)); \
        Z3_DIR_WRITE(INVERT_DIR(Z3_VS_Z, FWD)); Z4_DIR_WRITE(INVERT_DIR(Z4_VS_Z, FWD)); \
      }while(0)
</code></pre>
<p>I suspect that the code is heavily optimized (some written in assembly) ending up with very high-level concepts such as Bezier curve following tied directly with writing to the actual stepper.</p>
<p>Maybe I have stepped into a big problem with this code. It's difficult for someone who hasn't worked with it a lot to make simple changes. Maybe there is a need for a &quot;simple stepper&quot; driver that does not have a gazillion hardware dependencies that can be used for people like myself who just wish to do a quick experiment.</p>

CC BY-SA 4.0
2023-12-14T22:03:43.983Z
Note that the above answer does not mention how timing is accomplished.
Tom Cumming
CC BY-SA 4.0
2023-12-15T18:40:16.100Z
Maybe your looking at different code? #define Z_APPLY_DIR . . .  is  definitely in my stepper.cpp, not in stepper.h.
Tom Cumming
CC BY-SA 4.0
2023-12-20T23:06:29.097Z
Hi Tom, your last comment looks like to are trying to reply to someone. The way comments work is that you (usually) need to address someone using the @ symbol. Also the reply comment must be under the same post where the comment (that you are replying to) was made. As a new user, you might like to read [How do comments work?](https://meta.stackexchange.com/questions/19756/how-do-comments-work). Also, FYI, note that comments are ephemeral in nature and tend to get deleted after a time. So, any additional info (that needs to be kept) should be edited into the question and not placed in comments.
Greenonline
CC BY-SA 4.0
2023-12-14T22:02:56.003Z
2023-12-18T18:06:59.653Z
2023-12-18T18:06:59.653Z
Tom Cumming
<p>I suggest reading the existing Marlin documentation that's available regarding <a href="https://marlinfw.org/docs/setting/stepper_drivers.html" rel="nofollow noreferrer">stepper drivers</a> or <a href="https://marlinfw.org/docs/hardware/tmc_drivers.html" rel="nofollow noreferrer">trinamic drivers</a>.</p>
<p>It's probably also advisable to familiarize yourself with the modular files <a href="https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.1.x/Marlin/src/module/stepper.h" rel="nofollow noreferrer"><code>src/module/stepper.h</code></a>, <a href="https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.1.x/Marlin/src/module/stepper.cpp" rel="nofollow noreferrer"><code>src/module/stepper.cpp</code></a> files, or from the Voxel8 repository for example the <a href="https://github.com/Voxel8/Marlin/blob/master/Marlin/stepper_indirection.h" rel="nofollow noreferrer"><code>stepper_indirection.h</code></a> file, as they handle the stepper motor interface.</p>
<p>Understanding the existing code or even modifying an existing driver could help to achieve your objectives.</p>
<p>Also depending on your experience and requirements you might find some inspiration in several YouTube videos such as <a href="https://m.youtube.com/watch?v=5b6qWVo6lcU" rel="nofollow noreferrer">DIY Stepper Motor Driver From Scratch</a> or
<a href="https://m.youtube.com/watch?v=nafoHAhz8Ys" rel="nofollow noreferrer">EasyDriver A3967 Stepper Motor Driver Tutorial with Arduino Code</a>.</p>

CC BY-SA 4.0
2023-12-14T20:58:11.170Z
I've already been through the above. The documentation (mostly how to set #define's, not what I'm looking for), stepper.cpp appears to be dealing with mostly high level stuff, i.e., I see lots of code for bezier splines, etc. Maybe my problem is digging though reams of #if's and #defines just to find the code that actually talks to the hardware is such a pain.
Tom Cumming
CC BY-SA 4.0
2023-12-14T21:06:26.850Z
With regard to the videos; I've been writing code like this for decades, I don't need the "how a stepper motor works" answers. I already use an Arduino for proof-of-concept (as noted in my question). My question relates specifically how and where to add drivers to Marlin.
Tom Cumming
CC BY-SA 4.0
2023-12-14T21:33:59.917Z
Although the question fits on this site too, I think you might have more luck asking this on GitHub with the context you've just described, as in, what you've already achieved and tried.
Bob Ortiz
CC BY-SA 4.0
2023-12-13T22:29:39.057Z
2023-12-14T04:57:09.833Z
2023-12-14T04:57:09.833Z
Bob Ortiz
<p>I've been digging through the Marlin code from GitHub, and I'm hoping that someone could direct me where to add a custom motor driver. I figure someone here already is familiar with the code and it would save me a lot of time digging.</p>
<p>I know someone will ask why I'm asking how I can add my own drivers...</p>
<ol>
<li><p>To find out if what I'm trying to do has already been done by someone else, or if there is something close I could tweak (code reuse).</p>
</li>
<li><p>I am attempting to make an absolutely minimal controller board that drives really small steppers. I can easily drive the steppers directly with four TTL outputs (with some output protection of course). I have already experimentally shown it works and is solid.</p>
</li>
<li><p>More important than the above, I'd like to give it a try just for the learning experience. As they say, &quot;the journey is the destination&quot;.</p>
</li>
</ol>

CC BY-SA 4.0
2023-12-12T21:08:39.990Z
Welcome Tom. I don't understand the sentence 'I know someone will ask why I'm asking why I'd add my own drivers.'. Can you clarify it by editing your post?
Bob Ortiz
CC BY-SA 4.0
2023-12-13T19:35:39.427Z
@BobOrtiz - Hmmm, it's interesting when you think about it. It would be better put "I know someone will ask why I'm asking how I can add my own drivers...". As it currently stands, the meaning is: "I know that someone will ask me why I am asking why...", which isn't correct - even though the *actual* meaning is clear. The OP is really asking "*how* can they add a driver" ***not*** "why should they bother". Good catch :-)
Greenonline
CC BY-SA 4.0
2023-12-13T22:10:13.597Z
I updated the question with the @Greenonline's version. My experience with posting online questions is that there's usually a flurry of, "why do you want to do that?" responses. I was trying to head those off.
Tom Cumming
CC BY-SA 4.0
2023-12-13T22:11:57.990Z
Also, this is a serious question, and so far I've only received verbiage and spelling edits.  Am I asking in the right forum? Is there somewhere better to ask this question?
Tom Cumming
CC BY-SA 4.0
2023-12-13T22:39:30.473Z
I've tried to answer your main question although your second sub question suggest that you want to write a driver from scratch, and the title suggests that you only wonder 'how to add' an already existing custom driver.
Bob Ortiz
CC BY-SA 4.0
2023-12-15T12:06:46.930Z
Perhaps you could include `stepper.h`? That supports driving a stepper motor with an H-bridge such as a L298N. You could then use its `step()` function from within the Marlin code to interface with the library.
towe
<marlin><g-code><firmware><software><stepper-driver>
How do I add a custom motor driver to Marlin?
Tom Cumming
# How do I add a custom motor driver to Marlin?

(Asked by: username_0 on 2023-12-12)

I've been digging through the Marlin code from GitHub, and I'm hoping that someone could direct me where to add a custom motor driver. I figure someone here already is familiar with the code and it would save me a lot of time digging.

I know someone will ask why I'm asking how I can add my own drivers...

1. To find out if what I'm trying to do has already been done by someone else, or if there is something close I could tweak (code reuse).
2. I am attempting to make an absolutely minimal controller board that drives really small steppers. I can easily drive the steppers directly with four TTL outputs (with some output protection of course). I have already experimentally shown it works and is solid.
3. More important than the above, I'd like to give it a try just for the learning experience. As they say, "the journey is the destination".

**Tags:** marlin, g-code, firmware, software, stepper-driver
> **Comments:**
> **username_1**: Welcome Tom. I don't understand the sentence 'I know someone will ask why I'm asking why I'd add my own drivers.'. Can you clarify it by editing your post?  
> **username_2**: @BobOrtiz - Hmmm, it's interesting when you think about it. It would be better put "I know someone will ask why I'm asking how I can add my own drivers...". As it currently stands, the meaning is: "I know that someone will ask me why I am asking why...", which isn't correct - even though the *actual* meaning is clear. The OP is really asking "*how* can they add a driver" ***not*** "why should they bother". Good catch :-)  
> **username_0**: I updated the question with the @Greenonline's version. My experience with posting online questions is that there's usually a flurry of, "why do you want to do that?" responses. I was trying to head those off.  
> **username_0**: Also, this is a serious question, and so far I've only received verbiage and spelling edits.  Am I asking in the right forum? Is there somewhere better to ask this question?  
> **username_1**: I've tried to answer your main question although your second sub question suggest that you want to write a driver from scratch, and the title suggests that you only wonder 'how to add' an already existing custom driver.  
> **username_3**: Perhaps you could include `stepper.h`? That supports driving a stepper motor with an H-bridge such as a L298N. You could then use its `step()` function from within the Marlin code to interface with the library.  

---

## 2 answers

### Answer by username_0 on 2023-12-14. Score: 2

It is actually difficult to answer this question as the code is written to handle likely over a hundred different types of hardware, and multiple types of stepper hardware.
Starting from where the pins are actually defined up to the code that drives them, here's a quick breakdown.
The header files in src/pins/pins_*.h define the actual pins that are talking to the hardware. E.g. these files contain lots of #define preprocessor directive such as this #define that defines what pin on a certain processor controls the direction of the Z stepper motor;
#define Z_DIR_PIN 10

The header file indirection.h defines "higher level" #define's. Building on the above example, this macro is defined in indirection.h used to actually set the stepper motor direction.
#define Z_DIR_WRITE(STATE) WRITE(Z_DIR_PIN,INVERT_DIR(Z, STATE))

Finally, stepper.cpp will use the above macros to actually write to the hardware. As noted above the bulk of this code is #if/#else/#define preprocessor directives to support all of the many hardware/processor configurations. Stepper.h does have some even higher level macros, e.g.,
      #define Z_APPLY_DIR(FWD,Q) do{ \
        Z_DIR_WRITE(FWD); Z2_DIR_WRITE(INVERT_DIR(Z2_VS_Z, FWD)); \
        Z3_DIR_WRITE(INVERT_DIR(Z3_VS_Z, FWD)); Z4_DIR_WRITE(INVERT_DIR(Z4_VS_Z, FWD)); \
      }while(0)

I suspect that the code is heavily optimized (some written in assembly) ending up with very high-level concepts such as Bezier curve following tied directly with writing to the actual stepper.
Maybe I have stepped into a big problem with this code. It's difficult for someone who hasn't worked with it a lot to make simple changes. Maybe there is a need for a "simple stepper" driver that does not have a gazillion hardware dependencies that can be used for people like myself who just wish to do a quick experiment.

> **Comments:**
> **username_0**: Note that the above answer does not mention how timing is accomplished.  
> **username_0**: Maybe your looking at different code? #define Z_APPLY_DIR . . .  is  definitely in my stepper.cpp, not in stepper.h.  
> **username_2**: Hi Tom, your last comment looks like to are trying to reply to someone. The way comments work is that you (usually) need to address someone using the @ symbol. Also the reply comment must be under the same post where the comment (that you are replying to) was made. As a new user, you might like to read [How do comments work?](https://meta.stackexchange.com/questions/19756/how-do-comments-work). Also, FYI, note that comments are ephemeral in nature and tend to get deleted after a time. So, any additional info (that needs to be kept) should be edited into the question and not placed in comments.  

---

### Answer by username_1 on 2023-12-13. Score: 1

I suggest reading the existing Marlin documentation that's available regarding [stepper drivers](https://marlinfw.org/docs/setting/stepper_drivers.html) or [trinamic drivers](https://marlinfw.org/docs/hardware/tmc_drivers.html).

It's probably also advisable to familiarize yourself with the modular files [`src/module/stepper.h`](https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.1.x/Marlin/src/module/stepper.h), [`src/module/stepper.cpp`](https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.1.x/Marlin/src/module/stepper.cpp) files, or from the Voxel8 repository for example the [`stepper_indirection.h`](https://github.com/Voxel8/Marlin/blob/master/Marlin/stepper_indirection.h) file, as they handle the stepper motor interface.

Understanding the existing code or even modifying an existing driver could help to achieve your objectives.

Also depending on your experience and requirements you might find some inspiration in several YouTube videos such as [DIY Stepper Motor Driver From Scratch](https://m.youtube.com/watch?v=5b6qWVo6lcU) or
[EasyDriver A3967 Stepper Motor Driver Tutorial with Arduino Code](https://m.youtube.com/watch?v=nafoHAhz8Ys).

> **Comments:**
> **username_0**: I've already been through the above. The documentation (mostly how to set #define's, not what I'm looking for), stepper.cpp appears to be dealing with mostly high level stuff, i.e., I see lots of code for bezier splines, etc. Maybe my problem is digging though reams of #if's and #defines just to find the code that actually talks to the hardware is such a pain.  
> **username_0**: With regard to the videos; I've been writing code like this for decades, I don't need the "how a stepper motor works" answers. I already use an Arduino for proof-of-concept (as noted in my question). My question relates specifically how and where to add drivers to Marlin.  
> **username_1**: Although the question fits on this site too, I think you might have more luck asking this on GitHub with the context you've just described, as in, what you've already achieved and tried.  

---

