[fluksod + nixio] add { ctrl, delta, uart } dispatching

This commit is contained in:
Bart Van Der Meerssche 2011-01-21 20:31:18 +01:00
parent 0d3f076b5f
commit 2fa9a53766
3 changed files with 103 additions and 63 deletions

View File

@ -1,6 +1,6 @@
--[[
spi.lua - Lua 5.1 flukso module for spidev message processing
spi.lua - Lua 5.1 flukso module for spidev message processing and dispatching
Copyright (C) 2011 Bart Van Der Meerssche <bart.vandermeerssche@flukso.net>
@ -30,7 +30,11 @@ local getfenv, setmetatable =
module (...)
local modenv = getfenv()
local SPI_MAX_READ_BYTES = 256
local SPI_END_OF_MESSAGE = '.'
local SPI_FORWARD_TO_UART_PORT = 'u'
local SPI_FORWARD_TO_CTRL_PORT = 'l' -- 'l'ocal port
local SPI_MAX_READ_BYTES = 1024
--- Create a new spi message object.
--
@ -64,7 +68,7 @@ end
function encode(msg)
if msg.to == 'uart' then
msg.encoded = nixio.bin.hexlify(msg.body)
msg.encoded = nixio.bin.hexlify(msg.body or '')
return
end
@ -97,39 +101,39 @@ function encode(msg)
elseif msg.parsed.cmd == 'ct' then
else
return
end
msg.encoded = msg.encoded .. nixio.bin.numtohex(nixio.bin.dow_crc(msg.encoded), 1)
end
function tx(msg, cdev)
if msg.to == 'ctrl' or msg.to == 'delta' then
cdev:write('l' .. msg.encoded .. '.')
elseif msg.to == 'uart' then
cdev:write('u' .. msg.encoded)
if msg.encoded then
if (msg.to == 'ctrl' or msg.to == 'delta') then
cdev:write(SPI_FORWARD_TO_CTRL_PORT .. msg.encoded .. SPI_END_OF_MESSAGE)
elseif msg.to == 'uart' then
cdev:write(SPI_FORWARD_TO_UART_PORT .. msg.encoded)
end
end
end
function rx(msg, cdev)
msg.received = {}
msg.received.raw = cdev:read(SPI_MAX_READ_BYTES)
msg.received.l, msg.received.u = msg.received.raw:match('^l(%w*)%.?u(%w*)%.?$')
-- protect against nil values when match should fail
-- TODO error handling when no reply due to:
-- * sensor board not operational
-- * state machine not synced
msg.received.l, msg.received.u = msg.received.l or '', msg.received.u or ''
if msg.received.l ~= '' then
if msg.received.raw == '' then -- state machine not synced
msg.received.raw = cdev:read(SPI_MAX_READ_BYTES)
end
msg.received.l, msg.received.u = msg.received.raw:match('^l(%w*)%.?u(%w*)%.?$')
if msg.received.l then
msg.received.crc = msg.received.l:sub(-2, -1)
msg.received.l = msg.received.l:sub( 1, -3)
if nixio.bin.dow_crc(msg.received.l) ~= nixio.bin.hextonum(msg.received.crc) then
--> TODO implement near-end crc error counter
msg.received.l = ''
else
msg.received.l = nil
end
end
end
@ -137,11 +141,11 @@ end
function decode(msg)
msg.decoded = {}
if msg.received.u ~= '' then
msg.decoded.u = nixio.bin.unhexlify(msg.received.u)
if msg.received.u then
msg.decoded.uart = nixio.bin.unhexlify(msg.received.u)
end
if msg.received.l ~= '' then
if msg.received.l then
msg.decoded.cmd = msg.received.l:sub(1, 2)
msg.decoded.args = msg.received.l:sub(3, -1)
@ -154,34 +158,38 @@ function decode(msg)
msg.decoded[(i-1)*3 + 3] =
nixio.bin.hextonum(msg.decoded.args:sub((i-1)*18 + 11, (i-1)*18 + 18))
end
elseif msg.parsed.cmd == 'gv' then
elseif msg.parsed.cmd == 'gp' then
msg.decoded.delta = msg.decoded.cmd .. ' ' .. table.concat(msg.decoded, ' ')
elseif msg.decoded.cmd == 'gv' then
elseif msg.parsed.cmd == 'gc' then
elseif msg.decoded.cmd == 'gp' then
elseif msg.parsed.cmd == 'gm' then
elseif msg.decoded.cmd == 'gc' then
elseif msg.parsed.cmd == 'gw' then
elseif msg.decoded.cmd == 'gm' then
elseif msg.parsed.cmd == 'gb' then
elseif msg.decoded.cmd == 'gw' then
elseif msg.parsed.cmd == 'sv' then
elseif msg.decoded.cmd == 'gb' then
elseif msg.parsed.cmd == 'sp' then
elseif msg.decoded.cmd == 'sv' then
elseif msg.parsed.cmd == 'sc' then
elseif msg.decoded.cmd == 'sp' then
elseif msg.parsed.cmd == 'sm' then
elseif msg.decoded.cmd == 'sc' then
elseif msg.parsed.cmd == 'sw' then
elseif msg.decoded.cmd == 'sm' then
elseif msg.parsed.cmd == 'sb' then
elseif msg.decoded.cmd == 'sw' then
elseif msg.parsed.cmd == 'ct' then
elseif msg.decoded.cmd == 'sb' then
elseif msg.decoded.cmd == 'ct' then
elseif msg.decoded.cmd == 'zz' then
--> TODO implement far-end crc error counter
end
end
return { ctrl = msg.decoded.ctrl, delta = msg.decoded.delta, uart = msg.decoded.uart }
end

View File

@ -2,7 +2,7 @@
--[[
fluksod.lua - Lua part of fluksod
fluksod.lua - Lua part of the Flukso daemon
Copyright (C) 2011 Bart Van Der Meerssche <bart.vandermeerssche@flukso.net>
@ -21,30 +21,37 @@
]]--
require 'dbg'
require 'nixio'
require 'nixio.fs'
local spi = require 'flukso.spi'
local dbg = require 'dbg'
local spi = require 'flukso.spi'
local nixio = require 'nixio'
nixio.fs = require 'nixio.fs'
DAEMON = os.getenv('DAEMON') or 'fluksod'
DAEMON_PATH = os.getenv('DAEMON_PATH') or '/var/run/' .. DAEMON
local SPI_DEV = '/dev/spidev0.0'
local SPI_MAX_CLK_SPEED_HZ = 10e6
local SPI_MIN_BYTE_DELAY_US = 250
local SPI_TX_RX_DELAY_NS = 10e7
local POLL_TIMEOUT_MS = 100
local DAEMON = os.getenv('DAEMON') or 'fluksod'
local DAEMON_PATH = os.getenv('DAEMON_PATH') or '/var/run/' .. DAEMON
local O_RDWR_NONBLOCK = nixio.open_flags('rdwr', 'nonblock')
local POLLIN = nixio.poll_flags('in')
O_RDWR_NONBLOCK = nixio.open_flags('rdwr', 'nonblock')
POLLIN = nixio.poll_flags('in')
function mkfifos(input)
local path = string.format('%s/%s/', DAEMON_PATH, input)
nixio.fs.mkdirr(path)
nixio.fs.unlink(path .. 'in') --> clean up mess from previous run
nixio.fs.unlink(path .. 'out') --> idem
nixio.fs.unlink(path .. 'in') -- clean up mess from previous run
nixio.fs.unlink(path .. 'out') -- idem
nixio.fs.mkfifo(path .. 'in', '644')
nixio.fs.mkfifo(path .. 'out', '644')
local fdin = nixio.open(path .. 'in', O_RDWR_NONBLOCK)
local fdout = nixio.open(path .. 'out', O_RDWR_NONBLOCK)
return { fd = fdin, --> need this entry for nixio.poll
return { fd = fdin, -- need this entry for nixio.poll
fdin = fdin,
fdout = fdout,
events = POLLIN,
@ -58,21 +65,49 @@ local delta = mkfifos('delta')
local fds = { uart, ctrl, delta }
local spidev = nixio.open('/dev/spidev0.0', O_RDWR_NONBLOCK)
local spidev = nixio.open(SPI_DEV, O_RDWR_NONBLOCK)
nixio.spi.setspeed(spidev, SPI_MAX_CLK_SPEED_HZ, SPI_MIN_BYTE_DELAY_US)
while true do
if nixio.poll(fds, -1) then
if delta.revents == POLLIN then
--> TODO flush the delta fd after each POLLIN
local msg = spi.new_msg('delta', delta.line())
local msg
local poll = nixio.poll(fds, POLL_TIMEOUT_MS)
if poll == 0 then -- poll timed out, so time to 'poll' the spi bus
msg = spi.new_msg('', '')
elseif poll > 0 then
if ctrl.revents == POLLIN then
msg = spi.new_msg('ctrl', ctrl.line())
msg:parse()
msg:encode()
msg:tx(spidev)
nixio.nanosleep(0, 10e7) --> 10ms
msg:rx(spidev)
msg:decode()
--> dbg.vardump(msg)
delta.fdout:write(msg.decoded.cmd .. ' ' .. table.concat(msg.decoded, ' ') .. '\n')
elseif delta.revents == POLLIN then
-- TODO flush the delta fd after each POLLIN
msg = spi.new_msg('delta', delta.line())
msg:parse()
elseif uart.revents == POLLIN then
msg = spi.new_msg('uart', uart.line())
end
msg:encode()
msg:tx(spidev)
nixio.nanosleep(0, SPI_TX_RX_DELAY_NS)
end
if poll >= 0 then
msg:rx(spidev)
local dispatch = msg:decode()
-- dbg.vardump(msg)
if dispatch.ctrl then
ctrl.fdout:write(dispatch.ctrl .. '\n')
end
if dispatch.delta then
delta.fdout:write(dispatch.delta .. '\n')
end
if dispatch.uart then
uart.fdout:write(dispatch.uart .. '\n')
end
end
end

View File

@ -169,13 +169,10 @@ static int nixio_poll(lua_State *L) {
status = poll(fds, (nfds_t)len, timeout);
if (status == 0) {
if (status <= 0) {
free(fds);
lua_pushboolean(L, 0);
lua_pushinteger(L, status);
return 1;
} else if (status < 0) {
free(fds);
return nixio__perror(L);
}
for (i = 0; i < len; i++) {