libpynq (release 5EWC0-2023 version 0.2.6 of 2025-11-10 09:56)
Loading...
Searching...
No Matches
stepper.c
Go to the documentation of this file.
1/*
2Copyright (c) 2023 Eindhoven University of Technology
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20SOFTWARE.
21*/
22#include "stepper.h"
24#include "log.h"
25#include <platform.h>
26#include <stdio.h>
27#include <stdlib.h>
28
29static arm_shared stepper_handles;
30static volatile uint32_t *stepper_ptrs = NULL;
31
32#define STEPPER_REG_CONFIG 0
33
34#define STEPPER_REG_STEPS 1
35#define STEPPER_REG_CUR_STEPS 1
36
37#define STEPPER_REG_PERIOD 2
38#define STEPPER_REG_CUR_PERIOD 2
39
40#define STEPPER_REG_DUTY 3
41#define STEPPER_REG_CUR_DUTY 3
42
43#define STEPPER_REG_NXT_STEPS 4
44#define STEPPER_REG_NXT_PERIOD 5
45#define STEPPER_REG_NXT_DUTY 6
46#define STEPPER_REG_COUNT 7
47
48#define MIN_PULSE 0x10
49#define MIN_PERIOD (0x30 * 64)
50
51typedef union __attribute__((packed)) {
52 struct {
53 uint16_t step_l : 15;
54 uint8_t dir_l : 1;
55 uint16_t step_r : 15;
56 uint8_t dir_r : 1;
57 };
58 uint32_t val;
60
61typedef union {
62 struct {
63 uint16_t left;
64 uint16_t right;
65 };
66 uint32_t val;
67} pwm_set;
68
69void stepper_init(void) {
70 if (stepper_ptrs != NULL) {
71 pynq_error("Stepper library is already initialized\n");
72 }
73 stepper_ptrs = arm_shared_init(&(stepper_handles), axi_stepper_0, 4096);
74
75 // pulse length. Currently 160 ns
76 // TODO lookup datasheet to see minimum
77 pwm_set st = {.left = MIN_PULSE, .right = MIN_PULSE};
78 stepper_ptrs[STEPPER_REG_DUTY] = st.val;
79
80 st.left = st.right = 0x1000;
81 stepper_ptrs[STEPPER_REG_PERIOD] = st.val;
82}
83
84void stepper_enable(void) {
85 if (stepper_ptrs == NULL) {
86 pynq_error("STEPPER has not been initialized.\n");
87 }
88 // Set reset and lower enable pin
89 stepper_ptrs[STEPPER_REG_CONFIG] = 0x1;
90}
91void stepper_disable(void) {
92 if (stepper_ptrs == NULL) {
93 pynq_error("STEPPER has not been initialized.\n");
94 }
95 // Set reset and lower enable pin
96 stepper_ptrs[STEPPER_REG_CONFIG] = 0x0;
97}
98
99void stepper_destroy(void) {
100 if (stepper_ptrs == NULL) {
101 pynq_error("STEPPER has not been initialized.\n");
102 }
103
105 arm_shared_close(&(stepper_handles));
106 stepper_ptrs = NULL;
107}
108
110 if (stepper_ptrs == NULL) {
111 pynq_error("STEPPER has not been initialized.\n");
112 }
113 // Set reset and lower enable pin
114 stepper_ptrs[STEPPER_REG_CONFIG] = 0x2;
115}
116
118 if (stepper_ptrs == NULL) {
119 pynq_error("STEPPER has not been initialized.\n");
120 }
121 volatile steps *stp =
122 (volatile steps *)&(stepper_ptrs[STEPPER_REG_CUR_STEPS]);
123 steps now;
124 now.val = stp->val;
125
126 if (now.step_l == 0 && now.step_r == 0) {
127 return true;
128 }
129 return false;
130}
131
132void stepper_steps(int16_t left, int16_t right) {
133 if (stepper_ptrs == NULL) {
134 pynq_error("STEPPER has not been initialized.\n");
135 }
136 volatile steps *stp =
137 (volatile steps *)&(stepper_ptrs[STEPPER_REG_CUR_STEPS]);
138 steps now;
139 now.dir_r = (right < 0) ? 0 : 1;
140 now.dir_l = (left < 0) ? 0 : 1;
141 now.step_r = abs(right);
142 now.step_l = abs(left);
143
144 stp->val = now.val;
145}
146
147void stepper_set_speed(uint16_t left, uint16_t right) {
148 if (stepper_ptrs == NULL) {
149 pynq_error("STEPPER has not been initialized.\n");
150 }
151 if (left < (MIN_PERIOD) && right < (MIN_PERIOD)) {
152 pynq_error("STEPPER speed is invalid. Should be atleast %u ticks",
153 MIN_PERIOD);
154 }
155 volatile pwm_set *stp =
156 (volatile pwm_set *)&(stepper_ptrs[STEPPER_REG_PERIOD]);
157 pwm_set n;
158 n.left = left;
159 n.right = right;
160 stp->val = n.val;
161}
162
163void stepper_get_steps(int16_t *left, int16_t *right) {
164 if (stepper_ptrs == NULL) {
165 pynq_error("STEPPER has not been initialized.\n");
166 }
167 volatile steps *stp =
168 (volatile steps *)&(stepper_ptrs[STEPPER_REG_CUR_STEPS]);
169 volatile steps now;
170 now.val = stp->val;
171
172 if (now.dir_l == 0) {
173 *left = now.step_l;
174 } else {
175 *left = -now.step_l;
176 }
177 if (now.dir_r == 0) {
178 *right = -now.step_r;
179 } else {
180 *right = now.step_r;
181 }
182}
183
void arm_shared_close(arm_shared *handle)
void * arm_shared_init(arm_shared *handle, const uint32_t address, const uint32_t length)
#define pynq_error(...)
Definition log.h:118
void stepper_enable(void)
Definition stepper.c:84
void stepper_reset()
Definition stepper.c:109
void stepper_init(void)
Definition stepper.c:69
void stepper_get_steps(int16_t *left, int16_t *right)
Definition stepper.c:163
void stepper_destroy(void)
Definition stepper.c:99
void stepper_disable(void)
Definition stepper.c:91
void stepper_steps(int16_t left, int16_t right)
Definition stepper.c:132
bool stepper_steps_done(void)
Definition stepper.c:117
void stepper_set_speed(uint16_t left, uint16_t right)
Definition stepper.c:147
#define STEPPER_REG_DUTY
Definition stepper.c:40
steps
Definition stepper.c:59
#define STEPPER_REG_CUR_STEPS
Definition stepper.c:35
union __attribute__((packed))
Definition stepper.c:51
#define MIN_PERIOD
Definition stepper.c:49
#define STEPPER_REG_PERIOD
Definition stepper.c:37
#define MIN_PULSE
Definition stepper.c:48
#define STEPPER_REG_CONFIG
Definition stepper.c:32
uint16_t left
Definition stepper.c:63
uint16_t right
Definition stepper.c:64
uint32_t val
Definition stepper.c:66