grblHAL core  20251016
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-2025 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 #include "platform.h"
25 
26 // Sanity checks
27 
28 #if PROBE_ENABLE && !defined(PROBE_PIN)
29 #error "Probe input is not supported in this configuration!"
30 #endif
31 
32 #if SAFETY_DOOR_ENABLE && !defined(SAFETY_DOOR_PIN)
33 #error "Safety door input is not supported in this configuration!"
34 #endif
35 
36 #if MOTOR_FAULT_ENABLE && !defined(MOTOR_FAULT_PIN)
37 #error "Motor fault input is not supported in this configuration!"
38 #endif
39 
40 #if MOTOR_WARNING_ENABLE && !defined(MOTOR_WARNING_PIN)
41 #error "Motor warning input is not supported in this configuration!"
42 #endif
43 
44 #if I2C_STROBE_ENABLE && !defined(I2C_STROBE_PIN)
45 #error "I2C keypad/strobe is not supported in this configuration!"
46 #endif
47 
48 #if MPG_ENABLE == 1 && !defined(MPG_MODE_PIN)
49 #error "MPG mode input is not supported in this configuration!"
50 #endif
51 
52 #if QEI_SELECT_ENABLE && !defined(QEI_SELECT_PIN)
53 #error "Encoder select input is not supported in this configuration!"
54 #endif
55 
56 #define EXPANDER_PORT 1
57 
58 // Control input signals
59 
60 // Define the CONTROL_PORT symbol as a shorthand in the *_map.h file if all control inputs share the same port.
61 #ifdef CONTROL_PORT
62 
63 #ifndef RESET_PORT
64 #define RESET_PORT CONTROL_PORT
65 #endif
66 #ifndef FEED_HOLD_PORT
67 #define FEED_HOLD_PORT CONTROL_PORT
68 #endif
69 #ifndef CYCLE_START_PORT
70 #define CYCLE_START_PORT CONTROL_PORT
71 #endif
72 #ifndef ESTOP_PORT
73 #define ESTOP_PORT CONTROL_PORT
74 #endif
75 #ifndef PROBE_DISCONNECT_PORT
76 #define PROBE_DISCONNECT_PORT CONTROL_PORT
77 #endif
78 #ifndef STOP_DISABLE_PORT
79 #define STOP_DISABLE_PORT CONTROL_PORT
80 #endif
81 #ifndef BLOCK_DELETE_PORT
82 #define BLOCK_DELETE_PORT CONTROL_PORT
83 #endif
84 #ifndef SINGLE_BLOCK_PORT
85 #define SINGLE_BLOCK_PORT CONTROL_PORT
86 #endif
87 #ifndef MOTOR_FAULT_PORT
88 #define MOTOR_FAULT_PORT CONTROL_PORT
89 #endif
90 #ifndef MOTOR_WARNING_PORT
91 #define MOTOR_WARNING_PORT CONTROL_PORT
92 #endif
93 #ifndef LIMITS_OVERRIDE_PORT
94 #define LIMITS_OVERRIDE_PORT CONTROL_PORT
95 #endif
96 #if SAFETY_DOOR_ENABLE && !defined(SAFETY_DOOR_PORT)
97 #define SAFETY_DOOR_PORT CONTROL_PORT
98 #endif
99 
100 #endif // CONTROL_PORT
101 
102 #ifndef SD_DETECT_BIT
103 #ifdef SD_DETECT_PIN
104 #define SD_DETECT_BIT (1<<SD_DETECT_PIN)
105 #else
106 #define SD_DETECT_BIT 0
107 #endif
108 #endif
109 
110 #ifndef CONTROL_ENABLE
111 #define CONTROL_ENABLE 0
112 #endif
113 
114 #define a_cap(pin) .cap.pin
115 
116 #if defined(ESP_PLATFORM) || defined(RP2040) || defined(__IMXRT1062__)
117 #define add_aux_input(fn, aux, irq, signal_bit) { .function = fn, .irq_mode = irq, .signal.value = signal_bit, .port = IOPORT_UNASSIGNED, .gpio.pin = aux##_PIN },
118 #else
119 #define add_aux_input(fn, aux, irq, signal_bit) { .function = fn, .irq_mode = irq, .signal.value = signal_bit, .port = IOPORT_UNASSIGNED, .gpio.port = (void *)aux##_PORT, .gpio.pin = aux##_PIN },
120 #endif
121 #if defined(__IMXRT1062__) || defined(ESP_PLATFORM)
122 #define add_aux_output(fn, aux) { .function = fn, .port = IOPORT_UNASSIGNED, .gpio.pin = aux##_PIN },
123 #else
124 #define add_aux_output(fn, aux) { .function = fn, .port = IOPORT_UNASSIGNED, .gpio.port = (void *)aux##_PORT, .gpio.pin = aux##_PIN },
125 #endif
126 #define add_aux_input_scan(fn, irq, signal_bit) { .function = fn, .irq_mode = irq, .signal.value = signal_bit, .port = IOPORT_UNASSIGNED, .gpio.pin = 0xFF, .scan = On },
127 #define add_aux_input_no_signal(fn, irq) { .function = fn, .irq_mode = irq, .port = IOPORT_UNASSIGNED, .gpio.pin = 0xFE },
128 #define add_aux_output_exp(fn, aux) { .function = fn, .port = IOPORT_UNASSIGNED, .gpio.port = (void *)aux##_PORT, .gpio.pin = aux##_PIN },
129 
130 static aux_ctrl_t aux_ctrl[] = {
131 // The following pins are bound explicitly to aux input pins.
132 #ifdef RESET_PIN
133  #if (CONTROL_ENABLE & CONTROL_ESTOP)
134  add_aux_input(Input_EStop, RESET, IRQ_Mode_RisingFalling, SIGNALS_ESTOP_BIT)
135  #elif (CONTROL_ENABLE & CONTROL_RESET)
136  add_aux_input(Input_Reset, RESET, IRQ_Mode_RisingFalling, SIGNALS_RESET_BIT)
137  #endif
138 #endif
139 #if (CONTROL_ENABLE & CONTROL_FEED_HOLD) && defined(FEED_HOLD_PIN)
140  add_aux_input(Input_FeedHold, FEED_HOLD, IRQ_Mode_RisingFalling, SIGNALS_FEEDHOLD_BIT)
141 #endif
142 #if (CONTROL_ENABLE & CONTROL_CYCLE_START) && defined(CYCLE_START_PIN)
143  add_aux_input(Input_CycleStart, CYCLE_START, IRQ_Mode_RisingFalling, SIGNALS_CYCLESTART_BIT)
144 #endif
145 #if SAFETY_DOOR_ENABLE && defined(SAFETY_DOOR_PIN)
146  add_aux_input(Input_SafetyDoor, SAFETY_DOOR, IRQ_Mode_RisingFalling, SIGNALS_SAFETYDOOR_BIT)
147 #endif
148 #if MOTOR_FAULT_ENABLE && defined(MOTOR_FAULT_PIN)
149  add_aux_input(Input_MotorFault, MOTOR_FAULT, IRQ_Mode_RisingFalling, SIGNALS_MOTOR_FAULT_BIT)
150 #endif
151 #if MOTOR_WARNING_ENABLE && defined(MOTOR_WARNING_PIN)
152  add_aux_input(Input_MotorWarning, MOTOR_WARNING, IRQ_Mode_RisingFalling, SIGNALS_MOTOR_WARNING_BIT)
153 #endif
154 #if I2C_STROBE_ENABLE && defined(I2C_STROBE_PIN)
156 #endif
157 #if MPG_ENABLE == 1 && defined(MPG_MODE_PIN)
159 #endif
160 #if QEI_SELECT_ENABLE && defined(QEI_SELECT_PIN)
162 #endif
163 // Probe pins can be bound explicitly and can be "degraded" to not interrupt capable.
164 #if PROBE_ENABLE && defined(PROBE_PIN)
166 #endif
167 #if PROBE2_ENABLE && defined(PROBE2_PIN)
169 #endif
170 #if TOOLSETTER_ENABLE && defined(TOOLSETTER_PIN)
172 #endif
173 
174 // The following pins are allocated from remaining aux inputs pool
175 #if TOOLSETTER_ENABLE && !defined(TOOLSETTER_PIN)
177 #endif
178 #if PROBE2_ENABLE && !defined(PROBE2_PIN)
180 #endif
181 #if TLS_OVERTRAVEL_ENABLE
183 #endif
184 #if LIMITS_OVERRIDE_ENABLE
185  add_aux_input_scan(Input_LimitsOverride, IRQ_Mode_Change, SIGNALS_LIMITS_OVERRIDE_BIT)
186 #endif
187 #if STOP_DISABLE_ENABLE
188  add_aux_input_scan(Input_StopDisable, IRQ_Mode_Change, SIGNALS_STOPDISABLE_BIT)
189 #endif
190 #if BLOCK_DELETE_ENABLE
191  add_aux_input_scan(Input_BlockDelete, IRQ_Mode_Change, SIGNALS_BLOCKDELETE_BIT)
192 #endif
193 #if SINGLE_BLOCK_ENABLE
194  add_aux_input_scan(Input_SingleBlock, IRQ_Mode_Change, SIGNALS_SINGLE_BLOCK_BIT)
195 #endif
196 #if PROBE_DISCONNECT_ENABLE
197  add_aux_input_scan(Input_ProbeDisconnect, IRQ_Mode_Change, SIGNALS_PROBE_CONNECTED_BIT)
198 #endif
199 };
200 
201 static inline bool aux_ctrl_is_probe (pin_function_t function)
202 {
203  return function == Input_Probe || function == Input_Probe2 || function == Input_Toolsetter;
204 }
205 
206 #ifdef STM32_PLATFORM
207 
208 static inline aux_ctrl_t *aux_ctrl_get_fn (aux_gpio_t gpio)
209 {
210  aux_ctrl_t *ctrl_pin = NULL;
211 
212  if(sizeof(aux_ctrl) / sizeof(aux_ctrl_t)) {
213  uint_fast8_t idx;
214  for(idx = 0; ctrl_pin == NULL && aux_ctrl[idx].gpio.pin != 0xFF && idx < sizeof(aux_ctrl) / sizeof(aux_ctrl_t); idx++) {
215  if(aux_ctrl[idx].gpio.pin == gpio.pin && aux_ctrl[idx].gpio.port == gpio.port)
216  ctrl_pin = &aux_ctrl[idx];
217  }
218  }
219 
220  return ctrl_pin;
221 }
222 
223 #endif // STM32_PLATFORM
224 
225 static inline xbar_t *aux_ctrl_claim_port (aux_ctrl_t *aux_ctrl)
226 {
227  xbar_t *pin = NULL;
228 
229  if(aux_ctrl) {
230  if(aux_ctrl->port != IOPORT_UNASSIGNED && (pin = ioport_claim(Port_Digital, Port_Input, &aux_ctrl->port, NULL))) {
231 
232  aux_ctrl->gpio.port = pin->port;
233  aux_ctrl->gpio.pin = pin->pin;
234 
235  ioport_set_function(pin, aux_ctrl->function, &aux_ctrl->signal);
236  } else
237  aux_ctrl->port = IOPORT_UNASSIGNED;
238  }
239 
240  return pin;
241 }
242 
243 static inline aux_ctrl_t *aux_ctrl_remap_explicit (aux_gpio_t gpio, uint8_t port, void *input)
244 {
245  aux_ctrl_t *ctrl_pin = NULL;
246 
247  if(sizeof(aux_ctrl) / sizeof(aux_ctrl_t)) {
248 
249  uint_fast8_t idx;
250 
251  for(idx = 0; ctrl_pin == NULL && idx < sizeof(aux_ctrl) / sizeof(aux_ctrl_t) && aux_ctrl[idx].gpio.pin != 0xFF; idx++) {
252  if(aux_ctrl[idx].gpio.pin == gpio.pin && aux_ctrl[idx].gpio.port == gpio.port) {
253  ctrl_pin = &aux_ctrl[idx];
254  ctrl_pin->port = port;
255  ctrl_pin->input = input;
256  break;
257  }
258  }
259  }
260 
261  return ctrl_pin;
262 }
263 
264 static inline aux_ctrl_t *aux_ctrl_in_get (uint8_t port)
265 {
266  aux_ctrl_t *ctrl_pin = NULL;
267 
268  uint_fast8_t idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t);
269 
270  if(idx) do {
271  if(aux_ctrl[--idx].port == port)
272  ctrl_pin = &aux_ctrl[idx];
273  } while(idx && ctrl_pin == NULL);
274 
275  return ctrl_pin;
276 }
277 
278 static inline void aux_ctrl_irq_enable (settings_t *settings, ioport_interrupt_callback_ptr aux_irq_handler)
279 {
280  uint_fast8_t idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t);
281 
282  if(idx) do {
283  if(aux_ctrl[--idx].port != 0xFF && aux_ctrl[idx].irq_mode != IRQ_Mode_None) {
284  if(!aux_ctrl_is_probe(aux_ctrl[idx].function)) {
285  pin_irq_mode_t irq_mode;
286  if((irq_mode = aux_ctrl[idx].irq_mode) & IRQ_Mode_RisingFalling)
287  irq_mode = (settings->control_invert.mask & aux_ctrl[idx].signal.mask) ? IRQ_Mode_Falling : IRQ_Mode_Rising;
288  hal.port.register_interrupt_handler(aux_ctrl[idx].port, irq_mode, aux_irq_handler);
289  }
290  }
291  } while(idx);
292 }
293 
294 typedef bool (*aux_claim_explicit_ptr)(aux_ctrl_t *aux_ctrl);
295 
296 // Default/internal functions for aux_ctrl_claim_ports()
297 
298 static bool __claim_in_port (xbar_t *properties, uint8_t port, void *data)
299 {
300  if(ioport_claim(Port_Digital, Port_Input, &port, NULL)) {
301  ((aux_ctrl_t *)data)->port = port;
302  ((aux_ctrl_t *)data)->gpio.port = properties->port;
303  ((aux_ctrl_t *)data)->gpio.pin = properties->pin;
304  ioport_set_function(properties, ((aux_ctrl_t *)data)->function, &((aux_ctrl_t *)data)->signal);
305  }
306 
307  return ((aux_ctrl_t *)data)->port != IOPORT_UNASSIGNED;
308 }
309 
310 static bool __find_in_port (xbar_t *properties, uint8_t port, void *data)
311 {
312  ((aux_ctrl_t *)data)->port = port;
313 
314  return true;
315 }
316 
317 // --
318 
319 static inline void aux_ctrl_claim_ports (aux_claim_explicit_ptr aux_claim_explicit, ioports_enumerate_callback_ptr aux_claim)
320 {
321  uint_fast8_t idx;
322 
323  if(aux_claim == NULL)
324  aux_claim = __claim_in_port;
325 
326  for(idx = 0; idx < sizeof(aux_ctrl) / sizeof(aux_ctrl_t); idx++) {
327 
328  if(aux_ctrl[idx].port != IOPORT_UNASSIGNED)
329  aux_claim_explicit(&aux_ctrl[idx]);
330 
331  else {
332 
333  pin_cap_t cap = { .irq_mode = aux_ctrl[idx].irq_mode, .claimable = On };
334 
335  if(aux_ctrl[idx].gpio.pin == 0xFE) // Toolsetter and Probe2
336  ioports_enumerate(Port_Digital, Port_Input, cap, __find_in_port, (void *)&aux_ctrl[idx]);
337 #ifdef STM32_PLATFORM
338  if(aux_ctrl[idx].irq_mode == IRQ_Mode_None && !(aux_ctrl[idx].function == Input_Probe || aux_ctrl[idx].function == Input_LimitsOverride))
339  continue;
340 #endif
341  if(aux_ctrl[idx].gpio.pin == 0xFF) {
342  if(ioports_enumerate(Port_Digital, Port_Input, cap, aux_claim, (void *)&aux_ctrl[idx]))
343  hal.signals_cap.mask |= aux_ctrl[idx].signal.mask;
344  }
345  }
346  }
347 }
348 
349 static inline control_signals_t aux_ctrl_scan_status (control_signals_t signals)
350 {
351 #if PROBE_DISCONNECT_ENABLE || STOP_DISABLE_ENABLE || BLOCK_DELETE_ENABLE || SINGLE_BLOCK_ENABLE || LIMITS_OVERRIDE_ENABLE
352 
353  uint_fast8_t idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t);
354 
355  if(idx) do {
356  if(!aux_ctrl[--idx].scan)
357  break;
358  signals.mask &= ~aux_ctrl[idx].signal.mask;
359  if(aux_ctrl[idx].port != IOPORT_UNASSIGNED) {
360  #ifdef GRBL_ESP32 // Snowflake guru workaround
361  if(hal.port.wait_on_input(Port_Digital, aux_ctrl[idx].port, WaitMode_Immediate, FZERO) == 1)
362  signals.mask |= aux_ctrl[idx].cap.mask;
363  #else
364  if(hal.port.wait_on_input(Port_Digital, aux_ctrl[idx].port, WaitMode_Immediate, 0.0f) == 1)
365  signals.mask |= aux_ctrl[idx].signal.mask;
366  #endif
367  }
368  } while(idx);
369 
370 #endif
371 
372  return signals;
373 }
374 
375 // The following pins are bound explicitly to aux output pins
376 static aux_ctrl_out_t aux_ctrl_out[] = {
377 #if defined(ESP_PLATFORM) || defined(RP2040) // for now
378 #if defined(STEPPERS_ENABLE_PIN) && STEPPERS_ENABLE_PORT == EXPANDER_PORT
379  add_aux_output_exp(Output_StepperEnable, STEPPERS_ENABLE)
380 #endif
381 #if defined(X_ENABLE_PIN) && X_ENABLE_PORT == EXPANDER_PORT
383 #endif
384 #if defined(X2_ENABLE_PIN) && X2_ENABLE_PORT == EXPANDER_PORT
386 #endif
387 #if defined(Y_ENABLE_PIN) && Y_ENABLE_PORT == EXPANDER_PORT
389 #endif
390 #if defined(Y2_ENABLE_PIN) && Y2_ENABLE_PORT == EXPANDER_PORT
392 #endif
393 #if defined(XY_ENABLE_PIN) && XY_ENABLE_PORT == EXPANDER_PORT
395 #endif
396 #if defined(Z_ENABLE_PIN) && Z_ENABLE_PORT == EXPANDER_PORT
398 #endif
399 #if defined(Z2_ENABLE_PIN) && Z2_ENABLE_PORT == EXPANDER_PORT
401 #endif
402 #if defined(A_ENABLE_PIN) && A_ENABLE_PORT == EXPANDER_PORT
404 #endif
405 #if defined(B_ENABLE_PIN) && B_ENABLE_PORT == EXPANDER_PORT
407 #endif
408 #if defined(C_ENABLE_PIN) && C_ENABLE_PORT == EXPANDER_PORT
410 #endif
411 #if defined(U_ENABLE_PIN) && U_ENABLE_PORT == EXPANDER_PORT
413 #endif
414 #if defined(V_ENABLE_PIN) && V_ENABLE_PORT == EXPANDER_PORT
416 #endif
417 #endif //
418 
419 #ifdef SPINDLE_ENABLE_PIN
421 #endif
422 #ifdef SPINDLE_PWM_PIN
424 #endif
425 #ifdef SPINDLE_DIRECTION_PIN
426  add_aux_output(Output_SpindleDir, SPINDLE_DIRECTION)
427 #endif
428 #ifdef SPINDLE1_ENABLE_PIN
430 #endif
431 #ifdef SPINDLE1_DIRECTION_PIN
432  add_aux_output(Output_Spindle1Dir, SPINDLE1_DIRECTION)
433 #endif
434 #ifdef SPINDLE1_PWM_PIN
435  add_aux_output(Output_Spindle1PWM, SPINDLE1_PWM)
436 #endif
437 #ifdef COOLANT_FLOOD_PIN
439 #endif
440 #ifdef COOLANT_MIST_PIN
442 #endif
443 #ifdef COPROC_RESET_PIN
444  add_aux_output(Output_CoProc_Reset, COPROC_RESET)
445 #endif
446 #ifdef COPROC_BOOT0_PIN
447  add_aux_output(Output_CoProc_Boot0, COPROC_BOOT0)
448 #endif
449 #if defined(SPI_RST_PIN) && defined(RP2040)
450  #ifndef SPI_RST_PORT
451  #define SPI_RST_PORT 0
452  #endif
453  add_aux_output(Output_SPIRST, SPI_RST)
454 #endif
455 };
456 
457 static inline aux_ctrl_out_t *aux_out_remap_explicit (aux_gpio_t gpio, uint8_t port, void *output)
458 {
459  aux_ctrl_out_t *ctrl_pin = NULL;
460 
461  uint_fast8_t idx = sizeof(aux_ctrl_out) / sizeof(aux_ctrl_out_t);
462 
463  if(idx) do {
464  idx--;
465  if(aux_ctrl_out[idx].gpio.port == gpio.port && aux_ctrl_out[idx].gpio.pin == gpio.pin) {
466  ctrl_pin = &aux_ctrl_out[idx];
467  ctrl_pin->port = port;
468  ctrl_pin->output = output;
469  }
470  } while(idx && ctrl_pin == NULL);
471 
472  return ctrl_pin;
473 }
474 
475 typedef bool (*aux_claim_explicit_out_ptr)(aux_ctrl_out_t *aux_ctrl);
476 
477 // Default functions for aux_ctrl_claim_out_ports()
478 
479 static bool __claim_out_port (xbar_t *properties, uint8_t port, void *data)
480 {
481  if(((aux_ctrl_out_t *)data)->gpio.port == (void *)EXPANDER_PORT) {
482  if(((aux_ctrl_out_t *)data)->gpio.pin == properties->pin && properties->set_value)
483  ((aux_ctrl_out_t *)data)->port = port;
484  } else if(ioport_claim(Port_Digital, Port_Output, &port, xbar_fn_to_pinname(((aux_ctrl_out_t *)data)->function)))
485  ((aux_ctrl_out_t *)data)->port = port;
486 
487  return ((aux_ctrl_out_t *)data)->port != IOPORT_UNASSIGNED;
488 }
489 
490 static bool ___claim_out_port_explicit (aux_ctrl_out_t *aux_ctrl)
491 {
492  xbar_t *pin;
493 
494  if((pin = ioport_claim(Port_Digital, Port_Output, &aux_ctrl->port, NULL)))
495  ioport_set_function(pin, aux_ctrl->function, NULL);
496  else
497  aux_ctrl->port = IOPORT_UNASSIGNED;
498 
499  return aux_ctrl->port != IOPORT_UNASSIGNED;
500 }
501 
502 //
503 
504 static inline void aux_ctrl_claim_out_ports (aux_claim_explicit_out_ptr aux_claim_explicit, ioports_enumerate_callback_ptr aux_claim)
505 {
506  uint_fast8_t idx;
507 
508  if(aux_claim == NULL)
509  aux_claim = __claim_out_port;
510 
511  if(aux_claim_explicit == NULL)
512  aux_claim_explicit = ___claim_out_port_explicit;
513 
514  for(idx = 0; idx < sizeof(aux_ctrl_out) / sizeof(aux_ctrl_out_t); idx++) {
515  if(aux_ctrl_out[idx].gpio.port == (void *)EXPANDER_PORT) {
516  if(ioports_enumerate(Port_Digital, Port_Output, (pin_cap_t){ .external = On, .claimable = On }, aux_claim, &aux_ctrl_out[idx])) {
517  if((aux_ctrl_out[idx].output = ioport_claim(Port_Digital, Port_Output, &aux_ctrl_out[idx].port, NULL /*xbar_fn_to_pinname(aux_ctrl_out[idx].function)*/))) {
518  ioport_set_function((xbar_t *)aux_ctrl_out[idx].output, aux_ctrl_out[idx].function, NULL);
519  // TODO: else set description?
520  aux_claim_explicit(&aux_ctrl_out[idx]);
521  }
522  }
523  } else if(aux_ctrl_out[idx].gpio.pin == 0xFF) {
524  if(ioports_enumerate(Port_Digital, Port_Output, (pin_cap_t){ .claimable = On }, aux_claim, &aux_ctrl_out[idx]))
525  aux_claim_explicit(&aux_ctrl_out[idx]);
526  } else if(aux_ctrl_out[idx].port != IOPORT_UNASSIGNED)
527  aux_claim_explicit(&aux_ctrl_out[idx]);
528  }
529 }
530 
531 // Output Signals
532 
533 #if defined(SPINDLE_ENABLE_PIN) && !defined(SPINDLE_ENABLE_BIT)
534 #define SPINDLE_ENABLE_BIT (1<<SPINDLE_ENABLE_PIN)
535 #endif
536 #if defined(SPINDLE_DIRECTION_PIN) && !defined(SPINDLE_DIRECTION_BIT)
537 #define SPINDLE_DIRECTION_BIT (1<<SPINDLE_DIRECTION_PIN)
538 #endif
539 
540 #if defined(SPINDLE1_ENABLE_PIN) && !defined(SPINDLE1_ENABLE_BIT)
541 #define SPINDLE1_ENABLE_BIT (1<<SPINDLE1_ENABLE_PIN)
542 #endif
543 #if defined(SPINDLE1_DIRECTION_PIN) && !defined(SPINDLE1_DIRECTION_BIT)
544 #define SPINDLE1_DIRECTION_BIT (1<<SPINDLE1_DIRECTION_PIN)
545 #endif
546 
547 #if defined(COOLANT_FLOOD_PIN) && !defined(COOLANT_FLOOD_BIT)
548 #define COOLANT_FLOOD_BIT (1<<COOLANT_FLOOD_PIN)
549 #endif
550 #if defined(COOLANT_MIST_PIN) && !defined(COOLANT_MIST_BIT)
551 #define COOLANT_MIST_BIT (1<<COOLANT_MIST_PIN)
552 #endif
553 
554 #if defined(RTS_PIN) && !defined(RTS_BIT)
555 #define RTS_BIT (1<<RTS_PIN)
556 #endif
557 
558 #if defined(RS485_DIR_PIN) && !defined(RS485_DIR_BIT)
559 #define RS485_DIR_BIT (1<<RS485_DIR_PIN)
560 #endif
561 
562 // IRQ enabled input singnals
563 
564 #if QEI_ENABLE
565 #ifndef QEI_A_BIT
566 #define QEI_A_BIT (1<<QEI_A_PIN)
567 #endif
568 #ifndef QEI_B_BIT
569 #define QEI_B_BIT (1<<QEI_B_PIN)
570 #endif
571 #else
572 #define QEI_A_BIT 0
573 #define QEI_B_BIT 0
574 #endif
575 
576 #ifndef QEI_SELECT_BIT
577 #define QEI_SELECT_BIT 0
578 #endif
579 #ifndef MPG_MODE_BIT
580 #define MPG_MODE_BIT 0
581 #endif
582 #ifndef I2C_STROBE_BIT
583 #define I2C_STROBE_BIT 0
584 #endif
585 
586 // Do NOT #define PROBE_BIT 0 here!
587 
588 #if SPINDLE_ENCODER_ENABLE
589 #ifndef SPINDLE_PULSE_PIN
590 #error "Spindle encoder requires at least SPINDLE_PULSE_PIN defined in the board map!"
591 #endif
592 #if !defined(SPINDLE_PULSE_BIT) && defined(SPINDLE_PULSE_PIN)
593 #define SPINDLE_PULSE_BIT (1<<SPINDLE_PULSE_PIN)
594 #endif
595 #if !defined(SPINDLE_INDEX_BIT) && defined(SPINDLE_INDEX_PIN)
596 #define SPINDLE_INDEX_BIT (1<<SPINDLE_INDEX_PIN)
597 #endif
598 #endif
599 
600 #ifndef SPINDLE_INDEX_BIT
601 #define SPINDLE_INDEX_BIT 0
602 #endif
603 #ifndef SPINDLE_PULSE_BIT
604 #define SPINDLE_PULSE_BIT 0
605 #endif
606 
607 #if SPINDLE_ENCODER_ENABLE && (SPINDLE_INDEX_BIT + SPINDLE_PULSE_BIT) == 0
608 #error "Spindle encoder requires SPINDLE_PULSE_PIN and SPINDLE_INDEX_PIN defined in the board map!"
609 #endif
610 
611 #ifndef SPI_IRQ_PIN
612 #define SPI_IRQ_BIT 0
613 #elif !defined(SPI_IRQ_BIT)
614 #define SPI_IRQ_BIT (1<<SPI_IRQ_PIN)
615 #endif
616 
617 #ifndef DEVICES_IRQ_MASK
618 #define DEVICES_IRQ_MASK (SPI_IRQ_BIT|SPINDLE_INDEX_BIT|QEI_A_BIT|QEI_B_BIT|SD_DETECT_BIT)
619 #define DEVICES_IRQ_MASK_SUM (SPI_IRQ_BIT+SPINDLE_INDEX_BIT+QEI_A_BIT+QEI_B_BIT+SD_DETECT_BIT)
620 #endif
621 
622 // Auxillary input signals
623 
624 #ifdef AUXINPUT0_PIN
625 #define AUXINPUT0_BIT (1<<AUXINPUT0_PIN)
626 #else
627 #define AUXINPUT0_BIT 0
628 #endif
629 #ifdef AUXINPUT1_PIN
630 #define AUXINPUT1_BIT (1<<AUXINPUT1_PIN)
631 #else
632 #define AUXINPUT1_BIT 0
633 #endif
634 #ifdef AUXINPUT2_PIN
635 #define AUXINPUT2_BIT (1<<AUXINPUT2_PIN)
636 #else
637 #define AUXINPUT2_BIT 0
638 #endif
639 #ifdef AUXINPUT3_PIN
640 #define AUXINPUT3_BIT (1<<AUXINPUT3_PIN)
641 #else
642 #define AUXINPUT3_BIT 0
643 #endif
644 #ifdef AUXINPUT4_PIN
645 #define AUXINPUT4_BIT (1<<AUXINPUT4_PIN)
646 #else
647 #define AUXINPUT4_BIT 0
648 #endif
649 #ifdef AUXINPUT5_PIN
650 #define AUXINPUT5_BIT (1<<AUXINPUT5_PIN)
651 #else
652 #define AUXINPUT5_BIT 0
653 #endif
654 #ifdef AUXINPUT6_PIN
655 #define AUXINPUT6_BIT (1<<AUXINPUT6_PIN)
656 #else
657 #define AUXINPUT6_BIT 0
658 #endif
659 #ifdef AUXINPUT7_PIN
660 #define AUXINPUT7_BIT (1<<AUXINPUT7_PIN)
661 #else
662 #define AUXINPUT7_BIT 0
663 #endif
664 #ifdef AUXINPUT8_PIN
665 #define AUXINPUT8_BIT (1<<AUXINPUT8_PIN)
666 #else
667 #define AUXINPUT8_BIT 0
668 #endif
669 #ifdef AUXINPUT9_PIN
670 #define AUXINPUT9_BIT (1<<AUXINPUT9_PIN)
671 #else
672 #define AUXINPUT9_BIT 0
673 #endif
674 #ifdef AUXINPUT10_PIN
675 #define AUXINPUT10_BIT (1<<AUXINPUT10_PIN)
676 #else
677 #define AUXINPUT10_BIT 0
678 #endif
679 #ifdef AUXINPUT11_PIN
680 #define AUXINPUT11_BIT (1<<AUXINPUT11_PIN)
681 #else
682 #define AUXINPUT11_BIT 0
683 #endif
684 #ifdef AUXINPUT12_PIN
685 #define AUXINPUT12_BIT (1<<AUXINPUT12_PIN)
686 #else
687 #define AUXINPUT12_BIT 0
688 #endif
689 #ifdef AUXINPUT13_PIN
690 #define AUXINPUT13_BIT (1<<AUXINPUT13_PIN)
691 #else
692 #define AUXINPUT13_BIT 0
693 #endif
694 #ifdef AUXINPUT14_PIN
695 #define AUXINPUT14_BIT (1<<AUXINPUT14_PIN)
696 #else
697 #define AUXINPUT14_BIT 0
698 #endif
699 #ifdef AUXINPUT15_PIN
700 #define AUXINPUT15_BIT (1<<AUXINPUT15_PIN)
701 #else
702 #define AUXINPUT15_BIT 0
703 #endif
704 
705 #ifndef AUXINPUT_MASK
706 #define AUXINPUT_MASK (AUXINPUT0_BIT|AUXINPUT1_BIT|AUXINPUT2_BIT|AUXINPUT3_BIT|AUXINPUT4_BIT|AUXINPUT5_BIT|AUXINPUT6_BIT|AUXINPUT7_BIT|\
707  AUXINPUT8_BIT|AUXINPUT9_BIT|AUXINPUT10_BIT|AUXINPUT11_BIT|AUXINPUT12_BIT|AUXINPUT13_BIT|AUXINPUT4_BIT|AUXINPUT15_BIT)
708 #define AUXINPUT_MASK_SUM (AUXINPUT0_BIT+AUXINPUT1_BIT+AUXINPUT2_BIT+AUXINPUT3_BIT+AUXINPUT4_BIT+AUXINPUT5_BIT+AUXINPUT6_BIT+AUXINPUT7_BIT+\
709  AUXINPUT8_BIT+AUXINPUT9_BIT+AUXINPUT10_BIT+AUXINPUT11_BIT+AUXINPUT12_BIT+AUXINPUT13_BIT+AUXINPUT4_BIT+AUXINPUT15_BIT)
710 #endif
711 
712 /*EOF*/
const char * xbar_fn_to_pinname(pin_function_t fn)
Definition: crossbar.c:160
pin_function_t
Definition: crossbar.h:27
@ Input_FeedHold
Definition: crossbar.h:30
@ Input_Toolsetter
Definition: crossbar.h:58
@ Output_StepperEnableV
Definition: crossbar.h:182
@ Input_Reset
Definition: crossbar.h:29
@ Output_CoProc_Boot0
Definition: crossbar.h:236
@ Input_Probe
Definition: crossbar.h:43
@ Output_StepperEnableX
Definition: crossbar.h:172
@ Input_MotorFault
Definition: crossbar.h:37
@ Input_Probe2
Definition: crossbar.h:56
@ Input_MotorWarning
Definition: crossbar.h:38
@ Input_ToolsetterOvertravel
Definition: crossbar.h:41
@ Input_ProbeDisconnect
Definition: crossbar.h:36
@ Input_EStop
Definition: crossbar.h:35
@ Input_StopDisable
Definition: crossbar.h:34
@ Output_StepperEnableXY
Definition: crossbar.h:183
@ Input_LimitsOverride
Definition: crossbar.h:39
@ Output_CoProc_Reset
Definition: crossbar.h:235
@ Output_StepperEnableZ
Definition: crossbar.h:176
@ Input_QEI_Select
Definition: crossbar.h:260
@ Output_StepperEnableU
Definition: crossbar.h:181
@ Output_StepperEnableA
Definition: crossbar.h:178
@ Output_StepperEnableY2
Definition: crossbar.h:175
@ Input_BlockDelete
Definition: crossbar.h:33
@ Output_StepperEnable
Definition: crossbar.h:170
@ Output_SpindleDir
Definition: crossbar.h:186
@ Output_StepperEnableY
Definition: crossbar.h:174
@ Output_StepperEnableC
Definition: crossbar.h:180
@ Input_SingleBlock
Definition: crossbar.h:40
@ Output_SPIRST
Definition: crossbar.h:246
@ Output_SpindleOn
Definition: crossbar.h:185
@ Input_I2CStrobe
Definition: crossbar.h:253
@ Output_Spindle1Dir
Definition: crossbar.h:189
@ Output_SpindlePWM
Definition: crossbar.h:187
@ Output_CoolantMist
Definition: crossbar.h:191
@ Input_MPGSelect
Definition: crossbar.h:59
@ Output_Spindle1On
Definition: crossbar.h:188
@ Output_StepperEnableB
Definition: crossbar.h:179
@ Input_CycleStart
Definition: crossbar.h:31
@ Input_SafetyDoor
Definition: crossbar.h:32
@ Output_CoolantFlood
Definition: crossbar.h:192
@ Output_StepperEnableX2
Definition: crossbar.h:173
@ Output_StepperEnableZ2
Definition: crossbar.h:177
@ Output_Spindle1PWM
Definition: crossbar.h:190
pin_irq_mode_t
Pin interrupt modes, may be or'ed when reporting pin capability.
Definition: crossbar.h:561
@ IRQ_Mode_Rising
0b00001 (0x01)
Definition: crossbar.h:563
@ IRQ_Mode_RisingFalling
0b00011 (0x03) - only used to report port capability.
Definition: crossbar.h:565
@ IRQ_Mode_None
0b00000 (0x00)
Definition: crossbar.h:562
@ IRQ_Mode_Change
0b00100 (0x04)
Definition: crossbar.h:566
@ IRQ_Mode_Falling
0b00010 (0x02)
Definition: crossbar.h:564
#define SPINDLE_ENABLE
Definition: driver_opts.h:353
#define SPINDLE1_ENABLE
Definition: driver_opts.h:325
#define COOLANT_FLOOD
Definition: driver_opts.h:308
#define COOLANT_MIST
Definition: driver_opts.h:309
#define SPINDLE_PWM
Definition: driver_opts.h:317
@ WaitMode_Immediate
0 - This is the only mode allowed for analog inputs
Definition: gcode.h:283
DCRAM grbl_hal_t hal
Global HAL struct.
Definition: grbllib.c:91
xbar_t * 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:311
bool ioport_set_function(xbar_t *pin, pin_function_t function, driver_caps_t caps)
Set pin function.
Definition: ioports.c:387
bool ioports_enumerate(io_port_type_t type, io_port_direction_t dir, pin_cap_t filter, ioports_enumerate_callback_ptr callback, void *data)
Enumerate ports.
Definition: ioports.c:552
@ Port_Input
0
Definition: ioports.h:34
@ Port_Output
1
Definition: ioports.h:35
bool(* ioports_enumerate_callback_ptr)(xbar_t *properties, uint8_t port, void *data)
Definition: ioports.h:161
@ Port_Digital
1
Definition: ioports.h:30
#define IOPORT_UNASSIGNED
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:142
#define On
Definition: nuts_bolts.h:36
#define add_aux_input_scan(fn, irq, signal_bit)
Definition: pin_bits_masks.h:126
#define add_aux_input(fn, aux, irq, signal_bit)
Definition: pin_bits_masks.h:119
bool(* aux_claim_explicit_ptr)(aux_ctrl_t *aux_ctrl)
Definition: pin_bits_masks.h:294
#define add_aux_output(fn, aux)
Definition: pin_bits_masks.h:124
bool(* aux_claim_explicit_out_ptr)(aux_ctrl_out_t *aux_ctrl)
Definition: pin_bits_masks.h:475
#define add_aux_input_no_signal(fn, irq)
Definition: pin_bits_masks.h:127
#define add_aux_output_exp(fn, aux)
Definition: pin_bits_masks.h:128
#define EXPANDER_PORT
Definition: pin_bits_masks.h:56
settings_t settings
Definition: settings.c:46
Definition: crossbar.h:744
uint8_t port
Auxiliary port number, post claimed.
Definition: crossbar.h:746
void * output
Pointer to the driver input array entry for the pin.
Definition: crossbar.h:748
Definition: crossbar.h:734
pin_irq_mode_t irq_mode
Required IRQ mode for the input.
Definition: crossbar.h:737
control_signals_t signal
Set to the pin the input maps to, 0 if none.
Definition: crossbar.h:738
uint8_t port
Auxiliary port number, post claimed.
Definition: crossbar.h:736
void * input
Pointer to the driver input array entry for the pin.
Definition: crossbar.h:740
aux_gpio_t gpio
MCU port base address (may be NULL) and pin number.
Definition: crossbar.h:739
pin_function_t function
Pin function.
Definition: crossbar.h:735
Definition: crossbar.h:729
uint8_t pin
MCU pin number.
Definition: crossbar.h:731
void * port
MCU port address (may be NULL).
Definition: crossbar.h:730
io_port_t port
Optional handlers for axuillary I/O (adds support for M62-M66).
Definition: hal.h:679
control_signals_t signals_cap
Control input signals supported by the driver.
Definition: hal.h:715
wait_on_input_ptr wait_on_input
Optional handler for reading a digital or analog input.
Definition: ioports.h:171
ioport_register_interrupt_handler_ptr register_interrupt_handler
Definition: ioports.h:176
Definition: settings.h:870
control_signals_t control_invert
Definition: settings.h:882
Definition: crossbar.h:751
xbar_set_value_ptr set_value
Optional pointer to function to set port value.
Definition: crossbar.h:763
uint_fast8_t pin
Pin number.
Definition: crossbar.h:758
void * port
Optional pointer to the underlying peripheral or pin specific data.
Definition: crossbar.h:756
Definition: nuts_bolts.h:250
uint16_t mask
Definition: nuts_bolts.h:252
Definition: crossbar.h:619
uint32_t irq_mode
pin_irq_mode_t - IRQ modes
Definition: crossbar.h:626