libpynq  (release 5EID0-2023 version 0.3.0 of 2024-04-25 09:42 )
stepper.c
Go to the documentation of this file.
1 /*
2 Copyright (c) 2023 Eindhoven University of Technology
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
21 */
22 #include "stepper.h"
24 #include "log.h"
25 #include <platform.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 
29 static arm_shared stepper_handles;
30 static 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 
51 typedef 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 
61 typedef union {
62  struct {
63  uint16_t left;
64  uint16_t right;
65  };
66  uint32_t val;
67 } pwm_set;
68 
69 void 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 
84 void 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 }
91 void 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 
99 void stepper_destroy(void) {
100  if (stepper_ptrs == NULL) {
101  pynq_error("STEPPER has not been initialized.\n");
102  }
103 
104  stepper_disable();
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 
117 bool stepper_steps_done(void) {
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 
132 void 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 
147 void 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 
163 void 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 }
STEPPER_REG_CONFIG
#define STEPPER_REG_CONFIG
Definition: stepper.c:32
stepper_steps
void stepper_steps(int16_t left, int16_t right)
Definition: stepper.c:132
stepper.h
MIN_PERIOD
#define MIN_PERIOD
Definition: stepper.c:49
pynq_error
#define pynq_error(...)
Definition: log.h:118
stepper_get_steps
void stepper_get_steps(int16_t *left, int16_t *right)
Definition: stepper.c:163
arm_shared_memory_system.h
stepper_destroy
void stepper_destroy(void)
Definition: stepper.c:99
STEPPER_REG_PERIOD
#define STEPPER_REG_PERIOD
Definition: stepper.c:37
arm_shared_t
Definition: arm_shared_memory_system.h:39
arm_shared_close
void arm_shared_close(arm_shared *handle)
Definition: arm_shared_memory_system.c:70
stepper_disable
void stepper_disable(void)
Definition: stepper.c:91
pwm_set::right
uint16_t right
Definition: stepper.c:64
steps
steps
Definition: stepper.c:59
STEPPER_REG_CUR_STEPS
#define STEPPER_REG_CUR_STEPS
Definition: stepper.c:35
stepper_reset
void stepper_reset()
Definition: stepper.c:109
__attribute__
union __attribute__((packed))
Definition: stepper.c:51
pwm_set
Definition: stepper.c:61
log.h
arm_shared_init
void * arm_shared_init(arm_shared *handle, const uint32_t address, const uint32_t length)
Definition: arm_shared_memory_system.c:32
stepper_set_speed
void stepper_set_speed(uint16_t left, uint16_t right)
Definition: stepper.c:147
pwm_set::val
uint32_t val
Definition: stepper.c:66
MIN_PULSE
#define MIN_PULSE
Definition: stepper.c:48
stepper_steps_done
bool stepper_steps_done(void)
Definition: stepper.c:117
STEPPER_REG_DUTY
#define STEPPER_REG_DUTY
Definition: stepper.c:40
pwm_set::left
uint16_t left
Definition: stepper.c:63
stepper_init
void stepper_init(void)
Definition: stepper.c:69
stepper_enable
void stepper_enable(void)
Definition: stepper.c:84