diff --git a/hal/src/main/native/athena/DIO.cpp b/hal/src/main/native/athena/DIO.cpp index 45723597a8..7b6842e218 100644 --- a/hal/src/main/native/athena/DIO.cpp +++ b/hal/src/main/native/athena/DIO.cpp @@ -272,6 +272,29 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value, } { std::scoped_lock lock(digitalDIOMutex); + + tDIO::tOutputEnable currentOutputEnable = + digitalSystem->readOutputEnable(status); + + HAL_Bool isInput = false; + + if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) { + isInput = + ((currentOutputEnable.SPIPort >> remapSPIChannel(port->channel)) & + 1) != 0; + } else if (port->channel < kNumDigitalHeaders) { + isInput = ((currentOutputEnable.Headers >> port->channel) & 1) != 0; + } else { + isInput = ((currentOutputEnable.MXP >> remapMXPChannel(port->channel)) & + 1) != 0; + } + + if (isInput) { + *status = PARAMETER_OUT_OF_RANGE; + hal::SetLastError(status, "Cannot set output of an input channel"); + return; + } + tDIO::tDO currentDIO = digitalSystem->readDO(status); if (port->channel >= kNumDigitalHeaders + kNumDigitalMXPChannels) { diff --git a/hal/src/main/native/include/hal/DIO.h b/hal/src/main/native/include/hal/DIO.h index 306321478e..0f25192fbd 100644 --- a/hal/src/main/native/include/hal/DIO.h +++ b/hal/src/main/native/include/hal/DIO.h @@ -40,6 +40,11 @@ HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle, */ HAL_Bool HAL_CheckDIOChannel(int32_t channel); +/** + * Frees a DIO port. + * + * @param handle the DIO channel handle + */ void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle); /** diff --git a/hal/src/main/native/sim/DIO.cpp b/hal/src/main/native/sim/DIO.cpp index 0b85cd83dc..1b744a1625 100644 --- a/hal/src/main/native/sim/DIO.cpp +++ b/hal/src/main/native/sim/DIO.cpp @@ -174,6 +174,11 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value, value = 1; } } + if (SimDIOData[port->channel].isInput) { + *status = PARAMETER_OUT_OF_RANGE; + hal::SetLastError(status, "Cannot set output of an input channel"); + return; + } SimDIOData[port->channel].value = value; }