forked from grblHAL/core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ioports.c
128 lines (104 loc) · 4.43 KB
/
ioports.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
ioports.c - some wrapper functions for the ioports HAL API
Part of grblHAL
Copyright (c) 2021 Terje Io
Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Grbl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
*
* Some wrapper functions for the #io_port_t API.
* They perform the necessary checks for both availability of ports
* and advanced functionality simplifying plugin code that uses them.
*/
#include "hal.h"
static int16_t digital_in = -1, digital_out = -1, analog_in = -1, analog_out = -1;
static uint8_t ioports_count (io_port_type_t type, io_port_direction_t dir)
{
xbar_t *port;
uint8_t n_ports = 0;
// determine how many ports, including claimed ports, that are available
do {
if((port = hal.port.get_pin_info(type, dir, n_ports)))
n_ports++;
} while(port != NULL);
return n_ports;
}
/*! \brief Get number of digital or analog ports available.
\param type as an \a #io_port_type_t enum value.
\param dir as an \a #io_port_direction_t enum value.
\returns number of ports available including claimed ports if the API implementation supports that.
*/
uint8_t ioports_available (io_port_type_t type, io_port_direction_t dir)
{
uint8_t ports = 0;
if(hal.port.get_pin_info) {
if(type == Port_Digital) {
if(dir == Port_Input)
ports = digital_in == -1 ? (digital_in = ioports_count(type, dir)) : (uint8_t)digital_in;
else
ports = digital_out == -1 ? (digital_out = ioports_count(type, dir)) : (uint8_t)digital_out;
} else {
if(dir == Port_Input)
ports = analog_in == -1 ? (analog_in = ioports_count(type, dir)) : (uint8_t)analog_in;
else
ports = analog_out == -1 ? (analog_out = ioports_count(type, dir)) : (uint8_t)analog_out;
}
} else {
if(type == Port_Digital)
ports = dir == Port_Input ? hal.port.num_digital_in : hal.port.num_digital_out;
else
ports = dir == Port_Input ? hal.port.num_analog_in : hal.port.num_analog_out;
}
return ports;
}
/*! \brief Claim a digital or analog port for exclusive use.
\param type as an \a #io_port_type_t enum value.
\param dir as an \a #io_port_direction_t enum value.
\param port pointer to a \a uint8_t holding the ports aux number, returns the actual port number to use if successful.
\param description pointer to a \a char constant for the pin description.
\returns true if successful, false if not.
*/
bool ioport_claim (io_port_type_t type, io_port_direction_t dir, uint8_t *port, const char *description)
{
bool ok = false;
uint8_t n_ports = ioports_available(type, dir);
uint8_t base = type == Port_Digital
? (dir == Port_Input ? Input_Aux0 : Output_Aux0)
: (dir == Port_Input ? Input_Aux0 : Output_Aux0); // TODO add analog ports?
if(hal.port.claim != NULL) {
xbar_t *portinfo;
if(n_ports > 0) do {
n_ports--;
portinfo = hal.port.get_pin_info(type, dir, n_ports);
if((ok = portinfo && !portinfo->mode.claimed && (portinfo->function - base) == *port)) {
ok = hal.port.claim(type, dir, port, description);
break;
}
} while(n_ports && !ok);
} else if((ok = n_ports > 0)) {
if(type == Port_Digital)
*port = dir == Port_Input ? --hal.port.num_digital_in : --hal.port.num_digital_out;
else
*port = dir == Port_Input ? --hal.port.num_analog_in : --hal.port.num_analog_out;
if(hal.port.set_pin_description)
hal.port.set_pin_description(type, dir, *port, description);
}
return ok;
}
/*! \brief Check if ports can be claimed by aux number or not.
\returns true if ports can be claimed by aux number, false if claimed ports are allocated by the API.
*/
bool ioport_can_claim_explicit (void)
{
return !(hal.port.claim == NULL || hal.port.get_pin_info == NULL);
}