diff --git a/rtu/dev/redstone_rtu.lua b/rtu/dev/redstone_rtu.lua index 366e960..5772a10 100644 --- a/rtu/dev/redstone_rtu.lua +++ b/rtu/dev/redstone_rtu.lua @@ -36,7 +36,7 @@ function redstone_rtu.new(relay) -- change the phy in use (a relay or rs) ---@param new_phy table - function public.change_phy(new_phy) phy = new_phy end + function public.remount_phy(new_phy) phy = new_phy end -- NOTE: for runtime speed, inversion logic results in extra code here but less code when functions are called @@ -49,15 +49,15 @@ function redstone_rtu.new(relay) if color then if invert then - f_read = function () return digital_read(not rs.testBundledInput(side, color)) end + f_read = function () return digital_read(not phy.testBundledInput(side, color)) end else - f_read = function () return digital_read(rs.testBundledInput(side, color)) end + f_read = function () return digital_read(phy.testBundledInput(side, color)) end end else if invert then - f_read = function () return digital_read(not rs.getInput(side)) end + f_read = function () return digital_read(not phy.getInput(side)) end else - f_read = function () return digital_read(rs.getInput(side)) end + f_read = function () return digital_read(phy.getInput(side)) end end end @@ -74,50 +74,50 @@ function redstone_rtu.new(relay) if color then if invert then - f_read = function () return digital_read(not colors.test(rs.getBundledOutput(side), color)) end + f_read = function () return digital_read(not colors.test(phy.getBundledOutput(side), color)) end f_write = function (level) if level ~= IO_LVL.FLOATING and level ~= IO_LVL.DISCONNECT then - local output = rs.getBundledOutput(side) + local output = phy.getBundledOutput(side) -- inverted conditions if digital_write(level) then output = colors.subtract(output, color) else output = colors.combine(output, color) end - rs.setBundledOutput(side, output) + phy.setBundledOutput(side, output) end end else - f_read = function () return digital_read(colors.test(rs.getBundledOutput(side), color)) end + f_read = function () return digital_read(colors.test(phy.getBundledOutput(side), color)) end f_write = function (level) if level ~= IO_LVL.FLOATING and level ~= IO_LVL.DISCONNECT then - local output = rs.getBundledOutput(side) + local output = phy.getBundledOutput(side) if digital_write(level) then output = colors.combine(output, color) else output = colors.subtract(output, color) end - rs.setBundledOutput(side, output) + phy.setBundledOutput(side, output) end end end else if invert then - f_read = function () return digital_read(not rs.getOutput(side)) end + f_read = function () return digital_read(not phy.getOutput(side)) end f_write = function (level) if level ~= IO_LVL.FLOATING and level ~= IO_LVL.DISCONNECT then - rs.setOutput(side, not digital_write(level)) + phy.setOutput(side, not digital_write(level)) end end else - f_read = function () return digital_read(rs.getOutput(side)) end + f_read = function () return digital_read(phy.getOutput(side)) end f_write = function (level) if level ~= IO_LVL.FLOATING and level ~= IO_LVL.DISCONNECT then - rs.setOutput(side, digital_write(level)) + phy.setOutput(side, digital_write(level)) end end end @@ -129,15 +129,15 @@ function redstone_rtu.new(relay) -- link analog input ---@param side string function public.link_ai(side) - unit.connect_input_reg(function () return rs.getAnalogInput(side) end) + unit.connect_input_reg(function () return phy.getAnalogInput(side) end) end -- link analog output ---@param side string function public.link_ao(side) unit.connect_holding_reg( - function () return rs.getAnalogOutput(side) end, - function (value) rs.setAnalogOutput(side, value) end + function () return phy.getAnalogOutput(side) end, + function (value) phy.setAnalogOutput(side, value) end ) end diff --git a/rtu/startup.lua b/rtu/startup.lua index d875ae6..577a13e 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -140,10 +140,19 @@ local function main() local rtu_redstone = config.Redstone local rtu_devices = config.Peripherals + -- get a string representation of a port interface + ---@param entry rtu_rs_definition + ---@return string + local function entry_iface_name(entry) + return util.trinary(entry.color ~= nil, util.c(entry.side, "/", rsio.color_name(entry.color)), entry.side) + end + -- configure RTU gateway based on settings file definitions local function sys_config() -- redstone interfaces - local rs_rtus = {} ---@type { name: string, rtu: rtu_rs_device, phy: table|nil, banks: IO_PORT[][] }[] + local rs_rtus = {} ---@type { name: string, rtu: rtu_rs_device, phy: table|nil, banks: rtu_rs_definition[][] }[] + + local all_conns = {} -- go through redstone definitions list for entry_idx = 1, #rtu_redstone do @@ -152,7 +161,7 @@ local function main() local assignment local for_reactor = entry.unit local phy = entry.relay or 0 - local iface_name = util.trinary(entry.color ~= nil, util.c(entry.side, "/", rsio.color_name(entry.color)), entry.side) + local iface_name = entry_iface_name(entry) if util.is_int(entry.unit) and entry.unit > 0 and entry.unit < 5 then ---@cast for_reactor integer @@ -175,12 +184,12 @@ local function main() log.fatal(message) return false elseif not rs_rtus[entry.relay] then - log.debug(util.c("sys_config> allocated relay redstone RTU for interface ", entry.relay)) + log.debug(util.c("sys_config> allocated relay redstone RTU on interface ", entry.relay)) local relay = ppm.get_device(entry.relay) if not relay then - log.warning(util.c("sys_config> redstone relay ", entry.relay, " not connected")) + log.warning(util.c("sys_config> redstone relay ", entry.relay, " is not connected")) elseif ppm.get_type(entry.relay) ~= "redstone_relay" then log.warning(util.c("sys_config> redstone relay ", entry.relay, " is not a redstone relay")) end @@ -198,8 +207,9 @@ local function main() valid = util.trinary(entry.color == nil, true, rsio.is_color(entry.color)) end - local rs_rtu = rs_rtus[for_reactor].rtu - local conns = rs_rtus[phy].banks[for_reactor] + -- local rs_rtu = rs_rtus[phy].rtu + local bank = rs_rtus[phy].banks[for_reactor] + local conns = all_conns[for_reactor] if not valid then local message = util.c("sys_config> invalid redstone definition at block index #", entry_idx) @@ -216,10 +226,12 @@ local function main() println(message) log.warning(message) else - rs_rtu.link_di(entry.side, entry.color, entry.invert) + table.insert(bank, entry) + -- rs_rtu.link_di(entry.side, entry.color, entry.invert) end elseif mode == rsio.IO_MODE.DIGITAL_OUT then - rs_rtu.link_do(entry.side, entry.color, entry.invert) + table.insert(bank, entry) + -- rs_rtu.link_do(entry.side, entry.color, entry.invert) elseif mode == rsio.IO_MODE.ANALOG_IN then -- can't have duplicate inputs if util.table_contains(conns, entry.port) then @@ -227,25 +239,55 @@ local function main() println(message) log.warning(message) else - rs_rtu.link_ai(entry.side) + table.insert(bank, entry) + -- rs_rtu.link_ai(entry.side) end elseif mode == rsio.IO_MODE.ANALOG_OUT then - rs_rtu.link_ao(entry.side) + table.insert(bank, entry) + -- rs_rtu.link_ao(entry.side) else -- should be unreachable code, we already validated ports - log.error("sys_config> fell through if chain attempting to identify IO mode at block index #" .. entry_idx, true) + log.error("sys_config> failed to identify IO mode at block index #" .. entry_idx, true) println("sys_config> encountered a software error, check logs") return false end table.insert(conns, entry.port) - log.debug(util.c("sys_config> linked redstone ", #conns, ": ", rsio.to_string(entry.port), " (", iface_name, ") for ", assignment)) + log.debug(util.c("sys_config> banked redstone ", #conns, ": ", rsio.to_string(entry.port), " (", iface_name, ") for ", assignment)) end end -- create unit entries for redstone RTUs for _, def in pairs(rs_rtus) do + local rtu_conns = { [0] = {}, {}, {}, {}, {}} + + -- connect the IO banks + for for_reactor = 0, #def.banks do + local bank = def.banks[for_reactor] + local conns = rtu_conns[for_reactor] + + -- link redstone to the RTU + for i = 1, #bank do + local conn = bank[i] + + local mode = rsio.get_io_mode(conn.port) + if mode == rsio.IO_MODE.DIGITAL_IN then + def.rtu.link_di(conn.side, conn.color, conn.invert) + elseif mode == rsio.IO_MODE.DIGITAL_OUT then + def.rtu.link_do(conn.side, conn.color, conn.invert) + elseif mode == rsio.IO_MODE.ANALOG_IN then + def.rtu.link_ai(conn.side) + elseif mode == rsio.IO_MODE.ANALOG_OUT then + def.rtu.link_ao(conn.side) + end + + table.insert(conns, conn.port) + + log.debug(util.c("sys_config> linked redstone ", for_reactor, ".", #conns, ": ", rsio.to_string(conn.port), " (", entry_iface_name(conn), ")")) + end + end + local hw_state = util.trinary(def.phy, RTU_HW_STATE.OK, RTU_HW_STATE.OFFLINE) ---@class rtu_registry_entry @@ -256,7 +298,7 @@ local function main() index = false, ---@type integer|false reactor = nil, ---@type nil device = def.phy, ---@type table|nil - banks = def.banks, ---@type IO_PORT[][] + rs_conns = rtu_conns, ---@type IO_PORT[][]|nil is_multiblock = false, ---@type boolean formed = nil, ---@type boolean|nil hw_state = hw_state, ---@type RTU_HW_STATE diff --git a/rtu/threads.lua b/rtu/threads.lua index 7b872bf..e036a4e 100644 --- a/rtu/threads.lua +++ b/rtu/threads.lua @@ -133,7 +133,7 @@ local function handle_unit_mount(smem, println_ts, iface, type, device, unit) elseif unit.type == RTU_UNIT_TYPE.ENV_DETECTOR then unit.rtu, faulted = envd_rtu.new(device) elseif unit.type == RTU_UNIT_TYPE.REDSTONE then - unit.rtu.change_phy(device) + unit.rtu.remount_phy(device) else unknown = true log.error(util.c("failed to identify reconnected RTU unit type (", unit.name, ")"), true)