grblHAL core  20250104
pin_bits_masks.h
Go to the documentation of this file.
1 /*
2  pin_bits_masks.h - for adding bit definitions and masks
3 
4  NOTE: This file is not used by the core, it may be used by drivers
5 
6  Part of grblHAL
7 
8  Copyright (c) 2021-2024 Terje Io
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 // Sanity checks
25 
26 #if PROBE_ENABLE && !defined(PROBE_PIN)
27 #error "Probe input is not supported in this configuration!"
28 #endif
29 
30 #if SAFETY_DOOR_ENABLE && !defined(SAFETY_DOOR_PIN)
31 #error "Safety door input is not supported in this configuration!"
32 #endif
33 
34 #if MOTOR_FAULT_ENABLE && !defined(MOTOR_FAULT_PIN)
35 #error "Motor fault input is not supported in this configuration!"
36 #endif
37 
38 #if MOTOR_WARNING_ENABLE && !defined(MOTOR_WARNING_PIN)
39 #error "Motor warning input is not supported in this configuration!"
40 #endif
41 
42 #if I2C_STROBE_ENABLE && !defined(I2C_STROBE_PIN)
43 #error "I2C keypad/strobe is not supported in this configuration!"
44 #endif
45 
46 #if MPG_ENABLE == 1 && !defined(MPG_MODE_PIN)
47 #error "MPG mode input is not supported in this configuration!"
48 #endif
49 
50 #if QEI_SELECT_ENABLE && !defined(QEI_SELECT_PIN)
51 #error "Encoder select input is not supported in this configuration!"
52 #endif
53 
54 // Control input signals
55 
56 // Define the CONTROL_PORT symbol as a shorthand in the *_map.h file if all control inputs share the same port.
57 #ifdef CONTROL_PORT
58 
59 #ifndef RESET_PORT
60 #define RESET_PORT CONTROL_PORT
61 #endif
62 #ifndef FEED_HOLD_PORT
63 #define FEED_HOLD_PORT CONTROL_PORT
64 #endif
65 #ifndef CYCLE_START_PORT
66 #define CYCLE_START_PORT CONTROL_PORT
67 #endif
68 #ifndef ESTOP_PORT
69 #define ESTOP_PORT CONTROL_PORT
70 #endif
71 #ifndef PROBE_DISCONNECT_PORT
72 #define PROBE_DISCONNECT_PORT CONTROL_PORT
73 #endif
74 #ifndef STOP_DISABLE_PORT
75 #define STOP_DISABLE_PORT CONTROL_PORT
76 #endif
77 #ifndef BLOCK_DELETE_PORT
78 #define BLOCK_DELETE_PORT CONTROL_PORT
79 #endif
80 #ifndef SINGLE_BLOCK_PORT
81 #define SINGLE_BLOCK_PORT CONTROL_PORT
82 #endif
83 #ifndef MOTOR_FAULT_PORT
84 #define MOTOR_FAULT_PORT CONTROL_PORT
85 #endif
86 #ifndef MOTOR_WARNING_PORT
87 #define MOTOR_WARNING_PORT CONTROL_PORT
88 #endif
89 #ifndef LIMITS_OVERRIDE_PORT
90 #define LIMITS_OVERRIDE_PORT CONTROL_PORT
91 #endif
92 #if SAFETY_DOOR_ENABLE && !defined(SAFETY_DOOR_PORT)
93 #define SAFETY_DOOR_PORT CONTROL_PORT
94 #endif
95 
96 #endif // CONTROL_PORT
97 
98 #ifndef RESET_BIT
99 #ifdef RESET_PIN
100 #define RESET_BIT (1<<RESET_PIN)
101 #else
102 #define RESET_BIT 0
103 #endif
104 #endif
105 
106 #ifndef FEED_HOLD_BIT
107 #ifdef FEED_HOLD_PIN
108 #define FEED_HOLD_BIT (1<<FEED_HOLD_PIN)
109 #else
110 #define FEED_HOLD_BIT 0
111 #endif
112 #endif
113 
114 #ifndef CYCLE_START_BIT
115 #ifdef CYCLE_START_PIN
116 #define CYCLE_START_BIT (1<<CYCLE_START_PIN)
117 #else
118 #define CYCLE_START_BIT 0
119 #endif
120 #endif
121 
122 #ifndef ESTOP_BIT
123 #ifdef ESTOP_PIN
124 #define ESTOP_BIT (1<<ESTOP_PIN)
125 #else
126 #define ESTOP_BIT 0
127 #endif
128 #endif
129 
130 #ifndef SD_DETECT_BIT
131 #ifdef SD_DETECT_PIN
132 #define SD_DETECT_BIT (1<<SD_DETECT_PIN)
133 #else
134 #define SD_DETECT_BIT 0
135 #endif
136 #endif
137 
138 // Optional control signals
139 
140 #ifndef SAFETY_DOOR_BIT
141 #if defined(SAFETY_DOOR_PIN) && !defined(AUX_DEVICES)
142 #define SAFETY_DOOR_BIT (1<<SAFETY_DOOR_PIN)
143 #else
144 #define SAFETY_DOOR_BIT 0
145 #endif
146 #endif
147 
148 // Optional control signals, assigned to auxiliary input pins
149 
150 #ifndef MOTOR_FAULT_BIT
151 #if defined(MOTOR_FAULT_PIN) && !MOTOR_FAULT_ENABLE
152 #define MOTOR_FAULT_BIT (1<<MOTOR_FAULT_PIN)
153 #else
154 #define MOTOR_FAULT_BIT 0
155 #endif
156 #endif
157 
158 #ifndef MOTOR_WARNING_BIT
159 #if defined(MOTOR_WARNING_PIN) && !MOTOR_WARNING_ENABLE
160 #define MOTOR_WARNING_BIT (1<<MOTOR_WARNING_PIN)
161 #else
162 #define MOTOR_WARNING_BIT 0
163 #endif
164 #endif
165 
166 #ifndef PROBE_DISCONNECT_BIT
167 #if defined(PROBE_DISCONNECT_PIN) && !PROBE_DISCONNECT_ENABLE
168 #define PROBE_DISCONNECT_BIT (1<<PROBE_DISCONNECT_PIN)
169 #else
170 #define PROBE_DISCONNECT_BIT 0
171 #endif
172 #endif
173 
174 #ifndef STOP_DISABLE_BIT
175 #if defined(STOP_DISABLE_PIN) && !STOP_DISABLE_ENABLE
176 #define STOP_DISABLE_BIT (1<<STOP_DISABLE_PIN)
177 #else
178 #define STOP_DISABLE_BIT 0
179 #endif
180 #endif
181 
182 #ifndef BLOCK_DELETE_BIT
183 #if defined(BLOCK_DELETE_PIN) && !BLOCK_DELETE_ENABLE
184 #define BLOCK_DELETE_BIT (1<<BLOCK_DELETE_PIN)
185 #else
186 #define BLOCK_DELETE_BIT 0
187 #endif
188 #endif
189 
190 #ifndef SINGLE_BLOCK_BIT
191 #if defined(SINGLE_BLOCK_PIN) && !SINGLE_BLOCK_ENABLE
192 #define SINGLE_BLOCK_BIT (1<<SINGLE_BLOCK_PIN)
193 #else
194 #define SINGLE_BLOCK_BIT 0
195 #endif
196 #endif
197 
198 #ifndef LIMITS_OVERRIDE_BIT
199 #if defined(LIMITS_OVERRIDE_PIN) && !LIMITS_OVERRIDE_ENABLE
200 #define LIMITS_OVERRIDE_BIT (1<<LIMITS_OVERRIDE_PIN)
201 #else
202 #define LIMITS_OVERRIDE_BIT 0
203 #endif
204 #endif
205 
206 #if SAFETY_DOOR_ENABLE || MOTOR_FAULT_ENABLE || MOTOR_WARNING_ENABLE || PROBE_DISCONNECT_ENABLE || \
207  STOP_DISABLE_ENABLE || BLOCK_DELETE_ENABLE || SINGLE_BLOCK_ENABLE || LIMITS_OVERRIDE_ENABLE || \
208  (defined(AUX_DEVICES) && (PROBE_ENABLE || I2C_STROBE_ENABLE || MPG_ENABLE == 1 || QEI_SELECT_ENABLE)) || defined __DOXYGEN__
209 
210 #define AUX_CONTROLS_ENABLED 1
211 
212 #if PROBE_DISCONNECT_ENABLE || STOP_DISABLE_ENABLE || BLOCK_DELETE_ENABLE || SINGLE_BLOCK_ENABLE || LIMITS_OVERRIDE_ENABLE
213 #define AUX_CONTROLS_SCAN 1
214 #else
215 #define AUX_CONTROLS_SCAN 0
216 #endif
217 
218 static aux_ctrl_t aux_ctrl[] = {
219 // The following pins are bound explicitly to aux input pins
220 #if PROBE_ENABLE && defined(PROBE_PIN) && defined(AUX_DEVICES)
221 #ifdef PROBE_PORT
222  { .function = Input_Probe, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Rising|IRQ_Mode_Falling), .cap = { .value = 0 }, .pin = PROBE_PIN, .port = PROBE_PORT },
223 #else
224  { .function = Input_Probe, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Rising|IRQ_Mode_Falling), .cap = { .value = 0 }, .pin = PROBE_PIN, .port = NULL },
225 #endif
226 #endif
227 #if SAFETY_DOOR_ENABLE && defined(SAFETY_DOOR_PIN)
228 #ifdef SAFETY_DOOR_PORT
229  { .function = Input_SafetyDoor, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Rising|IRQ_Mode_Falling), .cap = { .safety_door_ajar = On }, .pin = SAFETY_DOOR_PIN, .port = SAFETY_DOOR_PORT },
230 #else
231  { .function = Input_SafetyDoor, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Rising|IRQ_Mode_Falling), .cap = { .safety_door_ajar = On }, .pin = SAFETY_DOOR_PIN, .port = NULL },
232 #endif
233 #endif
234 #if MOTOR_FAULT_ENABLE && defined(MOTOR_FAULT_PIN)
235 #ifdef MOTOR_FAULT_PORT
236  { .function = Input_MotorFault, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Rising|IRQ_Mode_Falling), .cap = { .motor_fault = On }, .pin = MOTOR_FAULT_PIN, .port = MOTOR_FAULT_PORT },
237 #else
238  { .function = Input_MotorFault, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Rising|IRQ_Mode_Falling), .cap = { .motor_fault = On }, .pin = MOTOR_FAULT_PIN, .port = NULL },
239 #endif
240 #if MOTOR_WARNING_ENABLE && defined(MOTOR_WARNING_PIN)
241 #ifdef MOTOR_WARNING_PORT
242  { .function = Input_MotorWarning, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Rising|IRQ_Mode_Falling), .cap = { .motor_fault = On }, .pin = MOTOR_WARNING_PIN, .port = MOTOR_WARNING_PORT },
243 #else
244  { .function = Input_MotorWarning, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Rising|IRQ_Mode_Falling), .cap = { .motor_warning = On }, .pin = MOTOR_WARNING_PIN, .port = NULL },
245 #endif
246 #endif
247 #endif
248 #if I2C_STROBE_ENABLE && defined(I2C_STROBE_PIN) && defined(AUX_DEVICES)
249 #ifdef I2C_STROBE_PORT
250  { .function = Input_I2CStrobe, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Change), .cap = { .value = 0 }, .pin = I2C_STROBE_PIN, .port = I2C_STROBE_PORT },
251 #else
252  { .function = Input_I2CStrobe, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Change), .cap = { .value = 0 }, .pin = I2C_STROBE_PIN, .port = NULL },
253 #endif
254 #endif
255 #if MPG_ENABLE == 1 && defined(MPG_MODE_PIN) && defined(AUX_DEVICES)
256 #ifdef MPG_MODE_PORT
257  { .function = Input_MPGSelect, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Change), .cap = { .value = 0 }, .pin = MPG_MODE_PIN, .port = MPG_MODE_PORT },
258 #else
259  { .function = Input_MPGSelect, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Change), .cap = { .value = 0 }, .pin = MPG_MODE_PIN, .port = NULL },
260 #endif
261 #endif
262 #if QEI_SELECT_ENABLE && defined(QEI_SELECT_PIN) && defined(AUX_DEVICES)
263 #ifdef QEI_SELECT_PORT
264  { .function = Input_QEI_Select, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Rising|IRQ_Mode_Falling), .cap = { .value = 0 }, .pin = QEI_SELECT_PIN, .port = QEI_SELECT_PORT },
265 #else
266  { .function = Input_QEI_Select, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Rising|IRQ_Mode_Falling), .cap = { .value = 0 }, .pin = QEI_SELECT_PIN, .port = NULL },
267 #endif
268 #endif
269 // The following pins are allocated from remaining aux inputs pool
270 #if LIMITS_OVERRIDE_ENABLE
271  { .function = Input_LimitsOverride, .aux_port = 0xFF, .irq_mode = IRQ_Mode_None, .cap = { .limits_override = On }, .pin = 0xFF, .port = NULL },
272 #endif
273 #if STOP_DISABLE_ENABLE
274  { .function = Input_StopDisable, .aux_port = 0xFF, .irq_mode = IRQ_Mode_Change, .cap = { .stop_disable = On }, .pin = 0xFF, .port = NULL },
275 #endif
276 #if BLOCK_DELETE_ENABLE
277  { .function = Input_BlockDelete, .aux_port = 0xFF, .irq_mode = IRQ_Mode_Change, .cap = { .block_delete = On }, .pin = 0xFF, .port = NULL },
278 #endif
279 #if SINGLE_BLOCK_ENABLE
280  { .function = Input_SingleBlock, .aux_port = 0xFF, .irq_mode = IRQ_Mode_Change, .cap = { .single_block = On }, .pin = 0xFF, .port = NULL },
281 #endif
282 #if PROBE_DISCONNECT_ENABLE
283  { .function = Input_ProbeDisconnect, .aux_port = 0xFF, .irq_mode = (pin_irq_mode_t)(IRQ_Mode_Rising|IRQ_Mode_Falling), .cap = { .probe_disconnected = On }, .pin = 0xFF, .port = NULL },
284 #endif
285 };
286 
287 static inline aux_ctrl_t *aux_ctrl_remap_explicit (void *port, uint8_t pin, uint8_t aux_port, void *input)
288 {
289  aux_ctrl_t *ctrl_pin = NULL;
290 
291  uint_fast8_t idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t);
292 
293  do {
294  idx--;
295  if(aux_ctrl[idx].port == port && aux_ctrl[idx].pin == pin) {
296  ctrl_pin = &aux_ctrl[idx];
297  ctrl_pin->aux_port = aux_port;
298  ctrl_pin->input = input;
299  }
300  } while(idx && ctrl_pin == NULL);
301 
302  return ctrl_pin;
303 }
304 
305 static inline aux_ctrl_t *aux_ctrl_get_pin (uint8_t aux_port)
306 {
307  aux_ctrl_t *ctrl_pin = NULL;
308 
309  uint_fast8_t idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t);
310 
311  do {
312  if(aux_ctrl[--idx].aux_port == aux_port)
313  ctrl_pin = &aux_ctrl[idx];
314  } while(idx && ctrl_pin == NULL);
315 
316  return ctrl_pin;
317 }
318 
319 static inline void aux_ctrl_irq_enable (settings_t *settings, ioport_interrupt_callback_ptr aux_irq_handler)
320 {
321  uint_fast8_t idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t);
322 
323  if(idx) do {
324  if(aux_ctrl[--idx].aux_port != 0xFF) {
325 #if PROBE_ENABLE && defined(PROBE_PIN) && defined(AUX_DEVICES)
326  if(aux_ctrl[idx].function == Input_Probe) {
327  xbar_t *xbar;
328  if((xbar = hal.port.get_pin_info(Port_Digital, Port_Input, aux_ctrl[idx].aux_port))) {
329  gpio_in_config_t cfg;
331  cfg.debounce = xbar->mode.debounce;
333  xbar->config(xbar, &cfg, false);
334  }
335  } else
336 #endif
337  if(aux_ctrl[idx].irq_mode != IRQ_Mode_None) {
338  if(aux_ctrl[idx].irq_mode & (IRQ_Mode_Falling|IRQ_Mode_Rising))
339  aux_ctrl[idx].irq_mode = (settings->control_invert.mask & aux_ctrl[idx].cap.mask) ? IRQ_Mode_Falling : IRQ_Mode_Rising;
340  hal.port.register_interrupt_handler(aux_ctrl[idx].aux_port, aux_ctrl[idx].irq_mode, aux_irq_handler);
341  }
342  }
343  } while(idx);
344 }
345 
346 typedef bool (*aux_claim_explicit_ptr)(aux_ctrl_t *aux_ctrl);
347 
348 static bool aux_ctrl_claim_port (xbar_t *properties, uint8_t port, void *data)
349 {
350  if(ioport_claim(Port_Digital, Port_Input, &port, xbar_fn_to_pinname(((aux_ctrl_t *)data)->function)))
351  ((aux_ctrl_t *)data)->aux_port = port;
352 
353  return ((aux_ctrl_t *)data)->aux_port != 0xFF;
354 }
355 
356 static inline void aux_ctrl_claim_ports (aux_claim_explicit_ptr aux_claim_explicit, ioports_enumerate_callback_ptr aux_claim)
357 {
358  uint_fast8_t idx;
359 
360  if(aux_claim == NULL)
361  aux_claim = aux_ctrl_claim_port;
362 
363  for(idx = 0; idx < sizeof(aux_ctrl) / sizeof(aux_ctrl_t); idx++) {
364  if(aux_ctrl[idx].pin == 0xFF) {
365  if(ioports_enumerate(Port_Digital, Port_Input, (pin_cap_t){ .irq_mode = aux_ctrl[idx].irq_mode, .claimable = On }, aux_claim, (void *)&aux_ctrl[idx]))
366  hal.signals_cap.mask |= aux_ctrl[idx].cap.mask;
367  } else if(aux_ctrl[idx].aux_port != 0xFF)
368  aux_claim_explicit(&aux_ctrl[idx]);
369  }
370 }
371 
372 #if AUX_CONTROLS_SCAN
373 
374 static inline control_signals_t aux_ctrl_scan_status (control_signals_t signals)
375 {
376  uint_fast8_t idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t);
377 
378  if(idx) do {
379  if(aux_ctrl[--idx].pin != 0xFF)
380  break;
381  if(aux_ctrl[idx].aux_port != 0xFF) {
382  signals.mask &= ~aux_ctrl[idx].cap.mask;
383 #ifdef GRBL_ESP32 // Snowflake guru workaround
384  if(hal.port.wait_on_input(Port_Digital, aux_ctrl[idx].aux_port, WaitMode_Immediate, FZERO) == 1)
385  signals.mask |= aux_ctrl[idx].cap.mask;
386 #else
387  if(hal.port.wait_on_input(Port_Digital, aux_ctrl[idx].aux_port, WaitMode_Immediate, 0.0f) == 1)
388  signals.mask |= aux_ctrl[idx].cap.mask;
389 #endif
390  }
391  } while(idx);
392 
393  return signals;
394 }
395 
396 #endif
397 
398 #else
399 #define AUX_CONTROLS_ENABLED 0
400 #define AUX_CONTROLS_SCAN 0
401 #endif
402 
403 #if defined(AUX_CONTROLS_OUT) && !defined(AUX_CONTROLS)
404 #define AUX_CONTROLS AUX_CONTROL_SPINDLE
405 #elif !defined(AUX_CONTROLS)
406 #define AUX_CONTROLS 0
407 #endif
408 
409 #if AUX_CONTROLS
410 
411 // The following pins are bound explicitly to aux output pins
412 static aux_ctrl_out_t aux_ctrl_out[] = {
413 #if AUX_CONTROLS & AUX_CONTROL_SPINDLE
414 #ifdef SPINDLE_ENABLE_PIN
415  #ifndef SPINDLE_ENABLE_PORT
416  #define SPINDLE_ENABLE_PORT NULL
417  #endif
418  { .function = Output_SpindleOn, .aux_port = 0xFF, .pin = SPINDLE_ENABLE_PIN, .port = SPINDLE_ENABLE_PORT },
419 #endif
420 #ifdef SPINDLE_PWM_PIN
421  #ifndef SPINDLE_PWM_PORT
422  #define SPINDLE_PWM_PORT NULL
423  #endif
424  { .function = Output_SpindlePWM, .aux_port = 0xFF, .pin = SPINDLE_PWM_PIN, .port = SPINDLE_PWM_PORT },
425 #endif
426 #ifdef SPINDLE_DIRECTION_PIN
427  #ifndef SPINDLE_DIRECTION_PORT
428  #define SPINDLE_DIRECTION_PORT NULL
429  #endif
430  { .function = Output_SpindleDir, .aux_port = 0xFF, .pin = SPINDLE_DIRECTION_PIN, .port = SPINDLE_DIRECTION_PORT },
431 #endif
432 
433 #ifdef SPINDLE1_ENABLE_PIN
434  #ifndef SPINDLE1_ENABLE_PORT
435  #define SPINDLE1_ENABLE_PORT NULL
436  #endif
437  { .function = Output_Spindle1On, .aux_port = 0xFF, .pin = SPINDLE1_ENABLE_PIN, .port = SPINDLE1_ENABLE_PORT },
438 #endif
439 #ifdef SPINDLE1_PWM_PIN
440  #ifndef SPINDLE1_PWM_PORT
441  #define SPINDLE1_PWM_PORT NULL
442  #endif
443  { .function = Output_Spindle1PWM, .aux_port = 0xFF, .pin = SPINDLE1_PWM_PIN, .port = SPINDLE1_PWM_PORT },
444 #endif
445 #ifdef SPINDLE1_DIRECTION_PIN
446  #ifndef SPINDLE1_DIRECTION_PORT
447  #define SPINDLE1_DIRECTION_PORT NULL
448  #endif
449  { .function = Output_Spindle1Dir, .aux_port = 0xFF, .pin = SPINDLE1_DIRECTION_PIN, .port = SPINDLE1_DIRECTION_PORT },
450 #endif
451 #endif // SPINDLES
452 
453 #if AUX_CONTROLS & AUX_CONTROL_COOLANT
454 #ifdef COOLANT_FLOOD_PIN
455  #ifndef COOLANT_FLOOD_PORT
456  #define COOLANT_FLOOD_PORT NULL
457  #endif
458  { .function = Output_CoolantFlood, .aux_port = 0xFF, .pin = COOLANT_FLOOD_PIN, .port = COOLANT_FLOOD_PORT },
459 #endif
460 #ifdef COOLANT_MIST_PIN
461  #ifndef COOLANT_MIST_PORT
462  #define COOLANT_MIST_PORT NULL
463  #endif
464  { .function = Output_CoolantMist, .aux_port = 0xFF, .pin = COOLANT_MIST_PIN, .port = COOLANT_MIST_PORT },
465 #endif
466 #endif // COOLANT
467 
468 #ifdef COPROC_RESET_PIN
469  #ifndef COPROC_RESET_PORT
470  #define COPROC_RESET_PORT NULL
471  #endif
472  { .function = Output_CoProc_Reset, .aux_port = 0xFF, .pin = COPROC_RESET_PIN, .port = COPROC_RESET_PORT },
473 #endif
474 #ifdef COPROC_BOOT0_PIN
475  #ifndef COPROC_BOOT0_PORT
476  #define COPROC_BOOT0_PORT NULL
477  #endif
478  { .function = Output_CoProc_Boot0, .aux_port = 0xFF, .pin = COPROC_BOOT0_PIN, .port = COPROC_BOOT0_PORT },
479 #endif
480 };
481 
482 static inline aux_ctrl_out_t *aux_out_remap_explicit (void *port, uint8_t pin, uint8_t aux_port, void *output)
483 {
484  aux_ctrl_out_t *ctrl_pin = NULL;
485 
486  uint_fast8_t idx = sizeof(aux_ctrl_out) / sizeof(aux_ctrl_out_t);
487 
488  if(idx) do {
489  idx--;
490  if(aux_ctrl_out[idx].port == port && aux_ctrl_out[idx].pin == pin) {
491  ctrl_pin = &aux_ctrl_out[idx];
492  ctrl_pin->aux_port = aux_port;
493  ctrl_pin->output = output;
494  }
495  } while(idx && ctrl_pin == NULL);
496 
497  return ctrl_pin;
498 }
499 
500 typedef bool (*aux_claim_explicit_out_ptr)(aux_ctrl_out_t *aux_ctrl);
501 
502 static bool aux_ctrl_claim_out_port (xbar_t *properties, uint8_t port, void *data)
503 {
504  if(ioport_claim(Port_Digital, Port_Output, &port, xbar_fn_to_pinname(((aux_ctrl_t *)data)->function)))
505  ((aux_ctrl_t *)data)->aux_port = port;
506 
507  return ((aux_ctrl_t *)data)->aux_port != 0xFF;
508 }
509 
510 static inline void aux_ctrl_claim_out_ports (aux_claim_explicit_out_ptr aux_claim_explicit, ioports_enumerate_callback_ptr aux_claim)
511 {
512  uint_fast8_t idx;
513 
514  if(aux_claim == NULL)
515  aux_claim = aux_ctrl_claim_out_port;
516 
517  for(idx = 0; idx < sizeof(aux_ctrl_out) / sizeof(aux_ctrl_out_t); idx++) {
518  if(aux_ctrl_out[idx].pin == 0xFF)
519  ioports_enumerate(Port_Digital, Port_Output, (pin_cap_t){ .claimable = On }, aux_claim, (void *)&aux_ctrl_out[idx]);
520  else if(aux_ctrl_out[idx].aux_port != 0xFF)
521  aux_claim_explicit(&aux_ctrl_out[idx]);
522  }
523 }
524 
525 #endif // AUX_CONTROLS
526 
527 //
528 
529 #ifndef CONTROL_MASK
530 #if SAFETY_DOOR_ENABLE
531 #define CONTROL_MASK (RESET_BIT|FEED_HOLD_BIT|CYCLE_START_BIT|ESTOP_BIT|PROBE_DISCONNECT_BIT|STOP_DISABLE_BIT|BLOCK_DELETE_BIT|SINGLE_BLOCK_BIT|MOTOR_FAULT_BIT|MOTOR_WARNING_BIT|LIMITS_OVERRIDE_BIT|SAFETY_DOOR_BIT)
532 #define CONTROL_MASK_SUM (RESET_BIT+FEED_HOLD_BIT+CYCLE_START_BIT+ESTOP_BIT+PROBE_DISCONNECT_BIT+STOP_DISABLE_BIT+BLOCK_DELETE_BIT+SINGLE_BLOCK_BIT+MOTOR_FAULT_BIT+MOTOR_WARNING_BIT+LIMITS_OVERRIDE_BIT+SAFETY_DOOR_BIT)
533 #else
534 #define CONTROL_MASK (RESET_BIT|FEED_HOLD_BIT|CYCLE_START_BIT|ESTOP_BIT|PROBE_DISCONNECT_BIT|STOP_DISABLE_BIT|BLOCK_DELETE_BIT|SINGLE_BLOCK_BIT|MOTOR_FAULT_BIT|MOTOR_WARNING_BIT|LIMITS_OVERRIDE_BIT)
535 #define CONTROL_MASK_SUM (RESET_BIT+FEED_HOLD_BIT+CYCLE_START_BIT+ESTOP_BIT+PROBE_DISCONNECT_BIT+STOP_DISABLE_BIT+BLOCK_DELETE_BIT+SINGLE_BLOCK_BIT+MOTOR_FAULT_BIT+MOTOR_WARNING_BIT+LIMITS_OVERRIDE_BIT)
536 #endif
537 #endif
538 
539 // Output Signals
540 
541 #if defined(SPINDLE_ENABLE_PIN) && !defined(SPINDLE_ENABLE_BIT)
542 #define SPINDLE_ENABLE_BIT (1<<SPINDLE_ENABLE_PIN)
543 #endif
544 #if defined(SPINDLE_DIRECTION_PIN) && !defined(SPINDLE_DIRECTION_BIT)
545 #define SPINDLE_DIRECTION_BIT (1<<SPINDLE_DIRECTION_PIN)
546 #endif
547 
548 #if defined(SPINDLE1_ENABLE_PIN) && !defined(SPINDLE1_ENABLE_BIT)
549 #define SPINDLE1_ENABLE_BIT (1<<SPINDLE1_ENABLE_PIN)
550 #endif
551 #if defined(SPINDLE1_DIRECTION_PIN) && !defined(SPINDLE1_DIRECTION_BIT)
552 #define SPINDLE1_DIRECTION_BIT (1<<SPINDLE1_DIRECTION_PIN)
553 #endif
554 
555 #if defined(COOLANT_FLOOD_PIN) && !defined(COOLANT_FLOOD_BIT)
556 #define COOLANT_FLOOD_BIT (1<<COOLANT_FLOOD_PIN)
557 #endif
558 #if defined(COOLANT_MIST_PIN) && !defined(COOLANT_MIST_BIT)
559 #define COOLANT_MIST_BIT (1<<COOLANT_MIST_PIN)
560 #endif
561 
562 #if defined(RTS_PIN) && !defined(RTS_BIT)
563 #define RTS_BIT (1<<RTS_PIN)
564 #endif
565 
566 // IRQ enabled input singnals
567 
568 #ifndef AUX_DEVICES
569 
570 // IRQ capability for the probe input is optional
571 #if defined(PROBE_PIN) && !defined(PROBE_BIT)
572 #define PROBE_BIT (1<<PROBE_PIN)
573 #endif
574 
575 #if defined(MPG_MODE_PIN) && !defined(MPG_MODE_BIT)
576 #define MPG_MODE_BIT (1<<MPG_MODE_PIN)
577 #endif
578 
579 #if defined(I2C_STROBE_PIN) && !defined(I2C_STROBE_BIT)
580 #define I2C_STROBE_BIT (1<<I2C_STROBE_PIN)
581 #endif
582 
583 #if defined(QEI_SELECT_PIN) && !defined(QEI_SELECT_BIT)
584 #define QEI_SELECT_BIT (1<<QEI_SELECT_PIN)
585 #endif
586 
587 #endif // !AUX_DEVICES
588 
589 #if QEI_ENABLE
590 #ifndef QEI_A_BIT
591 #define QEI_A_BIT (1<<QEI_A_PIN)
592 #endif
593 #ifndef QEI_B_BIT
594 #define QEI_B_BIT (1<<QEI_B_PIN)
595 #endif
596 #else
597 #define QEI_A_BIT 0
598 #define QEI_B_BIT 0
599 #endif
600 
601 #ifndef QEI_SELECT_BIT
602 #define QEI_SELECT_BIT 0
603 #endif
604 #ifndef MPG_MODE_BIT
605 #define MPG_MODE_BIT 0
606 #endif
607 #ifndef I2C_STROBE_BIT
608 #define I2C_STROBE_BIT 0
609 #endif
610 
611 // Do NOT #define PROBE_BIT 0 here!
612 
613 #if SPINDLE_ENCODER_ENABLE
614 #ifndef SPINDLE_PULSE_PIN
615 #error "Spindle encoder requires at least SPINDLE_PULSE_PIN defined in the board map!"
616 #endif
617 #if !defined(SPINDLE_PULSE_BIT) && defined(SPINDLE_PULSE_PIN)
618 #define SPINDLE_PULSE_BIT (1<<SPINDLE_PULSE_PIN)
619 #endif
620 #if !defined(SPINDLE_INDEX_BIT) && defined(SPINDLE_INDEX_PIN)
621 #define SPINDLE_INDEX_BIT (1<<SPINDLE_INDEX_PIN)
622 #endif
623 #endif
624 
625 #ifndef SPINDLE_INDEX_BIT
626 #define SPINDLE_INDEX_BIT 0
627 #endif
628 #ifndef SPINDLE_PULSE_BIT
629 #define SPINDLE_PULSE_BIT 0
630 #endif
631 
632 #if SPINDLE_SYNC_ENABLE && (SPINDLE_INDEX_BIT + SPINDLE_PULSE_BIT) == 0
633 #error "Spindle sync requires SPINDLE_PULSE_PIN and SPINDLE_INDEX_PIN defined in the board map!"
634 #endif
635 
636 #ifndef SPI_IRQ_PIN
637 #define SPI_IRQ_BIT 0
638 #elif !defined(SPI_IRQ_BIT)
639 #define SPI_IRQ_BIT (1<<SPI_IRQ_PIN)
640 #endif
641 
642 #ifndef DEVICES_IRQ_MASK
643 #ifdef AUX_DEVICES
644 #define DEVICES_IRQ_MASK (SPI_IRQ_BIT|SPINDLE_INDEX_BIT|QEI_A_BIT|QEI_B_BIT|SD_DETECT_BIT)
645 #define DEVICES_IRQ_MASK_SUM (SPI_IRQ_BIT+SPINDLE_INDEX_BIT+QEI_A_BIT+QEI_B_BIT+SD_DETECT_BIT)
646 #else
647 #define DEVICES_IRQ_MASK (MPG_MODE_BIT|I2C_STROBE_BIT|QEI_SELECT_BIT|SPI_IRQ_BIT|SPINDLE_INDEX_BIT|QEI_A_BIT|QEI_B_BIT|SD_DETECT_BIT)
648 #define DEVICES_IRQ_MASK_SUM (MPG_MODE_BIT+I2C_STROBE_BIT+QEI_SELECT_BIT+SPI_IRQ_BIT+SPINDLE_INDEX_BIT+QEI_A_BIT+QEI_B_BIT+SD_DETECT_BIT)
649 #endif
650 #endif
651 
652 // Auxillary input signals
653 
654 #ifdef AUXINPUT0_PIN
655 #define AUXINPUT0_BIT (1<<AUXINPUT0_PIN)
656 #else
657 #define AUXINPUT0_BIT 0
658 #endif
659 #ifdef AUXINPUT1_PIN
660 #define AUXINPUT1_BIT (1<<AUXINPUT1_PIN)
661 #else
662 #define AUXINPUT1_BIT 0
663 #endif
664 #ifdef AUXINPUT2_PIN
665 #define AUXINPUT2_BIT (1<<AUXINPUT2_PIN)
666 #else
667 #define AUXINPUT2_BIT 0
668 #endif
669 #ifdef AUXINPUT3_PIN
670 #define AUXINPUT3_BIT (1<<AUXINPUT3_PIN)
671 #else
672 #define AUXINPUT3_BIT 0
673 #endif
674 #ifdef AUXINPUT4_PIN
675 #define AUXINPUT4_BIT (1<<AUXINPUT4_PIN)
676 #else
677 #define AUXINPUT4_BIT 0
678 #endif
679 #ifdef AUXINPUT5_PIN
680 #define AUXINPUT5_BIT (1<<AUXINPUT5_PIN)
681 #else
682 #define AUXINPUT5_BIT 0
683 #endif
684 #ifdef AUXINPUT6_PIN
685 #define AUXINPUT6_BIT (1<<AUXINPUT6_PIN)
686 #else
687 #define AUXINPUT6_BIT 0
688 #endif
689 #ifdef AUXINPUT7_PIN
690 #define AUXINPUT7_BIT (1<<AUXINPUT7_PIN)
691 #else
692 #define AUXINPUT7_BIT 0
693 #endif
694 #ifdef AUXINPUT8_PIN
695 #define AUXINPUT8_BIT (1<<AUXINPUT8_PIN)
696 #else
697 #define AUXINPUT8_BIT 0
698 #endif
699 #ifdef AUXINPUT9_PIN
700 #define AUXINPUT9_BIT (1<<AUXINPUT9_PIN)
701 #else
702 #define AUXINPUT9_BIT 0
703 #endif
704 #ifdef AUXINPUT10_PIN
705 #define AUXINPUT10_BIT (1<<AUXINPUT10_PIN)
706 #else
707 #define AUXINPUT10_BIT 0
708 #endif
709 #ifdef AUXINPUT11_PIN
710 #define AUXINPUT11_BIT (1<<AUXINPUT11_PIN)
711 #else
712 #define AUXINPUT11_BIT 0
713 #endif
714 #ifdef AUXINPUT12_PIN
715 #define AUXINPUT12_BIT (1<<AUXINPUT12_PIN)
716 #else
717 #define AUXINPUT12_BIT 0
718 #endif
719 #ifdef AUXINPUT13_PIN
720 #define AUXINPUT13_BIT (1<<AUXINPUT13_PIN)
721 #else
722 #define AUXINPUT13_BIT 0
723 #endif
724 #ifdef AUXINPUT14_PIN
725 #define AUXINPUT14_BIT (1<<AUXINPUT14_PIN)
726 #else
727 #define AUXINPUT14_BIT 0
728 #endif
729 #ifdef AUXINPUT15_PIN
730 #define AUXINPUT15_BIT (1<<AUXINPUT15_PIN)
731 #else
732 #define AUXINPUT15_BIT 0
733 #endif
734 
735 #ifndef AUXINPUT_MASK
736 #define AUXINPUT_MASK (AUXINPUT0_BIT|AUXINPUT1_BIT|AUXINPUT2_BIT|AUXINPUT3_BIT|AUXINPUT4_BIT|AUXINPUT5_BIT|AUXINPUT6_BIT|AUXINPUT7_BIT|\
737  AUXINPUT8_BIT|AUXINPUT9_BIT|AUXINPUT10_BIT|AUXINPUT11_BIT|AUXINPUT12_BIT|AUXINPUT13_BIT|AUXINPUT4_BIT|AUXINPUT15_BIT)
738 #define AUXINPUT_MASK_SUM (AUXINPUT0_BIT+AUXINPUT1_BIT+AUXINPUT2_BIT+AUXINPUT3_BIT+AUXINPUT4_BIT+AUXINPUT5_BIT+AUXINPUT6_BIT+AUXINPUT7_BIT+\
739  AUXINPUT8_BIT+AUXINPUT9_BIT+AUXINPUT10_BIT+AUXINPUT11_BIT+AUXINPUT12_BIT+AUXINPUT13_BIT+AUXINPUT4_BIT+AUXINPUT15_BIT)
740 #endif
741 
742 /*EOF*/
const char * xbar_fn_to_pinname(pin_function_t fn)
Definition: crossbar.c:131
@ PullMode_None
0b00 (0x00)
Definition: crossbar.h:505
@ PullMode_Up
0b01 (0x01)
Definition: crossbar.h:506
@ Output_CoProc_Boot0
Definition: crossbar.h:191
@ Input_Probe
Definition: crossbar.h:43
@ Input_MotorFault
Definition: crossbar.h:37
@ Input_MotorWarning
Definition: crossbar.h:38
@ Input_ProbeDisconnect
Definition: crossbar.h:36
@ Input_StopDisable
Definition: crossbar.h:34
@ Input_LimitsOverride
Definition: crossbar.h:39
@ Output_CoProc_Reset
Definition: crossbar.h:190
@ Input_QEI_Select
Definition: crossbar.h:214
@ Input_BlockDelete
Definition: crossbar.h:33
@ Output_SpindleDir
Definition: crossbar.h:149
@ Input_SingleBlock
Definition: crossbar.h:40
@ Output_SpindleOn
Definition: crossbar.h:148
@ Input_I2CStrobe
Definition: crossbar.h:208
@ Output_Spindle1Dir
Definition: crossbar.h:152
@ Output_SpindlePWM
Definition: crossbar.h:150
@ Output_CoolantMist
Definition: crossbar.h:154
@ Input_MPGSelect
Definition: crossbar.h:47
@ Output_Spindle1On
Definition: crossbar.h:151
@ Input_SafetyDoor
Definition: crossbar.h:32
@ Output_CoolantFlood
Definition: crossbar.h:155
@ Output_Spindle1PWM
Definition: crossbar.h:153
pin_irq_mode_t
Pin interrupt modes, may be or'ed when reporting pin capability.
Definition: crossbar.h:478
@ IRQ_Mode_Rising
0b00001 (0x01)
Definition: crossbar.h:480
@ IRQ_Mode_None
0b00000 (0x00)
Definition: crossbar.h:479
@ IRQ_Mode_Change
0b00100 (0x04)
Definition: crossbar.h:483
@ IRQ_Mode_Falling
0b00010 (0x02)
Definition: crossbar.h:481
@ WaitMode_Immediate
0 - This is the only mode allowed for analog inputs
Definition: gcode.h:285
grbl_hal_t hal
Global HAL struct.
Definition: grbllib.c:91
bool ioport_claim(io_port_type_t type, io_port_direction_t dir, uint8_t *port, const char *description)
Claim a digital or analog port for exclusive use.
Definition: ioports.c:141
bool ioports_enumerate(io_port_type_t type, io_port_direction_t dir, pin_cap_t filter, ioports_enumerate_callback_ptr callback, void *data)
Definition: ioports.c:216
@ Port_Input
0
Definition: ioports.h:30
@ Port_Output
1
Definition: ioports.h:31
bool(* ioports_enumerate_callback_ptr)(xbar_t *properties, uint8_t port, void *data)
Definition: ioports.h:108
@ Port_Digital
1
Definition: ioports.h:26
void(* ioport_interrupt_callback_ptr)(uint8_t port, bool state)
Pointer to callback function for input port interrupt events.
Definition: ioports.h:98
#define On
Definition: nuts_bolts.h:36
bool(* aux_claim_explicit_ptr)(aux_ctrl_t *aux_ctrl)
Definition: pin_bits_masks.h:346
settings_t settings
Definition: settings.c:43
Definition: crossbar.h:636
uint8_t aux_port
Definition: crossbar.h:638
void * output
Definition: crossbar.h:641
pin_function_t function
Definition: crossbar.h:637
Definition: crossbar.h:626
uint8_t aux_port
Definition: crossbar.h:628
control_signals_t cap
Definition: crossbar.h:630
pin_irq_mode_t irq_mode
Definition: crossbar.h:629
void * input
Definition: crossbar.h:633
pin_function_t function
Definition: crossbar.h:627
/a cfg_data argument to /a xbar_config_ptr for gpio input pins
Definition: crossbar.h:587
bool debounce
Definition: crossbar.h:589
bool inverted
Definition: crossbar.h:588
pull_mode_t pull_mode
Definition: crossbar.h:590
io_port_t port
Optional handlers for axuillary I/O (adds support for M62-M66).
Definition: hal.h:625
control_signals_t signals_cap
Control input signals supported by the driver.
Definition: hal.h:660
wait_on_input_ptr wait_on_input
Optional handler for reading a digital or analog input.
Definition: ioports.h:118
ioport_register_interrupt_handler_ptr register_interrupt_handler
Definition: ioports.h:123
get_pin_info_ptr get_pin_info
Optional handler for getting information about an auxiliary pin.
Definition: ioports.h:120
Definition: settings.h:821
control_signals_t control_invert
Definition: settings.h:833
probeflags_t probe
Definition: settings.h:844
Definition: crossbar.h:644
pin_mode_t mode
Current pin configuration.
Definition: crossbar.h:652
xbar_config_ptr config
Optional pointer to function for configuring the port.
Definition: crossbar.h:653
Definition: system.h:137
uint16_t mask
Definition: system.h:139
Definition: crossbar.h:522
uint16_t debounce
Definition: crossbar.h:552
uint16_t invert_probe_pin
Definition: settings.h:589
uint16_t disable_probe_pullup
Definition: settings.h:590