Stepdance Software Library
Loading...
Searching...
No Matches
output_ports.hpp
1#include "arm_math.h"
2#include <sys/_stdint.h>
3#include "analog_in.hpp"
4#include "string.h"
5#include "configuration.hpp"
6
7/*
8Output Ports Module of the StepDance Control System
9
10This module is responsible for outputting a pulse-width encoded stream of step and direction pulses on a
11physical microcontroller pin.
12
13[More Details to be Added]
14
15A part of the Mixing Metaphors Project
16(c) 2025 Ilan Moyer, Jennifer Jacobs, Devon Frost, Emilie Yu
17
18*/
19
20#ifndef output_ports_h // prevent importing twice
21#define output_ports_h
26struct output_port_info_struct
27{ // we use this structure to store hardware-specific information for each available port
28 // Port Name (for reporting)
29 char PORT_NAME[10];
30
31 // Physical IO
32 uint8_t STEP_TEENSY_PIN; // TEENSY Pin #s
33 uint8_t DIR_TEENSY_PIN;
34
35 // Connecting FlexIO to Physical IO
36 uint8_t STEP_FLEXIO_PIN; // FlexIO Module Pin #s (remember, IMXRT modules have pins, which attach to physical "pads" on the chip)
37 uint8_t DIR_FLEXIO_PIN;
38 volatile uint32_t *STEP_PIN_IOMUXC_REGISTER; // mux register pointer for the step pin
39 volatile uint32_t *DIR_PIN_IOMUXC_REGISTER; // mux register pointer for the step pin
40 uint8_t STEP_PIN_IOMUXC_VALUE; // the mux register value for the step pin
41 uint8_t DIR_PIN_IOMUXC_VALUE; // the mux register value for the step pin
42
43 // FlexIO Module Setup
44 volatile uint32_t *STEP_SHIFTCTRL_REGISTER; // step shifter control register pointer
45 volatile uint32_t *DIR_SHIFTCTRL_REGISTER; // step shifter control register pointer
46 volatile uint32_t *STEP_SHIFTCFG_REGISTER; // step shifter config register pointer
47 volatile uint32_t *DIR_SHIFTCFG_REGISTER; // step shifter config register pointer
48 volatile uint32_t *STEP_SHIFTBUF; // step shift output buffer
49 volatile uint32_t *DIR_SHIFTBUF; // dir shift output buffer
50 uint8_t TIMER_ID; // 0-3 to identify the timer being used for this output port
51 volatile uint32_t *TIMCMP_REGISTER; // timer compare register pointer, sets the output length and frequency
52 volatile uint32_t *TIMCTL_REGISTER; // timer control register pointer
53 volatile uint32_t *TIMCFG_REGISTER; // timer config register
54 uint8_t VREF_TEENSY_PIN; // current vref pin on teensy
55 uint8_t ENABLE_TEENSY_PIN; // enable pin on teensy
56 uint8_t LIMIT_TEENSY_PIN; // limit switch pin on teensy
57};
58
59struct output_format_struct
60{
61 uint8_t FRAME_LENGTH_US; // length of the frame
62 uint8_t STEP_PULSE_START_TIME_US; // time from start of frame to start of the step pulse
63 uint8_t DIR_PULSE_START_TIME_US; // time from start of frame to start of the dir pulse
64 uint8_t SIGNAL_MIN_WIDTH_US; // pulse width in microseconds of shortest signal (index = 0)
65 uint8_t SIGNAL_GAP_US; // gap in microseconds between signals
66 uint8_t RATE_SHIFT; // 2^N bits per microsecond
67};
68
69// #define OUTPUT_FORMAT_STEPDANCE 0 //outputting a pulse-length encoded step stream, which supports multiple signals over a single stream
70// #define OUTPUT_FORMAT_DRIVER 1 //outputting a standard stepper driver stream.
71
72// OUTPUT SPEED SETTINGS
73#define OUTPUT_FRAME_32US 0 // frame is 32us long. This is the standard stepdance output frame, for a 25KHz framerate.
74#define OUTPUT_FRAME_16US 1 // 16us frame, supports up to 50KHz framerate
75#define OUTPUT_FRAME_8US 2 // 8us frame, supports up to 100KHz framerate
76#define OUTPUT_FRAME_4US 3 // 4us frame, supports up to 200KHz framerate
77
78// OUTPUT TRIGGERING
79#define OUTPUT_TRANSMIT_ON_FRAME 1 // transmits each stepdance frame
80#define OUTPUT_TRANSMIT_MANUAL 2 // transmits only with manual call to transmit();
81
82#define OUTPUT_A 0
83#define OUTPUT_B 1
84#define OUTPUT_C 2
85#define OUTPUT_D 3
86#define OUTPUT_A_LEGACY 0
87#define OUTPUT_B_LEGACY 1
88
89#define NUM_SIGNALS 6 // total number of signal types
90
91#define DIRECTION_FORWARD 1
92#define DIRECTION_REVERSE 0
93
94#define NUM_AVAILABLE_OUTPUT_PORTS 4 // max available output ports. NOTE: Should make this dynamic based on TEENSY version
96
105
106// Main Output Port Class
107
108class OutputPort : public Plugin{
112 public:
114 // -- STANDARD PORT FUNCTIONS --
119 void begin(uint8_t port_number); // initialize using only port number
120
125 void begin(uint8_t port_number, uint8_t output_format, uint8_t transmit_mode); //complete initializer
126
127 void add_signal(uint8_t signal_index, uint8_t signal_direction); //adds a signal to the current active frame
128 void transmit_frame(); //encodes and transmits the active frame
129 void step_now(uint8_t direction); //shortcut to immediately output a step at the minimum signal size
130 void step_now(uint8_t direction, uint8_t signal_index);
131
132 // -- DRIVER FUNCTIONS --
133 float32_t read_drive_current_amps(); // returns the last drive current reading
134 float32_t read_drive_current_amps(float32_t drive_current_gain_amps_per_volt); // sets the gain and then returns the last drive current reading
135 void set_drive_current_gain(float32_t amps_per_volt); // sets the drive current gain, in amps/volt
136 void enable_driver(); //enables the motor driver
137 void disable_driver(); //disables the motor driver
138 bool read_limit_switch(); //returns the current value of the limit switch
139
140 char port_name[10]; //stores the name of the port
141 void enroll(RPC *rpc, const String& instance_name);
143
144private:
145 // -- CONFIGURATION PARAMETERS --
146 uint8_t port_number; // the output port ID number
147 uint8_t format_index; // an index into the output_formats struct array.
148 uint8_t transmit_mode; // transmit on frame, or transmit manually
149 uint8_t FRAME_LENGTH_US; // length of the frame
150 uint8_t STEP_PULSE_START_TIME_US; // time from start of frame to start of the step pulse
151 uint8_t DIR_PULSE_START_TIME_US; // time from start of frame to start of the dir pulse
152 uint8_t SIGNAL_MIN_WIDTH_US; // pulse width in microseconds of shortest signal (index = 0)
153 uint8_t SIGNAL_GAP_US; // gap in microseconds between signals
154 uint8_t RATE_SHIFT; // 2^N bits per microsecond
155 static const struct output_port_info_struct port_info[]; // stores setup information for all four output ports
156 static const struct output_format_struct output_formats[]; // output formats for different frame sizes
157
158 // -- STATE VARIABLES --
159 volatile uint8_t active_signals[NUM_SIGNALS];
160 volatile uint8_t active_signal_directions[NUM_SIGNALS];
161 volatile uint32_t active_encoded_frame_step; // these get populated by the encode function
162 volatile uint32_t active_encoded_frame_dir;
163 volatile float32_t last_drive_current_reading_amps;
164
165 // DRIVER CONFIG AND STATE
166 // for reading driver-related peripherals
167 // storing this state allows us to configure on-the-fly when relevant functions get called.
168 volatile bool vref_is_configured = false;
169 volatile bool enable_is_configured = false;
170 volatile bool limitsw_is_configured = false;
171 float32_t drive_current_gain_amps_per_volt = 0; // stores the drive current gain setting.
172
173 // -- METHODS --
174 void encode(); // encodes the active_signal arrays into the active_encoded_frames
175 void transmit(); // transmits the active encoded frame
176 void clear_all_signals(); // clears all signals in the current active frame
177 void register_output_port(); // registers the output port
178
179 // -- ADC --
180 AnalogInput analog_vref;
181};
182
183void transmit_frames_on_all_output_ports(); // transmits across all output ports
184
185void iterate_across_all_output_ports(void (*target_function)(OutputPort *)); // allows user code to iterate across all output ports
186
187void enable_drivers(); // enables drivers on all registered output ports
188void disable_drivers(); // enables drivers on all registered output ports
189
190#endif // output_ports_h
AnalogInput components read values from physical user interface components and enable them to be mapp...
Definition analog_in.hpp:81
OutputPorts are modules that convert internal step commands into a frame of pulse signals on the phys...
Definition output_ports.hpp:108
void begin(uint8_t port_number)
Initialize the OutputPort with a port number corresponding to the target physical port on the Stepdan...
OutputPort()
Default constructor for OutputPort. Initializes an OutputPort instance with default,...
RPC class for handling remote procedure calls over serial streams.
Definition rpc.hpp:35