mirror of
https://github.com/grblHAL/core.git
synced 2026-08-17 16:41:45 +08:00
129 lines
4.4 KiB
C
129 lines
4.4 KiB
C
/*
|
|
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);
|
|
}
|