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