├── .DS_Store
├── .gitignore
├── README.md
├── firmware
├── .DS_Store
└── stepServo
│ ├── .cproject
│ ├── .project
│ ├── A4954.cpp
│ ├── A4954.h
│ ├── A5995.cpp
│ ├── A5995.h
│ ├── Adafruit_GFX.cpp
│ ├── Adafruit_GFX.h
│ ├── Adafruit_SSD1306.cpp
│ ├── Adafruit_SSD1306.h
│ ├── Flash.cpp
│ ├── Flash.h
│ ├── angle.h
│ ├── as5047d.cpp
│ ├── as5047d.h
│ ├── board.h
│ ├── calibration.cpp
│ ├── calibration.h
│ ├── command.cpp
│ ├── command.h
│ ├── commands.cpp
│ ├── commands.h
│ ├── eeprom.cpp
│ ├── eeprom.h
│ ├── fet_driver.cpp
│ ├── fet_driver.h
│ ├── ftoa.cpp
│ ├── ftoa.h
│ ├── gfxfont.h
│ ├── glcdfont.c
│ ├── nonvolatile.cpp
│ ├── nonvolatile.h
│ ├── nzs.cpp
│ ├── nzs.h
│ ├── nzs_lcd.cpp
│ ├── nzs_lcd.h
│ ├── planner.cpp
│ ├── planner.h
│ ├── sine.cpp
│ ├── sine.h
│ ├── stepper_controller.cpp
│ ├── stepper_controller.h
│ ├── stepper_nano_zero.ino
│ ├── syslog.cpp
│ ├── syslog.h
│ ├── utils.cpp
│ └── utils.h
├── hardware
├── NZS_A4954_R2.0.PrjPcb
├── NZS_A4954_R2_0.PcbDoc
├── Nano_stepper.SchDoc
├── Nano_zero_stepper_Schematics.pdf
├── Status Report.Txt
├── panel-RoundHoles.TXT
├── panel-SlotHoles.TXT
├── panel-macro.APR_LIB
├── panel.1
├── panel.DRR
├── panel.EXTREP
├── panel.GBL
├── panel.GBO
├── panel.GBP
├── panel.GBS
├── panel.GD1
├── panel.GKO
├── panel.GM1
├── panel.GM13
├── panel.GM15
├── panel.GM2
├── panel.GM3
├── panel.GML
├── panel.GPB
├── panel.GPT
├── panel.GTL
├── panel.GTO
├── panel.GTP
├── panel.GTS
├── panel.LDP
├── panel.REP
├── panel.RUL
└── panel.apr
└── stl
├── Helm.SLDPRT
├── Helm.STL
├── cover1.SLDPRT
├── cover1.STL
├── cover2.SLDPRT
└── cover2.STL
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 小步步伺服驱动板 Step Servo
2 |
3 | learn more at http://stepservo.cc
--------------------------------------------------------------------------------
/firmware/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/firmware/.DS_Store
--------------------------------------------------------------------------------
/firmware/stepServo/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
40 |
44 |
45 |
46 |
47 |
60 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/firmware/stepServo/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | NZS
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 |
14 |
15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
16 | full,incremental,
17 |
18 |
19 |
20 |
21 |
22 | org.eclipse.cdt.core.cnature
23 | org.eclipse.cdt.core.ccnature
24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
26 |
27 |
28 |
29 | arduino
30 | 2
31 | C:/Users/tramp_000/AppData/Local/Arduino15/packages/arduino/hardware/samd/1.6.8/cores/arduino
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/firmware/stepServo/A4954.cpp:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 | #include "A4954.h"
13 | #include "wiring_private.h"
14 | #include "syslog.h"
15 | #include "angle.h"
16 | #include "Arduino.h"
17 | #include "sine.h"
18 |
19 | static uint8_t pinState=0;
20 |
21 | #pragma GCC push_options
22 | #pragma GCC optimize ("-Ofast")
23 |
24 |
25 |
26 |
27 | #define DAC_MAX (0x01FFL)
28 | // Wait for synchronization of registers between the clock domains
29 | static __inline__ void syncTCC(Tcc* TCCx) __attribute__((always_inline, unused));
30 | static void syncTCC(Tcc* TCCx) {
31 | //int32_t t0=1000;
32 | while (TCCx->SYNCBUSY.reg & TCC_SYNCBUSY_MASK)
33 | {
34 | // t0--;
35 | // if (t0==0)
36 | // {
37 | // break;
38 | // }
39 | // delay(1);
40 | }
41 | }
42 |
43 |
44 | static inline void bridge1(int state)
45 | {
46 | if (state==0)
47 | {
48 | PORT->Group[g_APinDescription[PIN_A4954_IN1].ulPort].PINCFG[g_APinDescription[PIN_A4954_IN1].ulPin].bit.PMUXEN = 0;
49 | GPIO_OUTPUT(PIN_A4954_IN1);//pinMode(PIN_A4954_IN1,OUTPUT);
50 | GPIO_OUTPUT(PIN_A4954_IN2);//pinMode(PIN_A4954_IN2,OUTPUT);
51 | GPIO_HIGH(PIN_A4954_IN1);// digitalWrite(PIN_A4954_IN1, HIGH);
52 | GPIO_LOW(PIN_A4954_IN2);//digitalWrite(PIN_A4954_IN2, LOW);
53 | //pinPeripheral(PIN_A4954_IN2, PIO_TIMER_ALT);
54 | pinState=(pinState & 0x0C) | 0x1;
55 | }
56 | if (state==1)
57 | {
58 | PORT->Group[g_APinDescription[PIN_A4954_IN2].ulPort].PINCFG[g_APinDescription[PIN_A4954_IN2].ulPin].bit.PMUXEN = 0;
59 | GPIO_OUTPUT(PIN_A4954_IN2);//pinMode(PIN_A4954_IN2,OUTPUT);
60 | GPIO_OUTPUT(PIN_A4954_IN1);pinMode(PIN_A4954_IN1,OUTPUT);
61 | GPIO_LOW(PIN_A4954_IN1);//digitalWrite(PIN_A4954_IN1, LOW);
62 | GPIO_HIGH(PIN_A4954_IN2);//digitalWrite(PIN_A4954_IN2, HIGH);
63 | //pinPeripheral(PIN_A4954_IN1, PIO_TIMER);
64 | pinState=(pinState & 0x0C) | 0x2;
65 | }
66 | if (state==3)
67 | {
68 | GPIO_LOW(PIN_A4954_IN1);
69 | GPIO_LOW(PIN_A4954_IN2);
70 | //digitalWrite(PIN_A4954_IN1, LOW);
71 | //digitalWrite(PIN_A4954_IN2, LOW);
72 | }
73 | }
74 |
75 | static inline void bridge2(int state)
76 | {
77 | if (state==0)
78 | {
79 | PORT->Group[g_APinDescription[PIN_A4954_IN3].ulPort].PINCFG[g_APinDescription[PIN_A4954_IN3].ulPin].bit.PMUXEN = 0;
80 | GPIO_OUTPUT(PIN_A4954_IN3); //pinMode(PIN_A4954_IN3,OUTPUT);
81 | GPIO_OUTPUT(PIN_A4954_IN4);//pinMode(PIN_A4954_IN4,OUTPUT);
82 | GPIO_HIGH(PIN_A4954_IN3);//digitalWrite(PIN_A4954_IN3, HIGH);
83 | GPIO_LOW(PIN_A4954_IN4);//digitalWrite(PIN_A4954_IN4, LOW);
84 | //pinPeripheral(PIN_A4954_IN4, PIO_TIMER_ALT);
85 | pinState=(pinState & 0x03) | 0x4;
86 | }
87 | if (state==1)
88 | {
89 | PORT->Group[g_APinDescription[PIN_A4954_IN4].ulPort].PINCFG[g_APinDescription[PIN_A4954_IN4].ulPin].bit.PMUXEN = 0;
90 | GPIO_OUTPUT(PIN_A4954_IN4);//pinMode(PIN_A4954_IN4,OUTPUT);
91 | GPIO_OUTPUT(PIN_A4954_IN3);//pinMode(PIN_A4954_IN3,OUTPUT);
92 | GPIO_LOW(PIN_A4954_IN3);//digitalWrite(PIN_A4954_IN3, LOW);
93 | GPIO_HIGH(PIN_A4954_IN4);//digitalWrite(PIN_A4954_IN4, HIGH);
94 | //pinPeripheral(PIN_A4954_IN3, PIO_TIMER_ALT);
95 | pinState=(pinState & 0x03) | 0x8;
96 | }
97 | if (state==3)
98 | {
99 | GPIO_LOW(PIN_A4954_IN3);
100 | GPIO_LOW(PIN_A4954_IN4);
101 | //digitalWrite(PIN_A4954_IN3, LOW);
102 | //digitalWrite(PIN_A4954_IN4, LOW);
103 | }
104 | }
105 |
106 | static void enableTCC0(uint8_t percent)
107 | {
108 | #ifdef MECHADUINO_HARDWARE
109 | return;
110 | #else
111 | Tcc* TCCx = TCC0 ;
112 |
113 |
114 | uint32_t ulValue=((uint32_t)(100-percent)*480)/100;
115 | //ERROR("Enable TCC0");
116 |
117 | GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ;
118 |
119 | while ( GCLK->STATUS.bit.SYNCBUSY == 1 ) ;
120 |
121 | //ERROR("Setting TCC %d %d",ulValue,ulPin);
122 | TCCx->CTRLA.reg &= ~TCC_CTRLA_ENABLE;
123 | syncTCC(TCCx);
124 |
125 | // Set TCx as normal PWM
126 | TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;
127 | syncTCC(TCCx);
128 |
129 | // Set TCx in waveform mode Normal PWM
130 | TCCx->CC[1].reg = (uint32_t)ulValue; //ch5 //IN3
131 | syncTCC(TCCx);
132 |
133 | TCCx->CC[2].reg = (uint32_t)ulValue; //ch6 //IN4
134 | syncTCC(TCCx);
135 |
136 | TCCx->CC[3].reg = (uint32_t)ulValue; //ch7 //IN2
137 | syncTCC(TCCx);
138 |
139 | TCCx->CC[1].reg = (uint32_t)ulValue; //ch1 == ch5 //IN1
140 |
141 | syncTCC(TCCx);
142 |
143 | // Set PER to maximum counter value (resolution : 0xFF)
144 | TCCx->PER.reg = DAC_MAX;
145 | syncTCC(TCCx);
146 |
147 | // Enable TCCx
148 | TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ;
149 | syncTCC(TCCx);
150 | //ERROR("Enable TCC0 DONE");
151 | #endif
152 | }
153 |
154 | static void setDAC(uint32_t DAC1, uint32_t DAC2)
155 | {
156 | TCC1->CC[1].reg = (uint32_t)DAC1; //D9 PA07 - VREF12
157 | syncTCC(TCC1);
158 | TCC1->CC[0].reg = (uint32_t)DAC2; //D4 - VREF34
159 | syncTCC(TCC1);
160 |
161 |
162 | }
163 |
164 | static void setupDAC(void)
165 | {
166 | Tcc* TCCx = TCC1 ;
167 |
168 |
169 | pinPeripheral(PIN_A4954_VREF34, PIO_TIMER_ALT);
170 | pinPeripheral(PIN_A4954_VREF12, PIO_TIMER);
171 |
172 | GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ;
173 |
174 | while ( GCLK->STATUS.bit.SYNCBUSY == 1 ) ;
175 |
176 | //ERROR("Setting TCC %d %d",ulValue,ulPin);
177 | TCCx->CTRLA.reg &= ~TCC_CTRLA_ENABLE;
178 | syncTCC(TCCx);
179 |
180 | // Set TCx as normal PWM
181 | TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;
182 | syncTCC(TCCx);
183 |
184 | // Set TCx in waveform mode Normal PWM
185 | TCCx->CC[1].reg = (uint32_t)0;
186 | syncTCC(TCCx);
187 |
188 | TCCx->CC[0].reg = (uint32_t)0;
189 | syncTCC(TCCx);
190 |
191 | // Set PER to maximum counter value (resolution : 0xFFF = 12 bits)
192 | // =48e6/2^12=11kHz frequency
193 | TCCx->PER.reg = DAC_MAX;
194 | syncTCC(TCCx);
195 |
196 | // Enable TCCx
197 | TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ;
198 | syncTCC(TCCx);
199 |
200 | }
201 |
202 |
203 | void A4954::begin()
204 | {
205 | //setup the A4954 pins
206 | digitalWrite(PIN_A4954_IN3,LOW);
207 | pinMode(PIN_A4954_IN3,OUTPUT);
208 | digitalWrite(PIN_A4954_IN4,LOW);
209 | pinMode(PIN_A4954_IN4,OUTPUT);
210 | digitalWrite(PIN_A4954_IN2,LOW);
211 | pinMode(PIN_A4954_IN2,OUTPUT);
212 | digitalWrite(PIN_A4954_IN1,LOW);
213 | pinMode(PIN_A4954_IN1,OUTPUT);
214 |
215 | //setup the PWM for current on the A4954, set for low current
216 | digitalWrite(PIN_A4954_VREF12,LOW);
217 | digitalWrite(PIN_A4954_VREF34,LOW);
218 | pinMode(PIN_A4954_VREF34, OUTPUT);
219 | pinMode(PIN_A4954_VREF12, OUTPUT);
220 |
221 | enabled=true;
222 | lastStepMicros=0;
223 | forwardRotation=true;
224 |
225 | enableTCC0(90);
226 | setupDAC();
227 | //
228 | // int i=0;
229 | // bridge1(0);
230 | // bridge2(0);
231 | //while (1)
232 | // {
233 | // int32_t x;
234 | // WARNING("MA %d",i);
235 | // x=(int32_t)((int64_t)i*(DAC_MAX))/3300;
236 | // setDAC(x,x);
237 | // delay(1000);
238 | // i=i+10;
239 | // if (i>1000)
240 | // {
241 | // i=0;
242 | // }
243 | //
244 | // }
245 |
246 | //
247 | // WARNING("Setting DAC for 500mA output");
248 | // setDAC((int32_t)((int64_t)1000*(DAC_MAX))/3300,(int32_t)((int64_t)1000*(DAC_MAX))/3300);
249 | // bridge1(0);
250 | // bridge2(0);
251 | // while(1)
252 | // {
253 | //
254 | // }
255 | return;
256 | }
257 |
258 | void A4954::limitCurrent(uint8_t percent)
259 | {
260 | #ifdef MECHADUINO_HARDWARE
261 | return;
262 | #else
263 | //WARNING("current limit %d",percent);
264 | enableTCC0(percent);
265 | if (pinState & 0x01)
266 | {
267 | pinPeripheral(PIN_A4954_IN2, PIO_TIMER_ALT); //TCC0 WO[7]
268 | }
269 | if (pinState & 0x02)
270 | {
271 | pinPeripheral(PIN_A4954_IN1, PIO_TIMER); //TCC0 WO[1]
272 | }
273 | if (pinState & 0x04)
274 | {
275 | pinPeripheral(PIN_A4954_IN4, PIO_TIMER_ALT);
276 | }
277 | if (pinState & 0x08)
278 | {
279 | pinPeripheral(PIN_A4954_IN3, PIO_TIMER_ALT);
280 | }
281 | #endif
282 | }
283 |
284 |
285 | void A4954::enable(bool enable)
286 | {
287 | enabled=enable;
288 | if (enabled == false)
289 | {
290 | WARNING("A4954 disabled");
291 | setDAC(0,0); //turn current off
292 | bridge1(3); //tri state bridge outputs
293 | bridge2(3); //tri state bridge outputs
294 | }
295 | }
296 |
297 |
298 |
299 | //this is precise move and modulo of A4954_NUM_MICROSTEPS is a full step.
300 | // stepAngle is in A4954_NUM_MICROSTEPS units..
301 | // The A4954 has no idea where the motor is, so the calling function has to
302 | // to tell the A4954 what phase to drive motor coils.
303 | // A4954_NUM_MICROSTEPS is 256 by default so stepAngle of 1024 is 360 degrees
304 | // Note you can only move up to +/-A4954_NUM_MICROSTEPS from where you
305 | // currently are.
306 | int32_t A4954::move(int32_t stepAngle, uint32_t mA)
307 | {
308 | uint16_t angle;
309 | int32_t cos,sin;
310 | int32_t dacSin,dacCos;
311 | //static int i=0;
312 |
313 | if (enabled == false)
314 | {
315 | WARNING("A4954 disabled");
316 | setDAC(0,0); //turn current off
317 | bridge1(3); //tri state bridge outputs
318 | bridge2(3); //tri state bridge outputs
319 | }
320 |
321 | //WARNING("move %d %d",stepAngle,mA);
322 | //handle roll overs, could do with modulo operator
323 | stepAngle=stepAngle%SINE_STEPS;
324 |
325 | //figure out our sine Angle
326 | // note our SINE_STEPS is 4x of microsteps for a reason
327 | //angle=(stepAngle+(SINE_STEPS/8)) % SINE_STEPS;
328 | angle=(stepAngle);
329 |
330 | //calculate the sine and cosine of our angle
331 | sin=sine(angle);
332 | cos=cosine(angle);
333 |
334 | //if we are reverse swap the sign of one of the angels
335 | if (false == forwardRotation)
336 | {
337 | cos=-cos;
338 | }
339 |
340 | //scale sine result by current(mA)
341 | dacSin=((int32_t)mA*(int64_t)abs(sin))/SINE_MAX;
342 |
343 | //scale cosine result by current(mA)
344 | dacCos=((int32_t)mA*(int64_t)abs(cos))/SINE_MAX;
345 |
346 | // if (i==0)
347 | // {
348 | // WARNING("dacs are %d %d",dacSin,dacCos);
349 | // }
350 |
351 | //convert value into DAC scaled to 3300mA max
352 | dacCos=(int32_t)((int64_t)dacCos*(DAC_MAX))/3300;
353 | //convert value into DAC scaled to 3300mA max
354 | dacSin=(int32_t)((int64_t)dacSin*(DAC_MAX))/3300;
355 |
356 | //WARNING("dacs are %d %d ",dacSin,dacCos);
357 |
358 | setDAC(dacSin,dacCos);
359 |
360 | if (sin>0)
361 | {
362 | bridge1(1);
363 | }else
364 | {
365 | bridge1(0);
366 | }
367 | if (cos>0)
368 | {
369 | bridge2(1);
370 | }else
371 | {
372 | bridge2(0);
373 | }
374 |
375 | // if (i++>3000)
376 | // {
377 | // i=0;
378 | // }
379 | // YELLOW_LED(led);
380 | // led=(led+1) & 0x01;
381 | lastStepMicros=micros();
382 | return stepAngle;
383 | }
384 | #pragma GCC pop_options
385 |
386 |
--------------------------------------------------------------------------------
/firmware/stepServo/A4954.h:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 | #ifndef __A4954__H__
13 | #define __A4954__H__
14 | #include
15 | #include "board.h"
16 | #include "angle.h"
17 | #include "sine.h"
18 |
19 | #define A4954_NUM_MICROSTEPS (256)
20 | #define A4954_MIN_TIME_BETWEEN_STEPS_MICROS (1000)
21 |
22 | //prevent someone for making a mistake with the code
23 | #if ((A4954_NUM_MICROSTEPS*4) != SINE_STEPS)
24 | #error "SINE_STEPS must be 4x of Micro steps for the move function"
25 | #endif
26 |
27 |
28 |
29 | /*
30 | * When it comes to the stepper driver if we use angles
31 | * we will always have a rounding error. For example
32 | * a 0-65536(360) angle for 1.8 degree step is 327.68 so
33 | * if you increment 200 of these as 327 you have a 13.6 error
34 | * after one rotation.
35 | * If you use floating point the effect is the same but takes longer.
36 | *
37 | * The only error-less accumulation system is to use native units, ie full
38 | * steps and microsteps.
39 | *
40 | */
41 |
42 | class A4954
43 | {
44 | private:
45 | uint32_t lastStepMicros; // time in microseconds that last step happened
46 | bool forwardRotation=true;
47 | volatile bool enabled=true;
48 |
49 | public:
50 | void begin(void);
51 |
52 | //moves motor where the modulo of A4954_NUM_MICROSTEPS is a full step.
53 | int32_t move(int32_t stepAngle, uint32_t mA);
54 |
55 | uint32_t microsSinceStep(void) {return micros()-lastStepMicros;};
56 | void setRotationDirection(bool forward) {forwardRotation=forward;};
57 |
58 | void enable(bool enable);
59 | void limitCurrent(uint8_t percent); //higher more current
60 | };
61 |
62 |
63 |
64 | #endif //__A4954__H__
65 |
--------------------------------------------------------------------------------
/firmware/stepServo/A5995.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * A5995.cpp
3 | *
4 | * Created on: Feb 2, 2017
5 | * Author: tstern
6 | */
7 |
8 |
9 | #include "A5995.h"
10 | #include "wiring_private.h"
11 | #include "syslog.h"
12 | #include "angle.h"
13 | #include "Arduino.h"
14 | #include "sine.h"
15 |
16 | static uint8_t pinState=0;
17 |
18 | #pragma GCC push_options
19 | #pragma GCC optimize ("-Ofast")
20 |
21 |
22 |
23 |
24 | #define DAC_MAX (0x01FFL)
25 | // Wait for synchronization of registers between the clock domains
26 | static __inline__ void syncTCC(Tcc* TCCx) __attribute__((always_inline, unused));
27 | static void syncTCC(Tcc* TCCx) {
28 | //int32_t t0=1000;
29 | while (TCCx->SYNCBUSY.reg & TCC_SYNCBUSY_MASK)
30 | {
31 | // t0--;
32 | // if (t0==0)
33 | // {
34 | // break;
35 | // }
36 | // delay(1);
37 | }
38 | }
39 |
40 |
41 |
42 | static void setDAC(uint32_t DAC1, uint32_t DAC2)
43 | {
44 | TCC1->CC[1].reg = (uint32_t)DAC1; //D9 PA07 - VREF2
45 | syncTCC(TCC1);
46 | TCC1->CC[0].reg = (uint32_t)DAC2; //D4 - VREF1
47 | syncTCC(TCC1);
48 |
49 | }
50 |
51 | static void setupDAC(void)
52 | {
53 | Tcc* TCCx = TCC1 ;
54 |
55 |
56 | pinPeripheral(PIN_A5995_VREF1, PIO_TIMER_ALT);
57 | pinPeripheral(PIN_A5995_VREF2, PIO_TIMER);
58 |
59 | GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ;
60 |
61 | while ( GCLK->STATUS.bit.SYNCBUSY == 1 ) ;
62 |
63 | //ERROR("Setting TCC %d %d",ulValue,ulPin);
64 | TCCx->CTRLA.reg &= ~TCC_CTRLA_ENABLE;
65 | syncTCC(TCCx);
66 |
67 | // Set TCx as normal PWM
68 | TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM;
69 | syncTCC(TCCx);
70 |
71 | // Set TCx in waveform mode Normal PWM
72 | TCCx->CC[1].reg = (uint32_t)0;
73 | syncTCC(TCCx);
74 |
75 | TCCx->CC[0].reg = (uint32_t)0;
76 | syncTCC(TCCx);
77 |
78 | // Set PER to maximum counter value (resolution : 0xFFF = 12 bits)
79 | // =48e6/2^12=11kHz frequency
80 | TCCx->PER.reg = DAC_MAX;
81 | syncTCC(TCCx);
82 |
83 | // Enable TCCx
84 | TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ;
85 | syncTCC(TCCx);
86 |
87 | }
88 |
89 |
90 | void A5995::begin()
91 | {
92 | //setup the A5995 pins
93 | digitalWrite(PIN_A5995_ENABLE1,LOW);
94 | pinMode(PIN_A5995_ENABLE1,OUTPUT);
95 | digitalWrite(PIN_A5995_ENABLE2,LOW);
96 | pinMode(PIN_A5995_ENABLE2,OUTPUT);
97 | digitalWrite(PIN_A5995_MODE1,LOW);
98 | pinMode(PIN_A5995_MODE1,OUTPUT);
99 | digitalWrite(PIN_A5995_MODE2,LOW);
100 | pinMode(PIN_A5995_MODE2,OUTPUT);
101 | digitalWrite(PIN_A5995_PHASE1,LOW);
102 | pinMode(PIN_A5995_PHASE1,OUTPUT);
103 | digitalWrite(PIN_A5995_PHASE2,LOW);
104 | pinMode(PIN_A5995_PHASE2,OUTPUT);
105 |
106 | digitalWrite(PIN_A5995_SLEEPn,HIGH);
107 | pinMode(PIN_A5995_SLEEPn,OUTPUT);
108 |
109 |
110 |
111 | //setup the PWM for current on the A4954, set for low current
112 | digitalWrite(PIN_A5995_VREF1,LOW);
113 | digitalWrite(PIN_A5995_VREF2,LOW);
114 | pinMode(PIN_A5995_VREF1, OUTPUT);
115 | pinMode(PIN_A5995_VREF2, OUTPUT);
116 |
117 | enabled=true;
118 | lastStepMicros=0;
119 | forwardRotation=true;
120 |
121 | setupDAC();
122 |
123 |
124 | //
125 | // GPIO_HIGH(PIN_A5995_ENABLE1);
126 | // GPIO_HIGH(PIN_A5995_ENABLE2);
127 | // GPIO_LOW(PIN_A5995_MODE1);
128 | // GPIO_LOW(PIN_A5995_MODE2);
129 | // GPIO_HIGH(PIN_A5995_PHASE1);
130 | // GPIO_HIGH(PIN_A5995_PHASE2);
131 | // int i=0;;
132 | // while (1)
133 | // {
134 | // int32_t x;
135 | // WARNING("MA %d",i);
136 | // x=(int32_t)((int64_t)i*(DAC_MAX))/3300;
137 | // setDAC(x,x);
138 | // delay(1000);
139 | // i=i+10;
140 | // if (i>1000)
141 | // {
142 | // i=0;
143 | // }
144 | //
145 | // }
146 |
147 |
148 | return;
149 | }
150 |
151 |
152 |
153 | void A5995::enable(bool enable)
154 | {
155 | enabled=enable;
156 | if (enabled == false)
157 | {
158 | WARNING("A4954 disabled");
159 | setDAC(0,0); //turn current off
160 | GPIO_LOW(PIN_A5995_ENABLE1);
161 | GPIO_LOW(PIN_A5995_ENABLE2);
162 | GPIO_LOW(PIN_A5995_MODE1);
163 | GPIO_LOW(PIN_A5995_MODE2);
164 | GPIO_LOW(PIN_A5995_PHASE1);
165 | GPIO_LOW(PIN_A5995_PHASE2);
166 | }
167 | }
168 |
169 |
170 |
171 | //this is precise move and modulo of A4954_NUM_MICROSTEPS is a full step.
172 | // stepAngle is in A4954_NUM_MICROSTEPS units..
173 | // The A4954 has no idea where the motor is, so the calling function has to
174 | // to tell the A4954 what phase to drive motor coils.
175 | // A4954_NUM_MICROSTEPS is 256 by default so stepAngle of 1024 is 360 degrees
176 | // Note you can only move up to +/-A4954_NUM_MICROSTEPS from where you
177 | // currently are.
178 | int32_t A5995::move(int32_t stepAngle, uint32_t mA)
179 | {
180 | uint16_t angle;
181 | int32_t cos,sin;
182 | int32_t dacSin,dacCos;
183 | static int32_t lastSin=0,lastCos=0;
184 | static int i=1;
185 |
186 | if (enabled == false)
187 | {
188 | WARNING("A4954 disabled");
189 | setDAC(0,0); //turn current off
190 | GPIO_LOW(PIN_A5995_ENABLE1);
191 | GPIO_LOW(PIN_A5995_ENABLE2);
192 | GPIO_LOW(PIN_A5995_MODE1);
193 | GPIO_LOW(PIN_A5995_MODE2);
194 | GPIO_LOW(PIN_A5995_PHASE1);
195 | GPIO_LOW(PIN_A5995_PHASE2);
196 | return stepAngle;
197 | }
198 |
199 | //WARNING("move %d %d",stepAngle,mA);
200 |
201 | stepAngle=(stepAngle) % SINE_STEPS;
202 | //figure out our sine Angle
203 | // note our SINE_STEPS is 4x of microsteps for a reason
204 | //angle=(stepAngle+(SINE_STEPS/8)) % SINE_STEPS;
205 | angle=stepAngle;
206 |
207 | if (i==0)
208 | {
209 | WARNING("angle %d ",angle);
210 | }
211 | //calculate the sine and cosine of our angle
212 | sin=sine(angle);
213 | cos=cosine(angle);
214 |
215 | //if we are reverse swap the sign of one of the angels
216 | if (false == forwardRotation)
217 | {
218 | cos=-cos;
219 | }
220 |
221 | //scale sine result by current(mA)
222 | dacSin=((int32_t)mA*(int64_t)(sin))/SINE_MAX;
223 |
224 | if (i==0)
225 | {
226 | WARNING("dacsine %d ",dacSin);
227 | }
228 | // if ((lastSin-dacSin)>100) //decreasing current
229 | // {
230 | // GPIO_LOW(PIN_A5995_MODE2); //fast decay
231 | // } else
232 | // {
233 | // GPIO_HIGH(PIN_A5995_MODE2); //slow decay
234 | // }
235 | lastSin=dacSin;
236 |
237 | //convert value into DAC scaled to 3300mA max
238 | dacSin=(int32_t)((int64_t)abs(dacSin)*(DAC_MAX))/3300;
239 |
240 |
241 | //scale cosine result by current(mA)
242 | dacCos=((int32_t)mA*(int64_t)(cos))/SINE_MAX;
243 |
244 | if (i==0)
245 | {
246 | WARNING("daccos %d ",dacCos);
247 | }
248 | // if ((lastCos-dacCos)>100) //decreasing current
249 | // {
250 | // GPIO_LOW(PIN_A5995_MODE1); //fast decay
251 | // } else
252 | // {
253 | // GPIO_HIGH(PIN_A5995_MODE1); //slow decay
254 | // }
255 | lastCos=dacCos;
256 |
257 | //convert value into DAC scaled to 3300mA max
258 | dacCos=(int32_t)((int64_t)abs(dacCos)*(DAC_MAX))/3300;
259 |
260 |
261 | if (i==0)
262 | {
263 | WARNING("dacs are %d %d",dacSin,dacCos);
264 | }
265 | setDAC(dacSin,dacCos);
266 |
267 | GPIO_HIGH(PIN_A5995_ENABLE1);
268 | GPIO_HIGH(PIN_A5995_ENABLE2);
269 | GPIO_LOW(PIN_A5995_MODE1);
270 | GPIO_LOW(PIN_A5995_MODE2);
271 |
272 |
273 | if (i==0)
274 | {
275 | WARNING("sins are %d %d",sin,cos);
276 | }
277 |
278 | if (sin>0)
279 | {
280 | GPIO_HIGH(PIN_A5995_PHASE2);
281 | }else
282 | {
283 | GPIO_LOW(PIN_A5995_PHASE2);
284 |
285 | }
286 | if (cos>0)
287 | {
288 | GPIO_HIGH(PIN_A5995_PHASE1);
289 |
290 | }else
291 | {
292 | GPIO_LOW(PIN_A5995_PHASE1);
293 |
294 | }
295 |
296 | // i++;
297 | // if (i>3000) i=0;
298 | // YELLOW_LED(led);
299 | // led=(led+1) & 0x01;
300 | lastStepMicros=micros();
301 | return stepAngle;
302 | }
303 | #pragma GCC pop_options
304 |
305 |
306 |
307 |
--------------------------------------------------------------------------------
/firmware/stepServo/A5995.h:
--------------------------------------------------------------------------------
1 | /*
2 | * A5995.h
3 | *
4 | * Created on: Feb 2, 2017
5 | * Author: tstern
6 | */
7 |
8 | #ifndef A5995_H_
9 | #define A5995_H_
10 |
11 | #include
12 | #include "board.h"
13 | #include "angle.h"
14 | #include "sine.h"
15 |
16 | #define A5995_NUM_MICROSTEPS (256)
17 |
18 |
19 | //prevent someone for making a mistake with the code
20 | #if ((A5995_NUM_MICROSTEPS*4) != SINE_STEPS)
21 | #error "SINE_STEPS must be 4x of Micro steps for the move function"
22 | #endif
23 |
24 |
25 |
26 | /*
27 | * When it comes to the stepper driver if we use angles
28 | * we will always have a rounding error. For example
29 | * a 0-65536(360) angle for 1.8 degree step is 327.68 so
30 | * if you increment 200 of these as 327 you have a 13.6 error
31 | * after one rotation.
32 | * If you use floating point the effect is the same but takes longer.
33 | *
34 | * The only error-less accumulation system is to use native units, ie full
35 | * steps and microsteps.
36 | *
37 | */
38 |
39 | class A5995
40 | {
41 | private:
42 | uint32_t lastStepMicros; // time in microseconds that last step happened
43 | bool forwardRotation=true;
44 | volatile bool enabled=true;
45 |
46 | public:
47 | void begin(void);
48 |
49 | //moves motor where the modulo of A4954_NUM_MICROSTEPS is a full step.
50 | int32_t move(int32_t stepAngle, uint32_t mA);
51 |
52 | uint32_t microsSinceStep(void) {return micros()-lastStepMicros;};
53 | void setRotationDirection(bool forward) {forwardRotation=forward;};
54 |
55 | void enable(bool enable);
56 | void limitCurrent(uint8_t percent) {return;}; //Not used
57 | };
58 |
59 |
60 |
61 | #endif /* A5995_H_ */
62 |
--------------------------------------------------------------------------------
/firmware/stepServo/Adafruit_GFX.h:
--------------------------------------------------------------------------------
1 | #ifndef _ADAFRUIT_GFX_H
2 | #define _ADAFRUIT_GFX_H
3 |
4 | #if ARDUINO >= 100
5 | #include "Arduino.h"
6 | #include "Print.h"
7 | #else
8 | #include "WProgram.h"
9 | #endif
10 |
11 | #include "gfxfont.h"
12 |
13 | class Adafruit_GFX : public Print {
14 |
15 | public:
16 |
17 | Adafruit_GFX(int16_t w, int16_t h); // Constructor
18 |
19 | // This MUST be defined by the subclass:
20 | virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
21 |
22 | // These MAY be overridden by the subclass to provide device-specific
23 | // optimized code. Otherwise 'generic' versions are used.
24 | virtual void
25 | drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color),
26 | drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color),
27 | drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color),
28 | drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color),
29 | fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color),
30 | fillScreen(uint16_t color),
31 | invertDisplay(boolean i);
32 |
33 | // These exist only with Adafruit_GFX (no subclass overrides)
34 | void
35 | drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color),
36 | drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername,
37 | uint16_t color),
38 | fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color),
39 | fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername,
40 | int16_t delta, uint16_t color),
41 | drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
42 | int16_t x2, int16_t y2, uint16_t color),
43 | fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
44 | int16_t x2, int16_t y2, uint16_t color),
45 | drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,
46 | int16_t radius, uint16_t color),
47 | fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,
48 | int16_t radius, uint16_t color),
49 | drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap,
50 | int16_t w, int16_t h, uint16_t color),
51 | drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap,
52 | int16_t w, int16_t h, uint16_t color, uint16_t bg),
53 | drawBitmap(int16_t x, int16_t y, uint8_t *bitmap,
54 | int16_t w, int16_t h, uint16_t color),
55 | drawBitmap(int16_t x, int16_t y, uint8_t *bitmap,
56 | int16_t w, int16_t h, uint16_t color, uint16_t bg),
57 | drawXBitmap(int16_t x, int16_t y, const uint8_t *bitmap,
58 | int16_t w, int16_t h, uint16_t color),
59 | drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color,
60 | uint16_t bg, uint8_t size),
61 | setCursor(int16_t x, int16_t y),
62 | setTextColor(uint16_t c),
63 | setTextColor(uint16_t c, uint16_t bg),
64 | setTextSize(uint8_t s),
65 | setTextWrap(boolean w),
66 | setRotation(uint8_t r),
67 | cp437(boolean x=true),
68 | setFont(const GFXfont *f = NULL),
69 | getTextBounds(char *string, int16_t x, int16_t y,
70 | int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h),
71 | getTextBounds(const __FlashStringHelper *s, int16_t x, int16_t y,
72 | int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
73 |
74 | #if ARDUINO >= 100
75 | virtual size_t write(uint8_t);
76 | #else
77 | virtual void write(uint8_t);
78 | #endif
79 |
80 | int16_t height(void) const;
81 | int16_t width(void) const;
82 |
83 | uint8_t getRotation(void) const;
84 |
85 | // get current cursor position (get rotation safe maximum values, using: width() for x, height() for y)
86 | int16_t getCursorX(void) const;
87 | int16_t getCursorY(void) const;
88 |
89 | protected:
90 | const int16_t
91 | WIDTH, HEIGHT; // This is the 'raw' display w/h - never changes
92 | int16_t
93 | _width, _height, // Display w/h as modified by current rotation
94 | cursor_x, cursor_y;
95 | uint16_t
96 | textcolor, textbgcolor;
97 | uint8_t
98 | textsize,
99 | rotation;
100 | boolean
101 | wrap, // If set, 'wrap' text at right edge of display
102 | _cp437; // If set, use correct CP437 charset (default is off)
103 | GFXfont
104 | *gfxFont;
105 | };
106 |
107 | class Adafruit_GFX_Button {
108 |
109 | public:
110 | Adafruit_GFX_Button(void);
111 | void initButton(Adafruit_GFX *gfx, int16_t x, int16_t y,
112 | uint8_t w, uint8_t h, uint16_t outline, uint16_t fill,
113 | uint16_t textcolor, char *label, uint8_t textsize);
114 | void drawButton(boolean inverted = false);
115 | boolean contains(int16_t x, int16_t y);
116 |
117 | void press(boolean p);
118 | boolean isPressed();
119 | boolean justPressed();
120 | boolean justReleased();
121 |
122 | private:
123 | Adafruit_GFX *_gfx;
124 | int16_t _x, _y;
125 | uint16_t _w, _h;
126 | uint8_t _textsize;
127 | uint16_t _outlinecolor, _fillcolor, _textcolor;
128 | char _label[10];
129 |
130 | boolean currstate, laststate;
131 | };
132 |
133 | class GFXcanvas1 : public Adafruit_GFX {
134 |
135 | public:
136 | GFXcanvas1(uint16_t w, uint16_t h);
137 | ~GFXcanvas1(void);
138 | void drawPixel(int16_t x, int16_t y, uint16_t color),
139 | fillScreen(uint16_t color);
140 | uint8_t *getBuffer(void);
141 | private:
142 | uint8_t *buffer;
143 | };
144 |
145 | class GFXcanvas16 : public Adafruit_GFX {
146 | GFXcanvas16(uint16_t w, uint16_t h);
147 | ~GFXcanvas16(void);
148 | void drawPixel(int16_t x, int16_t y, uint16_t color),
149 | fillScreen(uint16_t color);
150 | uint16_t *getBuffer(void);
151 | private:
152 | uint16_t *buffer;
153 | };
154 |
155 | #endif // _ADAFRUIT_GFX_H
156 |
--------------------------------------------------------------------------------
/firmware/stepServo/Adafruit_SSD1306.h:
--------------------------------------------------------------------------------
1 | /*********************************************************************
2 | This is a library for our Monochrome OLEDs based on SSD1306 drivers
3 |
4 | Pick one up today in the adafruit shop!
5 | ------> http://www.adafruit.com/category/63_98
6 |
7 | These displays use SPI to communicate, 4 or 5 pins are required to
8 | interface
9 |
10 | Adafruit invests time and resources providing this open source code,
11 | please support Adafruit and open-source hardware by purchasing
12 | products from Adafruit!
13 |
14 | Written by Limor Fried/Ladyada for Adafruit Industries.
15 | BSD license, check license.txt for more information
16 | All text above, and the splash screen must be included in any redistribution
17 | *********************************************************************/
18 | #ifndef _Adafruit_SSD1306_H_
19 | #define _Adafruit_SSD1306_H_
20 |
21 | #if ARDUINO >= 100
22 | #include "Arduino.h"
23 | #define WIRE_WRITE Wire.write
24 | #else
25 | #include "WProgram.h"
26 | #define WIRE_WRITE Wire.send
27 | #endif
28 |
29 | #if defined(__SAM3X8E__)
30 | typedef volatile RwReg PortReg;
31 | typedef uint32_t PortMask;
32 | #define HAVE_PORTREG
33 | #elif defined(ARDUINO_ARCH_SAMD)
34 | // not supported
35 | #elif defined(ESP8266) || defined(ARDUINO_STM32_FEATHER)
36 | typedef volatile uint32_t PortReg;
37 | typedef uint32_t PortMask;
38 | #else
39 | typedef volatile uint8_t PortReg;
40 | typedef uint8_t PortMask;
41 | #define HAVE_PORTREG
42 | #endif
43 |
44 | #include
45 | #include "Adafruit_GFX.h"
46 |
47 | #define BLACK 0
48 | #define WHITE 1
49 | #define INVERSE 2
50 |
51 | #define SSD1306_I2C_ADDRESS 0x3C // 011110+SA0+RW - 0x3C or 0x3D
52 | // Address for 128x32 is 0x3C
53 | // Address for 128x64 is 0x3D (default) or 0x3C (if SA0 is grounded)
54 |
55 | /*=========================================================================
56 | SSD1306 Displays
57 | -----------------------------------------------------------------------
58 | The driver is used in multiple displays (128x64, 128x32, etc.).
59 | Select the appropriate display below to create an appropriately
60 | sized framebuffer, etc.
61 |
62 | SSD1306_128_64 128x64 pixel display
63 |
64 | SSD1306_128_32 128x32 pixel display
65 |
66 | SSD1306_96_16
67 |
68 | -----------------------------------------------------------------------*/
69 | #define SSD1306_128_64
70 | // #define SSD1306_128_32
71 | // #define SSD1306_96_16
72 | /*=========================================================================*/
73 |
74 | #if defined SSD1306_128_64 && defined SSD1306_128_32
75 | #error "Only one SSD1306 display can be specified at once in SSD1306.h"
76 | #endif
77 | #if !defined SSD1306_128_64 && !defined SSD1306_128_32 && !defined SSD1306_96_16
78 | #error "At least one SSD1306 display must be specified in SSD1306.h"
79 | #endif
80 |
81 | #if defined SSD1306_128_64
82 | #define SSD1306_LCDWIDTH 128
83 | #define SSD1306_LCDHEIGHT 64
84 | #endif
85 | #if defined SSD1306_128_32
86 | #define SSD1306_LCDWIDTH 128
87 | #define SSD1306_LCDHEIGHT 32
88 | #endif
89 | #if defined SSD1306_96_16
90 | #define SSD1306_LCDWIDTH 96
91 | #define SSD1306_LCDHEIGHT 16
92 | #endif
93 |
94 | #define SSD1306_SETCONTRAST 0x81
95 | #define SSD1306_DISPLAYALLON_RESUME 0xA4
96 | #define SSD1306_DISPLAYALLON 0xA5
97 | #define SSD1306_NORMALDISPLAY 0xA6
98 | #define SSD1306_INVERTDISPLAY 0xA7
99 | #define SSD1306_DISPLAYOFF 0xAE
100 | #define SSD1306_DISPLAYON 0xAF
101 |
102 | #define SSD1306_SETDISPLAYOFFSET 0xD3
103 | #define SSD1306_SETCOMPINS 0xDA
104 |
105 | #define SSD1306_SETVCOMDETECT 0xDB
106 |
107 | #define SSD1306_SETDISPLAYCLOCKDIV 0xD5
108 | #define SSD1306_SETPRECHARGE 0xD9
109 |
110 | #define SSD1306_SETMULTIPLEX 0xA8
111 |
112 | #define SSD1306_SETLOWCOLUMN 0x00
113 | #define SSD1306_SETHIGHCOLUMN 0x10
114 |
115 | #define SSD1306_SETSTARTLINE 0x40
116 |
117 | #define SSD1306_MEMORYMODE 0x20
118 | #define SSD1306_COLUMNADDR 0x21
119 | #define SSD1306_PAGEADDR 0x22
120 |
121 | #define SSD1306_COMSCANINC 0xC0
122 | #define SSD1306_COMSCANDEC 0xC8
123 |
124 | #define SSD1306_SEGREMAP 0xA0
125 |
126 | #define SSD1306_CHARGEPUMP 0x8D
127 |
128 | #define SSD1306_EXTERNALVCC 0x1
129 | #define SSD1306_SWITCHCAPVCC 0x2
130 |
131 | // Scrolling #defines
132 | #define SSD1306_ACTIVATE_SCROLL 0x2F
133 | #define SSD1306_DEACTIVATE_SCROLL 0x2E
134 | #define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
135 | #define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
136 | #define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
137 | #define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
138 | #define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
139 |
140 | class Adafruit_SSD1306 : public Adafruit_GFX {
141 | public:
142 | Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS);
143 | Adafruit_SSD1306(int8_t DC, int8_t RST, int8_t CS);
144 | Adafruit_SSD1306(int8_t RST = -1);
145 |
146 | bool begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC, uint8_t i2caddr = SSD1306_I2C_ADDRESS, bool reset=true);
147 | uint8_t ssd1306_command(uint8_t c);
148 |
149 | void clearDisplay(void);
150 | void invertDisplay(uint8_t i);
151 | void display();
152 |
153 | void startscrollright(uint8_t start, uint8_t stop);
154 | void startscrollleft(uint8_t start, uint8_t stop);
155 |
156 | void startscrolldiagright(uint8_t start, uint8_t stop);
157 | void startscrolldiagleft(uint8_t start, uint8_t stop);
158 | void stopscroll(void);
159 |
160 | void dim(boolean dim);
161 |
162 | void drawPixel(int16_t x, int16_t y, uint16_t color);
163 |
164 | virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
165 | virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
166 |
167 | private:
168 | int8_t _i2caddr, _vccstate, sid, sclk, dc, rst, cs;
169 | void fastSPIwrite(uint8_t c);
170 |
171 | boolean hwSPI;
172 | #ifdef HAVE_PORTREG
173 | PortReg *mosiport, *clkport, *csport, *dcport;
174 | PortMask mosipinmask, clkpinmask, cspinmask, dcpinmask;
175 | #endif
176 |
177 | inline void drawFastVLineInternal(int16_t x, int16_t y, int16_t h, uint16_t color) __attribute__((always_inline));
178 | inline void drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color) __attribute__((always_inline));
179 |
180 | };
181 |
182 | #endif /* _Adafruit_SSD1306_H_ */
183 |
--------------------------------------------------------------------------------
/firmware/stepServo/Flash.cpp:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 | #include "Flash.h"
13 | #include "syslog.h"
14 |
15 | bool flashInit(void){
16 | if (NVMCTRL->PARAM.bit.PSZ != 3)
17 | {
18 | ERROR("FLASH PAGE SIZE is not 64 bytes");
19 | return false;
20 | }
21 | return true;
22 | }
23 |
24 |
25 | static void erase(const volatile void *flash_ptr)
26 | {
27 | NVMCTRL->ADDR.reg = ((uint32_t)flash_ptr) / 2;
28 | NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER;
29 | while (!NVMCTRL->INTFLAG.bit.READY) { }
30 | }
31 |
32 | bool flashErase(const volatile void *flash_ptr, uint32_t size)
33 | {
34 | const uint8_t *ptr = (const uint8_t *)flash_ptr;
35 | while (size > FLASH_ROW_SIZE) {
36 | erase(ptr);
37 | ptr += FLASH_ROW_SIZE;
38 | size -= FLASH_ROW_SIZE;
39 | }
40 | if (size>0)
41 | {
42 | erase(ptr);
43 | }
44 | return true; //TODO should verify the erase
45 | }
46 |
47 | static inline uint32_t read_unaligned_uint32(const void *data)
48 | {
49 | union {
50 | uint32_t u32;
51 | uint8_t u8[4];
52 | } res;
53 | const uint8_t *d = (const uint8_t *)data;
54 | res.u8[0] = d[0];
55 | res.u8[1] = d[1];
56 | res.u8[2] = d[2];
57 | res.u8[3] = d[3];
58 | return res.u32;
59 | }
60 |
61 |
62 | void flashWrite(const volatile void *flash_ptr,const void *data, uint32_t size)
63 | {
64 | uint32_t *ptrPage;
65 | uint8_t *destPtr;
66 | uint8_t *srcPtr;
67 | uint32_t bytesInBlock;
68 | __attribute__((__aligned__(4))) uint8_t buffer[FLASH_ROW_SIZE];
69 | uint32_t offset;
70 |
71 | destPtr=(uint8_t *)flash_ptr;
72 | srcPtr=(uint8_t *)data;
73 |
74 | //LOG("flash write called");
75 | while(size>0)
76 | {
77 | uint32_t i,j;
78 |
79 | //calculate the maximum number of bytes we can write in page
80 | offset=((uint32_t)destPtr)%(FLASH_ROW_SIZE); //offset into page
81 | bytesInBlock=FLASH_ROW_SIZE-offset; //this is how many bytes we need to overwrite in this page
82 |
83 | //LOG("offset %d, bytesInBlock %d size %d", offset, bytesInBlock,size);
84 | //get pointer to start of page
85 | ptrPage=(uint32_t *) ((((uint32_t)destPtr)/(FLASH_ROW_SIZE)) * FLASH_ROW_SIZE);
86 |
87 | //LOG("pointer to page %d(0x%08x) %d",(uint32_t)ptrPage,(uint32_t)ptrPage,destPtr);
88 |
89 | //fill page buffer with data from flash
90 | memcpy(buffer,ptrPage,FLASH_ROW_SIZE);
91 |
92 | //now fill buffer with new data that needs changing
93 | i=bytesInBlock;
94 | if (sizeCTRLB.bit.MANW = 1;
142 |
143 | // Do writes in pages
144 | while (size)
145 | {
146 | // Execute "PBC" Page Buffer Clear
147 | NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_PBC;
148 | while (NVMCTRL->INTFLAG.bit.READY == 0) { }
149 |
150 | // Fill page buffer
151 | uint32_t i;
152 | for (i=0; i<(FLASH_PAGE_SIZE/4) && size; i++) //we write 4 bytes at a time
153 | {
154 | *dst_addr = read_unaligned_uint32(src_addr);
155 | src_addr += 4;
156 | dst_addr++;
157 | size--; //size is set to number of 32bit words in first line above
158 | }
159 |
160 | // Execute "WP" Write Page
161 | NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_WP;
162 | while (NVMCTRL->INTFLAG.bit.READY == 0) { }
163 | }
164 |
165 |
166 | }
167 |
--------------------------------------------------------------------------------
/firmware/stepServo/Flash.h:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 | #ifndef __FLASH__H__
13 | #define __FLASH__H__
14 |
15 | #include
16 | #include "syslog.h"
17 |
18 |
19 | #define FLASH_PAGE_SIZE_NZS (64) //bytes
20 | #define FLASH_ROW_SIZE (FLASH_PAGE_SIZE_NZS*4) //defined in the datasheet as 4x page size
21 | #define FLASH_ERASE_VALUE (0xFF) //value of flash after an erase
22 |
23 | #define FLASH_ALLOCATE(name, size) \
24 | __attribute__((__aligned__(FLASH_ROW_SIZE))) \
25 | const uint8_t name[(size+(FLASH_ROW_SIZE-1))/FLASH_ROW_SIZE*FLASH_ROW_SIZE] = { };
26 |
27 | bool flashInit(void); //this checks that our assumptions are true
28 |
29 | bool flashErase(const volatile void *flash_ptr, uint32_t size);
30 | void flashWrite(const volatile void *flash_ptr,const void *data,uint32_t size);
31 | void flashWritePage(const volatile void *flash_ptr, const void *data, uint32_t size);
32 |
33 | //you can read by dereferencing pointer but we will add a read
34 | static inline int32_t flashRead(const volatile void *flash_ptr, void *data, uint32_t size)
35 | {
36 | memcpy(data, (const void *)flash_ptr, size);
37 | }
38 |
39 |
40 |
41 |
42 | #endif //__FLASH__H__
43 |
--------------------------------------------------------------------------------
/firmware/stepServo/angle.h:
--------------------------------------------------------------------------------
1 | /*
2 | * angle.h
3 | *
4 | * Created on: Sep 1, 2016
5 | * Author: TStern
6 | *
7 | * Misfit Tech invests time and resources providing this open source code,
8 | * please support Misfit Tech and open-source hardware by purchasing
9 | * products from Misfit Tech, www.misifittech.net!
10 | *
11 | * Written by Trampas Stern for Misfit Tech.
12 | * BSD license, check license.txt for more information
13 | * All text above, must be included in any redistribution
14 | *********************************************************************/
15 |
16 | #ifndef ANGLE_H_
17 | #define ANGLE_H_
18 | #include
19 | #include
20 | #include
21 |
22 | #define ANGLE_STEPS (0x010000UL)
23 | #define ANGLE_MAX ((uint16_t)0x0FFFF)
24 |
25 | #define ANGLE_FROM_DEGREES(x) ((int32_t) ( ((float)ANGLE_STEPS*(float)(x)+180.0)/360.0 ) )
26 | #define ANGLE_T0_DEGREES(x) ( (float) ((float(x)*360.0 + (float)(ANGLE_STEPS/2))/((float)ANGLE_STEPS) ))
27 | class Angle
28 | {
29 | private:
30 | uint16_t angle;
31 | public:
32 | Angle(void) {angle=0;}
33 | Angle(int32_t x) {angle=(uint16_t)x;}
34 | Angle(const Angle &x) {angle=x.angle;}
35 |
36 | int16_t operator-( const Angle &a2)
37 | {
38 | int32_t x,y,dx;
39 | x=(int32_t)angle;
40 | y=(int32_t)a2.angle;
41 | dx=x-y;
42 | if (abs(x-y)>ANGLE_STEPS/2)
43 | {
44 | //we have a wrap condition
45 | if (x>y)
46 | {
47 | dx=x-(y+ANGLE_STEPS);
48 | }else if (xANGLE_MAX)
61 | // {
62 | // y=y-ANGLE_STEPS;
63 | // }
64 | // while(y<-ANGLE_MAX)
65 | // {
66 | // y=y+ANGLE_STEPS;
67 | // }
68 | //
69 | // dx=x-y;
70 | // if (abs(x-y)>ANGLE_STEPS/2)
71 | // {
72 | // //we have a wrap condition
73 | // if (x>y)
74 | // {
75 | // dx=x-(y+ANGLE_STEPS);
76 | // }else if (x=ANGLE_STEPS)
95 | {
96 | a=a-ANGLE_STEPS;
97 | }
98 | while (a<0)
99 | {
100 | a=a+ANGLE_STEPS;
101 | }
102 | return Angle((uint16_t)a);
103 | }
104 | Angle operator+(const unsigned long int x)
105 | {
106 | uint32_t a;
107 | a=(uint32_t)angle+ x;
108 | while (a>=ANGLE_STEPS)
109 | {
110 | a=a-ANGLE_STEPS;
111 | }
112 | return Angle((uint16_t)a);
113 | }
114 |
115 | operator uint16_t() const {return angle;}
116 | operator uint32_t() const {return (uint32_t)angle;}
117 | operator int32_t() const {return (int32_t)angle;}
118 |
119 |
120 |
121 | };
122 |
123 |
124 | #endif /* ANGLE_H_ */
125 |
--------------------------------------------------------------------------------
/firmware/stepServo/as5047d.cpp:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 | #include
13 | #include "syslog.h"
14 | #include "as5047d.h"
15 | #include "SPI.h"
16 | #include
17 | #include "board.h"
18 |
19 | #define AS5047D_CMD_NOP (0x0000)
20 | #define AS5047D_CMD_ERRFL (0x0001)
21 | #define AS5047D_CMD_PROG (0x0003)
22 | #define AS5047D_CMD_DIAAGC (0x3FFC)
23 | #define AS5047D_CMD_MAG (0x3FFD)
24 | #define AS5047D_CMD_ANGLEUNC (0x3FFE)
25 | #define AS5047D_CMD_ANGLECOM (0x3FFF)
26 |
27 | #pragma GCC push_options
28 | #pragma GCC optimize ("-Ofast")
29 |
30 | static int getBit(int16_t data, int bit)
31 | {
32 | return (data>>bit) & 0x01;
33 | }
34 |
35 | static int getParity(uint16_t data)
36 | {
37 | int i,bits;
38 | data=data & 0x7FFF; //mask out upper bit
39 |
40 | //count number of bits, brute force
41 | bits=0;
42 | for(i=0; i<16; i++)
43 | {
44 | if (0 != (data & ((0x0001)<>15 != getParity(data))
147 | {
148 | //parity did not match
149 | ERROR("read command parity error 0x%04X ",addr);
150 | error=true;
151 | return -2;
152 | }
153 |
154 | data=data & 0x3FFF; //mask off the error and parity bits
155 |
156 | return data;
157 | }
158 |
159 | //read the encoders
160 | int16_t AS5047D::readEncoderAngle(void)
161 | {
162 | return readAddress(AS5047D_CMD_ANGLECOM);
163 | }
164 |
165 | //pipelined read of the encoder angle used for high speed reads, but value is always one read behind
166 | int16_t AS5047D::readEncoderAnglePipeLineRead(void)
167 | {
168 | int16_t data;
169 | int error, t0=10;
170 | GPIO_LOW(chipSelectPin);//(chipSelectPin, LOW);
171 | //delayMicroseconds(1);
172 | do {
173 |
174 | // doing two 8 bit transfers is faster than one 16 bit
175 | data =(uint16_t)SPI.transfer(0xFF)<<8 | ((uint16_t)SPI.transfer(0xFF) & 0x0FF);
176 | t0--;
177 | if (t0<=0)
178 | {
179 | ERROR("AS5047D problem");
180 | break;
181 | }
182 | //data=SPI.transfer16(0xFFFF); //to speed things up we know the parity and address for the read
183 | }while(data & (1<<14)); //while error bit is set
184 |
185 | data=data & 0x3FFF; //mask off the error and parity bits
186 | GPIO_HIGH(chipSelectPin);
187 | //digitalWrite(chipSelectPin, HIGH);
188 | //TODO we really should check for errors and return a negative result or something
189 | return data;
190 | }
191 |
192 |
193 | void AS5047D::diagnostics(char *ptrStr)
194 | {
195 | int16_t data;
196 | int m,d;
197 |
198 | data=readAddress(AS5047D_CMD_DIAAGC);
199 |
200 | if (NULL == ptrStr)
201 | {
202 | LOG("DIAAGC: 0x%04X", data);
203 | LOG("MAGL: %d", getBit(data,11));
204 | LOG("MAGH: %d", getBit(data,10));
205 | LOG("COF: %d", getBit(data,9));
206 | LOG("LFGL: %d", getBit(data,8));
207 | LOG("AGC: %d", data & 0x0FF);
208 |
209 | data=readAddress(AS5047D_CMD_MAG);
210 | LOG("CMAG: 0x%04X(%d)",data,data);
211 |
212 | data=readAddress(AS5047D_CMD_ANGLEUNC);
213 | m=(int)((float)data*AS5047D_DEGREES_PER_BIT);
214 | d=(int)((float)data*AS5047D_DEGREES_PER_BIT*100 -m*100);
215 | LOG("CORDICANG: 0x%04X(%d) %d.%02d deg(est)",data,data,m,d);
216 |
217 | data=readAddress(AS5047D_CMD_ANGLECOM);
218 | m=(int)((float)data*AS5047D_DEGREES_PER_BIT);
219 | d=(int)((float)data*AS5047D_DEGREES_PER_BIT*100 -m*100);
220 | LOG("DAECANG: 0x%04X(%d) %d.%02d deg(est)",data,data,m,d);
221 | }else
222 | {
223 | sprintf(ptrStr,"DIAAGC: 0x%04X\n\r", data);
224 | sprintf(ptrStr,"%sMAGL: %d\n\r", ptrStr,getBit(data,11));
225 | sprintf(ptrStr,"%sMAGH: %d\n\r", ptrStr,getBit(data,10));
226 | sprintf(ptrStr,"%sCOF: %d\n\r", ptrStr, getBit(data,9));
227 | sprintf(ptrStr,"%sLFGL: %d\n\r", ptrStr, getBit(data,8));
228 | sprintf(ptrStr,"%sAGC: %d\n\r", ptrStr,data & 0x0FF);
229 |
230 | data=readAddress(AS5047D_CMD_MAG);
231 | sprintf(ptrStr,"%sCMAG: 0x%04X(%d)\n\r", ptrStr,data,data);
232 |
233 | data=readAddress(AS5047D_CMD_ANGLEUNC);
234 | m=(int)((float)data*AS5047D_DEGREES_PER_BIT);
235 | d=(int)((float)data*AS5047D_DEGREES_PER_BIT*100 -m*100);
236 | sprintf(ptrStr,"%sCORDICANG: 0x%04X(%d) %d.%02d deg(est)\n\r", ptrStr,data,data,m,d);
237 |
238 | data=readAddress(AS5047D_CMD_ANGLECOM);
239 | m=(int)((float)data*AS5047D_DEGREES_PER_BIT);
240 | d=(int)((float)data*AS5047D_DEGREES_PER_BIT*100 -m*100);
241 | sprintf(ptrStr,"%sDAECANG: 0x%04X(%d) %d.%02d deg(est)\n\r", ptrStr,data,data,m,d);
242 |
243 | }
244 | }
245 |
246 | #pragma GCC pop_options
247 |
248 |
--------------------------------------------------------------------------------
/firmware/stepServo/as5047d.h:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 | #ifndef __AS5047D_H__
13 | #define __AS5047D_H__
14 |
15 | #include
16 | #define AS5047D_DEGREES_PER_BIT (360.0/(float)(0x3FFF))
17 |
18 | class AS5047D {
19 | private:
20 | int chipSelectPin;
21 | int16_t readAddress(uint16_t addr);
22 | bool error=false;
23 | public:
24 | boolean begin(int csPin);
25 | int16_t readEncoderAngle(void);
26 | void diagnostics(char *ptrStr);
27 | int16_t readEncoderAnglePipeLineRead(void);
28 | bool getError(void) {return error;};
29 | };
30 |
31 | #endif //__AS5047D_H__
32 |
--------------------------------------------------------------------------------
/firmware/stepServo/calibration.h:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 | #ifndef __CALIBRAITON_H__
13 | #define __CALIBRAITON_H__
14 |
15 | #include
16 | #include "syslog.h"
17 | #include "angle.h"
18 |
19 |
20 | //this file implements a table that is linearly interpolated circular calibration table
21 | // it is assumed the data wraps around, ie you interpolated 65536==0
22 | //we want this to be "whole" steps, for 1.8 degree motors this should be 200.
23 | // 200 will work for 0.9 degree too, but could be 400. However 400 is not good for 1.8 degree motors
24 | #define CALIBRATION_TABLE_SIZE (200)
25 |
26 | #define CALIBRATION_STEPS ((uint32_t)ANGLE_STEPS) // this is one rotation ie 0-65535 aka 65536 steps is 0-360 degrees
27 |
28 | #define CALIBRATION_ERROR_NOT_SET (-1) //indicated that the calibration value is not set.
29 |
30 | #define CALIBRATION_UPDATE_RATE (32) //number of samples to keep 1 pole running average
31 | #define CALIBRATION_MIN_ERROR (4) //the minimal expected error on our calibration 4 ~=+/0.2 degrees
32 |
33 |
34 | typedef struct {
35 | uint16_t table[CALIBRATION_TABLE_SIZE];
36 | bool status;
37 | } FlashCalData_t;
38 |
39 |
40 |
41 |
42 |
43 | typedef struct {
44 | Angle value; //cal value
45 | int16_t error; //error assuming it is constantly updated
46 | } CalData_t;
47 |
48 | class CalibrationTable
49 | {
50 | private:
51 | CalData_t table[CALIBRATION_TABLE_SIZE];
52 |
53 | bool fastCalVaild=false;
54 | void loadFromFlash(void);
55 | bool flashGood(void); //returns true if the flash copy of calibration is valid
56 |
57 | void updateFastCal(void);
58 | void createFastCal(void);
59 |
60 | public:
61 | void init(void);
62 | void saveToFlash(void); //saves the calibration to flash
63 | bool updateTableValue(int32_t index, int32_t value);
64 | void updateTable(Angle actualAngle, Angle encoderValue);
65 | int getValue(Angle actualAngle, CalData_t *ptrData);
66 | Angle getCal(Angle actualAngle);
67 | bool calValid(void);
68 | Angle reverseLookup(Angle encoderAngle); //this turns encoder angle into real angle
69 | void printCalTable(void);
70 | void smoothTable(void);
71 |
72 | Angle fastReverseLookup(Angle encoderAngle);
73 | };
74 |
75 |
76 |
77 |
78 | #endif //__CALIBRAITON_H__
79 |
--------------------------------------------------------------------------------
/firmware/stepServo/command.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) Trampas Stern name of author
3 |
4 | This program is free software; you can redistribute it and/or
5 | modify it under the terms of the GNU General Public License
6 | as published by the Free Software Foundation; either version 2
7 | of the License.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 | */
18 |
19 | #include "command.h"
20 | #include
21 |
22 |
23 | #define ASCII_BACKSPACE 0x08
24 | #define ASCII_ESC 0x1B
25 | #define ASCII_UP_ARROW 0x9b
26 | //const char CMD_ANSI_UP[]= {ASCII_ESC,'[','A',0};
27 |
28 | int strcicmp(char const *a, char const *b)
29 | {
30 | for (;; a++, b++) {
31 | int d = tolower(*a) - tolower(*b);
32 | if (d != 0 || !*a)
33 | return d;
34 | }
35 | }
36 |
37 | int CommandInit(sCmdUart *ptrUart, uint8_t (*kbhit)(void), uint8_t (*getch)(void),uint8_t (*putch)(char data),uint8_t (*puts)(uint8_t *buffer, uint8_t size) )
38 | {
39 | ptrUart->kbhit=kbhit;
40 | ptrUart->getch=getch;
41 | ptrUart->putch=putch;
42 | ptrUart->puts=puts;
43 | ptrUart->histIndex=0;
44 | ptrUart->buffIndex=0;
45 | return 0;
46 | }
47 |
48 | #ifdef PGM_P //check and see if the PGM_P is defined for the AVR
49 |
50 | int CommandPrintf(sCmdUart *ptrUart, const char *fmt, ...)
51 | {
52 | int ret=0;
53 | char vastr[MAX_STRING]={0};
54 | //char str[MAX_STRING]={0};
55 | char *ptr;
56 | va_list ap;
57 |
58 | //LOG("Command printf");
59 | memset(vastr,0,MAX_STRING);
60 | va_start(ap,fmt);
61 | ret=vsprintf(vastr,(const char *)fmt,ap);
62 | //ret=sprintf(vastr,"%s\r\n",str);
63 | //LOG("%s",vastr);
64 | if (ptrUart->puts!=NULL)
65 | {
66 | return ptrUart->puts((uint8_t *)vastr, (uint8_t)ret);
67 | }
68 |
69 | if (ptrUart->putch!=NULL)
70 | {
71 | ptr=vastr;
72 | while(*ptr)
73 | {
74 | ptrUart->putch(*ptr++);
75 | }
76 |
77 | return ret;
78 | }
79 | return 0;
80 | }
81 |
82 |
83 | #else
84 | int CommandPrintf(sCmdUart *ptrUart, char *fmt, ...)
85 | {
86 | int ret=0;
87 | char vastr[MAX_STRING]={0};
88 | char *ptr;
89 | va_list ap;
90 |
91 |
92 | memset(vastr,0,MAX_STRING);
93 | va_start(ap,fmt);
94 | ret=vsprintf(vastr,(char *)fmt,ap);
95 | if (ptrUart->puts!=NULL)
96 | {
97 | return ptrUart->puts((uint8_t *)vastr, (uint8_t)ret);
98 | }
99 |
100 | if (ptrUart->putch!=NULL)
101 | {
102 | ptr=vastr;
103 | while(*ptr)
104 | {
105 | ptrUart->putch(*ptr++);
106 | }
107 |
108 | return ret;
109 | }
110 | return 0;
111 | }
112 | #endif
113 |
114 |
115 | // the delimiter is command/parameter delimiter
116 | // by default a ' '0x20 is used but for the TDR with GUI a ':' was preferred, not sure why
117 | // set to ' '/0x20 if you want normal command parsing, like DOS
118 | unsigned int CommandParse(sCmdUart *ptrUart,sCommand *ptrCmds, char *str, char delimitor )
119 | {
120 | char *ptr;
121 | char *ptr2;
122 | unsigned int i;
123 | //char cmd[MAX_STRING];
124 | char buff[MAX_CMD_LENGTH];
125 | char argv[MAX_ARGS][MAX_ARG_LENGTH];
126 | char *ptrArgv[MAX_ARGS];
127 | unsigned int numArgs;
128 | int emptyArg=0;
129 |
130 | sCommand cmd_list;
131 |
132 |
133 | while (*str==0x20 || *str=='\n' || *str=='\r' || *str=='\t') str++;
134 | //first we need find command and arguments
135 | ptr=strchr(str,delimitor); //find first char
136 |
137 | //LOG("2parsing %s",str);
138 |
139 |
140 | if (ptr==0)
141 | {
142 | //we have two options, frist whole thing is command
143 | //second bad command
144 | if(strlen(str)>0)
145 | ptr=str+strlen(str);
146 | else
147 | return 0; //bad command
148 | }
149 |
150 | //copy string to command buffer.
151 | i=0;
152 | ptr2=str;
153 | while(ptr!=0 && ptr!=ptr2 && i<(MAX_CMD_LENGTH-1))
154 | {
155 | //if (*ptr2!='\n' && *ptr2!='\r') //do not include newlines
156 | {
157 | buff[i++]=*ptr2;
158 | }
159 | ptr2++;
160 | }
161 | buff[i]=0;
162 |
163 | //now buff contains the command let's get the args
164 | numArgs=0;
165 | while(*ptr!=0 && (*ptr==' ' || *ptr==delimitor))
166 | ptr++; //increment pointer past ' '
167 | if (*ptr!=0)
168 | {
169 | if (*ptr==34) // " char
170 | {
171 | ptr++;
172 | ptr2=strchr(ptr,34); //find match
173 | } else if (*ptr==39) // 'char
174 | {
175 | ptr++;
176 | ptr2=strchr(ptr,39); //find match
177 | } else
178 | {
179 | ptr2=strchr(ptr,delimitor);
180 | }
181 | if (ptr2==0)
182 | {
183 | //we have two options, frist whole thing is command
184 | //second bad command
185 | //LOG("strlen ptr is %d",strlen(ptr));
186 | if(strlen(ptr)>0)
187 | ptr2=ptr+strlen(ptr);
188 | }
189 | emptyArg=0;
190 | while((ptr2!=0 && numArgs0)
230 | ptr2=ptr+strlen(ptr);
231 | }
232 | }
233 | }
234 | }
235 |
236 | for(i=0; ikbhit())
283 | {
284 | ptrUart->data=ptrUart->getch();
285 |
286 | //echo the data
287 | ptrUart->putch(ptrUart->data);
288 |
289 | //if the data is the CR we need to process buffer
290 | if (ptrUart->data==0x0D)
291 | {
292 | ptrUart->putch(0x0A);
293 | if (strlen(ptrUart->buffer)>0)
294 | {
295 | if (ptrUart->lastChar!=ASCII_UP_ARROW)
296 | {
297 | strcpy(ptrUart->bufferHist[ptrUart->histIndex],ptrUart->buffer);
298 | ptrUart->histIndex=(ptrUart->histIndex+1) % CMD_HISTORY;
299 | }
300 | CommandParse(ptrUart,ptrCmds,ptrUart->buffer,delimitor);
301 | }
302 |
303 | CommandPrintf(ptrUart,PSTR("\n\r%s"),cmdPrompt);
304 | ptrUart->buffIndex=0;
305 | ptrUart->buffer[ptrUart->buffIndex]=0;
306 | }
307 |
308 | if (ptrUart->data==ASCII_BACKSPACE) //backspace
309 | {
310 | if (ptrUart->buffIndex>0)
311 | {
312 | ptrUart->buffIndex--;
313 | ptrUart->buffer[ptrUart->buffIndex]='\0';
314 | //Echo the backspace
315 | ptrUart->putch(' ');
316 | ptrUart->putch(ASCII_BACKSPACE);
317 | }
318 | }else if (ptrUart->data != 0x0A && ptrUart->data !=0x0D && ptrUart->data<127)
319 | {
320 | ptrUart->buffer[ptrUart->buffIndex++]=ptrUart->data;
321 | ptrUart->buffer[ptrUart->buffIndex]=0;
322 | }
323 | if (ptrUart->buffIndex>=(MAX_CMD_LENGTH-1))
324 | {
325 | CommandPrintf(ptrUart,PSTR("\n\rERROR: Command buffer overflow\n\r"));\
326 | ERROR("Command buffer overflow");
327 | ptrUart->buffIndex=0;
328 | ptrUart->buffer[0]=0;
329 | CommandPrintf(ptrUart,PSTR("\n\r%s"),cmdPrompt);
330 | }
331 | }
332 |
333 |
334 | if (strstr(ptrUart->buffer,ANSI_UP)) //up arrow
335 | {
336 | uint8_t i;
337 |
338 | CommandPrintf(ptrUart,PSTR("\n\r%s"),cmdPrompt);
339 | i=CMD_HISTORY-1;
340 | if (ptrUart->histIndex>0)
341 | {
342 | i=ptrUart->histIndex-1;
343 | }
344 | if (strlen(ptrUart->bufferHist[i])>0)
345 | {
346 | strcpy(ptrUart->buffer,ptrUart->bufferHist[i]);
347 | ptrUart->buffIndex=strlen(ptrUart->buffer);
348 | CommandPrintf(ptrUart,PSTR("%s"),ptrUart->buffer);
349 | }else
350 | {
351 | ptrUart->buffIndex=0;
352 | ptrUart->buffer[0]=0;
353 | }
354 | ptrUart->data=ASCII_UP_ARROW;
355 | }
356 |
357 |
358 | ptrUart->lastChar=ptrUart->data;
359 | return 0;
360 | }
361 |
362 |
--------------------------------------------------------------------------------
/firmware/stepServo/command.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef __COMMAND_H
3 | #define __COMMAND_H
4 |
5 | #include
6 | #include
7 | #include "syslog.h"
8 | /*
9 | * Usage:
10 | *
11 | #include
12 | #include "uart_e0.h"
13 |
14 | sCmdUart KeyfobCmdUart; // UART used for the keyfob command line interface
15 |
16 | CMD_STR(help,"Displays this message");
17 |
18 | //List of supported commands
19 | sCommand KeyfobCmds[] =
20 | {
21 | COMMAND(help),
22 | {"",0,""}, //End of list signal
23 | };
24 |
25 | // print out the help strings for the commands
26 | static int help_cmd(sCmdUart *ptrUart,int argc, char * argv[])
27 | {
28 | sCommand cmd_list;
29 | int i;
30 |
31 | //now let's parse the command
32 | i=0;
33 | memcpy(&cmd_list, &KeyfobCmds[i], sizeof(sCommand));
34 | while(cmd_list.function!=0)
35 | {
36 |
37 | CommandPrintf(ptrUart,(cmd_list.name));
38 | CommandPrintf(ptrUart,PSTR(" - "));
39 | CommandPrintf(ptrUart,(cmd_list.help));
40 | CommandPrintf(ptrUart,PSTR("\n\r"));
41 | i=i+1;
42 | memcpy(&cmd_list, &KeyfobCmds[i], sizeof(sCommand));
43 | }
44 | return 0;
45 | }
46 |
47 | uint8_t KeyfobCmdGetChar(void)
48 | {
49 | uint8_t c;
50 | if (UARTE0_getc(&c)!=0)
51 | {
52 | ERROR("Uart getchar failed");
53 | return 0;
54 | }
55 | return c;
56 | }
57 | int KeyfobCmdInit(PIN tx_pin, PIN rx_pin, uint32_t baud)
58 | {
59 | LOG("UARTE0 init");
60 | UARTE0_Init(tx_pin, rx_pin, baud);
61 | CommandInit(&KeyfobCmdUart, UARTE0_kbhit, KeyfobCmdGetChar, UARTE0_putc,NULL); //set up the UART structure
62 | return 0;
63 | }
64 |
65 | int KeyfobCmdProcess(void)
66 | {
67 | return CommandProcess(&KeyfobCmdUart,KeyfobCmds,' ',KEYFOB_CMD_PROMPT);
68 | }
69 |
70 | Advantages:
71 | 1. You can actually have more than one UART/device connected to same command line interface.
72 | 2. works with harvard machines to save SRAM space using the PSTR functionality
73 | 3. You can swap out commands "on the fly"
74 |
75 |
76 | */
77 | #define MAX_CMD_LENGTH 60
78 | #define MAX_ARGS 10
79 | #define MAX_ARG_LENGTH 40
80 | #define CMD_HISTORY 3 //number of commands in history buffer
81 | #define ASCII_BACKSPACE 0x08
82 | #define ASCII_ESC 0x1B
83 | #define ASCII_UP_ARROW 0x9b
84 | #define ANSI_UP "\x1B[A\0"
85 |
86 | #define MAX_STRING 255
87 | //const char ANSI_UP[]= {ASCII_ESC,'[','A',0};
88 |
89 | typedef struct {
90 | uint8_t (*kbhit)(void);
91 | uint8_t (*getch)(void);
92 | uint8_t (*putch)(char data);
93 | uint8_t (*puts)(uint8_t *buffer, uint8_t size);
94 | uint8_t data;
95 | char buffer[MAX_CMD_LENGTH];
96 |
97 | char bufferHist[CMD_HISTORY][MAX_CMD_LENGTH];
98 | uint8_t histIndex;
99 | uint8_t buffIndex;
100 | uint8_t lastChar;
101 | }sCmdUart;
102 |
103 |
104 | #define COMMAND(NAME) { NAME ## _str, NAME ## _cmd, NAME ## _help}
105 |
106 |
107 | #ifdef PGM_P //check and see if the PGM_P is defined for the AVR
108 |
109 | //If so then we use the strings in flash not SRAM
110 | #define CMD_STR(NAME,STR) static const char NAME ## _help[] PROGMEM = STR; static const char NAME ## _str[] PROGMEM = #NAME; static int NAME ##_cmd(sCmdUart *ptrUart,int, char **);
111 | //Command structure
112 | typedef struct
113 | {
114 | PGM_P name;
115 | int (*function) (sCmdUart *ptrUart,int, char **);
116 | PGM_P help;
117 | } sCommand;
118 | int CommandPrintf(sCmdUart *ptrUart, const char *fmt, ...);
119 |
120 | #else
121 |
122 | #define CMD_STR(NAME,STR) static char NAME ## _help[] = STR; static char NAME ## _str[] = #NAME; static int NAME ##_cmd(sCmdUart *ptrUart,int, char **);
123 |
124 | //Command structure
125 | typedef struct
126 | {
127 | char *name;
128 | int (*function) (sCmdUart *ptrUart,int, char **);
129 | char *help;
130 | } sCommand;
131 |
132 | int CommandPrintf(sCmdUart *ptrUart, char *fmt, ...);
133 | #endif
134 |
135 |
136 | int CommandInit(sCmdUart *ptrUart, uint8_t (*kbhit)(void), uint8_t (*getch)(void),uint8_t (*putch)(char data),uint8_t (*puts)(uint8_t *buffer, uint8_t size));
137 | unsigned int CommandParse(sCmdUart *ptrUart,sCommand *ptrCmds, char *str, char delimitor);
138 | int CommandProcess(sCmdUart *ptrUart,sCommand *ptrCmds, char delimitor, char *cmdPrompt);
139 |
140 |
141 |
142 | #endif
143 |
144 |
--------------------------------------------------------------------------------
/firmware/stepServo/commands.h:
--------------------------------------------------------------------------------
1 | #ifndef __COMMANDS_H__
2 | #define __COMMANDS_H__
3 | #include
4 | #include "stepper_controller.h"
5 | #include "nzs.h"
6 |
7 | extern StepperCtrl stepperCtrl;
8 | extern eepromData_t PowerupEEPROM;
9 |
10 | void commandsInit(void);
11 | int commandsProcess(void);
12 |
13 | #endif //__COMMANDS_H__
14 |
--------------------------------------------------------------------------------
/firmware/stepServo/eeprom.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * eeprom.cpp
3 | *
4 | * Created on: May 30, 2017
5 | * Author: tstern
6 | */
7 | #include "eeprom.h"
8 | #include "calibration.h"
9 | #include "Flash.h"
10 | #include "board.h" //for divide with rounding macro
11 | #include
12 | #include "syslog.h"
13 |
14 | //since we will write the following structure into each page, we need to find our latest page
15 | // to do this we will use the header to contain a checksum and write counter.
16 | #define EEPROM_SIZE (FLASH_ROW_SIZE*2)
17 |
18 | typedef struct {
19 | uint16_t checksum;
20 | uint16_t count;
21 | }eepromHeader_t;
22 |
23 | #define EEPROM_DATA_SIZE (FLASH_PAGE_SIZE_NZS-sizeof(eepromHeader_t))
24 | typedef struct {
25 | eepromHeader_t header;
26 | uint8_t data[EEPROM_DATA_SIZE];
27 | } eepromData_t;
28 |
29 |
30 |
31 | static eepromData_t EEPROMCache;
32 |
33 | static int32_t NextPageWrite=-1;
34 |
35 | //we need to reserve two pages for EEPROM
36 | __attribute__((__aligned__(FLASH_ROW_SIZE))) const uint8_t NVM_eeprom[EEPROM_SIZE]={0xFFF};
37 |
38 |
39 | static uint16_t checksum(uint8_t *ptrData, uint32_t nBytes)
40 | {
41 | uint16_t sum=0;
42 | uint32_t i;
43 | i=0;
44 | //LOG("running checksum %d",nBytes);
45 | while(idata, EEPROM_DATA_SIZE);
61 | //LOG("checksum is %d %d",cs,ptrData->header.checksum);
62 |
63 | if (cs==ptrData->header.checksum)
64 | {
65 | //LOG("Page good %d",page);
66 | return true;
67 | }
68 | //LOG("page bad %d",page);
69 | return false;
70 | }
71 |
72 | static void printEEPROM(uint32_t page)
73 | {
74 | eepromData_t *ptrData;
75 | int i;
76 | ptrData=(eepromData_t *)&NVM_eeprom[page];
77 | LOG("count %d", ptrData->header.count);
78 | LOG("checksum %d", ptrData->header.checksum);
79 | for (i=0; i<10; i++)
80 | {
81 | LOG("Data[%d]=%02X",i,ptrData->data[i]);
82 | }
83 | }
84 |
85 | static uint32_t findLastGoodPage(void)
86 | {
87 | uint32_t lastGoodPage=0;
88 | uint32_t page;
89 | uint16_t lastCnt=0;
90 | eepromData_t *ptrData;
91 |
92 | page=0;
93 | while(page < (EEPROM_SIZE))
94 | {
95 | //LOG("checking page %d",page);
96 | if (isPageGood(page))
97 | {
98 | ptrData=(eepromData_t *)&NVM_eeprom[page];
99 |
100 | //check for roll over which is OK
101 | if (lastCnt==16534 && ptrData->header.count==1)
102 | {
103 | lastCnt=ptrData->header.count;
104 | lastGoodPage=page;
105 | }
106 | if (ptrData->header.count>lastCnt)
107 | {
108 | //make sure we have not rolled over.
109 | if ((ptrData->header.count-lastCnt)<(16534/2))
110 | {
111 | lastCnt=ptrData->header.count;
112 | lastGoodPage=page;
113 | }
114 | }
115 | }
116 | page=page + FLASH_PAGE_SIZE_NZS;
117 | }
118 | //LOG("last good page %d",lastGoodPage);
119 | return lastGoodPage;
120 | }
121 |
122 | //find the next page to write
123 | static uint32_t eepromGetNextWritPage(void)
124 | {
125 | eepromHeader_t *ptrHeader;
126 | uint32_t page;
127 | uint32_t row;
128 | int blockCount;
129 | int done=0;
130 |
131 | //start at first address:
132 | page=0;
133 |
134 | while(page < (EEPROM_SIZE))
135 | {
136 | //LOG("checking page %d",page);
137 | ptrHeader=(eepromHeader_t *) &NVM_eeprom[page];
138 | if (ptrHeader->count == 0xFFFF)
139 | {
140 | uint32_t i;
141 | uint8_t *ptrData;
142 | //uint8_t erasedByte=(uint8_t)ptrHeader->count;
143 | bool erased=true;
144 |
145 | //verify page is erased
146 | ptrData= (uint8_t *)&NVM_eeprom[page];
147 |
148 | for (i=0; i=EEPROM_SIZE)
175 | {
176 | row=0;
177 | //TODO we should make sure this not where good data is
178 | // however if it is what should we do?
179 | }
180 |
181 | //now we need to erase that row
182 | //WARNING("Erasing page %d",row*FLASH_ROW_SIZE);
183 | flashErase(&NVM_eeprom[row*FLASH_ROW_SIZE],FLASH_ROW_SIZE);
184 | page=row*FLASH_ROW_SIZE;
185 | //LOG("Next free page is %d",page);
186 | return page;
187 | }
188 |
189 |
190 | eepromError_t eepromInit(void)
191 | {
192 | uint32_t page;
193 |
194 |
195 | //find the last good page offset in flash
196 | page=findLastGoodPage();
197 | LOG("EEPROM Init found page %d",page);
198 | if (isPageGood(page))
199 | {
200 | LOG("EEPROM page good %d",page);
201 | memcpy(&EEPROMCache, &NVM_eeprom[page], sizeof(EEPROMCache));
202 |
203 | NextPageWrite=eepromGetNextWritPage();
204 | return EEPROM_OK;
205 | }
206 | //ERROR("page is bad");
207 | memset(&EEPROMCache, 0, sizeof(EEPROMCache));
208 | NextPageWrite=eepromGetNextWritPage();
209 | return EEPROM_CORRUPT;
210 | }
211 |
212 |
213 | int eepromWriteCache(uint8_t *ptrData, uint32_t size)
214 | {
215 | //LOG("Cache write %d",size);
216 | if (NextPageWrite==-1) //some one did not init the module
217 | {
218 | //lets handle gracefully and do it ourselves
219 | eepromInit();
220 | }
221 | if (size>EEPROM_DATA_SIZE)
222 | {
223 | size =EEPROM_DATA_SIZE;
224 | }
225 | memcpy(EEPROMCache.data, ptrData, size);
226 | EEPROMCache.header.checksum=checksum(EEPROMCache.data,EEPROM_DATA_SIZE);
227 |
228 |
229 | return size;
230 | }
231 |
232 | int eepromRead(uint8_t *ptrData, uint32_t size) //returns number of bytes actually read, whcih could be less than size requested
233 | {
234 | if (NextPageWrite==-1) //some one did not init the module
235 | {
236 | //lets handle gracefully and do it ourselves
237 | eepromInit();
238 | }
239 | if (size>EEPROM_DATA_SIZE)
240 | {
241 | size =EEPROM_DATA_SIZE;
242 | }
243 | if (EEPROMCache.header.count == 0)
244 | {
245 | return 0; //cache is new/corrupt
246 | }
247 | memcpy(ptrData, EEPROMCache.data, size);
248 | return size;
249 | }
250 |
251 | eepromError_t eepromFlush(void) //flush the cache to flash memory
252 | {
253 | if (NextPageWrite==-1)
254 | {
255 | ERROR("EEPROM WRITE FAILED");
256 | return EEPROM_FAILED; //most likely no one has written to cache
257 | }
258 | EEPROMCache.header.count++;
259 | if (EEPROMCache.header.count>=16535)
260 | {
261 | EEPROMCache.header.count=1;
262 | }
263 | //WARNING("Writting to Page %d",NextPageWrite);
264 | flashWrite(&NVM_eeprom[NextPageWrite], &EEPROMCache, sizeof(EEPROMCache));
265 |
266 | // printEEPROM(NextPageWrite);
267 |
268 | if (!SYSCTRL->PCLKSR.bit.BOD33DET) //if not in brown out condition find next write location
269 | {
270 | //LOG("getting next page to write");
271 | NextPageWrite=eepromGetNextWritPage(); //find next write location and erase if needed
272 | } else
273 | {
274 | //LOG("BOD active");
275 | NextPageWrite=-1; //else we will just clear NextPageWrite location just in case we recover from brown out
276 | }
277 | return EEPROM_OK;
278 | }
279 |
280 |
281 |
282 |
--------------------------------------------------------------------------------
/firmware/stepServo/eeprom.h:
--------------------------------------------------------------------------------
1 | /*
2 | * eeprom.h
3 | *
4 | * Created on: May 30, 2017
5 | * Author: tstern
6 | */
7 |
8 | #ifndef EEPROM_H_
9 | #define EEPROM_H_
10 | #include "Flash.h"
11 | #include "calibration.h"
12 | #include "board.h"
13 |
14 | /*
15 | * This EEPROM implementation provides 60bytes of "eeprom space" (we reserve 4 bytes for overhead)
16 | * The EEPROM uses two rows of flash (256 bytes per row), which
17 | * for the SAMD21G18A this allows a minimual 200k writes, but typically 1200k
18 | */
19 |
20 | typedef enum {
21 | EEPROM_OK =0,
22 | EEPROM_FAILED=1,
23 | EEPROM_CORRUPT=2,
24 | } eepromError_t;
25 |
26 |
27 | eepromError_t eepromInit(void);
28 | int eepromWriteCache(uint8_t *ptrData, uint32_t size); //returns number bytes written to cache
29 | eepromError_t eepromFlush(void); //flush the cache to flash memory
30 | int eepromRead(uint8_t *ptrData, uint32_t size); //returns number of bytes actually read, whcih could be less than size requested
31 |
32 | #endif /* EEPROM_H_ */
33 |
--------------------------------------------------------------------------------
/firmware/stepServo/fet_driver.h:
--------------------------------------------------------------------------------
1 | /*
2 | * fet_driver.h
3 | *
4 | * Created on: Dec 24, 2016
5 | * Author: tstern
6 | *
7 | * This file supports using discrete FETs as drivers for stepper motor
8 | *
9 | * Misfit Tech invests time and resources providing this open source code,
10 | * please support Misfit Tech and open-source hardware by purchasing
11 | * products from Misfit Tech, www.misifittech.net!
12 | *
13 | * Written by Trampas Stern for Misfit Tech.
14 | * BSD license, check license.txt for more information
15 | * All text above, must be included in any redistribution
16 | *********************************************************************/
17 |
18 | #ifndef FET_DRIVER_H_
19 | #define FET_DRIVER_H_
20 |
21 |
22 |
23 | #include
24 | #include "board.h"
25 | #include "angle.h"
26 | #include "sine.h"
27 |
28 | #ifdef NEMA_23_10A_HW
29 | #define FET_DRIVER_NUM_MICROSTEPS (SINE_STEPS/4) //number of steps to use for microstepping, default is 256
30 | #define FET_DRIVER_NUM_ZERO_AVG (100)
31 |
32 |
33 | #define FET_ADC_TO_MA(x) (((x)*2537)/1000)
34 | #define FET_MA_TO_ADC(x) (((x)*1000)/2537)
35 | //prvent someone for making a mistake with the code
36 | #if ((FET_DRIVER_NUM_MICROSTEPS*4) != SINE_STEPS)
37 | #error "SINE_STEPS must be 4x of Micro steps for the move function"
38 | #endif
39 |
40 | /*
41 | * When it comes to the stepper driver if we use angles
42 | * we will always have a rounding error. For example
43 | * a 0-65536(360) angle for 1.8 degree step is 327.68 so
44 | * if you increment 200 of these as 327 you have a 13.6 error
45 | * after one rotation.
46 | * If you use floating point the effect is the same but takes longer.
47 | *
48 | * The only error-less accumulation system is to use native units, ie full
49 | * steps and microsteps.
50 | *
51 | */
52 |
53 | class FetDriver
54 | {
55 | static FetDriver *ptrInstance;
56 | private:
57 | uint32_t lastStepMicros; // time in microseconds that last step happened
58 |
59 | int32_t PWM_Table_B[512];
60 | int32_t PWM_Table_A[512];
61 |
62 | bool forwardRotation=true;
63 | volatile bool enabled=true;
64 |
65 | volatile int32_t adc;
66 |
67 |
68 | volatile int32_t coilB_value=0;
69 | volatile int32_t coilB_Zero=-1;
70 | volatile int32_t coilB_SetPoint=100;
71 | volatile int32_t coilB_error=0;
72 |
73 | volatile int32_t coilA_value=0;
74 | volatile int32_t coilA_Zero=-1;
75 | volatile int32_t coilA_SetPoint=200;
76 | volatile int32_t coilA_error=0;
77 | void ctrl_update(uint16_t channel, uint16_t value);
78 | void measureCoilB_zero(void);
79 | void measureCoilA_zero(void);
80 | void CalTableB(int32_t maxMA);
81 | void CalTableA(int32_t maxMA);
82 | int coilA_PWM(int32_t value);
83 | void coilB_PWM(int32_t value);
84 | int32_t getCoilB_mA(void);
85 | int32_t getCoilA_mA(void);
86 | public:
87 |
88 | static void ADC_Callback(uint16_t channel, uint16_t value);
89 | void begin(void);
90 |
91 | //moves motor where the modulo of A4954_NUM_MICROSTEPS is a full step.
92 | int32_t move(int32_t stepAngle, uint32_t mA);
93 |
94 | uint32_t microsSinceStep(void) {return micros()-lastStepMicros;};
95 | void setRotationDirection(bool forward) {forwardRotation=forward;};
96 |
97 | void enable(bool enable) {enabled=enable;};
98 | void limitCurrent(uint8_t x) {return;};
99 | };
100 |
101 |
102 | #endif //#ifdef NEMA_23_10A_HW
103 | #endif /* FET_DRIVER_H_ */
104 |
--------------------------------------------------------------------------------
/firmware/stepServo/ftoa.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "board.h"
3 | #include "ftoa.h"
4 | /*******************************************************************
5 | * FUNCTION: ftoa
6 | * AUTHOR = TRAMPAS STERN
7 | * FILE = strio.c
8 | * DATE = 2/6/2003 4:27:14 PM
9 | *
10 | * PARAMETERS: long,*str, int count
11 | *
12 | * DESCRIPTION: Convets an float to string
13 | * format 'f', 'E', or 'e'
14 | *
15 | *
16 | * RETURNS:
17 | *
18 | * NOTE this code was found on the web and modified to actually work
19 | *******************************************************************/
20 | int ftoa (float x, char *str, char prec, char format)
21 | {
22 |
23 | int ie, i, k, ndig, fstyle;
24 | double y;
25 | char *start;
26 |
27 | start=str;
28 |
29 | //based on percission set number digits
30 | ndig=prec+1;
31 | if (prec<0)
32 | ndig=7;
33 | if (prec>22)
34 | ndig=23;
35 |
36 | fstyle = 0; //exponent 'e'
37 | if (format == 'f' || format == 'F')
38 | fstyle = 1; //normal 'f'
39 | if (format=='g' || format=='G')
40 | fstyle=2;
41 |
42 | ie = 0;
43 | /* if x negative, write minus and reverse */
44 | if ( x < 0)
45 | {
46 | *str++ = '-';
47 | x = -x;
48 | }
49 |
50 | //if (x<0.0) then increment by 10 till betwen 1.0 and 10.0
51 | if (x!=0.0)
52 | {
53 | while (x < 1.0)
54 | {
55 | x =x* 10.0;
56 | ie--;
57 | }
58 | }
59 |
60 | //if x>10 then let's shift it down
61 | while (x >= 10.0)
62 | {
63 | x = x*(1.0/10.0);
64 | ie++;
65 | }
66 |
67 | if (ABS(ie)>MAX_MANTISA)
68 | {
69 | if (fstyle==1)
70 | {
71 | fstyle=0;
72 | format='e';
73 | //ie=2;
74 | }
75 | }
76 |
77 |
78 | /* in f format, number of digits is related to size */
79 | if (fstyle)
80 | ndig =ndig + ie;
81 |
82 | if(prec==0 && ie>ndig && fstyle)
83 | {
84 | ndig=ie;
85 | }
86 |
87 | /* round. x is between 1 and 10 and ndig will be printed to
88 | right of decimal point so rounding is ... */
89 | y=1;
90 | for (i = 1; i < ndig; i++) //find lest significant digit
91 | y = y *(1.0/10.0); //multiply by 1/10 is faster than divides
92 |
93 | x = x+ y *(1.0/2.0); //add rounding
94 |
95 | /* repair rounding disasters */
96 | if (x >= 10.0)
97 | {
98 | x = 1.0;
99 | ie++;
100 | ndig++;
101 | }
102 |
103 | //check and see if the number is less than 1.0
104 | if (fstyle && ie<0)
105 | {
106 | *str++ = '0';
107 | if (prec!=0)
108 | *str++ = '.';
109 | if (ndig < 0)
110 | ie = ie-ndig; /* limit zeros if underflow */
111 | for (i = -1; i > ie; i--)
112 | *str++ = '0';
113 | }
114 |
115 | //for each digit
116 | for (i=0; i < ndig; i++)
117 | {
118 | float b;
119 | k = x; //k = most significant digit
120 | *str++ = k + '0'; //output the char representation
121 | if (((!fstyle && i==0) || (fstyle && i==ie)) && prec!=0)
122 | *str++ = '.'; //output a decimal point
123 | b=(float)k;
124 | //multiply by 10 before subtraction to remove
125 | //errors from limited number of bits in float.
126 | b=b*10.0;
127 | x=x*10.0;
128 | x =x - b; //subtract k from x
129 | //b=x+b;
130 | //x =x* 10.0; //get next digit
131 | }
132 |
133 | /* now, in estyle, put out exponent if not zero */
134 | if (!fstyle && ie != 0)
135 | {
136 | *str++ = format;
137 | if (ie < 0) //if number has negative exponent
138 | {
139 | ie = -ie;
140 | *str++ = '-';
141 | }
142 |
143 | //now we need to convert the exponent to string
144 | for (k=1000; k>ie; k=k/10); //find the decade of exponent
145 |
146 | for (; k > 0; k=k/10)
147 | {
148 | char t;
149 | t=DIV(ie,k);
150 | *str++ = t + '0';
151 | ie = ie -(t*k);
152 | }
153 |
154 | }
155 | *str++ = '\0';
156 | return (str-start); //return string length
157 | }
158 |
--------------------------------------------------------------------------------
/firmware/stepServo/ftoa.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ftoa.h
3 | *
4 | * Created on: Jan 6, 2017
5 | * Author: tstern
6 | */
7 |
8 | #ifndef FTOA_H_
9 | #define FTOA_H_
10 |
11 | #define MAX_MANTISA (1000)
12 |
13 | int ftoa (float x, char *str, char prec, char format);
14 |
15 |
16 |
17 | #endif /* FTOA_H_ */
18 |
--------------------------------------------------------------------------------
/firmware/stepServo/gfxfont.h:
--------------------------------------------------------------------------------
1 | // Font structures for newer Adafruit_GFX (1.1 and later).
2 | // Example fonts are included in 'Fonts' directory.
3 | // To use a font in your Arduino sketch, #include the corresponding .h
4 | // file and pass address of GFXfont struct to setFont(). Pass NULL to
5 | // revert to 'classic' fixed-space bitmap font.
6 |
7 | #ifndef _GFXFONT_H_
8 | #define _GFXFONT_H_
9 |
10 | typedef struct { // Data stored PER GLYPH
11 | uint16_t bitmapOffset; // Pointer into GFXfont->bitmap
12 | uint8_t width, height; // Bitmap dimensions in pixels
13 | uint8_t xAdvance; // Distance to advance cursor (x axis)
14 | int8_t xOffset, yOffset; // Dist from cursor pos to UL corner
15 | } GFXglyph;
16 |
17 | typedef struct { // Data stored for FONT AS A WHOLE:
18 | uint8_t *bitmap; // Glyph bitmaps, concatenated
19 | GFXglyph *glyph; // Glyph array
20 | uint8_t first, last; // ASCII extents
21 | uint8_t yAdvance; // Newline distance (y axis)
22 | } GFXfont;
23 |
24 | #endif // _GFXFONT_H_
25 |
--------------------------------------------------------------------------------
/firmware/stepServo/glcdfont.c:
--------------------------------------------------------------------------------
1 | // This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0.
2 | // See gfxfont.h for newer custom bitmap font info.
3 |
4 | #ifndef FONT5X7_H
5 | #define FONT5X7_H
6 |
7 | #ifdef __AVR__
8 | #include
9 | #include
10 | #elif defined(ESP8266)
11 | #include
12 | #else
13 | #define PROGMEM
14 | #endif
15 |
16 | // Standard ASCII 5x7 font
17 |
18 | static const unsigned char font[] PROGMEM = {
19 | 0x00, 0x00, 0x00, 0x00, 0x00,
20 | 0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
21 | 0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
22 | 0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
23 | 0x18, 0x3C, 0x7E, 0x3C, 0x18,
24 | 0x1C, 0x57, 0x7D, 0x57, 0x1C,
25 | 0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
26 | 0x00, 0x18, 0x3C, 0x18, 0x00,
27 | 0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
28 | 0x00, 0x18, 0x24, 0x18, 0x00,
29 | 0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
30 | 0x30, 0x48, 0x3A, 0x06, 0x0E,
31 | 0x26, 0x29, 0x79, 0x29, 0x26,
32 | 0x40, 0x7F, 0x05, 0x05, 0x07,
33 | 0x40, 0x7F, 0x05, 0x25, 0x3F,
34 | 0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
35 | 0x7F, 0x3E, 0x1C, 0x1C, 0x08,
36 | 0x08, 0x1C, 0x1C, 0x3E, 0x7F,
37 | 0x14, 0x22, 0x7F, 0x22, 0x14,
38 | 0x5F, 0x5F, 0x00, 0x5F, 0x5F,
39 | 0x06, 0x09, 0x7F, 0x01, 0x7F,
40 | 0x00, 0x66, 0x89, 0x95, 0x6A,
41 | 0x60, 0x60, 0x60, 0x60, 0x60,
42 | 0x94, 0xA2, 0xFF, 0xA2, 0x94,
43 | 0x08, 0x04, 0x7E, 0x04, 0x08,
44 | 0x10, 0x20, 0x7E, 0x20, 0x10,
45 | 0x08, 0x08, 0x2A, 0x1C, 0x08,
46 | 0x08, 0x1C, 0x2A, 0x08, 0x08,
47 | 0x1E, 0x10, 0x10, 0x10, 0x10,
48 | 0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
49 | 0x30, 0x38, 0x3E, 0x38, 0x30,
50 | 0x06, 0x0E, 0x3E, 0x0E, 0x06,
51 | 0x00, 0x00, 0x00, 0x00, 0x00,
52 | 0x00, 0x00, 0x5F, 0x00, 0x00,
53 | 0x00, 0x07, 0x00, 0x07, 0x00,
54 | 0x14, 0x7F, 0x14, 0x7F, 0x14,
55 | 0x24, 0x2A, 0x7F, 0x2A, 0x12,
56 | 0x23, 0x13, 0x08, 0x64, 0x62,
57 | 0x36, 0x49, 0x56, 0x20, 0x50,
58 | 0x00, 0x08, 0x07, 0x03, 0x00,
59 | 0x00, 0x1C, 0x22, 0x41, 0x00,
60 | 0x00, 0x41, 0x22, 0x1C, 0x00,
61 | 0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
62 | 0x08, 0x08, 0x3E, 0x08, 0x08,
63 | 0x00, 0x80, 0x70, 0x30, 0x00,
64 | 0x08, 0x08, 0x08, 0x08, 0x08,
65 | 0x00, 0x00, 0x60, 0x60, 0x00,
66 | 0x20, 0x10, 0x08, 0x04, 0x02,
67 | 0x3E, 0x51, 0x49, 0x45, 0x3E,
68 | 0x00, 0x42, 0x7F, 0x40, 0x00,
69 | 0x72, 0x49, 0x49, 0x49, 0x46,
70 | 0x21, 0x41, 0x49, 0x4D, 0x33,
71 | 0x18, 0x14, 0x12, 0x7F, 0x10,
72 | 0x27, 0x45, 0x45, 0x45, 0x39,
73 | 0x3C, 0x4A, 0x49, 0x49, 0x31,
74 | 0x41, 0x21, 0x11, 0x09, 0x07,
75 | 0x36, 0x49, 0x49, 0x49, 0x36,
76 | 0x46, 0x49, 0x49, 0x29, 0x1E,
77 | 0x00, 0x00, 0x14, 0x00, 0x00,
78 | 0x00, 0x40, 0x34, 0x00, 0x00,
79 | 0x00, 0x08, 0x14, 0x22, 0x41,
80 | 0x14, 0x14, 0x14, 0x14, 0x14,
81 | 0x00, 0x41, 0x22, 0x14, 0x08,
82 | 0x02, 0x01, 0x59, 0x09, 0x06,
83 | 0x3E, 0x41, 0x5D, 0x59, 0x4E,
84 | 0x7C, 0x12, 0x11, 0x12, 0x7C,
85 | 0x7F, 0x49, 0x49, 0x49, 0x36,
86 | 0x3E, 0x41, 0x41, 0x41, 0x22,
87 | 0x7F, 0x41, 0x41, 0x41, 0x3E,
88 | 0x7F, 0x49, 0x49, 0x49, 0x41,
89 | 0x7F, 0x09, 0x09, 0x09, 0x01,
90 | 0x3E, 0x41, 0x41, 0x51, 0x73,
91 | 0x7F, 0x08, 0x08, 0x08, 0x7F,
92 | 0x00, 0x41, 0x7F, 0x41, 0x00,
93 | 0x20, 0x40, 0x41, 0x3F, 0x01,
94 | 0x7F, 0x08, 0x14, 0x22, 0x41,
95 | 0x7F, 0x40, 0x40, 0x40, 0x40,
96 | 0x7F, 0x02, 0x1C, 0x02, 0x7F,
97 | 0x7F, 0x04, 0x08, 0x10, 0x7F,
98 | 0x3E, 0x41, 0x41, 0x41, 0x3E,
99 | 0x7F, 0x09, 0x09, 0x09, 0x06,
100 | 0x3E, 0x41, 0x51, 0x21, 0x5E,
101 | 0x7F, 0x09, 0x19, 0x29, 0x46,
102 | 0x26, 0x49, 0x49, 0x49, 0x32,
103 | 0x03, 0x01, 0x7F, 0x01, 0x03,
104 | 0x3F, 0x40, 0x40, 0x40, 0x3F,
105 | 0x1F, 0x20, 0x40, 0x20, 0x1F,
106 | 0x3F, 0x40, 0x38, 0x40, 0x3F,
107 | 0x63, 0x14, 0x08, 0x14, 0x63,
108 | 0x03, 0x04, 0x78, 0x04, 0x03,
109 | 0x61, 0x59, 0x49, 0x4D, 0x43,
110 | 0x00, 0x7F, 0x41, 0x41, 0x41,
111 | 0x02, 0x04, 0x08, 0x10, 0x20,
112 | 0x00, 0x41, 0x41, 0x41, 0x7F,
113 | 0x04, 0x02, 0x01, 0x02, 0x04,
114 | 0x40, 0x40, 0x40, 0x40, 0x40,
115 | 0x00, 0x03, 0x07, 0x08, 0x00,
116 | 0x20, 0x54, 0x54, 0x78, 0x40,
117 | 0x7F, 0x28, 0x44, 0x44, 0x38,
118 | 0x38, 0x44, 0x44, 0x44, 0x28,
119 | 0x38, 0x44, 0x44, 0x28, 0x7F,
120 | 0x38, 0x54, 0x54, 0x54, 0x18,
121 | 0x00, 0x08, 0x7E, 0x09, 0x02,
122 | 0x18, 0xA4, 0xA4, 0x9C, 0x78,
123 | 0x7F, 0x08, 0x04, 0x04, 0x78,
124 | 0x00, 0x44, 0x7D, 0x40, 0x00,
125 | 0x20, 0x40, 0x40, 0x3D, 0x00,
126 | 0x7F, 0x10, 0x28, 0x44, 0x00,
127 | 0x00, 0x41, 0x7F, 0x40, 0x00,
128 | 0x7C, 0x04, 0x78, 0x04, 0x78,
129 | 0x7C, 0x08, 0x04, 0x04, 0x78,
130 | 0x38, 0x44, 0x44, 0x44, 0x38,
131 | 0xFC, 0x18, 0x24, 0x24, 0x18,
132 | 0x18, 0x24, 0x24, 0x18, 0xFC,
133 | 0x7C, 0x08, 0x04, 0x04, 0x08,
134 | 0x48, 0x54, 0x54, 0x54, 0x24,
135 | 0x04, 0x04, 0x3F, 0x44, 0x24,
136 | 0x3C, 0x40, 0x40, 0x20, 0x7C,
137 | 0x1C, 0x20, 0x40, 0x20, 0x1C,
138 | 0x3C, 0x40, 0x30, 0x40, 0x3C,
139 | 0x44, 0x28, 0x10, 0x28, 0x44,
140 | 0x4C, 0x90, 0x90, 0x90, 0x7C,
141 | 0x44, 0x64, 0x54, 0x4C, 0x44,
142 | 0x00, 0x08, 0x36, 0x41, 0x00,
143 | 0x00, 0x00, 0x77, 0x00, 0x00,
144 | 0x00, 0x41, 0x36, 0x08, 0x00,
145 | 0x02, 0x01, 0x02, 0x04, 0x02,
146 | 0x3C, 0x26, 0x23, 0x26, 0x3C,
147 | 0x1E, 0xA1, 0xA1, 0x61, 0x12,
148 | 0x3A, 0x40, 0x40, 0x20, 0x7A,
149 | 0x38, 0x54, 0x54, 0x55, 0x59,
150 | 0x21, 0x55, 0x55, 0x79, 0x41,
151 | 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut
152 | 0x21, 0x55, 0x54, 0x78, 0x40,
153 | 0x20, 0x54, 0x55, 0x79, 0x40,
154 | 0x0C, 0x1E, 0x52, 0x72, 0x12,
155 | 0x39, 0x55, 0x55, 0x55, 0x59,
156 | 0x39, 0x54, 0x54, 0x54, 0x59,
157 | 0x39, 0x55, 0x54, 0x54, 0x58,
158 | 0x00, 0x00, 0x45, 0x7C, 0x41,
159 | 0x00, 0x02, 0x45, 0x7D, 0x42,
160 | 0x00, 0x01, 0x45, 0x7C, 0x40,
161 | 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut
162 | 0xF0, 0x28, 0x25, 0x28, 0xF0,
163 | 0x7C, 0x54, 0x55, 0x45, 0x00,
164 | 0x20, 0x54, 0x54, 0x7C, 0x54,
165 | 0x7C, 0x0A, 0x09, 0x7F, 0x49,
166 | 0x32, 0x49, 0x49, 0x49, 0x32,
167 | 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut
168 | 0x32, 0x4A, 0x48, 0x48, 0x30,
169 | 0x3A, 0x41, 0x41, 0x21, 0x7A,
170 | 0x3A, 0x42, 0x40, 0x20, 0x78,
171 | 0x00, 0x9D, 0xA0, 0xA0, 0x7D,
172 | 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut
173 | 0x3D, 0x40, 0x40, 0x40, 0x3D,
174 | 0x3C, 0x24, 0xFF, 0x24, 0x24,
175 | 0x48, 0x7E, 0x49, 0x43, 0x66,
176 | 0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
177 | 0xFF, 0x09, 0x29, 0xF6, 0x20,
178 | 0xC0, 0x88, 0x7E, 0x09, 0x03,
179 | 0x20, 0x54, 0x54, 0x79, 0x41,
180 | 0x00, 0x00, 0x44, 0x7D, 0x41,
181 | 0x30, 0x48, 0x48, 0x4A, 0x32,
182 | 0x38, 0x40, 0x40, 0x22, 0x7A,
183 | 0x00, 0x7A, 0x0A, 0x0A, 0x72,
184 | 0x7D, 0x0D, 0x19, 0x31, 0x7D,
185 | 0x26, 0x29, 0x29, 0x2F, 0x28,
186 | 0x26, 0x29, 0x29, 0x29, 0x26,
187 | 0x30, 0x48, 0x4D, 0x40, 0x20,
188 | 0x38, 0x08, 0x08, 0x08, 0x08,
189 | 0x08, 0x08, 0x08, 0x08, 0x38,
190 | 0x2F, 0x10, 0xC8, 0xAC, 0xBA,
191 | 0x2F, 0x10, 0x28, 0x34, 0xFA,
192 | 0x00, 0x00, 0x7B, 0x00, 0x00,
193 | 0x08, 0x14, 0x2A, 0x14, 0x22,
194 | 0x22, 0x14, 0x2A, 0x14, 0x08,
195 | 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code
196 | 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block
197 | 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block
198 | 0x00, 0x00, 0x00, 0xFF, 0x00,
199 | 0x10, 0x10, 0x10, 0xFF, 0x00,
200 | 0x14, 0x14, 0x14, 0xFF, 0x00,
201 | 0x10, 0x10, 0xFF, 0x00, 0xFF,
202 | 0x10, 0x10, 0xF0, 0x10, 0xF0,
203 | 0x14, 0x14, 0x14, 0xFC, 0x00,
204 | 0x14, 0x14, 0xF7, 0x00, 0xFF,
205 | 0x00, 0x00, 0xFF, 0x00, 0xFF,
206 | 0x14, 0x14, 0xF4, 0x04, 0xFC,
207 | 0x14, 0x14, 0x17, 0x10, 0x1F,
208 | 0x10, 0x10, 0x1F, 0x10, 0x1F,
209 | 0x14, 0x14, 0x14, 0x1F, 0x00,
210 | 0x10, 0x10, 0x10, 0xF0, 0x00,
211 | 0x00, 0x00, 0x00, 0x1F, 0x10,
212 | 0x10, 0x10, 0x10, 0x1F, 0x10,
213 | 0x10, 0x10, 0x10, 0xF0, 0x10,
214 | 0x00, 0x00, 0x00, 0xFF, 0x10,
215 | 0x10, 0x10, 0x10, 0x10, 0x10,
216 | 0x10, 0x10, 0x10, 0xFF, 0x10,
217 | 0x00, 0x00, 0x00, 0xFF, 0x14,
218 | 0x00, 0x00, 0xFF, 0x00, 0xFF,
219 | 0x00, 0x00, 0x1F, 0x10, 0x17,
220 | 0x00, 0x00, 0xFC, 0x04, 0xF4,
221 | 0x14, 0x14, 0x17, 0x10, 0x17,
222 | 0x14, 0x14, 0xF4, 0x04, 0xF4,
223 | 0x00, 0x00, 0xFF, 0x00, 0xF7,
224 | 0x14, 0x14, 0x14, 0x14, 0x14,
225 | 0x14, 0x14, 0xF7, 0x00, 0xF7,
226 | 0x14, 0x14, 0x14, 0x17, 0x14,
227 | 0x10, 0x10, 0x1F, 0x10, 0x1F,
228 | 0x14, 0x14, 0x14, 0xF4, 0x14,
229 | 0x10, 0x10, 0xF0, 0x10, 0xF0,
230 | 0x00, 0x00, 0x1F, 0x10, 0x1F,
231 | 0x00, 0x00, 0x00, 0x1F, 0x14,
232 | 0x00, 0x00, 0x00, 0xFC, 0x14,
233 | 0x00, 0x00, 0xF0, 0x10, 0xF0,
234 | 0x10, 0x10, 0xFF, 0x10, 0xFF,
235 | 0x14, 0x14, 0x14, 0xFF, 0x14,
236 | 0x10, 0x10, 0x10, 0x1F, 0x00,
237 | 0x00, 0x00, 0x00, 0xF0, 0x10,
238 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
239 | 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
240 | 0xFF, 0xFF, 0xFF, 0x00, 0x00,
241 | 0x00, 0x00, 0x00, 0xFF, 0xFF,
242 | 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
243 | 0x38, 0x44, 0x44, 0x38, 0x44,
244 | 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta
245 | 0x7E, 0x02, 0x02, 0x06, 0x06,
246 | 0x02, 0x7E, 0x02, 0x7E, 0x02,
247 | 0x63, 0x55, 0x49, 0x41, 0x63,
248 | 0x38, 0x44, 0x44, 0x3C, 0x04,
249 | 0x40, 0x7E, 0x20, 0x1E, 0x20,
250 | 0x06, 0x02, 0x7E, 0x02, 0x02,
251 | 0x99, 0xA5, 0xE7, 0xA5, 0x99,
252 | 0x1C, 0x2A, 0x49, 0x2A, 0x1C,
253 | 0x4C, 0x72, 0x01, 0x72, 0x4C,
254 | 0x30, 0x4A, 0x4D, 0x4D, 0x30,
255 | 0x30, 0x48, 0x78, 0x48, 0x30,
256 | 0xBC, 0x62, 0x5A, 0x46, 0x3D,
257 | 0x3E, 0x49, 0x49, 0x49, 0x00,
258 | 0x7E, 0x01, 0x01, 0x01, 0x7E,
259 | 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
260 | 0x44, 0x44, 0x5F, 0x44, 0x44,
261 | 0x40, 0x51, 0x4A, 0x44, 0x40,
262 | 0x40, 0x44, 0x4A, 0x51, 0x40,
263 | 0x00, 0x00, 0xFF, 0x01, 0x03,
264 | 0xE0, 0x80, 0xFF, 0x00, 0x00,
265 | 0x08, 0x08, 0x6B, 0x6B, 0x08,
266 | 0x36, 0x12, 0x36, 0x24, 0x36,
267 | 0x06, 0x0F, 0x09, 0x0F, 0x06,
268 | 0x00, 0x00, 0x18, 0x18, 0x00,
269 | 0x00, 0x00, 0x10, 0x10, 0x00,
270 | 0x30, 0x40, 0xFF, 0x01, 0x01,
271 | 0x00, 0x1F, 0x01, 0x01, 0x1E,
272 | 0x00, 0x19, 0x1D, 0x17, 0x12,
273 | 0x00, 0x3C, 0x3C, 0x3C, 0x3C,
274 | 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP
275 | };
276 | #endif // FONT5X7_H
277 |
--------------------------------------------------------------------------------
/firmware/stepServo/nonvolatile.cpp:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 | #include "nonvolatile.h"
13 | #include "Flash.h" //thanks to Kent Larsen for pointing out the lower case error
14 | #include
15 |
16 |
17 |
18 |
19 | //we use this so we can hard code calibration table
20 | // be sure to set the last word as status flag
21 | // this save time calibrating each time we do a code build
22 | #ifdef NZS_FAST_CAL
23 | __attribute__((__aligned__(FLASH_ROW_SIZE))) const uint16_t NVM_flash[16640]={ //allocates 33280 bytes
24 | #else
25 | __attribute__((__aligned__(FLASH_ROW_SIZE))) const uint16_t NVM_flash[256]={ //allocates 512 bytes
26 | #endif
27 | //insert the getcal command calibration data here
28 | 0xFFFF
29 | };
30 |
31 |
32 |
33 | static_assert (sizeof(nvm_t)CalibrationTable,ptrData,size);
45 | return true;
46 | }
47 |
48 | bool nvmWrite_sPID(float Kp, float Ki, float Kd)
49 | {
50 | PIDparams_t pid;
51 |
52 | pid.Kp=Kp;
53 | pid.Ki=Ki;
54 | pid.Kd=Kd;
55 | pid.parametersVaild=true;
56 |
57 | flashWrite((void *)&NVM->sPID,&pid,sizeof(pid));
58 | return true;
59 | }
60 |
61 | bool nvmWrite_vPID(float Kp, float Ki, float Kd)
62 | {
63 | PIDparams_t pid;
64 |
65 | pid.Kp=Kp;
66 | pid.Ki=Ki;
67 | pid.Kd=Kd;
68 | pid.parametersVaild=true;
69 |
70 | flashWrite((void *)&NVM->vPID,&pid,sizeof(pid));
71 | return true;
72 | }
73 |
74 | bool nvmWrite_pPID(float Kp, float Ki, float Kd)
75 | {
76 | PIDparams_t pid;
77 |
78 | pid.Kp=Kp;
79 | pid.Ki=Ki;
80 | pid.Kd=Kd;
81 | pid.parametersVaild=true;
82 |
83 | flashWrite((void *)&NVM->pPID,&pid,sizeof(pid));
84 | return true;
85 | }
86 |
87 | bool nvmWriteSystemParms(SystemParams_t &systemParams)
88 | {
89 | systemParams.parametersVaild=true;
90 |
91 | flashWrite((void *)&NVM->SystemParams,&systemParams,sizeof(systemParams));
92 | return true;
93 | }
94 |
95 | bool nvmWriteMotorParms(MotorParams_t &motorParams)
96 | {
97 | motorParams.parametersVaild=true;
98 |
99 | flashWrite((void *)&NVM->motorParams,&motorParams,sizeof(motorParams));
100 | return true;
101 | }
102 |
103 | bool nvmErase(void)
104 | {
105 | bool data=false;
106 | uint16_t cs=0;
107 |
108 | flashWrite((void *)&NVM->CalibrationTable.status,&data,sizeof(data));
109 | flashWrite((void *)&NVM->sPID.parametersVaild ,&data,sizeof(data));
110 | flashWrite((void *)&NVM->vPID.parametersVaild ,&data,sizeof(data));
111 | flashWrite((void *)&NVM->pPID.parametersVaild ,&data,sizeof(data));
112 | flashWrite((void *)&NVM->motorParams.parametersVaild ,&data,sizeof(data));
113 | flashWrite((void *)&NVM->SystemParams.parametersVaild ,&data,sizeof(data));
114 | #ifdef NZS_FAST_CAL
115 | flashWrite((void *)&NVM->FastCal.checkSum,&cs,sizeof(cs));
116 | #endif
117 | }
118 |
119 |
--------------------------------------------------------------------------------
/firmware/stepServo/nonvolatile.h:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 | #ifndef __NONVOLATILE__H__
13 | #define __NONVOLATILE__H__
14 |
15 | #include "calibration.h"
16 | #include "board.h"
17 |
18 |
19 | typedef struct {
20 | float Kp;
21 | float Ki;
22 | float Kd;
23 | bool parametersVaild;
24 | } PIDparams_t;
25 |
26 | typedef struct {
27 | int32_t currentMa; //maximum current for the motor
28 | int32_t currentHoldMa; //hold current for the motor
29 | bool motorWiring; //forward wiring of motor or reverse
30 | int32_t fullStepsPerRotation; //how many full steps per rotation is the motor
31 | bool parametersVaild;
32 | } MotorParams_t;
33 |
34 | typedef struct {
35 | int32_t microsteps; //number of microsteps on the dir/step pin interface from host
36 | RotationDir_t dirPinRotation; //is the direction pin high for clockwise or counterClockWise
37 | int32_t errorLimit; //error limit before error pin asserts 65536==360degrees
38 | ErrorPinMode_t errorPinMode; //is error pin used for enable, error, or bidirectional
39 | feedbackCtrl_t controllerMode; //feedback mode for the controller
40 | bool parametersVaild;
41 | } SystemParams_t;
42 |
43 | #ifdef NZS_FAST_CAL
44 | typedef struct {
45 | uint16_t angle[16384];
46 | uint16_t checkSum;
47 | }FastCal_t;
48 | #endif
49 |
50 | typedef struct {
51 | FlashCalData_t CalibrationTable;
52 | __attribute__((__aligned__(8))) PIDparams_t sPID; //simple PID parameters
53 | __attribute__((__aligned__(8))) PIDparams_t pPID; //position PID parameters
54 | __attribute__((__aligned__(8))) PIDparams_t vPID; //velocity PID parameters
55 | __attribute__((__aligned__(8))) SystemParams_t SystemParams;
56 | __attribute__((__aligned__(8))) MotorParams_t motorParams;
57 | #ifdef NZS_FAST_CAL
58 | __attribute__((__aligned__(8))) FastCal_t FastCal;
59 | #endif
60 | } nvm_t;
61 |
62 | #ifdef NZS_FAST_CAL
63 | extern const uint16_t NVM_flash[16640];
64 | #else
65 | extern const uint16_t NVM_flash[256];
66 | #endif
67 | #define NVM ((const nvm_t *)NVM_flash)
68 |
69 | bool nvmWriteCalTable(void *ptrData, uint32_t size);
70 | bool nvmWrite_sPID(float Kp, float Ki, float Kd);
71 | bool nvmWrite_pPID(float Kp, float Ki, float Kd);
72 | bool nvmWrite_vPID(float Kp, float Ki, float Kd);
73 | bool nvmWriteSystemParms(SystemParams_t &systemParams);
74 | bool nvmWriteMotorParms(MotorParams_t &motorParams);
75 | bool nvmErase(void);
76 |
77 | #endif // __NONVOLATILE__H__
78 |
--------------------------------------------------------------------------------
/firmware/stepServo/nzs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * nzs.h
3 | *
4 | * Created on: Dec 8, 2016
5 | * Author: trampas
6 | *
7 | * Misfit Tech invests time and resources providing this open source code,
8 | * please support Misfit Tech and open-source hardware by purchasing
9 | * products from Misfit Tech, www.misifittech.net!
10 | *
11 | * Written by Trampas Stern for Misfit Tech.
12 | * BSD license, check license.txt for more information
13 | * All text above, must be included in any redistribution
14 | *********************************************************************/
15 |
16 | #ifndef NZS_H_
17 | #define NZS_H_
18 |
19 | #include "board.h"
20 | #include "nzs_lcd.h"
21 | #include "stepper_controller.h"
22 | #include "planner.h"
23 |
24 | typedef struct
25 | {
26 | int64_t angle;
27 | uint16_t encoderAngle;
28 | uint8_t valid;
29 | }eepromData_t;
30 |
31 | class NZS //nano Zero Stepper
32 | {
33 |
34 | public:
35 | void begin(void);
36 | void loop(void);
37 |
38 | };
39 |
40 |
41 | #endif /* NZS_H_ */
42 |
--------------------------------------------------------------------------------
/firmware/stepServo/nzs_lcd.h:
--------------------------------------------------------------------------------
1 | /*
2 | * nzs_lcd.h
3 | *
4 | * Created on: Dec 8, 2016
5 | * Author: trampas
6 | *
7 | *
8 | * Misfit Tech invests time and resources providing this open source code,
9 | * please support Misfit Tech and open-source hardware by purchasing
10 | * products from Misfit Tech, www.misifittech.net!
11 | *
12 | * Written by Trampas Stern for Misfit Tech.
13 | * BSD license, check license.txt for more information
14 | * All text above, must be included in any redistribution
15 | *********************************************************************/
16 |
17 | #ifndef NZS_LCD_H_
18 | #define NZS_LCD_H_
19 |
20 | #include "Arduino.h"
21 | #include "syslog.h"
22 | #include "board.h"
23 | #include "stepper_controller.h"
24 |
25 | #include "Adafruit_GFX.h"
26 | #include "Adafruit_SSD1306.h"
27 | #include "gfxfont.h"
28 |
29 |
30 | typedef struct {
31 | char str[15];
32 | } options_t;
33 |
34 | typedef struct {
35 | char str[15];
36 |
37 | //only one of the following should be not null
38 | int (*func)(int argc, char *argv[]);
39 | options_t *ptrOptions;
40 |
41 | } menuItem_t;
42 |
43 |
44 |
45 |
46 |
47 | class NZS_LCD
48 | {
49 | private:
50 | bool displayEnabled;
51 | Adafruit_SSD1306 display;
52 | StepperCtrl *ptrStepperCtrl;
53 | menuItem_t *ptrMenu;
54 | int32_t menuIndex;
55 | bool menuActive;
56 |
57 | options_t *ptrOptions;
58 | int32_t optionIndex;
59 |
60 | int32_t buttonState;
61 |
62 | void updateLCD(void);
63 | void showMenu(void);
64 | void updateMenu(void);
65 | void showOptions(void);
66 | public:
67 | void forceMenuActive(void);
68 | void setMenu(menuItem_t *pMenu);
69 | void begin(StepperCtrl *ptrStepperCtrl); //sets up the LCD
70 | void process(void); //processes the LCD and updates as needed
71 | void showSplash(void);
72 | void lcdShow(const char *line1, const char *line2,const char *line3);
73 |
74 |
75 | };
76 |
77 |
78 | #endif /* NZS_LCD_H_ */
79 |
--------------------------------------------------------------------------------
/firmware/stepServo/planner.cpp:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 | #include "planner.h"
13 |
14 | #include "board.h"
15 | #include "wiring_private.h"
16 | #include "syslog.h"
17 | #include "angle.h"
18 | #include "Arduino.h"
19 |
20 | #define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.STATUS.bit.SYNCBUSY);
21 |
22 | //define the planner class as being global
23 | Planner SmartPlanner;
24 |
25 | static bool enterTC3CriticalSection()
26 | {
27 | bool state=NVIC_IS_IRQ_ENABLED(TC3_IRQn);
28 | NVIC_DisableIRQ(TC3_IRQn);
29 | return state;
30 | }
31 |
32 | static void exitTC3CriticalSection(bool prevState)
33 | {
34 | if (prevState)
35 | {
36 | NVIC_EnableIRQ(TC3_IRQn);
37 | } //else do nothing
38 | }
39 |
40 |
41 |
42 |
43 | void TC3_Init(void)
44 | {
45 | // Enable GCLK for TC3
46 | GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )) ;
47 | while (GCLK->STATUS.bit.SYNCBUSY);
48 |
49 | TC3->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE; // Disable TCx
50 | WAIT_TC16_REGS_SYNC(TC3) // wait for sync
51 |
52 | TC3->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16; // Set Timer counter Mode to 16 bits
53 | WAIT_TC16_REGS_SYNC(TC3)
54 |
55 | TC3->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ; // Set TC as normal Normal Frq
56 | WAIT_TC16_REGS_SYNC(TC3)
57 |
58 | TC3->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV2; // Set perscaler
59 | WAIT_TC16_REGS_SYNC(TC3)
60 |
61 |
62 | TC3->COUNT16.CC[0].reg = F_CPU/PLANNER_UPDATE_RATE_HZ/2; //divide by two because of prescaler
63 |
64 | WAIT_TC16_REGS_SYNC(TC3)
65 |
66 |
67 | TC3->COUNT16.INTENSET.reg = 0; // disable all interrupts
68 | TC3->COUNT16.INTENSET.bit.OVF = 1; // enable overfollow
69 |
70 |
71 |
72 | NVIC_SetPriority(TC3_IRQn, 3);
73 |
74 |
75 | // Enable InterruptVector
76 | NVIC_EnableIRQ(TC3_IRQn);
77 |
78 |
79 | // Enable TC
80 | TC3->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
81 | WAIT_TC16_REGS_SYNC(TC3);
82 | }
83 |
84 |
85 | void TC3_Handler(void)
86 | {
87 | //do the planner tick
88 | SmartPlanner.tick();
89 | //SerialUSB.println('x');
90 | TC3->COUNT16.INTFLAG.bit.OVF = 1; //clear interrupt by writing 1 to flag
91 | }
92 |
93 | void Planner::begin(StepperCtrl *ptrStepper)
94 | {
95 |
96 | ptrStepperCtrl=ptrStepper;
97 | currentMode=PLANNER_NONE;
98 | //setup the timer and interrupt as the last thing
99 | TC3_Init();
100 | }
101 |
102 | void Planner::tick(void)
103 | {
104 | if (currentMode == PLANNER_NONE)
105 | {
106 | return; //do nothing
107 | }
108 |
109 | if (PLANNER_CV == currentMode)
110 | {
111 | // SerialUSB.println(currentSetAngle);
112 | // SerialUSB.println(endAngle);
113 | // SerialUSB.println(tickIncrement);
114 | // SerialUSB.println(fabs(currentSetAngle-endAngle));
115 | // SerialUSB.println(fabs(tickIncrement*2));
116 | // SerialUSB.println();
117 | int32_t x;
118 | if (fabs(currentSetAngle-endAngle) >= fabs(tickIncrement))
119 | {
120 | currentSetAngle+=tickIncrement;
121 | x=ANGLE_FROM_DEGREES(currentSetAngle);
122 | ptrStepperCtrl->moveToAbsAngle(x);
123 | }else
124 | {
125 | //we are done, make sure we end at the right point
126 | //SerialUSB.println("done");
127 | x=ANGLE_FROM_DEGREES(endAngle);
128 | ptrStepperCtrl->moveToAbsAngle(x);
129 | currentMode=PLANNER_NONE;
130 | }
131 | }
132 |
133 |
134 | }
135 |
136 | void Planner::stop(void)
137 | {
138 | bool state;
139 | state = enterTC3CriticalSection();
140 | currentMode=PLANNER_NONE;
141 | exitTC3CriticalSection(state);
142 | }
143 |
144 | bool Planner::moveConstantVelocity(float finalAngle, float rpm)
145 | {
146 | bool state;
147 | state = enterTC3CriticalSection();
148 |
149 | //first determine if operation is in progress
150 | if (PLANNER_NONE != currentMode)
151 | {
152 | //we are in operation return false
153 | SerialUSB.println("planner operational");
154 | exitTC3CriticalSection(state);
155 | return false;
156 | }
157 |
158 | //get current posistion
159 | startAngle = ANGLE_T0_DEGREES(ptrStepperCtrl->getCurrentAngle());
160 |
161 | //deterime the tick increment
162 | tickIncrement=360.0*fabs(rpm)/60/PLANNER_UPDATE_RATE_HZ;
163 |
164 |
165 |
166 | //set the desired end angle
167 | endAngle=finalAngle;
168 |
169 |
170 | //set the current angle
171 | currentSetAngle=startAngle;
172 |
173 | if (startAngle>endAngle)
174 | {
175 | SerialUSB.println("reverse");
176 | tickIncrement=-tickIncrement;
177 | }
178 |
179 | // SerialUSB.println(currentSetAngle);
180 | // SerialUSB.println(endAngle);
181 | // SerialUSB.println(tickIncrement);
182 | // SerialUSB.println();
183 |
184 | currentMode=PLANNER_CV;
185 |
186 | exitTC3CriticalSection(state);
187 | return true;
188 | }
189 |
--------------------------------------------------------------------------------
/firmware/stepServo/planner.h:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 |
13 | /*
14 | * This file implements a trajectory planner for use with serial
15 | * interface. It allows the smart stepper to move at constant velocity.
16 | * Additionally you can move to some location at constant velocity or
17 | * with a trajectory curve
18 | */
19 |
20 | #ifndef PLANNER_H_
21 | #define PLANNER_H_
22 | #include "board.h"
23 | #include "stepper_controller.h"
24 |
25 | #define PLANNER_UPDATE_RATE_HZ (3000UL) //how often planner updates PID
26 |
27 | typedef enum {
28 | PLANNER_NONE =0,
29 | PLANNER_CV =1, //constant velocity
30 | //PLANNER_CA =2, //constant accleration
31 | //PLANNER_S_CURVE =3, //s-curve move
32 | } PlannerMode;
33 | class Planner
34 | {
35 | private:
36 | StepperCtrl *ptrStepperCtrl;
37 | volatile PlannerMode currentMode=PLANNER_NONE;
38 | //todo we should not use floating point, rather use "Angle"
39 | volatile float endAngle;
40 | volatile float startAngle;
41 | volatile float currentSetAngle;
42 | volatile float tickIncrement;
43 |
44 | public:
45 | void begin(StepperCtrl *ptrStepper);
46 | bool moveConstantVelocity(float finalAngle, float rpm); //moves to the final location at a constant RPM
47 | void tick(void); //this is called on regulat tick interval
48 | void stop(void);
49 | bool done(void) {return currentMode==PLANNER_NONE;}
50 | };
51 |
52 |
53 | extern Planner SmartPlanner;
54 |
55 |
56 | #endif /* PLANNER_H_ */
57 |
--------------------------------------------------------------------------------
/firmware/stepServo/sine.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * since.cpp
3 | *
4 | * Created on: Dec 24, 2016
5 | * Author: tstern
6 | *
7 | * Misfit Tech invests time and resources providing this open source code,
8 | * please support Misfit Tech and open-source hardware by purchasing
9 | * products from Misfit Tech, www.misifittech.net!
10 | *
11 | * Written by Trampas Stern for Misfit Tech.
12 | * BSD license, check license.txt for more information
13 | * All text above, must be included in any redistribution
14 | *********************************************************************/
15 |
16 | #include "sine.h"
17 |
18 | #pragma GCC push_options
19 | #pragma GCC optimize ("-Ofast")
20 |
21 | #ifdef NZS_FAST_SINE
22 | static const int16_t sineTable[1280]={
23 | 0,201,402,603,804,1005,1206,1407,1608,1808,2009,2210,2410,2611,2811,3011,
24 | 3212,3412,3611,3811,4011,4210,4410,4609,4808,5007,5205,5404,5602,5800,5998,6195,
25 | 6392,6589,6786,6983,7179,7375,7571,7766,7962,8156,8351,8545,8739,8933,9126,9319,
26 | 9512,9704,9896,10087,10278,10469,10659,10849,11039,11228,11417,11605,11793,11980,12167,12353,
27 | 12539,12725,12910,13094,13278,13462,13645,13828,14010,14191,14372,14553,14732,14912,15090,15269,
28 | 15446,15623,15800,15976,16151,16325,16499,16673,16846,17018,17189,17360,17530,17700,17869,18037,
29 | 18204,18371,18537,18703,18868,19032,19195,19357,19519,19680,19841,20000,20159,20317,20475,20631,
30 | 20787,20942,21097,21250,21403,21554,21705,21856,22005,22154,22301,22448,22594,22739,22884,23027,
31 | 23170,23312,23452,23592,23732,23870,24007,24143,24279,24413,24547,24680,24812,24942,25072,25201,
32 | 25329,25456,25583,25708,25832,25955,26077,26199,26319,26438,26556,26674,26790,26905,27019,27133,
33 | 27245,27356,27466,27575,27683,27791,27897,28001,28105,28208,28310,28411,28510,28609,28706,28803,
34 | 28898,28992,29085,29178,29268,29358,29447,29535,29621,29707,29791,29874,29956,30037,30117,30195,
35 | 30273,30349,30425,30499,30572,30643,30714,30783,30852,30919,30985,31050,31113,31176,31237,31297,
36 | 31356,31414,31471,31526,31580,31633,31685,31736,31785,31834,31881,31926,31971,32015,32057,32098,
37 | 32138,32176,32214,32250,32285,32319,32351,32382,32413,32441,32469,32496,32521,32545,32568,32589,
38 | 32609,32629,32646,32663,32678,32693,32706,32717,32728,32737,32745,32752,32757,32762,32765,32767,
39 | 32767,32767,32765,32762,32757,32752,32745,32737,32728,32717,32706,32693,32678,32663,32646,32629,
40 | 32609,32589,32568,32545,32521,32496,32469,32441,32413,32382,32351,32319,32285,32250,32214,32176,
41 | 32138,32098,32057,32015,31971,31926,31881,31834,31785,31736,31685,31633,31580,31526,31471,31414,
42 | 31356,31297,31237,31176,31113,31050,30985,30919,30852,30783,30714,30643,30572,30499,30425,30349,
43 | 30273,30195,30117,30037,29956,29874,29791,29707,29621,29535,29447,29358,29268,29178,29085,28992,
44 | 28898,28803,28706,28609,28510,28411,28310,28208,28105,28001,27897,27791,27683,27575,27466,27356,
45 | 27245,27133,27019,26905,26790,26674,26556,26438,26319,26199,26077,25955,25832,25708,25583,25456,
46 | 25329,25201,25072,24942,24812,24680,24547,24413,24279,24143,24007,23870,23732,23592,23452,23312,
47 | 23170,23027,22884,22739,22594,22448,22301,22154,22005,21856,21705,21554,21403,21250,21097,20942,
48 | 20787,20631,20475,20317,20159,20000,19841,19680,19519,19357,19195,19032,18868,18703,18537,18371,
49 | 18204,18037,17869,17700,17530,17360,17189,17018,16846,16673,16499,16325,16151,15976,15800,15623,
50 | 15446,15269,15090,14912,14732,14553,14372,14191,14010,13828,13645,13462,13278,13094,12910,12725,
51 | 12539,12353,12167,11980,11793,11605,11417,11228,11039,10849,10659,10469,10278,10087,9896,9704,
52 | 9512,9319,9126,8933,8739,8545,8351,8156,7962,7766,7571,7375,7179,6983,6786,6589,
53 | 6392,6195,5998,5800,5602,5404,5205,5007,4808,4609,4410,4210,4011,3811,3611,3412,
54 | 3212,3011,2811,2611,2410,2210,2009,1808,1608,1407,1206,1005,804,603,402,201,
55 | 0,-201,-402,-603,-804,-1005,-1206,-1407,-1608,-1809,-2010,-2210,-2411,-2611,-2812,-3012,
56 | -3212,-3412,-3612,-3812,-4011,-4211,-4410,-4609,-4808,-5007,-5206,-5404,-5602,-5800,-5998,-6196,
57 | -6393,-6590,-6787,-6983,-7180,-7376,-7571,-7767,-7962,-8157,-8352,-8546,-8740,-8933,-9127,-9320,
58 | -9512,-9704,-9896,-10088,-10279,-10470,-10660,-10850,-11039,-11228,-11417,-11605,-11793,-11980,-12167,-12354,
59 | -12540,-12725,-12910,-13095,-13279,-13463,-13646,-13828,-14010,-14192,-14373,-14553,-14733,-14912,-15091,-15269,
60 | -15447,-15624,-15800,-15976,-16151,-16326,-16500,-16673,-16846,-17018,-17190,-17361,-17531,-17700,-17869,-18037,
61 | -18205,-18372,-18538,-18703,-18868,-19032,-19195,-19358,-19520,-19681,-19841,-20001,-20160,-20318,-20475,-20632,
62 | -20788,-20943,-21097,-21250,-21403,-21555,-21706,-21856,-22006,-22154,-22302,-22449,-22595,-22740,-22884,-23028,
63 | -23170,-23312,-23453,-23593,-23732,-23870,-24007,-24144,-24279,-24414,-24548,-24680,-24812,-24943,-25073,-25202,
64 | -25330,-25457,-25583,-25708,-25832,-25956,-26078,-26199,-26319,-26439,-26557,-26674,-26790,-26906,-27020,-27133,
65 | -27245,-27357,-27467,-27576,-27684,-27791,-27897,-28002,-28106,-28209,-28310,-28411,-28511,-28609,-28707,-28803,
66 | -28899,-28993,-29086,-29178,-29269,-29359,-29448,-29535,-29622,-29707,-29791,-29875,-29957,-30038,-30117,-30196,
67 | -30273,-30350,-30425,-30499,-30572,-30644,-30715,-30784,-30852,-30919,-30985,-31050,-31114,-31176,-31238,-31298,
68 | -31357,-31415,-31471,-31527,-31581,-31634,-31686,-31736,-31786,-31834,-31881,-31927,-31972,-32015,-32057,-32098,
69 | -32138,-32177,-32214,-32250,-32285,-32319,-32352,-32383,-32413,-32442,-32470,-32496,-32521,-32545,-32568,-32590,
70 | -32610,-32629,-32647,-32664,-32679,-32693,-32706,-32718,-32728,-32738,-32746,-32752,-32758,-32762,-32765,-32767,
71 | -32768,-32767,-32765,-32762,-32758,-32752,-32746,-32738,-32728,-32718,-32706,-32693,-32679,-32664,-32647,-32629,
72 | -32610,-32590,-32568,-32545,-32521,-32496,-32470,-32442,-32413,-32383,-32352,-32319,-32285,-32250,-32214,-32177,
73 | -32138,-32098,-32057,-32015,-31972,-31927,-31881,-31834,-31786,-31736,-31686,-31634,-31581,-31527,-31471,-31415,
74 | -31357,-31298,-31238,-31176,-31114,-31050,-30985,-30919,-30852,-30784,-30715,-30644,-30572,-30499,-30425,-30350,
75 | -30273,-30196,-30117,-30038,-29957,-29875,-29791,-29707,-29622,-29535,-29448,-29359,-29269,-29178,-29086,-28993,
76 | -28899,-28803,-28707,-28609,-28511,-28411,-28310,-28209,-28106,-28002,-27897,-27791,-27684,-27576,-27467,-27357,
77 | -27245,-27133,-27020,-26906,-26790,-26674,-26557,-26439,-26319,-26199,-26078,-25956,-25832,-25708,-25583,-25457,
78 | -25330,-25202,-25073,-24943,-24812,-24680,-24548,-24414,-24279,-24144,-24007,-23870,-23732,-23593,-23453,-23312,
79 | -23170,-23028,-22884,-22740,-22595,-22449,-22302,-22154,-22006,-21856,-21706,-21555,-21403,-21250,-21097,-20943,
80 | -20788,-20632,-20475,-20318,-20160,-20001,-19841,-19681,-19520,-19358,-19195,-19032,-18868,-18703,-18538,-18372,
81 | -18205,-18037,-17869,-17700,-17531,-17361,-17190,-17018,-16846,-16673,-16500,-16326,-16151,-15976,-15800,-15624,
82 | -15447,-15269,-15091,-14912,-14733,-14553,-14373,-14192,-14010,-13828,-13646,-13463,-13279,-13095,-12910,-12725,
83 | -12540,-12354,-12167,-11980,-11793,-11605,-11417,-11228,-11039,-10850,-10660,-10470,-10279,-10088,-9896,-9704,
84 | -9512,-9320,-9127,-8933,-8740,-8546,-8352,-8157,-7962,-7767,-7571,-7376,-7180,-6983,-6787,-6590,
85 | -6393,-6196,-5998,-5800,-5602,-5404,-5206,-5007,-4808,-4609,-4410,-4211,-4011,-3812,-3612,-3412,
86 | -3212,-3012,-2812,-2611,-2411,-2210,-2010,-1809,-1608,-1407,-1206,-1005,-804,-603,-402,-201,
87 | 0,201,402,603,804,1005,1206,1407,1608,1808,2009,2210,2410,2611,2811,3011,
88 | 3212,3412,3611,3811,4011,4210,4410,4609,4808,5007,5205,5404,5602,5800,5998,6195,
89 | 6392,6589,6786,6983,7179,7375,7571,7766,7962,8156,8351,8545,8739,8933,9126,9319,
90 | 9512,9704,9896,10087,10278,10469,10659,10849,11039,11228,11417,11605,11793,11980,12167,12353,
91 | 12539,12725,12910,13094,13278,13462,13645,13828,14010,14191,14372,14553,14732,14912,15090,15269,
92 | 15446,15623,15800,15976,16151,16325,16499,16673,16846,17018,17189,17360,17530,17700,17869,18037,
93 | 18204,18371,18537,18703,18868,19032,19195,19357,19519,19680,19841,20000,20159,20317,20475,20631,
94 | 20787,20942,21097,21250,21403,21554,21705,21856,22005,22154,22301,22448,22594,22739,22884,23027,
95 | 23170,23312,23452,23592,23732,23870,24007,24143,24279,24413,24547,24680,24812,24942,25072,25201,
96 | 25329,25456,25583,25708,25832,25955,26077,26199,26319,26438,26556,26674,26790,26905,27019,27133,
97 | 27245,27356,27466,27575,27683,27791,27897,28001,28105,28208,28310,28411,28510,28609,28706,28803,
98 | 28898,28992,29085,29178,29268,29358,29447,29535,29621,29707,29791,29874,29956,30037,30117,30195,
99 | 30273,30349,30425,30499,30572,30643,30714,30783,30852,30919,30985,31050,31113,31176,31237,31297,
100 | 31356,31414,31471,31526,31580,31633,31685,31736,31785,31834,31881,31926,31971,32015,32057,32098,
101 | 32138,32176,32214,32250,32285,32319,32351,32382,32413,32441,32469,32496,32521,32545,32568,32589,
102 | 32609,32629,32646,32663,32678,32693,32706,32717,32728,32737,32745,32752,32757,32762,32765,32767
103 | };
104 | #else
105 | static const uint16_t sineTable[257]={
106 | 0,402,804,1206,1608,2010,2412,2814,3216,3617,4019,4420,4821,5222,5623,6023,
107 | 6424,6824,7223,7623,8022,8421,8820,9218,9616,10014,10411,10808,11204,11600,11996,12391,
108 | 12785,13179,13573,13966,14359,14751,15142,15533,15924,16313,16703,17091,17479,17866,18253,18639,
109 | 19024,19408,19792,20175,20557,20939,21319,21699,22078,22456,22834,23210,23586,23960,24334,24707,
110 | 25079,25450,25820,26189,26557,26925,27291,27656,28020,28383,28745,29106,29465,29824,30181,30538,
111 | 30893,31247,31600,31952,32302,32651,32999,33346,33692,34036,34379,34721,35061,35400,35738,36074,
112 | 36409,36743,37075,37406,37736,38064,38390,38715,39039,39361,39682,40001,40319,40635,40950,41263,
113 | 41575,41885,42194,42500,42806,43109,43411,43712,44011,44308,44603,44897,45189,45479,45768,46055,
114 | 46340,46624,46905,47185,47464,47740,48014,48287,48558,48827,49095,49360,49624,49885,50145,50403,
115 | 50659,50913,51166,51416,51664,51911,52155,52398,52638,52877,53113,53348,53580,53811,54039,54266,
116 | 54490,54713,54933,55151,55367,55582,55794,56003,56211,56417,56620,56822,57021,57218,57413,57606,
117 | 57797,57985,58171,58356,58537,58717,58895,59070,59243,59414,59582,59749,59913,60075,60234,60391,
118 | 60546,60699,60850,60998,61144,61287,61429,61567,61704,61838,61970,62100,62227,62352,62475,62595,
119 | 62713,62829,62942,63053,63161,63267,63371,63472,63571,63668,63762,63853,63943,64030,64114,64196,
120 | 64276,64353,64428,64500,64570,64638,64703,64765,64826,64883,64939,64992,65042,65090,65136,65179,
121 | 65219,65258,65293,65327,65357,65386,65412,65435,65456,65475,65491,65504,65515,65524,65530,65534,
122 | 65535,
123 | };
124 | #endif
125 |
126 |
127 |
128 |
129 | int16_t sine(uint16_t angle)
130 | {
131 | #ifdef NZS_FAST_SINE
132 | return sineTable[angle];
133 | #else
134 | int sign=1;
135 | int16_t ret;
136 | //our sine table has 1024 points per rotation so convert angle to closest step
137 |
138 | if (angle>=(SINE_STEPS/2))
139 | {
140 | sign=-1;
141 | }
142 |
143 | angle=angle % (SINE_STEPS/2); //limit to 0-180 as sign takes care of 180-360
144 |
145 | if (angle>(SINE_STEPS/4-1)) //if we are greater than 90 we need to look up table backwards
146 | {
147 | angle=(SINE_STEPS/2)-angle;
148 | }
149 |
150 | ret=(int16_t)(sineTable[angle]/2)*sign;
151 | return ret;
152 | #endif
153 | }
154 |
155 | int16_t cosine(uint16_t angle)
156 | {
157 | #ifdef NZS_FAST_SINE
158 | angle=angle+(SINE_STEPS/4);
159 | return sineTable[angle];
160 | #else
161 |
162 | int sign=1;
163 | int16_t ret;
164 | //our sine table has 1024 points per rotation so convert angle to closest step
165 |
166 | if (angle>=(SINE_STEPS/4) and angle<(3*(SINE_STEPS/4)))
167 | {
168 | sign=-1;
169 | }
170 |
171 | angle=angle % (SINE_STEPS/2); //limit to 0-180 as sign takes care of 180-360
172 |
173 | if (angle>(SINE_STEPS/4-1)) //if we are greater than 90 we need to look up table backwards
174 | {
175 | angle=(SINE_STEPS/2)-angle;
176 | }
177 |
178 | //for cosine we need 90 degree phase shift
179 | angle=(SINE_STEPS/4)-angle;
180 |
181 | ret=(int16_t)(sineTable[angle]/2)*sign;
182 | return ret;
183 | #endif
184 | }
185 |
186 | #pragma GCC pop_options
187 |
--------------------------------------------------------------------------------
/firmware/stepServo/sine.h:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * sine.h
3 | *
4 | * Created on: Dec 24, 2016
5 | * Author: tstern
6 | *
7 | * Misfit Tech invests time and resources providing this open source code,
8 | * please support Misfit Tech and open-source hardware by purchasing
9 | * products from Misfit Tech, www.misifittech.net!
10 | *
11 | * Written by Trampas Stern for Misfit Tech.
12 | * BSD license, check license.txt for more information
13 | * All text above, must be included in any redistribution
14 | *********************************************************************/
15 |
16 |
17 | #ifndef SINE_H_
18 | #define SINE_H_
19 |
20 | #include "board.h"
21 |
22 | #define SINE_STEPS (1024L)
23 |
24 | #define SINE_MAX ((int32_t)(32768L))
25 |
26 |
27 | int16_t sine(uint16_t angle);
28 | int16_t cosine(uint16_t angle);
29 |
30 |
31 | #endif /* SINE_H_ */
32 |
--------------------------------------------------------------------------------
/firmware/stepServo/stepper_controller.h:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 | #ifndef __STEPPER_CONTROLLER_H__
13 | #define __STEPPER_CONTROLLER_H__
14 |
15 | #include "syslog.h"
16 | #include "board.h"
17 | #include "as5047d.h"
18 | #include "calibration.h"
19 | #include "A4954.h"
20 | #include "A5995.h"
21 | #include "nonvolatile.h"
22 | #include "fet_driver.h" //for the NEMA23 10A
23 |
24 |
25 | #define N_DATA (1024)
26 |
27 |
28 | typedef enum {
29 | STEPCTRL_NO_ERROR=0,
30 | STEPCTRL_NO_POWER=1, //no power to motor
31 | STEPCTRL_NO_CAL=2, //calibration not set
32 | STEPCTRL_NO_ENCODER=3, //encoder not working
33 | } stepCtrlError_t;
34 |
35 |
36 | typedef struct {
37 | int32_t Kp;
38 | int32_t Ki;
39 | int32_t Kd;
40 | } PID_t;
41 |
42 |
43 | typedef __attribute__((packed, aligned(4))) struct {
44 | int32_t microSecs;
45 | int32_t desiredLoc;
46 | int32_t actualLoc;
47 | int32_t angle;
48 | int32_t ma;
49 | } Location_t;
50 |
51 |
52 | typedef struct {
53 | int32_t angle;
54 | int32_t ma;
55 | }Control_t;
56 |
57 | #define MAX_NUM_LOCATIONS (64) //maximum number of locations to buffer
58 |
59 |
60 | //this scales the PID parameters from Flash to floating point
61 | // to fixed point int32_t values
62 | #define CTRL_PID_SCALING (1024)
63 |
64 | class StepperCtrl
65 | {
66 | private:
67 | volatile bool enableFeedback; //true if we are using PID control algorithm
68 | AS5047D encoder;
69 | #ifdef NEMA_23_10A_HW
70 | FetDriver stepperDriver;
71 | #else
72 | #ifdef A5995_DRIVER
73 | A5995 stepperDriver;
74 | #else
75 | A4954 stepperDriver;
76 | #endif
77 | #endif
78 | uint16_t startUpEncoder;
79 | volatile int32_t ticks=0;
80 | volatile Location_t locs[MAX_NUM_LOCATIONS];
81 | volatile int32_t locReadIndx=0;
82 | volatile int32_t locWriteIndx=0;
83 |
84 | volatile MotorParams_t motorParams;
85 | volatile SystemParams_t systemParams;
86 | volatile bool enabled;
87 |
88 |
89 |
90 | volatile int32_t loopTimeus; //time to run loop in microseconds
91 |
92 | volatile PID_t sPID; //simple control loop PID parameters
93 | volatile PID_t pPID; //positional current based PID control parameters
94 | volatile PID_t vPID; //velocity PID control parameters
95 |
96 | volatile int64_t numSteps; //this is the number of steps we have taken from our start angle
97 |
98 | volatile int32_t loopError;
99 |
100 | volatile int64_t currentLocation; //estimate of the current location from encoder feedback
101 | // the current location lower 16 bits is angle (0-360 degrees in 65536 steps) while upper
102 | // bits is the number of full rotations.
103 |
104 | //this is used for the velocity PID feedback
105 | // units are in Angles/sec where 1 Angle=360deg/65536
106 | volatile int64_t velocity;
107 |
108 | int64_t zeroAngleOffset=0;
109 |
110 |
111 | //volatile int16_t data[N_DATA];
112 |
113 | //does linear interpolation of the encoder calibration table
114 | int32_t getAngleCalibration(int32_t encoderAngle);
115 |
116 | //updates the currentMeasuredAngle with our best guess where we are
117 | Angle sampleAngle(void);
118 | Angle sampleMeanEncoder(int32_t numSamples);
119 |
120 | float measureStepSize(void); //steps motor and estimates step size
121 | uint32_t measureMaxCalibrationError(void);
122 | void setLocationFromEncoder(void);
123 |
124 | void motorReset(void);
125 | void updateStep(int dir, uint16_t steps);
126 |
127 |
128 | bool pidFeedback(int64_t desiredLoc, int64_t currentLoc, Control_t *ptrCtrl);
129 | bool simpleFeedback(int64_t desiredLoc, int64_t currentLoc,Control_t *ptrCtrl);
130 | bool vpidFeedback(int64_t desiredLoc, int64_t currentLoc,Control_t *ptrCtrl);
131 | int64_t getCurrentLocation(void);
132 | int64_t getDesiredLocation(void);
133 | void updateLocTable(int64_t desiredLoc, int64_t currentLoc,Control_t *ptrCtrl);
134 |
135 | int64_t calculatePhasePrediction(int64_t currentLoc);
136 |
137 | public:
138 | uint16_t getStartupEncoder(void) {return startUpEncoder;}
139 | int32_t getLocation(Location_t *ptrLoc);
140 |
141 | Angle getEncoderAngle(void);
142 |
143 | void setAngle(int64_t loc);
144 |
145 | int64_t getZeroAngleOffset(void);
146 | void PrintData(void);
147 | void setVelocity(int64_t vel); //set velocity for vPID mode
148 | int64_t getVelocity(void);
149 | int32_t getLoopError(void) {return loopError;}; //assume atomic read
150 |
151 | bool calibrationValid(void) { return calTable.calValid();} //returns true if calbiration is good
152 |
153 | void updateParamsFromNVM(void); //updates the parameters from NVM
154 | CalibrationTable calTable;
155 | //void printData(void);
156 |
157 | bool calibrateEncoder(void); //do manual calibration of the encoder
158 | Angle maxCalibrationError(void); //measures the maximum calibration error as an angle
159 |
160 | void moveToAbsAngle(int32_t a);
161 | void moveToAngle(int32_t a, uint32_t ma);
162 |
163 | stepCtrlError_t begin(void); //returns false if we can not use motor
164 |
165 | bool processFeedback(void); // does the feedback loop
166 |
167 | feedbackCtrl_t getControlMode(void) { return systemParams.controllerMode;};
168 |
169 | void requestStep(int dir, uint16_t steps); //requests a step, if feedback controller is off motor does not move
170 |
171 | void feedback(bool enable);
172 | bool getFeedback(void) {return enableFeedback;}
173 |
174 | void encoderDiagnostics(char *ptrStr);
175 | int32_t measureError(void);
176 |
177 | //these two functions are compenstated by the zero offset
178 | int64_t getCurrentAngle(void);
179 | int64_t getDesiredAngle(void);
180 |
181 | void move(int dir, uint16_t steps); //forces motor to move even if feedback controller is turned off.
182 | void enable(bool enable);
183 | bool getEnable(void) {return enabled;}
184 |
185 | int32_t getLoopTime(void) { return loopTimeus;}
186 |
187 | void PID_Autotune(void);
188 | void setZero(void);
189 | };
190 |
191 | #endif //__STEPPER_CONTROLLER_H__
192 |
193 |
--------------------------------------------------------------------------------
/firmware/stepServo/stepper_nano_zero.ino:
--------------------------------------------------------------------------------
1 | #include "nzs.h"
2 |
3 | NZS nzs;
4 |
5 |
6 | void setup() {
7 | nzs.begin();
8 | }
9 |
10 |
11 | void loop() {
12 | nzs.loop();
13 | }
14 |
--------------------------------------------------------------------------------
/firmware/stepServo/syslog.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * syslog.c
3 | *
4 | * Created on: Sep 14, 2011
5 | * Author: trampas.stern
6 | *
7 | * Misfit Tech invests time and resources providing this open source code,
8 | * please support Misfit Tech and open-source hardware by purchasing
9 | * products from Misfit Tech, www.misifittech.net!
10 | *
11 | * Written by Trampas Stern for Misfit Tech.
12 | * BSD license, check license.txt for more information
13 | * All text above, must be included in any redistribution
14 | *********************************************************************/
15 | #include "syslog.h"
16 | #include
17 |
18 |
19 | #define ANSI_WHITE "\033[37m"
20 | #define ANSI_NORMAL "\033[0m"
21 | #define ANSI_BLINK "\033[5m"
22 | #define ANSI_BLUE "\033[34m"
23 | #define ANSI_MAGENTA "\033[35m"
24 | #define ANSI_CYAN "\033[36m"
25 | #define ANSI_WHITE "\033[37m"
26 | #define ANSI_RED "\033[31m"
27 | #define ANSI_GREEN "\033[32m"
28 | #define ANSI_PINK "\033[35m\033[1m"
29 | #define ANSI_BROWN "\033[33m"
30 | #define ANSI_YELLOW "\033[33m\033[1m"
31 | #define ANSI_BLACK "\033[30m"
32 | #define ANSI_BELL_AND_RED "\a\033[31m"
33 |
34 | #define NEW_LINE "\n\r"
35 |
36 | Uart *ptrSerial=NULL;
37 | eLogLevel SyslogLevelToWrite;
38 |
39 | static char buffer[SYSLOG_BUFFER_SIZE];
40 | static unsigned int BufIndex=0;
41 |
42 | static int SysLog_Enabled=1;
43 |
44 | int SysLogDisable(void)
45 | {
46 | SysLog_Enabled=0;
47 | return 0;
48 | }
49 |
50 | int SysLogEnable(void)
51 | {
52 | SysLog_Enabled=1;
53 | return 0;
54 | }
55 |
56 | int SysLogIsEnabled(void)
57 | {
58 | return SysLog_Enabled;
59 | }
60 |
61 | void SysLogPuts(const char *ptrStr)
62 | {
63 | if (!SysLog_Enabled)
64 | return;
65 |
66 | if (NULL == ptrSerial)
67 | {
68 | while(*ptrStr)
69 | {
70 |
71 | SYSLOG_PUTC(*ptrStr);
72 | ptrStr++;
73 | }
74 | } else
75 | {
76 | ptrSerial->write(ptrStr);
77 | }
78 | }
79 |
80 | int SysLogInitDone=0;
81 | void SysLogInit(Uart *ptrSerialObj, eLogLevel LevelToWrite)
82 | {
83 | ptrSerial=ptrSerialObj;
84 | SyslogLevelToWrite=LevelToWrite;
85 |
86 | SysLogInitDone=1;
87 | BufIndex=0;
88 | memset(buffer,0,SYSLOG_BUFFER_SIZE);
89 | }
90 |
91 |
92 | int SysLogProcessing=0; // this is used such that syslog can be reentrent
93 | int SysLogMissed=0;
94 |
95 |
96 | void SysLog(eLogLevel priorty, const char *fmt, ...)
97 | {
98 | //UINT32 ret;
99 | int previousState=SysLog_Enabled;
100 | char vastr[MAX_SYSLOG_STRING]={0};
101 | //char outstr[MAX_SYSLOG_STRING]={0};
102 |
103 |
104 | va_list ap;
105 |
106 | if (SysLogProcessing)
107 | {
108 | //we have a syslog from a syslog call thus return as not much we can do...
109 | //memset(buffer,0,SYSLOG_BUFFER_SIZE);
110 | va_start(ap,fmt);
111 | vsnprintf(&buffer[BufIndex],SYSLOG_BUFFER_SIZE-BufIndex,(char *)fmt,ap);
112 | BufIndex=strlen(buffer);
113 | snprintf(&buffer[BufIndex],SYSLOG_BUFFER_SIZE-BufIndex,NEW_LINE);
114 | BufIndex=strlen(buffer);
115 | SysLogMissed++; //set flag that we missed a call
116 | return;
117 | }
118 |
119 | SysLogProcessing=1;
120 |
121 | //stop the watch dog will doing a SysLog print
122 | Sys_WDogHoldOn();
123 |
124 | if(!SysLogInitDone)
125 | {
126 | SysLogInit(NULL, LOG_WARNING); //not sure who is reseting serial port but before we print set it up
127 | WARNING("You should init SysLog");
128 | //SysLogInitDone=0;
129 | }
130 |
131 | //Send out a * that we missed a SysLog Message before this current message
132 | if (SysLogMissed)
133 | {
134 | //SysLogPuts(ANSI_RED);
135 | SysLogPuts("*** Reentrant Log call possible loss of message(s):");
136 | SysLogPuts(NEW_LINE);
137 | if (BufIndex>0)
138 | {
139 | SysLogPuts(buffer);
140 | memset(buffer,0,SYSLOG_BUFFER_SIZE);
141 | BufIndex=0;
142 | }
143 | //SysLogPuts(ANSI_RED);
144 | SysLogPuts("***********");
145 | SysLogPuts(NEW_LINE);
146 | SysLogMissed=0;
147 | }
148 | memset(vastr,0,MAX_SYSLOG_STRING);
149 | va_start(ap,fmt);
150 | //#ifndef PGM_P
151 | #if 1
152 | vsnprintf(vastr,MAX_SYSLOG_STRING,(char *)fmt,ap);
153 | #else
154 | vsprintf_P(vastr,(const char *)fmt,ap);
155 | #endif
156 | //get time and store in datetimestr if desired
157 | //sprintf(outstr, "[%s] %s\r\n", datetimestr, vastr);
158 |
159 |
160 |
161 | if (priorty<=LOG_ERROR)
162 | {
163 | SysLog_Enabled=1;
164 | SysLogPuts(ANSI_RED);
165 |
166 | }else if (priorty==LOG_DEBUG)
167 | {
168 | SysLogPuts(ANSI_WHITE);
169 | }else if (priorty==LOG_WARNING)
170 | {
171 | SysLogPuts(ANSI_BLUE);
172 | }
173 |
174 | #ifdef RTC_H_
175 | #ifdef TIME_H_
176 | {
177 | struct tm tp;
178 | RTC_Time_s tm;
179 | time_t secs;
180 | char datetimestr[MAX_SYSLOG_STRING]={0};
181 |
182 | RTC_ReadTime(&tm);
183 | secs=tm.seconds;
184 | convertFlexNetTime((time_t *)&secs, &tp);
185 | time_str(datetimestr,&tp);
186 | SysLogPuts(datetimestr);
187 |
188 | if (priorty<=SyslogLevelToWrite && SysLogWriteFunc!=NULL)
189 | {
190 | SysLogWriteFunc(datetimestr,strlen(datetimestr));
191 | }
192 | }
193 | #endif
194 | #endif
195 |
196 | SysLogPuts(vastr);
197 | //
198 | // if (priorty<=SyslogLevelToWrite && SysLogWriteFunc!=NULL)
199 | // {
200 | // SysLogWriteFunc(vastr,strlen(vastr));
201 | // SysLogWriteFunc(NEW_LINE,strlen(NEW_LINE));
202 | // }
203 |
204 |
205 | SysLogPuts(ANSI_NORMAL);
206 | SysLogPuts(NEW_LINE);
207 |
208 |
209 |
210 | if (priorty == LOG_EMERG) {
211 | //you can reboot processor here
212 | }
213 |
214 | //start the watch dog where left off..
215 | Sys_WDogHoldOff();
216 | SysLogProcessing=0;
217 | SysLog_Enabled=previousState;
218 | return;
219 | }
220 |
221 |
--------------------------------------------------------------------------------
/firmware/stepServo/syslog.h:
--------------------------------------------------------------------------------
1 | /*
2 | * syslog.h
3 | *
4 | * Created on: Sep 14, 2011
5 | * Author: trampas.stern
6 | *
7 | * Misfit Tech invests time and resources providing this open source code,
8 | * please support Misfit Tech and open-source hardware by purchasing
9 | * products from Misfit Tech, www.misifittech.net!
10 | *
11 | * Written by Trampas Stern for Misfit Tech.
12 | * BSD license, check license.txt for more information
13 | * All text above, must be included in any redistribution
14 | *********************************************************************/
15 |
16 | #ifndef SYSLOG_H_
17 | #define SYSLOG_H_
18 |
19 | #include
20 | #include
21 | #include
22 | #include "Arduino.h"
23 | #include "variant.h"
24 |
25 | #ifdef __cplusplus
26 | extern "C"
27 | {
28 | #endif // __cplusplus
29 |
30 | #define SYSLOG_BUFFER_SIZE (250)
31 |
32 | #define MAX_SYSLOG_STRING (250)
33 | #define __FILENAME1__ (__builtin_strrchr(__FILE__, '\\') ? __builtin_strrchr(__FILE__, '\\') + 1 : __FILE__)
34 | #define __FILENAME__ (__builtin_strrchr(__FILENAME1__, '/') ? __builtin_strrchr(__FILENAME1__, '/') + 1 : __FILENAME1__)
35 |
36 | #define SYSLOG_WRITE(buffer,nBytes)
37 |
38 | #ifdef CMD_SERIAL_PORT
39 | #define SYSLOG_PUTC(x)
40 | #else
41 | #define SYSLOG_PUTC(x) //SerialUSB.write(x)
42 | #endif
43 |
44 | #define Sys_WDogHoldOn()
45 | #define Sys_WDogHoldOff()
46 | /*
47 | * priorities/facilities are encoded into a single 32-bit quantity, where the
48 | * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
49 | * (0-big number). Both the priorities and the facilities map roughly
50 | * one-to-one to strings in the syslogd(8) source code. This mapping is
51 | * included in this file.
52 | *
53 | * priorities (these are ordered)
54 | */
55 |
56 | typedef enum _eLogLevel {
57 | LOG_EMERG = 0, // system is unusable
58 | LOG_ALERT = 1, // action must be taken immediately
59 | LOG_CRIT = 2, // critical conditions
60 | LOG_ERROR = 3, // error conditions
61 | LOG_WARNING = 4, // warning conditions
62 | LOG_NOTICE = 5, // normal but significant condition
63 | LOG_INFO = 6, // informational
64 | LOG_DEBUG = 7, // debug-level messages
65 | LOG_DISABLED = 8 // disabled messages
66 | } eLogLevel;
67 |
68 | #if 0
69 | #define CONCAT(x, y) CONCAT_(x, y)
70 | #define CONCAT_(x, y) x##y
71 |
72 | #define ID(...) __VA_ARGS__
73 |
74 | #define IFMULTIARG(if,then,else) \
75 | CONCAT(IFMULTIARG_, IFMULTIARG_(if, \
76 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
77 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
78 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
79 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
80 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
81 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
82 | 1, 1, 0, ))(then,else)
83 | #define IFMULTIARG_(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, \
84 | _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \
85 | _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \
86 | _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, \
87 | _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \
88 | _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \
89 | _60, _61, _62, _63, ...) _63
90 | #define IFMULTIARG_0(then, else) else
91 | #define IFMULTIARG_1(then, else) then
92 |
93 | #define PROVIDE_SECOND_ARGUMENT(x, ...) CONCAT( IFMULTIARG(ID(__VA_ARGS__), INSERT_, ADD_), SECOND_ARGUMENT ) (x, __VA_ARGS__)
94 | #define PROVIDE_SECOND_ARGUMENT2(x, y, ...) CONCAT( IFMULTIARG(ID(__VA_ARGS__), INSERT_, ADD_), SECOND_ARGUMENT2 ) (x, y, __VA_ARGS__)
95 |
96 | #define ADD_SECOND_ARGUMENT(x, y) y, x
97 | #define INSERT_SECOND_ARGUMENT(x, y, ...) y, x, __VA_ARGS__
98 |
99 | #define ADD_SECOND_ARGUMENT2(x, z, y) y, x, z
100 | #define INSERT_SECOND_ARGUMENT2(x, z, y, ...) y, x, z, __VA_ARGS__
101 |
102 | #endif
103 | //#define DEBUG1(...) printf( "DEBUG %s %s: "
104 | //PROVIDE_SECOND_ARGUMENT2(__FILE__, __LINE__, __VA_ARGS__))
105 |
106 |
107 | //TXT(x) macro is used for system which can store strings in flash, like AVR processors
108 | #ifndef TXT
109 | #define TXT(x) x
110 | #endif
111 |
112 | void SysLog(eLogLevel priorty, const char *fmt, ...);
113 |
114 |
115 |
116 | static inline const char * __file__( const char *filename ) {
117 | char const *p = strrchr( filename, '/' );
118 | if ( p )
119 | return p+1;
120 | else
121 | return filename;
122 | } // __file__
123 |
124 |
125 | //These macros abstract the logging and append the file and line number to errors.
126 | #ifndef SYSLOG_DISABLE
127 | //#ifndef PGM_P
128 | #if 1
129 | //EMERG means system is unstable thus will force a reboot!
130 | #define EMERG(fmt, ...) SysLog( LOG_EMERG, "EMERG: %s %4d: " fmt, __FILENAME__, __LINE__, ## __VA_ARGS__ )
131 | #define ALERT(fmt, ...) SysLog( LOG_ALERT, "ALERT: %s %4d: " fmt, __FILENAME__, __LINE__, ## __VA_ARGS__ )
132 | #define CRITICAL(fmt, ...) SysLog( LOG_CRIT, "CRITICAL: %s %4d: " fmt, __FILENAME__, __LINE__, ## __VA_ARGS__ )
133 | #define ERROR(fmt, ...) SysLog( LOG_ERROR, "ERROR: %s %4d: " fmt, __FILENAME__, __LINE__, ## __VA_ARGS__ )
134 | #define WARNING(fmt, ...) SysLog( LOG_WARNING, "WARNING: %s %4d: " fmt, __FILENAME__, __LINE__, ## __VA_ARGS__ )
135 | #define NOTICE(fmt, ...) SysLog( LOG_NOTICE, "NOTICE: %s %4d: " fmt, __FILENAME__, __LINE__, ## __VA_ARGS__ )
136 | #define INFO(fmt, ...) SysLog( LOG_INFO, "INFO: %s %4d: " fmt, __FILENAME__, __LINE__, ## __VA_ARGS__ )
137 | #define LOG(fmt, ...) SysLog( LOG_DEBUG, "%s %4d: " fmt, __FILENAME__ , __LINE__, ## __VA_ARGS__ )
138 | //
139 | //#define EMERG(...) SysLog( LOG_EMERG, "EMERG: %15s %4d: " PROVIDE_SECOND_ARGUMENT2(BASE_FILE_NAME, __LINE__,__VA_ARGS__ ) )
140 | //#define ALERT(...) SysLog( LOG_ALERT, "ALERT: %15s %4d: " PROVIDE_SECOND_ARGUMENT2(BASE_FILE_NAME, __LINE__,__VA_ARGS__ ) )
141 | //#define CRITICAL(...) SysLog( LOG_CRIT, "CRITICAL: %15s %4d: " PROVIDE_SECOND_ARGUMENT2(BASE_FILE_NAME, __LINE__,__VA_ARGS__ ) )
142 | //#define ERROR(...) SysLog( LOG_ERROR, "ERROR: %15s %4d: " PROVIDE_SECOND_ARGUMENT2(BASE_FILE_NAME, __LINE__,__VA_ARGS__ ) )
143 | //#define WARNING(...) SysLog( LOG_WARNING, "WARNING: %15s %4d: " PROVIDE_SECOND_ARGUMENT2(BASE_FILE_NAME, __LINE__,__VA_ARGS__ ) )
144 | //#define NOTICE(...) SysLog( LOG_NOTICE, "NOTICE: %15s %4d: " PROVIDE_SECOND_ARGUMENT2(BASE_FILE_NAME, __LINE__,__VA_ARGS__ ) )
145 | //#define INFO(...) SysLog( LOG_INFO, "INFO: %15s %4d: " PROVIDE_SECOND_ARGUMENT2(BASE_FILE_NAME, __LINE__,__VA_ARGS__ ) )
146 | //#define LOG(...) SysLog( LOG_DEBUG, "%s %4d: " PROVIDE_SECOND_ARGUMENT2(BASE_FILE_NAME, __LINE__,__VA_ARGS__ ) )
147 | #else
148 | //EMERG means system is unstable thus will force a reboot!
149 | #define EMERG(fmt, ...) SysLog( LOG_EMERG, PSTR("EMERG: %15s %4d: " fmt), __file__(__FILE__), __LINE__, ## __VA_ARGS__ )
150 | #define ALERT(fmt, ...) SysLog( LOG_ALERT, PSTR("ALERT: %15s %4d: " fmt), __file__(__FILE__), __LINE__, ## __VA_ARGS__ )
151 | #define CRITICAL(fmt, ...) SysLog( LOG_CRIT, PSTR("CRITICAL: %15s %4d: " fmt), __file__(__FILE__), __LINE__, ## __VA_ARGS__ )
152 | #define ERROR(fmt, ...) SysLog( LOG_ERROR, PSTR("ERROR: %15s %4d: " fmt), __file__(__FILE__), __LINE__, ## __VA_ARGS__ )
153 | #define WARNING(fmt, ...) SysLog( LOG_WARNING, PSTR("WARNING: %15s %4d: " fmt), __file__(__FILE__), __LINE__, ## __VA_ARGS__ )
154 | #define NOTICE(fmt, ...) SysLog( LOG_NOTICE, PSTR("NOTICE: %15s %4d: " fmt), __file__(__FILE__), __LINE__, ## __VA_ARGS__ )
155 | #define INFO(fmt, ...) SysLog( LOG_INFO, PSTR("INFO: %15s %4d: " fmt), __file__(__FILE__), __LINE__, ## __VA_ARGS__ )
156 | #define LOG(fmt, ...) SysLog( LOG_DEBUG, PSTR("%15s %4d: " fmt), __file__(__FILE__), __LINE__, ## __VA_ARGS__ )
157 |
158 | #endif
159 | #else
160 | #define EMERG(fmt, ...)
161 | #define ALERT(fmt, ...)
162 | #define CRITICAL(fmt, ...)
163 | #define ERROR(fmt, ...)
164 | #define WARNING(fmt, ...)
165 | #define NOTICE(fmt, ...)
166 | #define INFO(fmt, ...)
167 | #define LOG(fmt, ...)
168 |
169 | #endif //SYSLOG_DIABLE
170 |
171 | //Note that if you are running debug code with JTAG the assert will stop
172 | // However you might want to run release code with syslog enabled for testing
173 | // where you want error logging, but asserts are not enabled.
174 | // Thus this macro does error logging and an assert.
175 | //This macro assumed to take a constant string as argument
176 |
177 |
178 | //this can be enabled to log asserts to the history file, if you have code space to do it.
179 | #ifdef ASSERT_HISTORY
180 | #define ASSERT(x) {if(!(x)){ERROR(#x); HISTORY_ASSERT();} assert(x);}
181 | #define ASSERT_ERROR(x) {HISTORY_ASSERT(); ERROR(x); ASSERT_FAIL(x);}
182 | #else
183 | #define ASSERT(x) {if(!(x)){ERROR(#x);} assert(x);}
184 | #define ASSERT_ERROR(x) {ERROR(x); ASSERT_FAIL(x);}
185 | #endif
186 |
187 |
188 | void SysLogInit(Uart *ptrSerialObj, eLogLevel LevelToWrite);
189 | int SysLogDisable(void);
190 | int SysLogEnable(void);
191 | int SysLogIsEnabled(void);
192 |
193 | #ifdef __cplusplus
194 | }
195 | #endif // __cplusplus
196 |
197 | #endif /* SYSLOG_H_ */
198 |
--------------------------------------------------------------------------------
/firmware/stepServo/utils.cpp:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 |
13 | #include "utils.h"
14 | #include "syslog.h"
15 |
16 | double CubicInterpolate(
17 | double y0,double y1,
18 | double y2,double y3,
19 | double mu)
20 | {
21 | double a0,a1,a2,a3,mu2;
22 |
23 | mu2 = mu*mu;
24 | a0 = y3 - y2 - y0 + y1;
25 | a1 = y0 - y1 - a0;
26 | a2 = y2 - y0;
27 | a3 = y1;
28 |
29 | return(a0*mu*mu2+a1*mu2+a2*mu+a3);
30 | }
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/firmware/stepServo/utils.h:
--------------------------------------------------------------------------------
1 | /**********************************************************************
2 | * Author: tstern
3 | *
4 | * Misfit Tech invests time and resources providing this open source code,
5 | * please support Misfit Tech and open-source hardware by purchasing
6 | * products from Misfit Tech, www.misifittech.net!
7 | *
8 | * Written by Trampas Stern for Misfit Tech.
9 | * BSD license, check license.txt for more information
10 | * All text above, must be included in any redistribution
11 | *********************************************************************/
12 |
13 | /* this file contains generic utilities and functions */
14 |
15 | #ifndef UTILS_H_
16 | #define UTILS_H_
17 |
18 |
19 | double CubicInterpolate(
20 | double y0,double y1,
21 | double y2,double y3,
22 | double mu);
23 |
24 |
25 |
26 |
27 | #endif /* UTILS_H_ */
28 |
--------------------------------------------------------------------------------
/hardware/NZS_A4954_R2.0.PrjPcb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/hardware/NZS_A4954_R2.0.PrjPcb
--------------------------------------------------------------------------------
/hardware/NZS_A4954_R2_0.PcbDoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/hardware/NZS_A4954_R2_0.PcbDoc
--------------------------------------------------------------------------------
/hardware/Nano_stepper.SchDoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/hardware/Nano_stepper.SchDoc
--------------------------------------------------------------------------------
/hardware/Nano_zero_stepper_Schematics.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/hardware/Nano_zero_stepper_Schematics.pdf
--------------------------------------------------------------------------------
/hardware/Status Report.Txt:
--------------------------------------------------------------------------------
1 | Source PCB Design panel.PcbDoc contains embedded board array. It is recomended to generate individual BOM for each embedded board PCB design.
2 |
3 | Output: NC Drill Files
4 | Type : NC Drill
5 | From : Project [Free Documents]
6 | Generated File[panel-RoundHoles.TXT]
7 | Generated File[panel-SlotHoles.TXT]
8 | Generated File[panel.LDP]
9 | Generated File[panel.DRR]
10 |
11 |
12 | Files Generated : 4
13 | Documents Printed : 0
14 |
15 | Finished Output Generation At 7:25:51 AM On 10/11/2016
16 |
--------------------------------------------------------------------------------
/hardware/panel-SlotHoles.TXT:
--------------------------------------------------------------------------------
1 | M48
2 | ;Layer_Color=9474304
3 | ;FILE_FORMAT=2:5
4 | INCH,LZ
5 | ;TYPE=PLATED
6 | T3F00S00C0.01968
7 | T4F00S00C0.02165
8 | ;TYPE=NON_PLATED
9 | %
10 | G90
11 | G05
12 | T03
13 | G00X0311728Y0181964
14 | M15
15 | G01X0314287
16 | M16
17 | G00X0311728Y0209524
18 | M15
19 | G01X0314287
20 | M16
21 | G00X0131728Y0209524
22 | M15
23 | G01X0134287
24 | M16
25 | G00X0131728Y0181964
26 | M15
27 | G01X0134287
28 | M16
29 | G00X0131728Y0361964
30 | M15
31 | G01X0134287
32 | M16
33 | G00X0131728Y0389524
34 | M15
35 | G01X0134287
36 | M16
37 | G00X0311728Y0389524
38 | M15
39 | G01X0314287
40 | M16
41 | G00X0311728Y0361964
42 | M15
43 | G01X0314287
44 | M16
45 | T04
46 | G00X0324031Y0186492
47 | M15
48 | G01Y0185311
49 | M16
50 | G00X0324031Y0206177
51 | M15
52 | G01Y0204996
53 | M16
54 | G00X0144031Y0206177
55 | M15
56 | G01Y0204996
57 | M16
58 | G00X0144031Y0186492
59 | M15
60 | G01Y0185311
61 | M16
62 | G00X0144031Y0366492
63 | M15
64 | G01Y0365311
65 | M16
66 | G00X0144031Y0386177
67 | M15
68 | G01Y0384996
69 | M16
70 | G00X0324031Y0386177
71 | M15
72 | G01Y0384996
73 | M16
74 | G00X0324031Y0366492
75 | M15
76 | G01Y0365311
77 | M16
78 | M17
79 | M30
80 |
--------------------------------------------------------------------------------
/hardware/panel-macro.APR_LIB:
--------------------------------------------------------------------------------
1 | G04:AMPARAMS|DCode=11|XSize=31.5mil|YSize=35.43mil|CornerRadius=7.87mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=270.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
2 | %AMROUNDEDRECTD11*
3 | 21,1,0.03150,0.01969,0,0,270.0*
4 | 21,1,0.01575,0.03543,0,0,270.0*
5 | 1,1,0.01575,-0.00984,-0.00787*
6 | 1,1,0.01575,-0.00984,0.00787*
7 | 1,1,0.01575,0.00984,0.00787*
8 | 1,1,0.01575,0.00984,-0.00787*
9 | %
10 | G04:AMPARAMS|DCode=18|XSize=31.5mil|YSize=31.5mil|CornerRadius=7.87mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=90.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
11 | %AMROUNDEDRECTD18*
12 | 21,1,0.03150,0.01575,0,0,90.0*
13 | 21,1,0.01575,0.03150,0,0,90.0*
14 | 1,1,0.01575,0.00787,0.00787*
15 | 1,1,0.01575,0.00787,-0.00787*
16 | 1,1,0.01575,-0.00787,-0.00787*
17 | 1,1,0.01575,-0.00787,0.00787*
18 | %
19 | G04:AMPARAMS|DCode=20|XSize=27.56mil|YSize=51.18mil|CornerRadius=6.89mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=90.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
20 | %AMROUNDEDRECTD20*
21 | 21,1,0.02756,0.03740,0,0,90.0*
22 | 21,1,0.01378,0.05118,0,0,90.0*
23 | 1,1,0.01378,0.01870,0.00689*
24 | 1,1,0.01378,0.01870,-0.00689*
25 | 1,1,0.01378,-0.01870,-0.00689*
26 | 1,1,0.01378,-0.01870,0.00689*
27 | %
28 | G04:AMPARAMS|DCode=22|XSize=23.62mil|YSize=35.43mil|CornerRadius=5.91mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=270.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
29 | %AMROUNDEDRECTD22*
30 | 21,1,0.02362,0.02362,0,0,270.0*
31 | 21,1,0.01181,0.03543,0,0,270.0*
32 | 1,1,0.01181,-0.01181,-0.00591*
33 | 1,1,0.01181,-0.01181,0.00591*
34 | 1,1,0.01181,0.01181,0.00591*
35 | 1,1,0.01181,0.01181,-0.00591*
36 | %
37 | G04:AMPARAMS|DCode=25|XSize=78.74mil|YSize=39.37mil|CornerRadius=9.84mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=0.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
38 | %AMROUNDEDRECTD25*
39 | 21,1,0.07874,0.01969,0,0,0.0*
40 | 21,1,0.05906,0.03937,0,0,0.0*
41 | 1,1,0.01969,0.02953,-0.00984*
42 | 1,1,0.01969,-0.02953,-0.00984*
43 | 1,1,0.01969,-0.02953,0.00984*
44 | 1,1,0.01969,0.02953,0.00984*
45 | %
46 | G04:AMPARAMS|DCode=27|XSize=9.84mil|YSize=33.47mil|CornerRadius=0mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=135.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=Round|*
47 | %AMOVALD27*
48 | 21,1,0.02362,0.00984,0.00000,0.00000,225.0*
49 | 1,1,0.00984,0.00835,0.00835*
50 | 1,1,0.00984,-0.00835,-0.00835*
51 | %
52 | G04:AMPARAMS|DCode=28|XSize=9.84mil|YSize=35.43mil|CornerRadius=0mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=135.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=Round|*
53 | %AMOVALD28*
54 | 21,1,0.02559,0.00984,0.00000,0.00000,225.0*
55 | 1,1,0.00984,0.00905,0.00905*
56 | 1,1,0.00984,-0.00905,-0.00905*
57 | %
58 | G04:AMPARAMS|DCode=29|XSize=9.84mil|YSize=33.47mil|CornerRadius=0mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=225.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=Round|*
59 | %AMOVALD29*
60 | 21,1,0.02362,0.00984,0.00000,0.00000,315.0*
61 | 1,1,0.00984,-0.00835,0.00835*
62 | 1,1,0.00984,0.00835,-0.00835*
63 | %
64 | G04:AMPARAMS|DCode=30|XSize=9.84mil|YSize=35.43mil|CornerRadius=0mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=225.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=Round|*
65 | %AMOVALD30*
66 | 21,1,0.02559,0.00984,0.00000,0.00000,315.0*
67 | 1,1,0.00984,-0.00905,0.00905*
68 | 1,1,0.00984,0.00905,-0.00905*
69 | %
70 | G04:AMPARAMS|DCode=31|XSize=9.84mil|YSize=33.47mil|CornerRadius=2.46mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=225.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
71 | %AMROUNDEDRECTD31*
72 | 21,1,0.00984,0.02854,0,0,225.0*
73 | 21,1,0.00492,0.03347,0,0,225.0*
74 | 1,1,0.00492,-0.01183,0.00835*
75 | 1,1,0.00492,-0.00835,0.01183*
76 | 1,1,0.00492,0.01183,-0.00835*
77 | 1,1,0.00492,0.00835,-0.01183*
78 | %
79 | G04:AMPARAMS|DCode=63|XSize=23.62mil|YSize=62.99mil|CornerRadius=5.91mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=0.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
80 | %AMROUNDEDRECTD63*
81 | 21,1,0.02362,0.05118,0,0,0.0*
82 | 21,1,0.01181,0.06299,0,0,0.0*
83 | 1,1,0.01181,0.00591,-0.02559*
84 | 1,1,0.01181,-0.00591,-0.02559*
85 | 1,1,0.01181,-0.00591,0.02559*
86 | 1,1,0.01181,0.00591,0.02559*
87 | %
88 | G04:AMPARAMS|DCode=72|XSize=39.5mil|YSize=43.43mil|CornerRadius=11.87mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=270.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
89 | %AMROUNDEDRECTD72*
90 | 21,1,0.03950,0.01969,0,0,270.0*
91 | 21,1,0.01575,0.04343,0,0,270.0*
92 | 1,1,0.02375,-0.00984,-0.00787*
93 | 1,1,0.02375,-0.00984,0.00787*
94 | 1,1,0.02375,0.00984,0.00787*
95 | 1,1,0.02375,0.00984,-0.00787*
96 | %
97 | G04:AMPARAMS|DCode=79|XSize=39.5mil|YSize=39.5mil|CornerRadius=11.87mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=90.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
98 | %AMROUNDEDRECTD79*
99 | 21,1,0.03950,0.01575,0,0,90.0*
100 | 21,1,0.01575,0.03950,0,0,90.0*
101 | 1,1,0.02375,0.00787,0.00787*
102 | 1,1,0.02375,0.00787,-0.00787*
103 | 1,1,0.02375,-0.00787,-0.00787*
104 | 1,1,0.02375,-0.00787,0.00787*
105 | %
106 | G04:AMPARAMS|DCode=81|XSize=35.56mil|YSize=59.18mil|CornerRadius=10.89mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=90.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
107 | %AMROUNDEDRECTD81*
108 | 21,1,0.03556,0.03740,0,0,90.0*
109 | 21,1,0.01378,0.05918,0,0,90.0*
110 | 1,1,0.02178,0.01870,0.00689*
111 | 1,1,0.02178,0.01870,-0.00689*
112 | 1,1,0.02178,-0.01870,-0.00689*
113 | 1,1,0.02178,-0.01870,0.00689*
114 | %
115 | G04:AMPARAMS|DCode=83|XSize=31.62mil|YSize=43.43mil|CornerRadius=9.91mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=270.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
116 | %AMROUNDEDRECTD83*
117 | 21,1,0.03162,0.02362,0,0,270.0*
118 | 21,1,0.01181,0.04343,0,0,270.0*
119 | 1,1,0.01981,-0.01181,-0.00591*
120 | 1,1,0.01981,-0.01181,0.00591*
121 | 1,1,0.01981,0.01181,0.00591*
122 | 1,1,0.01981,0.01181,-0.00591*
123 | %
124 | G04:AMPARAMS|DCode=86|XSize=86.74mil|YSize=47.37mil|CornerRadius=13.84mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=0.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
125 | %AMROUNDEDRECTD86*
126 | 21,1,0.08674,0.01969,0,0,0.0*
127 | 21,1,0.05906,0.04737,0,0,0.0*
128 | 1,1,0.02769,0.02953,-0.00984*
129 | 1,1,0.02769,-0.02953,-0.00984*
130 | 1,1,0.02769,-0.02953,0.00984*
131 | 1,1,0.02769,0.02953,0.00984*
132 | %
133 | G04:AMPARAMS|DCode=88|XSize=17.84mil|YSize=41.47mil|CornerRadius=0mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=135.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=Round|*
134 | %AMOVALD88*
135 | 21,1,0.02362,0.01784,0.00000,0.00000,225.0*
136 | 1,1,0.01784,0.00835,0.00835*
137 | 1,1,0.01784,-0.00835,-0.00835*
138 | %
139 | G04:AMPARAMS|DCode=89|XSize=17.84mil|YSize=43.43mil|CornerRadius=0mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=135.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=Round|*
140 | %AMOVALD89*
141 | 21,1,0.02559,0.01784,0.00000,0.00000,225.0*
142 | 1,1,0.01784,0.00905,0.00905*
143 | 1,1,0.01784,-0.00905,-0.00905*
144 | %
145 | G04:AMPARAMS|DCode=90|XSize=17.84mil|YSize=41.47mil|CornerRadius=0mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=225.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=Round|*
146 | %AMOVALD90*
147 | 21,1,0.02362,0.01784,0.00000,0.00000,315.0*
148 | 1,1,0.01784,-0.00835,0.00835*
149 | 1,1,0.01784,0.00835,-0.00835*
150 | %
151 | G04:AMPARAMS|DCode=91|XSize=17.84mil|YSize=43.43mil|CornerRadius=0mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=225.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=Round|*
152 | %AMOVALD91*
153 | 21,1,0.02559,0.01784,0.00000,0.00000,315.0*
154 | 1,1,0.01784,-0.00905,0.00905*
155 | 1,1,0.01784,0.00905,-0.00905*
156 | %
157 | G04:AMPARAMS|DCode=92|XSize=17.84mil|YSize=41.47mil|CornerRadius=6.46mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=225.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
158 | %AMROUNDEDRECTD92*
159 | 21,1,0.01784,0.02854,0,0,225.0*
160 | 21,1,0.00492,0.04147,0,0,225.0*
161 | 1,1,0.01292,-0.01183,0.00835*
162 | 1,1,0.01292,-0.00835,0.01183*
163 | 1,1,0.01292,0.01183,-0.00835*
164 | 1,1,0.01292,0.00835,-0.01183*
165 | %
166 | G04:AMPARAMS|DCode=112|XSize=31.62mil|YSize=70.99mil|CornerRadius=9.91mil|HoleSize=0mil|Usage=FLASHONLY|Rotation=0.000|XOffset=0mil|YOffset=0mil|HoleType=Round|Shape=RoundedRectangle|*
167 | %AMROUNDEDRECTD112*
168 | 21,1,0.03162,0.05118,0,0,0.0*
169 | 21,1,0.01181,0.07099,0,0,0.0*
170 | 1,1,0.01981,0.00591,-0.02559*
171 | 1,1,0.01981,-0.00591,-0.02559*
172 | 1,1,0.01981,-0.00591,0.02559*
173 | 1,1,0.01981,0.00591,0.02559*
174 | %
175 |
--------------------------------------------------------------------------------
/hardware/panel.1:
--------------------------------------------------------------------------------
1 | G04 Layer_Color=255*
2 | %FSLAX25Y25*%
3 | %MOIN*%
4 | G70*
5 | G01*
6 | G75*
7 | M02*
8 |
--------------------------------------------------------------------------------
/hardware/panel.DRR:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------------------------------------------------------------------------------------
2 | NCDrill File Report For: panel.PcbDoc 10/11/2016 7:25:51 AM
3 | ----------------------------------------------------------------------------------------------------------------------------------
4 |
5 | Layer Pair : Top Layer to Bottom Layer
6 | ASCII RoundHoles File : panel-RoundHoles.TXT
7 | ASCII SlotHoles File : panel-SlotHoles.TXT
8 |
9 | Tool Hole Size Hole Tolerance Hole Type Hole Count Plated Tool Travel
10 | ----------------------------------------------------------------------------------------------------------------------------------
11 | T1 8mil (0.2mm) Round 36 PTH 6.70inch (170.16mm)
12 | T2 12mil (0.305mm) Round 492 PTH 63.35inch (1609.14mm)
13 | T3 20mil (0.5mm) Slot 8 PTH 13.21inch (335.65mm)
14 | T4 22mil (0.55mm) Slot 8 PTH 12.48inch (317.02mm)
15 | T5 27mil (0.686mm) Round 40 PTH 7.00inch (177.80mm)
16 | T6 40mil (1.016mm) Round 32 PTH 9.08inch (230.70mm)
17 | T7 43mil (1.1mm) Round 40 PTH 9.00inch (228.60mm)
18 | T8 51mil (1.3mm) Round 8 PTH 6.00inch (152.40mm)
19 | T9 138mil (3.5mm) Round 16 PTH 15.74inch (399.88mm)
20 | T10 31mil (0.787mm) Round 192 NPTH 28.19inch (715.91mm)
21 | ----------------------------------------------------------------------------------------------------------------------------------
22 | Totals 872
23 |
24 | Total Processing Time (hh:mm:ss) : 00:00:00
25 |
--------------------------------------------------------------------------------
/hardware/panel.EXTREP:
--------------------------------------------------------------------------------
1 | ------------------------------------------------------------------------------------------
2 | Gerber File Extension Report For: panel.GBR 10/11/2016 7:23:43 AM
3 | ------------------------------------------------------------------------------------------
4 |
5 |
6 | ------------------------------------------------------------------------------------------
7 | Layer Extension Layer Description
8 | ------------------------------------------------------------------------------------------
9 | .GTL Top Layer
10 | .GBL Bottom Layer
11 | .GPB Bottom Pad Master
12 | .GPT Top Pad Master
13 | .GTO Top Overlay
14 | .GTP Top Paste
15 | .GTS Top Solder
16 | .GBS Bottom Solder
17 | .GBP Bottom Paste
18 | .GBO Bottom Overlay
19 | .GKO Keep-Out Layer
20 | .GM1 Mechanical 1
21 | .GM3 Mechanical 3
22 | .GM2 Mechanical 2
23 | .GM13 Mechanical 13
24 | .GM15 Mechanical 15
25 | .1 Dielectric 1
26 | .GML Multi-Layer
27 | .GD1 Drill Drawing
28 | ------------------------------------------------------------------------------------------
29 |
--------------------------------------------------------------------------------
/hardware/panel.GM1:
--------------------------------------------------------------------------------
1 | G04 Layer_Color=16711935*
2 | %FSLAX25Y25*%
3 | %MOIN*%
4 | G70*
5 | G01*
6 | G75*
7 | M02*
8 |
--------------------------------------------------------------------------------
/hardware/panel.GM2:
--------------------------------------------------------------------------------
1 | G04 Layer_Color=8388736*
2 | %FSLAX25Y25*%
3 | %MOIN*%
4 | G70*
5 | G01*
6 | G75*
7 | %ADD68C,0.00500*%
8 | D68*
9 | X134044Y222344D02*
10 | G03*
11 | X134044Y222344I-2000J0D01*
12 | G01*
13 | Y232344D02*
14 | G03*
15 | X134044Y232344I-2000J0D01*
16 | G01*
17 | Y242344D02*
18 | G03*
19 | X134044Y242344I-2000J0D01*
20 | G01*
21 | Y252344D02*
22 | G03*
23 | X134044Y252344I-2000J0D01*
24 | G01*
25 | X237244Y252744D02*
26 | G03*
27 | X237244Y252744I-2000J0D01*
28 | G01*
29 | X227244D02*
30 | G03*
31 | X227244Y252744I-2000J0D01*
32 | G01*
33 | X217244D02*
34 | G03*
35 | X217244Y252744I-2000J0D01*
36 | G01*
37 | X207244D02*
38 | G03*
39 | X207244Y252744I-2000J0D01*
40 | G01*
41 | X314044Y222344D02*
42 | G03*
43 | X314044Y222344I-2000J0D01*
44 | G01*
45 | Y232344D02*
46 | G03*
47 | X314044Y232344I-2000J0D01*
48 | G01*
49 | Y242344D02*
50 | G03*
51 | X314044Y242344I-2000J0D01*
52 | G01*
53 | Y252344D02*
54 | G03*
55 | X314044Y252344I-2000J0D01*
56 | G01*
57 | X417244Y252744D02*
58 | G03*
59 | X417244Y252744I-2000J0D01*
60 | G01*
61 | X407244D02*
62 | G03*
63 | X407244Y252744I-2000J0D01*
64 | G01*
65 | X397244D02*
66 | G03*
67 | X397244Y252744I-2000J0D01*
68 | G01*
69 | X387244D02*
70 | G03*
71 | X387244Y252744I-2000J0D01*
72 | G01*
73 | X134044Y402344D02*
74 | G03*
75 | X134044Y402344I-2000J0D01*
76 | G01*
77 | Y412344D02*
78 | G03*
79 | X134044Y412344I-2000J0D01*
80 | G01*
81 | Y422344D02*
82 | G03*
83 | X134044Y422344I-2000J0D01*
84 | G01*
85 | Y432344D02*
86 | G03*
87 | X134044Y432344I-2000J0D01*
88 | G01*
89 | X237244Y432744D02*
90 | G03*
91 | X237244Y432744I-2000J0D01*
92 | G01*
93 | X227244D02*
94 | G03*
95 | X227244Y432744I-2000J0D01*
96 | G01*
97 | X217244D02*
98 | G03*
99 | X217244Y432744I-2000J0D01*
100 | G01*
101 | X207244D02*
102 | G03*
103 | X207244Y432744I-2000J0D01*
104 | G01*
105 | X314044Y402344D02*
106 | G03*
107 | X314044Y402344I-2000J0D01*
108 | G01*
109 | Y412344D02*
110 | G03*
111 | X314044Y412344I-2000J0D01*
112 | G01*
113 | Y422344D02*
114 | G03*
115 | X314044Y422344I-2000J0D01*
116 | G01*
117 | Y432344D02*
118 | G03*
119 | X314044Y432344I-2000J0D01*
120 | G01*
121 | X417244Y432744D02*
122 | G03*
123 | X417244Y432744I-2000J0D01*
124 | G01*
125 | X407244D02*
126 | G03*
127 | X407244Y432744I-2000J0D01*
128 | G01*
129 | X397244D02*
130 | G03*
131 | X397244Y432744I-2000J0D01*
132 | G01*
133 | X387244D02*
134 | G03*
135 | X387244Y432744I-2000J0D01*
136 | G01*
137 | M02*
138 |
--------------------------------------------------------------------------------
/hardware/panel.GM3:
--------------------------------------------------------------------------------
1 | G04 Layer_Color=12566272*
2 | %FSLAX25Y25*%
3 | %MOIN*%
4 | G70*
5 | G01*
6 | G75*
7 | %ADD40C,0.02000*%
8 | %ADD117C,0.04724*%
9 | D40*
10 | X160800Y531193D02*
11 | Y511200D01*
12 | X170797D01*
13 | X174129Y514532D01*
14 | Y517865D01*
15 | X170797Y521197D01*
16 | X160800D01*
17 | X170797D01*
18 | X174129Y524529D01*
19 | Y527861D01*
20 | X170797Y531193D01*
21 | X160800D01*
22 | X184126Y511200D02*
23 | X190790D01*
24 | X194123Y514532D01*
25 | Y521197D01*
26 | X190790Y524529D01*
27 | X184126D01*
28 | X180793Y521197D01*
29 | Y514532D01*
30 | X184126Y511200D01*
31 | X204119Y524529D02*
32 | X210784D01*
33 | X214116Y521197D01*
34 | Y511200D01*
35 | X204119D01*
36 | X200787Y514532D01*
37 | X204119Y517865D01*
38 | X214116D01*
39 | X220781Y524529D02*
40 | Y511200D01*
41 | Y517865D01*
42 | X224113Y521197D01*
43 | X227445Y524529D01*
44 | X230777D01*
45 | X254103Y531193D02*
46 | Y511200D01*
47 | X244106D01*
48 | X240774Y514532D01*
49 | Y521197D01*
50 | X244106Y524529D01*
51 | X254103D01*
52 | X290758Y531193D02*
53 | X284093D01*
54 | X280761Y527861D01*
55 | Y514532D01*
56 | X284093Y511200D01*
57 | X290758D01*
58 | X294090Y514532D01*
59 | Y527861D01*
60 | X290758Y531193D01*
61 | X300755Y524529D02*
62 | Y514532D01*
63 | X304087Y511200D01*
64 | X314084D01*
65 | Y524529D01*
66 | X324081Y527861D02*
67 | Y524529D01*
68 | X320748D01*
69 | X327413D01*
70 | X324081D01*
71 | Y514532D01*
72 | X327413Y511200D01*
73 | X337410D02*
74 | X344074D01*
75 | X340742D01*
76 | Y531193D01*
77 | X337410D01*
78 | X354071Y511200D02*
79 | X360735D01*
80 | X357403D01*
81 | Y524529D01*
82 | X354071D01*
83 | X370732Y511200D02*
84 | Y524529D01*
85 | X380729D01*
86 | X384061Y521197D01*
87 | Y511200D01*
88 | X400723D02*
89 | X394058D01*
90 | X390726Y514532D01*
91 | Y521197D01*
92 | X394058Y524529D01*
93 | X400723D01*
94 | X404055Y521197D01*
95 | Y517865D01*
96 | X390726D01*
97 | D117*
98 | X357900Y124200D02*
99 | X358000Y113200D01*
100 | X358600Y112600D01*
101 | X418000D01*
102 | Y124200D01*
103 | X357900D02*
104 | X418000D01*
105 | X361600Y290100D02*
106 | X361900Y304300D01*
107 | X361600Y290100D02*
108 | X405600D01*
109 | X405900Y289800D01*
110 | X406000Y289900D01*
111 | Y304500D01*
112 | X362100D02*
113 | X406000D01*
114 | X361900Y304300D02*
115 | X362100Y304500D01*
116 | X182100Y112800D02*
117 | Y124400D01*
118 | Y112800D02*
119 | X182800Y112100D01*
120 | X235400D01*
121 | Y123800D01*
122 | X234800Y124400D02*
123 | X235400Y123800D01*
124 | X182100Y124400D02*
125 | X234800D01*
126 | X114600Y407900D02*
127 | X125400Y407800D01*
128 | X114600Y407900D02*
129 | X114700Y407800D01*
130 | Y357300D02*
131 | Y407800D01*
132 | Y357300D02*
133 | X124600D01*
134 | X125400Y358100D01*
135 | Y407800D01*
136 | X115000Y240000D02*
137 | X125400D01*
138 | X115000Y180000D02*
139 | Y240000D01*
140 | Y180000D02*
141 | X125400D01*
142 | Y240000D01*
143 | X291000Y177000D02*
144 | Y228000D01*
145 | Y177000D02*
146 | X305000D01*
147 | Y228000D01*
148 | X291000D02*
149 | X305000D01*
150 | X177100Y304500D02*
151 | X235100D01*
152 | Y290000D02*
153 | Y304500D01*
154 | X177100Y290000D02*
155 | X235100D01*
156 | X177100D02*
157 | Y304500D01*
158 | X291000Y134000D02*
159 | Y150000D01*
160 | X281500Y124500D02*
161 | X291000Y134000D01*
162 | X263000Y124500D02*
163 | X281500D01*
164 | X262500Y125000D02*
165 | X263000Y124500D01*
166 | X262500Y112500D02*
167 | Y125000D01*
168 | Y112500D02*
169 | X332500D01*
170 | X333000Y113000D01*
171 | Y124000D01*
172 | X315500D02*
173 | X333000D01*
174 | X305500Y134000D02*
175 | X315500Y124000D01*
176 | X305500Y134000D02*
177 | Y150000D01*
178 | X291000D02*
179 | X305500D01*
180 | X125000Y133000D02*
181 | Y152500D01*
182 | Y133000D02*
183 | X125500D01*
184 | X134500Y124000D01*
185 | X135000Y124500D01*
186 | X154500D01*
187 | Y112000D02*
188 | Y124500D01*
189 | X154000Y112500D02*
190 | X154500Y112000D01*
191 | X115000Y112500D02*
192 | X154000D01*
193 | X115000D02*
194 | Y152000D01*
195 | X114500Y152500D02*
196 | X115000Y152000D01*
197 | X114500Y152500D02*
198 | X125000D01*
199 | X114550Y330100D02*
200 | X114987Y265000D01*
201 | X125500Y265000D01*
202 | X125500Y280500D01*
203 | X135000Y290000D01*
204 | X149500D01*
205 | Y304500D01*
206 | X134500D02*
207 | X149500D01*
208 | X125500Y313500D02*
209 | X134500Y304500D01*
210 | X125500Y313500D02*
211 | Y330100D01*
212 | X114550D02*
213 | X125500D01*
214 | X290281Y401131D02*
215 | X290900Y402700D01*
216 | X290281Y401131D02*
217 | X291107Y364800D01*
218 | X305500D01*
219 | Y402700D01*
220 | X290900D02*
221 | X305500D01*
222 | X290500Y314000D02*
223 | Y337500D01*
224 | X281000Y304500D02*
225 | X290500Y314000D01*
226 | X262000Y304500D02*
227 | X281000D01*
228 | X262000Y290000D02*
229 | Y304500D01*
230 | Y290000D02*
231 | X281000D01*
232 | X291000Y280000D01*
233 | Y255500D02*
234 | Y280000D01*
235 | Y255500D02*
236 | X304500D01*
237 | X305000Y255000D01*
238 | Y280500D01*
239 | X315000Y290500D01*
240 | X334500D01*
241 | Y304500D01*
242 | X314500D02*
243 | X334500D01*
244 | X314500D02*
245 | Y305000D01*
246 | X305500Y314000D02*
247 | X314500Y305000D01*
248 | X305500Y314000D02*
249 | Y337500D01*
250 | X290500D02*
251 | X305500D01*
252 | X471000Y134000D02*
253 | Y152500D01*
254 | X461500Y124500D02*
255 | X471000Y134000D01*
256 | X444600Y124500D02*
257 | X461500D01*
258 | X444600Y112500D02*
259 | Y124500D01*
260 | Y112500D02*
261 | X480000D01*
262 | X482500Y115000D01*
263 | Y152500D01*
264 | X471000D02*
265 | X482500D01*
266 | X470500Y177500D02*
267 | Y215000D01*
268 | Y177500D02*
269 | X482500D01*
270 | Y215000D01*
271 | X470500D02*
272 | X482500D01*
273 | X471000Y338100D02*
274 | X482500D01*
275 | Y242300D02*
276 | Y338100D01*
277 | X471000Y242300D02*
278 | X482500D01*
279 | X471000D02*
280 | Y280000D01*
281 | X470000D02*
282 | X471000D01*
283 | X459500Y290500D02*
284 | X470000Y280000D01*
285 | X432500Y290500D02*
286 | X459500D01*
287 | X432500D02*
288 | Y304000D01*
289 | X432000Y304500D02*
290 | X432500Y304000D01*
291 | X432000Y304500D02*
292 | X461000D01*
293 | X471000Y314500D01*
294 | Y338100D01*
295 | X471000Y400400D02*
296 | X471000Y365000D01*
297 | X482500D01*
298 | X480000D02*
299 | X482500D01*
300 | X480000D02*
301 | Y367500D01*
302 | X480000Y400400D02*
303 | X480000Y367500D01*
304 | X471000Y400400D02*
305 | X480000D01*
306 | X435000Y470000D02*
307 | Y480000D01*
308 | X480000D01*
309 | Y428000D02*
310 | Y480000D01*
311 | Y428000D02*
312 | X480500Y427500D01*
313 | X470500D02*
314 | X480500D01*
315 | X470500D02*
316 | Y459500D01*
317 | X471000Y460000D01*
318 | X461000Y470000D02*
319 | X471000Y460000D01*
320 | X435000Y470000D02*
321 | X461000D01*
322 | X366100D02*
323 | Y480000D01*
324 | X409500D01*
325 | Y470000D02*
326 | Y480000D01*
327 | X366100Y470000D02*
328 | X409500D01*
329 | X253900D02*
330 | Y480000D01*
331 | X338700D01*
332 | Y470000D02*
333 | Y480000D01*
334 | X315000Y470000D02*
335 | X338700D01*
336 | X305000Y460000D02*
337 | X315000Y470000D01*
338 | X305000Y460000D02*
339 | X305500Y459500D01*
340 | Y430000D02*
341 | Y459500D01*
342 | X291000Y430000D02*
343 | X305500D01*
344 | X291000D02*
345 | Y460000D01*
346 | X290500D02*
347 | X291000D01*
348 | X280500Y470000D02*
349 | X290500Y460000D01*
350 | X253900Y470000D02*
351 | X280500D01*
352 | X190000D02*
353 | X227500D01*
354 | Y480000D01*
355 | X190000D02*
356 | X227500D01*
357 | X190000Y470000D02*
358 | Y480000D01*
359 | X135500Y470000D02*
360 | X157500D01*
361 | X125500Y460000D02*
362 | X135500Y470000D01*
363 | X125000Y460000D02*
364 | X125500D01*
365 | X125000Y435000D02*
366 | Y460000D01*
367 | X115000Y435000D02*
368 | X125000D01*
369 | X115000D02*
370 | Y480000D01*
371 | X157500D01*
372 | Y470000D02*
373 | Y480000D01*
374 | X100000Y100000D02*
375 | X493700D01*
376 | Y493700D01*
377 | X100000D02*
378 | X493700D01*
379 | X100000Y100000D02*
380 | Y493700D01*
381 | M02*
382 |
--------------------------------------------------------------------------------
/hardware/panel.GML:
--------------------------------------------------------------------------------
1 | G04 Layer_Color=12632256*
2 | %FSLAX25Y25*%
3 | %MOIN*%
4 | G70*
5 | G01*
6 | G75*
7 | %ADD49C,0.01000*%
8 | %ADD50O,0.04724X0.09449*%
9 | %ADD51O,0.06102X0.03543*%
10 | %ADD52O,0.03740X0.04921*%
11 | %ADD53C,0.07000*%
12 | %ADD54R,0.07000X0.07000*%
13 | %ADD55C,0.04000*%
14 | %ADD56R,0.04000X0.04000*%
15 | %ADD57R,0.07000X0.07000*%
16 | %ADD58C,0.07874*%
17 | D49*
18 | X125000Y260000D02*
19 | D03*
20 | Y265000D02*
21 | D03*
22 | Y255000D02*
23 | D03*
24 | Y250000D02*
25 | D03*
26 | Y245000D02*
27 | D03*
28 | Y240000D02*
29 | D03*
30 | X124600Y152500D02*
31 | D03*
32 | Y157500D02*
33 | D03*
34 | Y162500D02*
35 | D03*
36 | Y167500D02*
37 | D03*
38 | Y177500D02*
39 | D03*
40 | Y172500D02*
41 | D03*
42 | X290600Y150000D02*
43 | D03*
44 | Y155000D02*
45 | D03*
46 | Y160000D02*
47 | D03*
48 | Y165000D02*
49 | D03*
50 | Y175000D02*
51 | D03*
52 | Y170000D02*
53 | D03*
54 | X305100Y150000D02*
55 | D03*
56 | Y155000D02*
57 | D03*
58 | Y160000D02*
59 | D03*
60 | Y165000D02*
61 | D03*
62 | Y175000D02*
63 | D03*
64 | Y170000D02*
65 | D03*
66 | X291400Y229800D02*
67 | D03*
68 | Y234800D02*
69 | D03*
70 | Y239800D02*
71 | D03*
72 | Y244800D02*
73 | D03*
74 | Y254800D02*
75 | D03*
76 | Y249800D02*
77 | D03*
78 | X304800Y229300D02*
79 | D03*
80 | Y234300D02*
81 | D03*
82 | Y239300D02*
83 | D03*
84 | Y244300D02*
85 | D03*
86 | Y254300D02*
87 | D03*
88 | Y249300D02*
89 | D03*
90 | X125200Y409200D02*
91 | D03*
92 | Y414200D02*
93 | D03*
94 | Y419200D02*
95 | D03*
96 | Y424200D02*
97 | D03*
98 | Y434200D02*
99 | D03*
100 | Y429200D02*
101 | D03*
102 | X291200Y338300D02*
103 | D03*
104 | Y343300D02*
105 | D03*
106 | Y348300D02*
107 | D03*
108 | Y353300D02*
109 | D03*
110 | Y363300D02*
111 | D03*
112 | Y358300D02*
113 | D03*
114 | X291000Y404100D02*
115 | D03*
116 | Y409100D02*
117 | D03*
118 | Y414100D02*
119 | D03*
120 | Y419100D02*
121 | D03*
122 | Y429100D02*
123 | D03*
124 | Y424100D02*
125 | D03*
126 | X304900Y404500D02*
127 | D03*
128 | Y409500D02*
129 | D03*
130 | Y414500D02*
131 | D03*
132 | Y419500D02*
133 | D03*
134 | Y429500D02*
135 | D03*
136 | Y424500D02*
137 | D03*
138 | X304700Y338200D02*
139 | D03*
140 | Y343200D02*
141 | D03*
142 | Y348200D02*
143 | D03*
144 | Y353200D02*
145 | D03*
146 | Y363200D02*
147 | D03*
148 | Y358200D02*
149 | D03*
150 | X471200Y401400D02*
151 | D03*
152 | Y406400D02*
153 | D03*
154 | Y411400D02*
155 | D03*
156 | Y416400D02*
157 | D03*
158 | Y426400D02*
159 | D03*
160 | Y421400D02*
161 | D03*
162 | X471600Y339500D02*
163 | D03*
164 | Y344500D02*
165 | D03*
166 | Y349500D02*
167 | D03*
168 | Y354500D02*
169 | D03*
170 | Y364500D02*
171 | D03*
172 | Y359500D02*
173 | D03*
174 | Y216100D02*
175 | D03*
176 | Y221100D02*
177 | D03*
178 | Y226100D02*
179 | D03*
180 | Y231100D02*
181 | D03*
182 | Y241100D02*
183 | D03*
184 | Y236100D02*
185 | D03*
186 | X470600Y152500D02*
187 | D03*
188 | Y157500D02*
189 | D03*
190 | Y162500D02*
191 | D03*
192 | Y167500D02*
193 | D03*
194 | Y177500D02*
195 | D03*
196 | Y172500D02*
197 | D03*
198 | X443700Y124400D02*
199 | D03*
200 | X438700D02*
201 | D03*
202 | X433700D02*
203 | D03*
204 | X428700D02*
205 | D03*
206 | X418700D02*
207 | D03*
208 | X423700D02*
209 | D03*
210 | X357000Y124000D02*
211 | D03*
212 | X352000D02*
213 | D03*
214 | X347000D02*
215 | D03*
216 | X342000D02*
217 | D03*
218 | X332000D02*
219 | D03*
220 | X337000D02*
221 | D03*
222 | X360500Y289900D02*
223 | D03*
224 | X355500D02*
225 | D03*
226 | X350500D02*
227 | D03*
228 | X345500D02*
229 | D03*
230 | X335500D02*
231 | D03*
232 | X340500D02*
233 | D03*
234 | X432500Y290100D02*
235 | D03*
236 | X427500D02*
237 | D03*
238 | X422500D02*
239 | D03*
240 | X417500D02*
241 | D03*
242 | X407500D02*
243 | D03*
244 | X412500D02*
245 | D03*
246 | X431400Y303700D02*
247 | D03*
248 | X426400D02*
249 | D03*
250 | X421400D02*
251 | D03*
252 | X416400D02*
253 | D03*
254 | X406400D02*
255 | D03*
256 | X411400D02*
257 | D03*
258 | X360600Y304500D02*
259 | D03*
260 | X355600D02*
261 | D03*
262 | X350600D02*
263 | D03*
264 | X345600D02*
265 | D03*
266 | X335600D02*
267 | D03*
268 | X340600D02*
269 | D03*
270 | X365000Y469600D02*
271 | D03*
272 | X360000D02*
273 | D03*
274 | X355000D02*
275 | D03*
276 | X350000D02*
277 | D03*
278 | X340000D02*
279 | D03*
280 | X345000D02*
281 | D03*
282 | X435000D02*
283 | D03*
284 | X430000D02*
285 | D03*
286 | X425000D02*
287 | D03*
288 | X420000D02*
289 | D03*
290 | X410000D02*
291 | D03*
292 | X415000D02*
293 | D03*
294 | X252600D02*
295 | D03*
296 | X247600D02*
297 | D03*
298 | X242600D02*
299 | D03*
300 | X237600D02*
301 | D03*
302 | X227600D02*
303 | D03*
304 | X232600D02*
305 | D03*
306 | X183200Y469800D02*
307 | D03*
308 | X178200D02*
309 | D03*
310 | X173200D02*
311 | D03*
312 | X168200D02*
313 | D03*
314 | X158200D02*
315 | D03*
316 | X163200D02*
317 | D03*
318 | X175500Y303900D02*
319 | D03*
320 | X170500D02*
321 | D03*
322 | X165500D02*
323 | D03*
324 | X160500D02*
325 | D03*
326 | X150500D02*
327 | D03*
328 | X155500D02*
329 | D03*
330 | X175700Y290100D02*
331 | D03*
332 | X170700D02*
333 | D03*
334 | X165700D02*
335 | D03*
336 | X160700D02*
337 | D03*
338 | X150700D02*
339 | D03*
340 | X155700D02*
341 | D03*
342 | X260900Y303300D02*
343 | D03*
344 | X255900D02*
345 | D03*
346 | X250900D02*
347 | D03*
348 | X245900D02*
349 | D03*
350 | X235900D02*
351 | D03*
352 | X240900D02*
353 | D03*
354 | X261100Y290100D02*
355 | D03*
356 | X256100D02*
357 | D03*
358 | X251100D02*
359 | D03*
360 | X246100D02*
361 | D03*
362 | X236100D02*
363 | D03*
364 | X241100D02*
365 | D03*
366 | X261300Y123800D02*
367 | D03*
368 | X256300D02*
369 | D03*
370 | X251300D02*
371 | D03*
372 | X246300D02*
373 | D03*
374 | X236300D02*
375 | D03*
376 | X241300D02*
377 | D03*
378 | X180500Y124000D02*
379 | D03*
380 | X175500D02*
381 | D03*
382 | X170500D02*
383 | D03*
384 | X165500D02*
385 | D03*
386 | X155500D02*
387 | D03*
388 | X160500D02*
389 | D03*
390 | X125100Y351700D02*
391 | D03*
392 | Y356700D02*
393 | D03*
394 | Y346700D02*
395 | D03*
396 | Y341700D02*
397 | D03*
398 | Y336700D02*
399 | D03*
400 | Y331700D02*
401 | D03*
402 | D50*
403 | X147744Y146744D02*
404 | D03*
405 | X269791D02*
406 | D03*
407 | Y268791D02*
408 | D03*
409 | X147744D02*
410 | D03*
411 | X327744Y146744D02*
412 | D03*
413 | X449791D02*
414 | D03*
415 | Y268791D02*
416 | D03*
417 | X327744D02*
418 | D03*
419 | X147744Y326744D02*
420 | D03*
421 | X269791D02*
422 | D03*
423 | Y448791D02*
424 | D03*
425 | X147744D02*
426 | D03*
427 | X327744Y326744D02*
428 | D03*
429 | X449791D02*
430 | D03*
431 | Y448791D02*
432 | D03*
433 | X327744D02*
434 | D03*
435 | D51*
436 | X133008Y181964D02*
437 | D03*
438 | Y209524D02*
439 | D03*
440 | X313008Y181964D02*
441 | D03*
442 | Y209524D02*
443 | D03*
444 | X133008Y361964D02*
445 | D03*
446 | Y389524D02*
447 | D03*
448 | X313008Y361964D02*
449 | D03*
450 | Y389524D02*
451 | D03*
452 | D52*
453 | X144031Y185901D02*
454 | D03*
455 | Y205587D02*
456 | D03*
457 | X324031Y185901D02*
458 | D03*
459 | Y205587D02*
460 | D03*
461 | X144031Y365901D02*
462 | D03*
463 | Y385587D02*
464 | D03*
465 | X324031Y365901D02*
466 | D03*
467 | Y385587D02*
468 | D03*
469 | D53*
470 | X132044Y222344D02*
471 | D03*
472 | Y232344D02*
473 | D03*
474 | Y242344D02*
475 | D03*
476 | X235244Y252744D02*
477 | D03*
478 | X225244D02*
479 | D03*
480 | X215244D02*
481 | D03*
482 | X283500Y171200D02*
483 | D03*
484 | Y181200D02*
485 | D03*
486 | Y191200D02*
487 | D03*
488 | Y201200D02*
489 | D03*
490 | Y211200D02*
491 | D03*
492 | Y221200D02*
493 | D03*
494 | Y231200D02*
495 | D03*
496 | Y241200D02*
497 | D03*
498 | Y251200D02*
499 | D03*
500 | X312044Y222344D02*
501 | D03*
502 | Y232344D02*
503 | D03*
504 | Y242344D02*
505 | D03*
506 | X415244Y252744D02*
507 | D03*
508 | X405244D02*
509 | D03*
510 | X395244D02*
511 | D03*
512 | X463500Y171200D02*
513 | D03*
514 | Y181200D02*
515 | D03*
516 | Y191200D02*
517 | D03*
518 | Y201200D02*
519 | D03*
520 | Y211200D02*
521 | D03*
522 | Y221200D02*
523 | D03*
524 | Y231200D02*
525 | D03*
526 | Y241200D02*
527 | D03*
528 | Y251200D02*
529 | D03*
530 | X132044Y402344D02*
531 | D03*
532 | Y412344D02*
533 | D03*
534 | Y422344D02*
535 | D03*
536 | X235244Y432744D02*
537 | D03*
538 | X225244D02*
539 | D03*
540 | X215244D02*
541 | D03*
542 | X283500Y351200D02*
543 | D03*
544 | Y361200D02*
545 | D03*
546 | Y371200D02*
547 | D03*
548 | Y381200D02*
549 | D03*
550 | Y391200D02*
551 | D03*
552 | Y401200D02*
553 | D03*
554 | Y411200D02*
555 | D03*
556 | Y421200D02*
557 | D03*
558 | Y431200D02*
559 | D03*
560 | X312044Y402344D02*
561 | D03*
562 | Y412344D02*
563 | D03*
564 | Y422344D02*
565 | D03*
566 | X415244Y432744D02*
567 | D03*
568 | X405244D02*
569 | D03*
570 | X395244D02*
571 | D03*
572 | X463500Y351200D02*
573 | D03*
574 | Y361200D02*
575 | D03*
576 | Y371200D02*
577 | D03*
578 | Y381200D02*
579 | D03*
580 | Y391200D02*
581 | D03*
582 | Y401200D02*
583 | D03*
584 | Y411200D02*
585 | D03*
586 | Y421200D02*
587 | D03*
588 | Y431200D02*
589 | D03*
590 | D54*
591 | X132044Y252344D02*
592 | D03*
593 | X312044D02*
594 | D03*
595 | X132044Y432344D02*
596 | D03*
597 | X312044D02*
598 | D03*
599 | D55*
600 | X141744Y166744D02*
601 | D03*
602 | Y171744D02*
603 | D03*
604 | X146744Y166744D02*
605 | D03*
606 | Y171744D02*
607 | D03*
608 | X151744Y166744D02*
609 | D03*
610 | Y171744D02*
611 | D03*
612 | X156744Y166744D02*
613 | D03*
614 | Y171744D02*
615 | D03*
616 | X161744Y166744D02*
617 | D03*
618 | X321744D02*
619 | D03*
620 | Y171744D02*
621 | D03*
622 | X326744Y166744D02*
623 | D03*
624 | Y171744D02*
625 | D03*
626 | X331744Y166744D02*
627 | D03*
628 | Y171744D02*
629 | D03*
630 | X336744Y166744D02*
631 | D03*
632 | Y171744D02*
633 | D03*
634 | X341744Y166744D02*
635 | D03*
636 | X141744Y346744D02*
637 | D03*
638 | Y351744D02*
639 | D03*
640 | X146744Y346744D02*
641 | D03*
642 | Y351744D02*
643 | D03*
644 | X151744Y346744D02*
645 | D03*
646 | Y351744D02*
647 | D03*
648 | X156744Y346744D02*
649 | D03*
650 | Y351744D02*
651 | D03*
652 | X161744Y346744D02*
653 | D03*
654 | X321744D02*
655 | D03*
656 | Y351744D02*
657 | D03*
658 | X326744Y346744D02*
659 | D03*
660 | Y351744D02*
661 | D03*
662 | X331744Y346744D02*
663 | D03*
664 | Y351744D02*
665 | D03*
666 | X336744Y346744D02*
667 | D03*
668 | Y351744D02*
669 | D03*
670 | X341744Y346744D02*
671 | D03*
672 | D56*
673 | X161744Y171744D02*
674 | D03*
675 | X341744D02*
676 | D03*
677 | X161744Y351744D02*
678 | D03*
679 | X341744D02*
680 | D03*
681 | D57*
682 | X205244Y252744D02*
683 | D03*
684 | X283500Y161200D02*
685 | D03*
686 | X385244Y252744D02*
687 | D03*
688 | X463500Y161200D02*
689 | D03*
690 | X205244Y432744D02*
691 | D03*
692 | X283500Y341200D02*
693 | D03*
694 | X385244Y432744D02*
695 | D03*
696 | X463500Y341200D02*
697 | D03*
698 | D58*
699 | X235744Y276244D02*
700 | D03*
701 | X215744D02*
702 | D03*
703 | X415744D02*
704 | D03*
705 | X395744D02*
706 | D03*
707 | X235744Y456244D02*
708 | D03*
709 | X215744D02*
710 | D03*
711 | X415744D02*
712 | D03*
713 | X395744D02*
714 | D03*
715 | M02*
716 |
--------------------------------------------------------------------------------
/hardware/panel.LDP:
--------------------------------------------------------------------------------
1 | Layer Pairs Export File for PCB: C:\Users\TSTERN\Google Drive\projects\Stepper_feedback\hardware\NZS_A4954_R2.0\panel.PcbDoc
2 | LayersSetName=Top_Bot_Thru_Holes|DrillFile=panel-roundholes.txt|DrillLayers=gtl,gbl
3 | LayersSetName=Top_Bot_Slot_Holes|DrillFile=panel-slotholes.txt|DrillLayers=gtl,gbl
4 |
--------------------------------------------------------------------------------
/hardware/panel.REP:
--------------------------------------------------------------------------------
1 | *************************************************************
2 | FileName = panel.GBR
3 | AutoAperture = True
4 | *************************************************************
5 | Generating : Top Layer
6 | File : panel.GTL
7 |
8 | Adding Layer : Top Layer
9 |
10 | Adding Layer : Multi-Layer
11 |
12 |
13 | Used DCodes :
14 | D10
15 | D11
16 | D12
17 | D13
18 | D14
19 | D15
20 | D16
21 | D17
22 | D18
23 | D19
24 | D20
25 | D21
26 | D22
27 | D23
28 | D24
29 | D25
30 | D26
31 | D27
32 | D28
33 | D29
34 | D30
35 | D31
36 | D32
37 | D33
38 | D34
39 | D35
40 | D36
41 | D37
42 | D38
43 | D39
44 | D40
45 | D41
46 | D42
47 | D43
48 | D44
49 | D45
50 | D46
51 | D47
52 | D48
53 | D49
54 | D50
55 | D51
56 | D52
57 | D53
58 | D54
59 | D55
60 | D56
61 | D57
62 | D58
63 | D59
64 | D60
65 | *************************************************************
66 |
67 | *************************************************************
68 | Generating : Bottom Layer
69 | File : panel.GBL
70 |
71 | Adding Layer : Bottom Layer
72 |
73 | Adding Layer : Multi-Layer
74 |
75 |
76 | Used DCodes :
77 | D13
78 | D24
79 | D38
80 | D40
81 | D41
82 | D43
83 | D48
84 | D49
85 | D50
86 | D51
87 | D52
88 | D53
89 | D54
90 | D55
91 | D56
92 | D57
93 | D58
94 | D59
95 | D60
96 | D61
97 | D62
98 | D63
99 | D64
100 | D65
101 | D66
102 | *************************************************************
103 |
104 | *************************************************************
105 | Generating : Bottom Pad Master
106 | File : panel.GPB
107 |
108 | Adding Layer : Bottom Layer
109 |
110 | Adding Layer : Multi-Layer
111 |
112 |
113 | Used DCodes :
114 | D13
115 | D24
116 | D49
117 | D50
118 | D51
119 | D52
120 | D53
121 | D54
122 | D55
123 | D56
124 | D57
125 | D58
126 | D61
127 | D62
128 | D63
129 | D64
130 | D65
131 | D66
132 | *************************************************************
133 |
134 | *************************************************************
135 | Generating : Top Pad Master
136 | File : panel.GPT
137 |
138 | Adding Layer : Top Layer
139 |
140 | Adding Layer : Multi-Layer
141 |
142 |
143 | Used DCodes :
144 | D10
145 | D11
146 | D12
147 | D13
148 | D14
149 | D15
150 | D16
151 | D17
152 | D18
153 | D19
154 | D20
155 | D21
156 | D22
157 | D23
158 | D24
159 | D25
160 | D26
161 | D27
162 | D28
163 | D29
164 | D30
165 | D31
166 | D32
167 | D33
168 | D34
169 | D35
170 | D36
171 | D37
172 | D49
173 | D50
174 | D51
175 | D52
176 | D53
177 | D54
178 | D55
179 | D56
180 | D57
181 | D58
182 | *************************************************************
183 |
184 | *************************************************************
185 | Generating : Top Overlay
186 | File : panel.GTO
187 |
188 | Adding Layer : Top Overlay
189 |
190 |
191 | Used DCodes :
192 | D43
193 | D45
194 | D67
195 | D68
196 | D69
197 | D70
198 | *************************************************************
199 |
200 | *************************************************************
201 | Generating : Top Paste
202 | File : panel.GTP
203 |
204 | Adding Layer : Top Paste
205 |
206 | Adding Layer : Top Layer
207 |
208 | Adding Layer : Multi-Layer
209 |
210 |
211 | Used DCodes :
212 | D10
213 | D11
214 | D12
215 | D13
216 | D14
217 | D15
218 | D16
219 | D17
220 | D18
221 | D19
222 | D20
223 | D21
224 | D22
225 | D23
226 | D24
227 | D25
228 | D26
229 | D27
230 | D28
231 | D29
232 | D30
233 | D31
234 | D32
235 | D33
236 | D34
237 | D35
238 | D36
239 | D37
240 | D43
241 | *************************************************************
242 |
243 | *************************************************************
244 | Generating : Top Solder
245 | File : panel.GTS
246 |
247 | Adding Layer : Top Solder
248 |
249 | Adding Layer : Top Layer
250 |
251 | Adding Layer : Multi-Layer
252 |
253 |
254 | Used DCodes :
255 | D43
256 | D71
257 | D72
258 | D73
259 | D74
260 | D75
261 | D76
262 | D77
263 | D78
264 | D79
265 | D80
266 | D81
267 | D82
268 | D83
269 | D84
270 | D85
271 | D86
272 | D87
273 | D88
274 | D89
275 | D90
276 | D91
277 | D92
278 | D93
279 | D94
280 | D95
281 | D96
282 | D97
283 | D98
284 | D99
285 | D100
286 | D101
287 | D102
288 | D103
289 | D104
290 | D105
291 | D106
292 | D107
293 | D108
294 | *************************************************************
295 |
296 | *************************************************************
297 | Generating : Bottom Solder
298 | File : panel.GBS
299 |
300 | Adding Layer : Bottom Solder
301 |
302 | Adding Layer : Bottom Layer
303 |
304 | Adding Layer : Multi-Layer
305 |
306 |
307 | Used DCodes :
308 | D43
309 | D74
310 | D85
311 | D99
312 | D100
313 | D101
314 | D102
315 | D103
316 | D104
317 | D105
318 | D106
319 | D107
320 | D108
321 | D109
322 | D110
323 | D111
324 | D112
325 | D113
326 | D114
327 | D115
328 | *************************************************************
329 |
330 | *************************************************************
331 | Generating : Bottom Paste
332 | File : panel.GBP
333 |
334 | Adding Layer : Bottom Paste
335 |
336 | Adding Layer : Bottom Layer
337 |
338 | Adding Layer : Multi-Layer
339 |
340 |
341 | Used DCodes :
342 | D13
343 | D24
344 | D43
345 | D61
346 | D62
347 | D63
348 | D64
349 | D65
350 | D66
351 | *************************************************************
352 |
353 | *************************************************************
354 | Generating : Bottom Overlay
355 | File : panel.GBO
356 |
357 | Adding Layer : Bottom Overlay
358 |
359 |
360 | Used DCodes :
361 | D43
362 | D67
363 | D69
364 | D116
365 | *************************************************************
366 |
367 | *************************************************************
368 | Generating : Keep-Out Layer
369 | File : panel.GKO
370 |
371 | Adding Layer : Keep-Out Layer
372 |
373 |
374 | Used DCodes :
375 | D38
376 | D45
377 | *************************************************************
378 |
379 | *************************************************************
380 | Generating : Mechanical 1
381 | File : panel.GM1
382 |
383 | Adding Layer : Mechanical 1
384 |
385 |
386 | Used DCodes :
387 | *************************************************************
388 |
389 | *************************************************************
390 | Generating : Mechanical 3
391 | File : panel.GM3
392 |
393 | Adding Layer : Mechanical 3
394 |
395 |
396 | Used DCodes :
397 | D40
398 | D117
399 | *************************************************************
400 |
401 | *************************************************************
402 | Generating : Mechanical 2
403 | File : panel.GM2
404 |
405 | Adding Layer : Mechanical 2
406 |
407 |
408 | Used DCodes :
409 | D68
410 | *************************************************************
411 |
412 | *************************************************************
413 | Generating : Mechanical 13
414 | File : panel.GM13
415 |
416 | Adding Layer : Mechanical 13
417 |
418 |
419 | Used DCodes :
420 | D118
421 | *************************************************************
422 |
423 | *************************************************************
424 | Generating : Mechanical 15
425 | File : panel.GM15
426 |
427 | Adding Layer : Mechanical 15
428 |
429 |
430 | Used DCodes :
431 | D118
432 | D119
433 | *************************************************************
434 |
435 | *************************************************************
436 | Generating : Dielectric 1
437 | File : panel.1
438 |
439 | Adding Layer : Dielectric 1
440 |
441 |
442 | Used DCodes :
443 | *************************************************************
444 |
445 | *************************************************************
446 | Generating : Multi-Layer
447 | File : panel.GML
448 |
449 | Adding Layer : Multi-Layer
450 |
451 |
452 | Used DCodes :
453 | D49
454 | D50
455 | D51
456 | D52
457 | D53
458 | D54
459 | D55
460 | D56
461 | D57
462 | D58
463 | *************************************************************
464 |
465 | *************************************************************
466 | Generating : Drill Drawing
467 | File : panel.GD1
468 |
469 | Adding Drill Pair : Top Layer-Bottom Layer
470 |
471 | Adding Layer : Drill Drawing
472 |
473 |
474 | Used DCodes :
475 | D120
476 | D121
477 | D122
478 | *************************************************************
479 |
480 |
--------------------------------------------------------------------------------
/hardware/panel.RUL:
--------------------------------------------------------------------------------
1 | DRC Rules Export File for PCB: C:\Users\TSTERN\Google Drive\projects\Stepper_feedback\hardware\NZS_A4954_R2.0\panel.PcbDoc
2 | RuleKind=ShortCircuit|RuleName=ShortCircuit|Scope=Board|Allowed=0
3 | RuleKind=Clearance|RuleName=Clearance|Scope=Board|Minimum=10.00
4 | RuleKind=Width|RuleName=Width|Scope=Board|Minimum=10.00
5 | RuleKind=SolderMaskExpansion|RuleName=SolderMaskExpansion|Scope=Board|Minimum=4.00
6 |
--------------------------------------------------------------------------------
/hardware/panel.apr:
--------------------------------------------------------------------------------
1 | D10 RECTANGULAR 31.496 35.433 0.000 FLASH 270.000
2 | D12 RECTANGULAR 39.370 70.866 0.000 FLASH 270.000
3 | D13 RECTANGULAR 31.496 33.465 0.000 FLASH 90.000
4 | D14 RECTANGULAR 15.748 68.898 0.000 FLASH 270.000
5 | D15 RECTANGULAR 47.244 94.488 0.000 FLASH 270.000
6 | D16 RECTANGULAR 47.244 122.047 0.000 FLASH 270.000
7 | D17 RECTANGULAR 47.244 70.866 0.000 FLASH 0.000
8 | D19 RECTANGULAR 31.496 31.496 0.000 FLASH 90.000
9 | D21 RECTANGULAR 27.559 51.181 0.000 FLASH 90.000
10 | D23 RECTANGULAR 23.622 35.433 0.000 FLASH 270.000
11 | D24 RECTANGULAR 35.433 29.528 0.000 FLASH 0.000
12 | D26 RECTANGULAR 202.756 202.756 0.000 FLASH 135.000
13 | D32 RECTANGULAR 66.929 39.370 0.000 FLASH 270.000
14 | D33 RECTANGULAR 118.110 118.110 0.000 FLASH 180.000
15 | D34 ROUNDED 17.716 55.118 0.000 FLASH 270.000
16 | D35 RECTANGULAR 17.716 55.118 0.000 FLASH 270.000
17 | D36 RECTANGULAR 27.559 37.402 0.000 FLASH 90.000
18 | D37 RECTANGULAR 125.000 45.000 0.000 FLASH 0.000
19 | D38 ROUNDED 6.000 6.000 0.000 LINE 0.000
20 | D39 ROUNDED 30.000 30.000 0.000 LINE 0.000
21 | D40 ROUNDED 20.000 20.000 0.000 LINE 0.000
22 | D41 ROUNDED 40.000 40.000 0.000 LINE 0.000
23 | D42 ROUNDED 16.000 16.000 0.000 LINE 0.000
24 | D43 ROUNDED 8.000 8.000 0.000 LINE 0.000
25 | D44 ROUNDED 25.000 25.000 0.000 LINE 0.000
26 | D45 ROUNDED 10.000 10.000 0.000 LINE 0.000
27 | D46 ROUNDED 50.000 50.000 0.000 LINE 0.000
28 | D47 ROUNDED 15.000 15.000 0.000 LINE 0.000
29 | D48 ROUNDED 60.000 60.000 0.000 LINE 0.000
30 | D49 ROUNDED 10.000 10.000 0.000 FLASH 0.000
31 | D50 ROUNDED 47.244 94.488 0.000 FLASH 0.000
32 | D51 ROUNDED 35.433 61.024 0.000 FLASH 270.000
33 | D52 ROUNDED 49.213 37.402 0.000 FLASH 270.000
34 | D53 ROUNDED 70.000 70.000 0.000 FLASH 0.000
35 | D54 RECTANGULAR 70.000 70.000 0.000 FLASH 0.000
36 | D55 ROUNDED 40.000 40.000 0.000 FLASH 0.000
37 | D56 RECTANGULAR 40.000 40.000 0.000 FLASH 0.000
38 | D57 RECTANGULAR 70.000 70.000 0.000 FLASH 90.000
39 | D58 ROUNDED 78.740 78.740 0.000 FLASH 0.000
40 | D59 ROUNDED 24.000 24.000 0.000 FLASH 0.000
41 | D60 ROUNDED 19.685 19.685 0.000 FLASH 0.000
42 | D61 RECTANGULAR 31.496 33.465 0.000 FLASH 180.000
43 | D62 RECTANGULAR 35.433 29.528 0.000 FLASH 90.000
44 | D64 RECTANGULAR 23.622 62.992 0.000 FLASH 0.000
45 | D65 RECTANGULAR 17.716 55.118 0.000 FLASH 0.000
46 | D66 ROUNDED 17.716 55.118 0.000 FLASH 0.000
47 | D67 ROUNDED 9.842 9.842 0.000 LINE 0.000
48 | D68 ROUNDED 5.000 5.000 0.000 LINE 0.000
49 | D69 ROUNDED 7.874 7.874 0.000 LINE 0.000
50 | D70 ROUNDED 14.000 14.000 0.000 LINE 0.000
51 | D71 RECTANGULAR 39.496 43.433 0.000 FLASH 270.000
52 | D73 RECTANGULAR 47.370 78.866 0.000 FLASH 270.000
53 | D74 RECTANGULAR 39.496 41.465 0.000 FLASH 90.000
54 | D75 RECTANGULAR 23.748 76.898 0.000 FLASH 270.000
55 | D76 RECTANGULAR 55.244 102.488 0.000 FLASH 270.000
56 | D77 RECTANGULAR 55.244 130.047 0.000 FLASH 270.000
57 | D78 RECTANGULAR 55.244 78.866 0.000 FLASH 0.000
58 | D80 RECTANGULAR 39.496 39.496 0.000 FLASH 90.000
59 | D82 RECTANGULAR 35.559 59.181 0.000 FLASH 90.000
60 | D84 RECTANGULAR 31.622 43.433 0.000 FLASH 270.000
61 | D85 RECTANGULAR 43.433 37.528 0.000 FLASH 0.000
62 | D87 RECTANGULAR 210.756 210.756 0.000 FLASH 135.000
63 | D93 RECTANGULAR 74.929 47.370 0.000 FLASH 270.000
64 | D94 RECTANGULAR 126.110 126.110 0.000 FLASH 180.000
65 | D95 ROUNDED 25.716 63.118 0.000 FLASH 270.000
66 | D96 RECTANGULAR 25.716 63.118 0.000 FLASH 270.000
67 | D97 RECTANGULAR 35.559 45.402 0.000 FLASH 90.000
68 | D98 RECTANGULAR 133.000 53.000 0.000 FLASH 0.000
69 | D99 ROUNDED 18.000 18.000 0.000 FLASH 0.000
70 | D100 ROUNDED 55.244 102.488 0.000 FLASH 0.000
71 | D101 ROUNDED 43.433 69.024 0.000 FLASH 270.000
72 | D102 ROUNDED 57.213 45.402 0.000 FLASH 270.000
73 | D103 ROUNDED 78.000 78.000 0.000 FLASH 0.000
74 | D104 RECTANGULAR 78.000 78.000 0.000 FLASH 0.000
75 | D105 ROUNDED 48.000 48.000 0.000 FLASH 0.000
76 | D106 RECTANGULAR 48.000 48.000 0.000 FLASH 0.000
77 | D107 RECTANGULAR 78.000 78.000 0.000 FLASH 90.000
78 | D108 ROUNDED 86.740 86.740 0.000 FLASH 0.000
79 | D109 RECTANGULAR 130.000 250.000 0.000 FLASH 0.000
80 | D110 RECTANGULAR 39.496 41.465 0.000 FLASH 180.000
81 | D111 RECTANGULAR 43.433 37.528 0.000 FLASH 90.000
82 | D113 RECTANGULAR 31.622 70.992 0.000 FLASH 0.000
83 | D114 RECTANGULAR 25.716 63.118 0.000 FLASH 0.000
84 | D115 ROUNDED 25.716 63.118 0.000 FLASH 0.000
85 | D116 ROUNDED 23.622 23.622 0.000 LINE 0.000
86 | D117 ROUNDED 47.244 47.244 0.000 LINE 0.000
87 | D118 ROUNDED 3.937 3.937 0.000 LINE 0.000
88 | D119 ROUNDED 1.968 1.968 0.000 LINE 0.000
89 | D120 ROUNDED 2.000 2.000 0.000 LINE 0.000
90 | D121 ROUNDED 2.667 2.667 0.000 LINE 0.000
91 | D122 ROUNDED 1.333 1.333 0.000 LINE 0.000
92 |
--------------------------------------------------------------------------------
/stl/Helm.SLDPRT:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/stl/Helm.SLDPRT
--------------------------------------------------------------------------------
/stl/Helm.STL:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/stl/Helm.STL
--------------------------------------------------------------------------------
/stl/cover1.SLDPRT:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/stl/cover1.SLDPRT
--------------------------------------------------------------------------------
/stl/cover1.STL:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/stl/cover1.STL
--------------------------------------------------------------------------------
/stl/cover2.SLDPRT:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/stl/cover2.SLDPRT
--------------------------------------------------------------------------------
/stl/cover2.STL:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kaizhi-singtown/stepServo/82482ecb6c9cf0ee52a0698e996605d1f5935393/stl/cover2.STL
--------------------------------------------------------------------------------