From 2fa9a537666072117dad7e6775bafb30228ac2c9 Mon Sep 17 00:00:00 2001 From: Bart Van Der Meerssche Date: Fri, 21 Jan 2011 20:31:18 +0100 Subject: [PATCH] [fluksod + nixio] add { ctrl, delta, uart } dispatching --- .../package/flukso/luasrc/flukso/spi.lua | 76 +++++++++-------- .../openwrt/package/flukso/luasrc/fluksod.lua | 83 +++++++++++++------ .../package/luci/libs/nixio/src/poll.c | 7 +- 3 files changed, 103 insertions(+), 63 deletions(-) diff --git a/mote/v2/openwrt/package/flukso/luasrc/flukso/spi.lua b/mote/v2/openwrt/package/flukso/luasrc/flukso/spi.lua index a27bcea..3525ecf 100644 --- a/mote/v2/openwrt/package/flukso/luasrc/flukso/spi.lua +++ b/mote/v2/openwrt/package/flukso/luasrc/flukso/spi.lua @@ -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 @@ -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 diff --git a/mote/v2/openwrt/package/flukso/luasrc/fluksod.lua b/mote/v2/openwrt/package/flukso/luasrc/fluksod.lua index cbfa1e3..0e2f68c 100755 --- a/mote/v2/openwrt/package/flukso/luasrc/fluksod.lua +++ b/mote/v2/openwrt/package/flukso/luasrc/fluksod.lua @@ -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 @@ -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 diff --git a/mote/v2/openwrt/package/luci/libs/nixio/src/poll.c b/mote/v2/openwrt/package/luci/libs/nixio/src/poll.c index 1211bc7..fec9f54 100644 --- a/mote/v2/openwrt/package/luci/libs/nixio/src/poll.c +++ b/mote/v2/openwrt/package/luci/libs/nixio/src/poll.c @@ -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++) {