119 lines
5.6 KiB
Markdown
119 lines
5.6 KiB
Markdown
# DCC module
|
|
| Since | Origin / Contributor | Maintainer | Source |
|
|
| :----- | :-------------------- | :---------- | :------ |
|
|
| 2019-12-28 | [vsky279](https://github.com/vsky279) | [vsky279](https://github.com/vsky279) | [dcc.c](../../app/modules/dcc.c)|
|
|
|
|
The dcc module implements decoder of the [National Model Railroad Association](https://www.nmra.org/) (NMRA) Digital Command Control (DCC) decoder - see [DCC wiki](https://dccwiki.com/Introduction_to_DCC) for details.
|
|
|
|
The hardware needed to decode the DCC signal can be built based on different DCC decoders implementation for Arduino, for inspiration see [https://mrrwa.org/dcc-decoder-interface/](https://mrrwa.org/dcc-decoder-interface/). Basically the signal from the DCC bus is connected via an optocoupler to any GPIO pin. The DCC bus can be also used to power the ESP.
|
|
|
|
The module is based on the project NmraDcc [https://github.com/mrrwa/NmraDcc](https://github.com/mrrwa/NmraDcc) by Alex Shepherd. The module is based on the version from May 2005, commit [6d12e6cd3f5f520020d49946652a94c1e3473f6b](https://github.com/mrrwa/NmraDcc/tree/6d12e6cd3f5f520020d49946652a94c1e3473f6b).
|
|
|
|
## dcc.setup()
|
|
|
|
Initializes the dcc module and links callback functions.
|
|
|
|
#### Syntax
|
|
`dcc.setup(DCC_command, ManufacturerId, VersionId, Flags, OpsModeAddressBaseCV, CV_callback)`
|
|
|
|
#### Parameters
|
|
- `DCC_command(cmd, params)` calllback function that is called when a DCC command is decoded. `cmd` parameters is one of the following values. `params` contains a collection of parameters specific to given command.
|
|
- `dcc.DCC_RESET` no additional parameters, `params` is `nil`.
|
|
- `dcc.DCC_IDLE` no additional parameters, `params` is `nil`.
|
|
- `dcc.DCC_SPEED` parameters collection members are `Addr`, `AddrType`, `Speed`,`Dir`, `SpeedSteps`.
|
|
- `dcc.DCC_SPEED_RAW` parameters collection members are `Addr`, `AddrType`, `Raw`.
|
|
- `dcc.DCC_FUNC` parameters collection members are `Addr`, `AddrType`, `FuncGrp`,`FuncState`.
|
|
- `dcc.DCC_TURNOUT` parameters collection members are `BoardAddr`, `OutputPair`, `Direction`,`OutputPower` or `Addr`, `Direction`,`OutputPower`.
|
|
- `dcc.DCC_ACCESSORY` parameters collection has one member `BoardAddr` or `Addr` or `State`.
|
|
- `dcc.DCC_RAW` parameters collection member are `Size`, `PreambleBits`, `Data1` to `Data6`.
|
|
- `dcc.DCC_SERVICEMODE` parameters collection has one member `InServiceMode`.
|
|
- `ManufacturerId` Manufacturer ID returned in CV 8. Commonly `dcc.MAN_ID_DIY`.
|
|
- `VersionId` Version ID returned in CV 7.
|
|
- `Flags` one of or combination (OR operator) of
|
|
- `dcc.FLAGS_MY_ADDRESS_ONLY`Only process packets with My Address.
|
|
- `dcc.FLAGS_DCC_ACCESSORY_DECODER` Decoder is an accessory decode.
|
|
- `dcc.FLAGS_OUTPUT_ADDRESS_MODE` This flag applies to accessory decoders only. Accessory decoders normally have 4 paired outputs and a single address refers to all 4 outputs. Setting this flag causes each address to refer to a single output.
|
|
- `dcc.FLAGS_AUTO_FACTORY_DEFAULT` Call DCC command callback with `dcc.CV_RESET` command if CV 7 & 8 == 255.
|
|
- `OpsModeAddressBaseCV` Ops Mode base address. Set it to 0?
|
|
- `CV_callback(operation, param)` callback function that is called when any manipulation with CV ([Configuarion Variable](https://dccwiki.com/Configuration_Variable)) is requested.
|
|
- `dcc.CV_VALID`to determine if a given CV is valid. This callback must determine if a CV is valid and return the appropriate value. `param` collection has members `CV` and `Value`.
|
|
- `dcc.CV_READ` to read a CV. This callback must return the value of the CV. `param` collection has one member `CV` determing the CV number to be read.
|
|
- `dcc.CV_WRITE` to write a value to a CV. This callback must write the Value to the CV and return the value of the CV. `param` collection has members `CV` and `Value`.
|
|
- `dcc.CV_RESET` Called when CVs must be reset to their factory defaults.
|
|
|
|
#### Returns
|
|
`nil`
|
|
|
|
#### Example
|
|
`bit` module is used in the example though it is not needed for the dcc module functionality.
|
|
```lua
|
|
local PIN = 2 -- GPIO4
|
|
|
|
local addr = 0x12a
|
|
|
|
CV = {[29]=0,
|
|
[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 DCC_command(cmd, params)
|
|
if cmd == dcc.DCC_IDLE then
|
|
return
|
|
elseif cmd == dcc.DCC_TURNOUT then
|
|
print("Turnout command")
|
|
elseif cmd == dcc.DCC_SPEED then
|
|
print("Speed command")
|
|
elseif cmd == dcc.DCC_FUNC then
|
|
print("Function command")
|
|
else
|
|
print("Other command", cmd)
|
|
end
|
|
|
|
for i,j in pairs(params) do
|
|
print(i, j)
|
|
end
|
|
print(("="):rep(80))
|
|
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
|
|
elseif operation == CV_RESET then
|
|
oper = "Reset"
|
|
CV = {}
|
|
end
|
|
print(("[CV_callback] %s CV %d%s"):format(oper, param.CV or `nil`, param.Value and "\tValue: "..param.Value or "\tValue: nil"))
|
|
return result
|
|
end
|
|
|
|
dcc.setup(PIN,
|
|
DCC_command,
|
|
dcc.MAN_ID_DIY, 1,
|
|
--bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT, dcc.FLAGS_DCC_ACCESSORY_DECODER, dcc.FLAGS_MY_ADDRESS_ONLY),
|
|
bit.bor(dcc.FLAGS_AUTO_FACTORY_DEFAULT),
|
|
0, -- ???
|
|
CV_callback)
|
|
```
|
|
|
|
## dcc.close()
|
|
|
|
Stops the dcc module.
|
|
|
|
#### Syntax
|
|
`dcc.close()`
|
|
|
|
#### Parameters
|
|
`nil`
|
|
|
|
#### Returns
|
|
`nil`
|