2019-12-28 14:10:11 +01:00
|
|
|
-- Simple example for responding to NMRA DCC commands
|
|
|
|
-- author @voborsky
|
|
|
|
local PIN = 2 -- GPIO4
|
|
|
|
|
|
|
|
local addr = 0x12a
|
|
|
|
|
2019-12-31 00:53:54 +01:00
|
|
|
local CV = {[29]=0,
|
2019-12-28 14:10:11 +01:00
|
|
|
[1]=bit.band(addr, 0x3f), --CV_ACCESSORY_DECODER_ADDRESS_LSB (6 bits)
|
|
|
|
[9]=bit.band(bit.rshift(addr,6), 0x7) --CV_ACCESSORY_DECODER_ADDRESS_MSB (3 bits)
|
|
|
|
}
|
|
|
|
|
|
|
|
local function deepcopy(orig)
|
|
|
|
local orig_type = type(orig)
|
|
|
|
local copy
|
|
|
|
if orig_type == 'table' then
|
|
|
|
copy = {}
|
|
|
|
for orig_key, orig_value in next, orig, nil do
|
|
|
|
copy[deepcopy(orig_key)] = deepcopy(orig_value)
|
|
|
|
end
|
|
|
|
setmetatable(copy, deepcopy(getmetatable(orig)))
|
|
|
|
else -- number, string, boolean, etc
|
|
|
|
copy = orig
|
|
|
|
end
|
|
|
|
return copy
|
|
|
|
end
|
|
|
|
|
|
|
|
local cmd_last
|
|
|
|
local params_last
|
|
|
|
|
|
|
|
local function is_new(cmd, params)
|
|
|
|
if cmd ~= cmd_last then return true end
|
|
|
|
for i,j in pairs(params) do
|
|
|
|
if params_last[i] ~= j then return true end
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
local function DCC_command(cmd, params)
|
|
|
|
if not is_new(cmd, params) then return end
|
2019-12-31 00:53:54 +01:00
|
|
|
if cmd == dcc.DCC_IDLE then
|
2019-12-28 14:10:11 +01:00
|
|
|
return
|
|
|
|
elseif cmd == dcc.DCC_TURNOUT then
|
2019-12-31 00:53:54 +01:00
|
|
|
print("Turnout command")
|
2019-12-28 14:10:11 +01:00
|
|
|
elseif cmd == dcc.DCC_SPEED then
|
2019-12-31 00:53:54 +01:00
|
|
|
print("Speed command")
|
2019-12-28 14:10:11 +01:00
|
|
|
elseif cmd == dcc.DCC_FUNC then
|
2019-12-31 00:53:54 +01:00
|
|
|
print("Function command")
|
2019-12-28 14:10:11 +01:00
|
|
|
else
|
|
|
|
print("Other command", cmd)
|
|
|
|
end
|
2019-12-31 00:53:54 +01:00
|
|
|
|
2019-12-28 14:10:11 +01:00
|
|
|
for i,j in pairs(params) do
|
|
|
|
print(i, j)
|
|
|
|
end
|
|
|
|
print(("="):rep(80))
|
|
|
|
cmd_last = cmd
|
|
|
|
params_last = deepcopy(params)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function CV_callback(operation, param)
|
|
|
|
local oper = ""
|
|
|
|
local result
|
|
|
|
if operation == dcc.CV_WRITE then
|
|
|
|
oper = "Write"
|
|
|
|
CV[param.CV]=param.Value
|
|
|
|
elseif operation == dcc.CV_READ then
|
|
|
|
oper = "Read"
|
|
|
|
result = CV[param.CV]
|
|
|
|
elseif operation == dcc.CV_VALID then
|
|
|
|
oper = "Valid"
|
|
|
|
result = 1
|
2019-12-31 00:53:54 +01:00
|
|
|
elseif operation == dcc.CV_RESET then
|
2019-12-28 14:10:11 +01:00
|
|
|
oper = "Reset"
|
|
|
|
CV = {}
|
|
|
|
end
|
2019-12-31 00:53:54 +01:00
|
|
|
print(("[CV_callback] %s CV %d%s")
|
|
|
|
:format(oper, param.CV, param.Value and "\tValue: "..param.Value or "\tValue: nil"))
|
2019-12-28 14:10:11 +01:00
|
|
|
return result
|
|
|
|
end
|
|
|
|
|
|
|
|
dcc.setup(PIN,
|
|
|
|
DCC_command,
|
2019-12-31 00:53:54 +01:00
|
|
|
dcc.MAN_ID_DIY, 1,
|
|
|
|
-- Accessories (turnouts) decoder:
|
|
|
|
--bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT, dcc.FLAGS_DCC_ACCESSORY_DECODER, dcc.FLAGS_MY_ADDRESS_ONLY),
|
|
|
|
-- Cab (train) decoder
|
|
|
|
bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT),
|
2019-12-28 14:10:11 +01:00
|
|
|
0, -- ???
|
|
|
|
CV_callback)
|