grblHAL core  20260619
nuts_bolts.h
Go to the documentation of this file.
1 /*
2  nuts_bolts.h - Header file for shared definitions, variables, and functions
3 
4  Part of grblHAL
5 
6  Copyright (c) 2017-2026 Terje Io
7  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
8  Copyright (c) 2009-2011 Simen Svale Skogsrud
9 
10  grblHAL is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  grblHAL is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
22 */
23 
24 #ifndef _NUTS_BOLTS_H_
25 #define _NUTS_BOLTS_H_
26 
27 #include "grbl.h"
28 #include "errors.h"
29 
30 #ifndef true
31 #define false 0
32 #define true 1
33 #endif
34 
35 #define Off 0
36 #define On 1
37 
38 #define SOME_LARGE_VALUE 1.0E+38f
39 #ifndef M_PI
40 #define M_PI 3.14159265358979323846f
41 #endif
42 
43 #define TOLERANCE_EQUAL 0.0001f
44 
45 #define RADDEG 0.01745329251994329577f // Radians per degree
46 #define DEGRAD 57.29577951308232087680f // Degrees per radians
47 #define SQRT3 1.73205080756887729353f
48 #define SIN120 0.86602540378443864676f
49 #define COS120 -0.5f
50 #define TAN60 1.73205080756887729353f
51 #define SIN30 0.5f
52 #define TAN30 0.57735026918962576451f
53 #define TAN30_2 0.28867513459481288225f
54 
55 #define ABORTED (sys.abort || sys.cancel)
56 #define IS_AXIS_LETTER(c) (AXIS3_LETTER == c || AXIS4_LETTER == c || AXIS5_LETTER == c || AXIS6_LETTER == c || AXIS7_LETTER == c)
57 #define IS_AXIS_LETTER_VALID(c) (c == 'A' || c == 'B' || c == 'C' || c == 'U' || c == 'V' || c == 'W')
58 //#define AXIS_LETTER_FN_IDX(c) ((c >= 'X' && c <= 'Z') ? ((c - 'X') << 1) : ((c >= 'A' && c <= 'C') ? c - 'A' + 6 : ((c >= 'U' && c <= 'W') ? c - 'U' + 9 : -1)))
59 
60 // Convert character to uppercase
61 #define CAPS(c) ((c >= 'a' && c <= 'z') ? (c & 0x5F) : c)
62 #define LCAPS(c) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c)
63 
64 #if !(defined(STM32F103xB) || defined(STM32F303xC))
65 #ifndef UNUSED
66 #define UNUSED(x) (void)(x)
67 #endif
68 #endif
69 
70 // Axis array index values. Must start with 0 and be continuous.
71 #define X_AXIS 0 // Axis indexing value.
72 #define Y_AXIS 1
73 #define Z_AXIS 2
74 #define X_AXIS_BIT bit(X_AXIS)
75 #define Y_AXIS_BIT bit(Y_AXIS)
76 #define Z_AXIS_BIT bit(Z_AXIS)
77 #if N_AXIS > 3
78 #define AXIS3_IDX 3
79 #define AXIS3_BIT bit(AXIS3_IDX)
80 #endif
81 #if N_AXIS > 4
82 #define AXIS4_IDX 4
83 #define AXIS4_BIT bit(AXIS4_IDX)
84 #endif
85 #if N_AXIS > 5
86 #define AXIS5_IDX 5
87 #define AXIS5_BIT bit(AXIS5_IDX)
88 #endif
89 #if N_AXIS > 6
90 #define AXIS6_IDX 6
91 #define AXIS6_BIT bit(AXIS6_IDX)
92 #endif
93 #if N_AXIS == 8
94 #define AXIS7_IDX 7
95 #define AXIS7_BIT bit(AXIS7_IDX)
96 #endif
97 
98 #if N_AXIS == 3
99 #define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT)
100 #elif N_AXIS == 4
101 #define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|AXIS3_BIT)
102 #elif N_AXIS == 5
103 #define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|AXIS3_BIT|AXIS4_BIT)
104 #elif N_AXIS == 6
105 #define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|AXIS3_BIT|AXIS4_BIT|AXIS5_BIT)
106 #elif N_AXIS == 7
107 #define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|AXIS3_BIT|AXIS4_BIT|AXIS5_BIT|AXIS6_BIT)
108 #else
109 #define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|AXIS3_BIT|AXIS4_BIT|AXIS5_BIT|AXIS6_BIT|AXIS7_BIT)
110 #endif
111 
112 #ifdef AXIS7_IDX
113 #define N_ABC_AXIS 5
114 #elif defined(AXIS6_IDX)
115 #define N_ABC_AXIS 4
116 #elif defined(AXIS5_IDX)
117 #define N_ABC_AXIS 3
118 #elif defined(AXIS4_IDX)
119 #define N_ABC_AXIS 2
120 #elif defined(AXIS3_IDX)
121 #define N_ABC_AXIS 1
122 #else
123 #define N_ABC_AXIS 0
124 #endif
125 
126 #define AXIS0_LETTER 'X'
127 #define AXIS1_LETTER 'Y'
128 #define AXIS2_LETTER 'Z'
129 
130 #if N_AXIS > 3
131  #if AXIS_REMAP_ABC2UVW
132  #define AXIS3_LETTER 'U'
133  #elif !defined(AXIS3_LETTER)
134  #define AXIS3_LETTER 'A'
135  #elif !IS_AXIS_LETTER_VALID(AXIS3_LETTER)
136  #error "Illegal axis letter assigned!"
137  #endif
138 #else
139  #define AXIS3_LETTER 0
140 #endif
141 
142 #if N_AXIS > 4
143  #if AXIS_REMAP_ABC2UVW
144  #define AXIS4_LETTER 'V'
145  #elif !defined(AXIS4_LETTER)
146  #define AXIS4_LETTER 'B'
147  #elif !IS_AXIS_LETTER_VALID(AXIS4_LETTER)
148  #error "Illegal axis letter assigned!"
149  #endif
150 #else
151  #define AXIS4_LETTER 0
152 #endif
153 
154 #if N_AXIS > 5
155  #if AXIS_REMAP_ABC2UVW
156  #define AXIS5_LETTER 'W'
157  #elif !defined(AXIS5_LETTER)
158  #define AXIS5_LETTER 'C'
159  #elif !IS_AXIS_LETTER_VALID(AXIS5_LETTER)
160  #error "Illegal axis letter assigned!"
161  #endif
162 #else
163  #define AXIS5_LETTER 0
164 #endif
165 
166 #if N_AXIS > 6
167  #if !defined(AXIS6_LETTER)
168  #define AXIS6_LETTER 'U'
169  #elif !IS_AXIS_LETTER_VALID(AXIS6_LETTER)
170  #error "Illegal axis letter assigned!"
171  #endif
172 #else
173  #define AXIS6_LETTER 0
174 #endif
175 
176 #if N_AXIS > 7
177  #if !defined(AXIS7_LETTER)
178  #define AXIS7_LETTER 'V'
179  #elif !IS_AXIS_LETTER_VALID(AXIS7_LETTER)
180  #error "Illegal axis letter assigned!"
181  #endif
182 #else
183  #define AXIS7_LETTER 0
184 #endif
185 
186 #if N_AXIS == 4
187 #define AXIS_LETTER_TO_IDX(c) AXIS3_IDX
188 #elif N_AXIS == 5
189 #define AXIS_LETTER_TO_IDX(c) \
190 (c == AXIS3_LETTER ? AXIS3_IDX : \
191 (c == AXIS4_LETTER ? AXIS4_IDX : -1))
192 #elif N_AXIS == 6
193 #define AXIS_LETTER_TO_IDX(c) \
194 (c == AXIS3_LETTER ? AXIS3_IDX : \
195 (c == AXIS4_LETTER ? AXIS4_IDX : \
196 (c == AXIS5_LETTER ? AXIS5_IDX : -1)))
197 #elif N_AXIS == 7
198 #define AXIS_LETTER_TO_IDX(c) \
199 (c == AXIS3_LETTER ? AXIS3_IDX : \
200 (c == AXIS4_LETTER ? AXIS4_IDX : \
201 (c == AXIS5_LETTER ? AXIS5_IDX : \
202 (c == AXIS6_LETTER ? AXIS6_IDX : -1))))
203 #elif N_AXIS == 8
204 #define AXIS_LETTER_TO_IDX(c) \
205 (c == AXIS3_LETTER ? AXIS3_IDX : \
206 (c == AXIS4_LETTER ? AXIS4_IDX : \
207 (c == AXIS5_LETTER ? AXIS5_IDX : \
208 (c == AXIS6_LETTER ? AXIS6_IDX : \
209 (c == AXIS7_LETTER ? AXIS7_IDX : -1)))))
210 #endif
211 
212 #if IS_AXIS_LETTER('A')
213 #define A_AXIS AXIS_LETTER_TO_IDX('A')
214 #define A_AXIS_BIT bit(A_AXIS)
215 #endif
216 
217 #if IS_AXIS_LETTER('B')
218 #define B_AXIS AXIS_LETTER_TO_IDX('B')
219 #define B_AXIS_BIT bit(B_AXIS)
220 #endif
221 
222 #if IS_AXIS_LETTER('C')
223 #define C_AXIS AXIS_LETTER_TO_IDX('C')
224 #define C_AXIS_BIT bit(C_AXIS)
225 #endif
226 
227 #if !LATHE_UVW_OPTION
228 
229 #if IS_AXIS_LETTER('U')
230 #define U_AXIS AXIS_LETTER_TO_IDX('U')
231 #define U_AXIS_BIT bit(U_AXIS)
232 #endif
233 
234 #if IS_AXIS_LETTER('V')
235 #define V_AXIS AXIS_LETTER_TO_IDX('V')
236 #define V_AXIS_BIT bit(V_AXIS)
237 #endif
238 
239 #if IS_AXIS_LETTER('W')
240 #define W_AXIS AXIS_LETTER_TO_IDX('W')
241 #define W_AXIS_BIT bit(W_AXIS)
242 #endif
243 
244 #endif
245 
246 typedef uint32_t line_number_t;
247 
248 typedef union {
249  uint8_t mask;
250  uint8_t bits;
251  uint8_t value;
252  struct {
253  uint8_t x :1,
254  y :1,
255  z :1
256 #if N_AXIS > 3
257  #ifdef A_AXIS
258  , a :1
259  #endif
260  #ifdef B_AXIS
261  , b :1
262  #endif
263  #ifdef C_AXIS
264  , c :1
265  #endif
266  #ifdef U_AXIS
267  , u :1
268  #endif
269  #ifdef V_AXIS
270  , v :1
271  #endif
272  #ifdef W_AXIS
273  , w :1
274  #endif
275 #endif
276 ;
277  };
278  struct {
279  uint8_t a0 :1,
280  a1 :1,
281  a2 :1,
282  a3 :1,
283  a4 :1,
284  a5 :1,
285  a6 :1,
286  a7 :1;
287  };
289 
291 typedef union {
292  float values[N_AXIS];
293  struct {
294  float x;
295  float y;
296  float z;
297 #if N_AXIS > 3
298  #ifdef A_AXIS
299  float a;
300  #endif
301  #ifdef B_AXIS
302  float b;
303  #endif
304  #ifdef C_AXIS
305  float c;
306  #endif
307  #ifdef U_AXIS
308  float u;
309  #endif
310  #ifdef V_AXIS
311  float v;
312  #endif
313  #ifdef W_AXIS
314  float w;
315  #endif
316 #endif
317  };
318 } coord_data_t;
319 
321 typedef struct {
323 #ifdef ROTATION_ENABLE
324  float rotation;
325 #endif
327 
328 typedef union {
329  int32_t value[N_AXIS];
330  struct {
331  int32_t x;
332  int32_t y;
333  int32_t z;
334 #if N_AXIS > 3
335  #ifdef B_AXIS
336  int32_t a;
337  #endif
338  #ifdef B_AXIS
339  int32_t b;
340  #endif
341  #ifdef C_AXIS
342  int32_t c;
343  #endif
344  #ifdef U_AXIS
345  int32_t u;
346  #endif
347  #ifdef V_AXIS
348  int32_t v;
349  #endif
350  #ifdef W_AXIS
351  int32_t w;
352  #endif
353 #endif
354  };
355 } mpos_t;
356 
357 typedef union {
358  float values[2];
359  struct {
360  float x;
361  float y;
362  };
363 } point_2d_t;
364 
365 typedef union {
366  float values[3];
367  struct {
368  float x;
369  float y;
370  float z;
371  };
372 } point_3d_t;
373 
375 typedef union {
376  uint8_t axis[3];
377  struct {
378  uint8_t axis_0;
379  uint8_t axis_1;
380  uint8_t axis_linear;
381  };
382 } plane_t;
383 
384 #pragma pack(push, 1)
385 
387 typedef union {
388  uint32_t bits;
389  struct {
394  };
396 
398 typedef struct {
402 
404 typedef union {
405  uint16_t state;
406  home_signals_t details; // Stepper driver signals states.
408 
410 typedef struct {
414 
415 #pragma pack(pop)
416 
417 // NOTE: the pin_function_t enum must be kept in sync with any changes!
418 typedef union {
419  uint16_t bits;
420  uint16_t mask;
421  uint16_t value;
422  struct {
423  uint16_t reset :1,
429  e_stop :1,
439  };
441 
442 typedef enum {
446 
447 // Conversions
448 #define MM_PER_INCH (25.40f)
449 #define INCH_PER_MM (0.0393701f)
450 
451 #define MAX_INT_DIGITS 9 // Maximum number of digits in int32 (and float)
452 #define STRLEN_COORDVALUE (MAX_INT_DIGITS + N_DECIMAL_COORDVALUE_INCH + 1) // 8.4 format - excluding terminating null
453 
454 // Useful macros
455 #ifndef max
456 #define max(a,b) (((a) > (b)) ? (a) : (b))
457 #endif
458 #ifndef min
459 #define min(a,b) (((a) < (b)) ? (a) : (b))
460 #endif
461 #ifndef constrain
462 #define constrain(val, min, max) ((val) < (min) ? (min) : ((val) > (max) ? (max) : (val)))
463 #endif
464 #define clear_vector(a) memset(a, 0, sizeof(a))
465 #define isequal_position_vector(a, b) !memcmp(a, b, sizeof(coord_data_t))
466 #define is0_position_vector(a) !memcmp(a, &((coord_data_t){0}), sizeof(coord_data_t))
467 
468 // Bit field and masking macros
469 #ifndef bit
470 #define bit(n) (1UL << (n))
471 #endif
472 #define bit_true(x, mask) (x) |= (mask)
473 #define bit_false(x, mask) (x) &= ~(mask)
474 #define BIT_SET(x, bit, v) { if (v) { x |= (bit); } else { x &= ~(bit); } }
475 
476 #define bit_istrue(x, mask) (((x) & (mask)) != 0)
477 #define bit_isfalse(x, mask) (((x) & (mask)) == 0)
478 
479 extern char const *const axis_letter[];
480 extern const coord_data_t null_vector;
481 
482 // Converts an uint32 variable to string.
483 char *uitoa (uint32_t n);
484 
485 // Converts a float variable to string with the specified number of decimal places.
486 char *ftoa (float n, uint8_t decimal_places);
487 
488 // Trim trailing zeros and possibly decimal point
489 char *trim_float (char *s);
490 
491 // Returns true if float value is a whole number (integer)
492 bool isintf (float value);
493 
494 status_code_t read_uint (const char *line, uint_fast8_t *char_counter, uint32_t *uint_ptr);
495 
496 // Read a floating point value from a string. Line points to the input buffer, char_counter
497 // is the indexer pointing to the current character of the line, while float_ptr is
498 // a pointer to the result variable. Returns true when it succeeds
499 bool read_float (const char *line, uint_fast8_t *char_counter, float *float_ptr);
500 
501 // Non-blocking delay function used for general operation and suspend features.
502 bool delay_sec (float seconds, delaymode_t mode);
503 
504 float convert_delta_vector_to_unit_vector(float *vector);
505 
506 void rotate (coord_data_t *pt, plane_t plane, float angle /*rad*/);
507 
508 // parse ISO8601 datetime
509 struct tm *get_datetime (const char *s);
510 
511 char *strcaps (char *s);
512 
513 uint_fast8_t bit_count (uint32_t bits);
514 
515 void dummy_handler (void);
516 
517 #ifdef _WIN32
518 
519 static int ffs (int i)
520 {
521  int idx = 0;
522 
523  while(i) {
524  idx++;
525  if(i & 1)
526  break;
527  i >>= 1;
528  }
529 
530  return idx;
531 }
532 
533 #endif // _WIN32
534 
535 #endif
#define N_AXIS
Defines number of axes supported - minimum 3, maximum 8. If more than 3 axes are configured a complia...
Definition: config.h:42
status_code_t
Definition: errors.h:31
float convert_delta_vector_to_unit_vector(float *vector)
Definition: nuts_bolts.c:343
struct tm * get_datetime(const char *s)
Definition: nuts_bolts.c:375
char * strcaps(char *s)
Definition: nuts_bolts.c:436
bool isintf(float value)
Definition: nuts_bolts.c:318
uint32_t line_number_t
Definition: nuts_bolts.h:246
void rotate(coord_data_t *pt, plane_t plane, float angle)
Definition: nuts_bolts.c:364
char const *const axis_letter[]
Definition: nuts_bolts.c:85
char * ftoa(float n, uint8_t decimal_places)
Definition: nuts_bolts.c:126
const coord_data_t null_vector
Definition: nuts_bolts.c:62
uint_fast8_t bit_count(uint32_t bits)
Definition: nuts_bolts.c:452
char * uitoa(uint32_t n)
Definition: nuts_bolts.c:107
delaymode_t
Definition: nuts_bolts.h:442
@ DelayMode_SysSuspend
Definition: nuts_bolts.h:444
@ DelayMode_Dwell
Definition: nuts_bolts.h:443
bool delay_sec(float seconds, delaymode_t mode)
Definition: nuts_bolts.c:324
bool read_float(const char *line, uint_fast8_t *char_counter, float *float_ptr)
Definition: nuts_bolts.c:253
char * trim_float(char *s)
Definition: nuts_bolts.c:181
status_code_t read_uint(const char *line, uint_fast8_t *char_counter, uint32_t *uint_ptr)
Definition: nuts_bolts.c:195
void dummy_handler(void)
Definition: nuts_bolts.c:464
Coordinate system data.
Definition: nuts_bolts.h:321
coord_data_t coord
Definition: nuts_bolts.h:322
Home switches struct, consists of two packed axes_signals_t structs.
Definition: nuts_bolts.h:398
axes_signals_t a
Primary home switches status, optional. Limit signals are used for homing if not available.
Definition: nuts_bolts.h:399
axes_signals_t b
Secondary home switch(es) status, required for auto squaring enabled axes if primary switches are ava...
Definition: nuts_bolts.h:400
// Stepper driver warning and fault signal states, consists of two packed stepper_state_t structs in ...
Definition: nuts_bolts.h:410
stepper_state_t warning
Stepper drivers warning states.
Definition: nuts_bolts.h:411
stepper_state_t fault
Stepper drivers fault states.
Definition: nuts_bolts.h:412
Definition: vfs.h:50
Definition: nuts_bolts.h:248
uint8_t x
Definition: nuts_bolts.h:253
uint8_t y
Definition: nuts_bolts.h:254
uint8_t bits
Definition: nuts_bolts.h:250
uint8_t a1
Definition: nuts_bolts.h:280
uint8_t a5
Definition: nuts_bolts.h:284
uint8_t a7
Definition: nuts_bolts.h:286
uint8_t value
Definition: nuts_bolts.h:251
uint8_t a4
Definition: nuts_bolts.h:283
uint8_t mask
Definition: nuts_bolts.h:249
uint8_t a0
Definition: nuts_bolts.h:279
uint8_t z
Definition: nuts_bolts.h:276
uint8_t a2
Definition: nuts_bolts.h:281
uint8_t a6
Definition: nuts_bolts.h:285
uint8_t a3
Definition: nuts_bolts.h:282
Definition: nuts_bolts.h:418
uint16_t probe_overtravel
used for probe (toolsetter) protection
Definition: nuts_bolts.h:436
uint16_t bits
Definition: nuts_bolts.h:419
uint16_t stop_disable
Definition: nuts_bolts.h:428
uint16_t limits_override
Definition: nuts_bolts.h:433
uint16_t cycle_start
Definition: nuts_bolts.h:425
uint16_t feed_hold
Definition: nuts_bolts.h:424
uint16_t probe_disconnected
Definition: nuts_bolts.h:430
uint16_t reset
Definition: nuts_bolts.h:423
uint16_t safety_door_ajar
Definition: nuts_bolts.h:426
uint16_t motor_fault
Definition: nuts_bolts.h:431
uint16_t motor_warning
Definition: nuts_bolts.h:432
uint16_t deasserted
used for probe protection
Definition: nuts_bolts.h:438
uint16_t mask
Definition: nuts_bolts.h:420
uint16_t e_stop
M1.
Definition: nuts_bolts.h:429
uint16_t block_delete
Definition: nuts_bolts.h:427
uint16_t value
Definition: nuts_bolts.h:421
uint16_t probe_triggered
used for probe protection
Definition: nuts_bolts.h:437
uint16_t tls_overtravel
Definition: nuts_bolts.h:435
uint16_t single_block
Definition: nuts_bolts.h:434
Coordinate data.
Definition: nuts_bolts.h:291
float y
Definition: nuts_bolts.h:295
float x
Definition: nuts_bolts.h:294
float z
Definition: nuts_bolts.h:296
Limit switches struct, consists of four packed axes_signals_t structs in 32 bits.
Definition: nuts_bolts.h:387
axes_signals_t min
Min limit switches status, required.
Definition: nuts_bolts.h:390
axes_signals_t min2
Secondary min limit switch(es) status, required for auto squaring enabled axes.
Definition: nuts_bolts.h:392
axes_signals_t max2
Secondary max limit switches status, optional (of no practical use?).
Definition: nuts_bolts.h:393
axes_signals_t max
Max limit switches status, optional.
Definition: nuts_bolts.h:391
uint32_t bits
Definition: nuts_bolts.h:388
Definition: nuts_bolts.h:328
int32_t z
Definition: nuts_bolts.h:333
int32_t y
Definition: nuts_bolts.h:332
int32_t x
Definition: nuts_bolts.h:331
Axis index to plane assignment.
Definition: nuts_bolts.h:375
uint8_t axis_linear
Definition: nuts_bolts.h:380
uint8_t axis_0
Definition: nuts_bolts.h:378
uint8_t axis_1
Definition: nuts_bolts.h:379
Definition: nuts_bolts.h:357
float y
Definition: nuts_bolts.h:361
float x
Definition: nuts_bolts.h:360
Definition: nuts_bolts.h:365
float y
Definition: nuts_bolts.h:369
float x
Definition: nuts_bolts.h:368
float z
Definition: nuts_bolts.h:370
Stepper driver states struct.
Definition: nuts_bolts.h:404
home_signals_t details
Definition: nuts_bolts.h:406
uint16_t state
Definition: nuts_bolts.h:405