[fluksod] skeleton implementation of message processing on spidev bus
This commit is contained in:
parent
221636f5cf
commit
f3516415bd
|
@ -3,7 +3,7 @@
|
|||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=flukso
|
||||
PKG_VERSION:=2.0
|
||||
PKG_VERSION:=2.0-alpha
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
@ -11,10 +11,12 @@ PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
|||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/flukso
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
DEPENDS:=+libdaemon +ntpclient +liblua +luci-nixio +rrdtool1
|
||||
TITLE:=Flukso - community metering
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
DEPENDS:=+libdaemon +ntpclient +liblua +luci-nixio +rrdtool1
|
||||
TITLE:=Flukso - community metering
|
||||
URL:=http://www.flukso.net
|
||||
MAINTAINER:=Bart Van Der Meerssche <bart.vandermeerssche@flukso.net>
|
||||
endef
|
||||
|
||||
define Package/flukso/description
|
||||
|
@ -32,10 +34,12 @@ define Package/flukso/install
|
|||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/dbg.lua $(1)/usr/lib/lua/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/rrd
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/rrd/*.lua $(1)/usr/lib/lua/rrd/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/flukso
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/flukso/*.lua $(1)/usr/lib/lua/flukso/
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/luad $(1)/usr/sbin/
|
||||
$(LN) /usr/sbin/luad $(1)/usr/sbin/spid
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/spi/spid.lua $(1)/usr/sbin/
|
||||
$(LN) /usr/sbin/luad $(1)/usr/sbin/fluksod
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fluksod.lua $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,flukso))
|
||||
|
|
|
@ -0,0 +1,517 @@
|
|||
--[[
|
||||
/*
|
||||
* Copyright (c) 2007 Tim Kelly/Dialectronics
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
|
||||
* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
|
||||
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
--]]
|
||||
|
||||
|
||||
module(..., package.seeall);
|
||||
|
||||
local hex2bin = {
|
||||
["0"] = "0000",
|
||||
["1"] = "0001",
|
||||
["2"] = "0010",
|
||||
["3"] = "0011",
|
||||
["4"] = "0100",
|
||||
["5"] = "0101",
|
||||
["6"] = "0110",
|
||||
["7"] = "0111",
|
||||
["8"] = "1000",
|
||||
["9"] = "1001",
|
||||
["a"] = "1010",
|
||||
["b"] = "1011",
|
||||
["c"] = "1100",
|
||||
["d"] = "1101",
|
||||
["e"] = "1110",
|
||||
["f"] = "1111"
|
||||
}
|
||||
|
||||
|
||||
|
||||
local bin2hex = {
|
||||
["0000"] = "0",
|
||||
["0001"] = "1",
|
||||
["0010"] = "2",
|
||||
["0011"] = "3",
|
||||
["0100"] = "4",
|
||||
["0101"] = "5",
|
||||
["0110"] = "6",
|
||||
["0111"] = "7",
|
||||
["1000"] = "8",
|
||||
["1001"] = "9",
|
||||
["1010"] = "A",
|
||||
["1011"] = "B",
|
||||
["1100"] = "C",
|
||||
["1101"] = "D",
|
||||
["1110"] = "E",
|
||||
["1111"] = "F"
|
||||
}
|
||||
|
||||
--[[
|
||||
local dec2hex = {
|
||||
["0"] = "0",
|
||||
["1"] = "1",
|
||||
["2"] = "2",
|
||||
["3"] = "3",
|
||||
["4"] = "4",
|
||||
["5"] = "5",
|
||||
["6"] = "6",
|
||||
["7"] = "7",
|
||||
["8"] = "8",
|
||||
["9"] = "9",
|
||||
["10"] = "A",
|
||||
["11"] = "B",
|
||||
["12"] = "C",
|
||||
["13"] = "D",
|
||||
["14"] = "E",
|
||||
["15"] = "F"
|
||||
}
|
||||
--]]
|
||||
|
||||
|
||||
-- These functions are big-endian and take up to 32 bits
|
||||
|
||||
-- Hex2Bin
|
||||
-- Bin2Hex
|
||||
-- Hex2Dec
|
||||
-- Dec2Hex
|
||||
-- Bin2Dec
|
||||
-- Dec2Bin
|
||||
|
||||
|
||||
function Hex2Bin(s)
|
||||
|
||||
-- s -> hexadecimal string
|
||||
|
||||
local ret = ""
|
||||
local i = 0
|
||||
|
||||
|
||||
for i in string.gfind(s, ".") do
|
||||
i = string.lower(i)
|
||||
|
||||
ret = ret..hex2bin[i]
|
||||
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
|
||||
function Bin2Hex(s)
|
||||
|
||||
-- s -> binary string
|
||||
|
||||
local l = 0
|
||||
local h = ""
|
||||
local b = ""
|
||||
local rem
|
||||
|
||||
l = string.len(s)
|
||||
rem = l % 4
|
||||
l = l-1
|
||||
h = ""
|
||||
|
||||
-- need to prepend zeros to eliminate mod 4
|
||||
if (rem > 0) then
|
||||
s = string.rep("0", 4 - rem)..s
|
||||
end
|
||||
|
||||
for i = 1, l, 4 do
|
||||
b = string.sub(s, i, i+3)
|
||||
h = h..bin2hex[b]
|
||||
end
|
||||
|
||||
return h
|
||||
|
||||
end
|
||||
|
||||
|
||||
function Bin2Dec(s)
|
||||
|
||||
-- s -> binary string
|
||||
|
||||
local num = 0
|
||||
local ex = string.len(s) - 1
|
||||
local l = 0
|
||||
|
||||
l = ex + 1
|
||||
for i = 1, l do
|
||||
b = string.sub(s, i, i)
|
||||
if b == "1" then
|
||||
num = num + 2^ex
|
||||
end
|
||||
ex = ex - 1
|
||||
end
|
||||
|
||||
return string.format("%u", num)
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
function Dec2Bin(s, num)
|
||||
|
||||
-- s -> Base10 string
|
||||
-- num -> string length to extend to
|
||||
|
||||
local n
|
||||
|
||||
if (num == nil) then
|
||||
n = 0
|
||||
else
|
||||
n = num
|
||||
end
|
||||
|
||||
s = string.format("%x", s)
|
||||
|
||||
s = Hex2Bin(s)
|
||||
|
||||
while string.len(s) < n do
|
||||
s = "0"..s
|
||||
end
|
||||
|
||||
return s
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
function Hex2Dec(s)
|
||||
|
||||
-- s -> hexadecimal string
|
||||
|
||||
local s = Hex2Bin(s)
|
||||
|
||||
return Bin2Dec(s)
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
function Dec2Hex(s)
|
||||
|
||||
-- s -> Base10 string
|
||||
|
||||
s = string.format("%x", s)
|
||||
|
||||
return s
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- These functions are big-endian and will extend to 32 bits
|
||||
|
||||
-- BMAnd
|
||||
-- BMNAnd
|
||||
-- BMOr
|
||||
-- BMXOr
|
||||
-- BMNot
|
||||
|
||||
|
||||
function BMAnd(v, m)
|
||||
|
||||
-- v -> hex string to be masked
|
||||
-- m -> hex string mask
|
||||
|
||||
-- s -> hex string as masked
|
||||
|
||||
-- bv -> binary string of v
|
||||
-- bm -> binary string mask
|
||||
|
||||
local bv = Hex2Bin(v)
|
||||
local bm = Hex2Bin(m)
|
||||
|
||||
local i = 0
|
||||
local s = ""
|
||||
|
||||
while (string.len(bv) < 32) do
|
||||
bv = "0000"..bv
|
||||
end
|
||||
|
||||
while (string.len(bm) < 32) do
|
||||
bm = "0000"..bm
|
||||
end
|
||||
|
||||
|
||||
for i = 1, 32 do
|
||||
cv = string.sub(bv, i, i)
|
||||
cm = string.sub(bm, i, i)
|
||||
if cv == cm then
|
||||
if cv == "1" then
|
||||
s = s.."1"
|
||||
else
|
||||
s = s.."0"
|
||||
end
|
||||
else
|
||||
s = s.."0"
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
return Bin2Hex(s)
|
||||
|
||||
end
|
||||
|
||||
|
||||
function BMNAnd(v, m)
|
||||
|
||||
-- v -> hex string to be masked
|
||||
-- m -> hex string mask
|
||||
|
||||
-- s -> hex string as masked
|
||||
|
||||
-- bv -> binary string of v
|
||||
-- bm -> binary string mask
|
||||
|
||||
local bv = Hex2Bin(v)
|
||||
local bm = Hex2Bin(m)
|
||||
|
||||
local i = 0
|
||||
local s = ""
|
||||
|
||||
while (string.len(bv) < 32) do
|
||||
bv = "0000"..bv
|
||||
end
|
||||
|
||||
while (string.len(bm) < 32) do
|
||||
bm = "0000"..bm
|
||||
end
|
||||
|
||||
|
||||
for i = 1, 32 do
|
||||
cv = string.sub(bv, i, i)
|
||||
cm = string.sub(bm, i, i)
|
||||
if cv == cm then
|
||||
if cv == "1" then
|
||||
s = s.."0"
|
||||
else
|
||||
s = s.."1"
|
||||
end
|
||||
else
|
||||
s = s.."1"
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
return Bin2Hex(s)
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
function BMOr(v, m)
|
||||
|
||||
-- v -> hex string to be masked
|
||||
-- m -> hex string mask
|
||||
|
||||
-- s -> hex string as masked
|
||||
|
||||
-- bv -> binary string of v
|
||||
-- bm -> binary string mask
|
||||
|
||||
local bv = Hex2Bin(v)
|
||||
local bm = Hex2Bin(m)
|
||||
|
||||
local i = 0
|
||||
local s = ""
|
||||
|
||||
while (string.len(bv) < 32) do
|
||||
bv = "0000"..bv
|
||||
end
|
||||
|
||||
while (string.len(bm) < 32) do
|
||||
bm = "0000"..bm
|
||||
end
|
||||
|
||||
|
||||
for i = 1, 32 do
|
||||
cv = string.sub(bv, i, i)
|
||||
cm = string.sub(bm, i, i)
|
||||
if cv == "1" then
|
||||
s = s.."1"
|
||||
elseif cm == "1" then
|
||||
s = s.."1"
|
||||
else
|
||||
s = s.."0"
|
||||
end
|
||||
end
|
||||
|
||||
return Bin2Hex(s)
|
||||
|
||||
end
|
||||
|
||||
function BMXOr(v, m)
|
||||
|
||||
-- v -> hex string to be masked
|
||||
-- m -> hex string mask
|
||||
|
||||
-- s -> hex string as masked
|
||||
|
||||
-- bv -> binary string of v
|
||||
-- bm -> binary string mask
|
||||
|
||||
local bv = Hex2Bin(v)
|
||||
local bm = Hex2Bin(m)
|
||||
|
||||
local i = 0
|
||||
local s = ""
|
||||
|
||||
while (string.len(bv) < 32) do
|
||||
bv = "0000"..bv
|
||||
end
|
||||
|
||||
while (string.len(bm) < 32) do
|
||||
bm = "0000"..bm
|
||||
end
|
||||
|
||||
|
||||
for i = 1, 32 do
|
||||
cv = string.sub(bv, i, i)
|
||||
cm = string.sub(bm, i, i)
|
||||
if cv == "1" then
|
||||
if cm == "0" then
|
||||
s = s.."1"
|
||||
else
|
||||
s = s.."0"
|
||||
end
|
||||
elseif cm == "1" then
|
||||
if cv == "0" then
|
||||
s = s.."1"
|
||||
else
|
||||
s = s.."0"
|
||||
end
|
||||
else
|
||||
-- cv and cm == "0"
|
||||
s = s.."0"
|
||||
end
|
||||
end
|
||||
|
||||
return Bin2Hex(s)
|
||||
|
||||
end
|
||||
|
||||
|
||||
function BMNot(v, m)
|
||||
|
||||
-- v -> hex string to be masked
|
||||
-- m -> hex string mask
|
||||
|
||||
-- s -> hex string as masked
|
||||
|
||||
-- bv -> binary string of v
|
||||
-- bm -> binary string mask
|
||||
|
||||
local bv = Hex2Bin(v)
|
||||
local bm = Hex2Bin(m)
|
||||
|
||||
local i = 0
|
||||
local s = ""
|
||||
|
||||
while (string.len(bv) < 32) do
|
||||
bv = "0000"..bv
|
||||
end
|
||||
|
||||
while (string.len(bm) < 32) do
|
||||
bm = "0000"..bm
|
||||
end
|
||||
|
||||
|
||||
for i = 1, 32 do
|
||||
cv = string.sub(bv, i, i)
|
||||
cm = string.sub(bm, i, i)
|
||||
if cm == "1" then
|
||||
if cv == "1" then
|
||||
-- turn off
|
||||
s = s.."0"
|
||||
else
|
||||
-- turn on
|
||||
s = s.."1"
|
||||
end
|
||||
else
|
||||
-- leave untouched
|
||||
s = s..cv
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
return Bin2Hex(s)
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- these functions shift right and left, adding zeros to lost or gained bits
|
||||
-- returned values are 32 bits long
|
||||
|
||||
-- BShRight(v, nb)
|
||||
-- BShLeft(v, nb)
|
||||
|
||||
|
||||
function BShRight(v, nb)
|
||||
|
||||
-- v -> hexstring value to be shifted
|
||||
-- nb -> number of bits to shift to the right
|
||||
|
||||
-- s -> binary string of v
|
||||
|
||||
local s = Hex2Bin(v)
|
||||
|
||||
while (string.len(s) < 32) do
|
||||
s = "0000"..s
|
||||
end
|
||||
|
||||
s = string.sub(s, 1, 32 - nb)
|
||||
|
||||
while (string.len(s) < 32) do
|
||||
s = "0"..s
|
||||
end
|
||||
|
||||
return Bin2Hex(s)
|
||||
|
||||
end
|
||||
|
||||
function BShLeft(v, nb)
|
||||
|
||||
-- v -> hexstring value to be shifted
|
||||
-- nb -> number of bits to shift to the right
|
||||
|
||||
-- s -> binary string of v
|
||||
|
||||
local s = Hex2Bin(v)
|
||||
|
||||
while (string.len(s) < 32) do
|
||||
s = "0000"..s
|
||||
end
|
||||
|
||||
s = string.sub(s, nb + 1, 32)
|
||||
|
||||
while (string.len(s) < 32) do
|
||||
s = s.."0"
|
||||
end
|
||||
|
||||
return Bin2Hex(s)
|
||||
|
||||
end
|
|
@ -0,0 +1,210 @@
|
|||
--[[
|
||||
|
||||
spi.lua - Lua 5.1 flukso module for spidev message processing
|
||||
|
||||
Copyright (C) 2011 Bart Van Der Meerssche <bart.vandermeerssche@flukso.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
]]--
|
||||
|
||||
local nixio = require 'nixio'
|
||||
local BinDecHex = require 'flukso.BinDecHex'
|
||||
|
||||
local os, table, string =
|
||||
os, table, string
|
||||
|
||||
local getfenv, setmetatable, tonumber =
|
||||
getfenv, setmetatable, tonumber
|
||||
|
||||
module (...)
|
||||
local modenv = getfenv()
|
||||
|
||||
-- private
|
||||
local function dow_crc(sequence, crc)
|
||||
crc = crc or 0x00
|
||||
|
||||
local r1 = { 0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
|
||||
0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41 }
|
||||
|
||||
local r2 = { 0x00, 0x9d, 0x23, 0xbe, 0x46, 0xdb, 0x65, 0xf8,
|
||||
0x8c, 0x11, 0xaf, 0x32, 0xca, 0x57, 0xe9, 0x74 }
|
||||
|
||||
local first_char = sequence:sub(1, 1)
|
||||
|
||||
if first_char ~= '' then
|
||||
local i = nixio.bit.band(nixio.bit.bxor(first_char:byte(), crc), 0xff)
|
||||
crc = nixio.bit.bxor(r1[nixio.bit.band(i, 0xf) + 1], r2[nixio.bit.rshift(i, 4) + 1])
|
||||
return dow_crc(sequence:sub(2, -1), crc)
|
||||
else
|
||||
return nixio.bin.hexlify(string.char(crc))
|
||||
end
|
||||
end
|
||||
|
||||
--- Create a new spi message object.
|
||||
--
|
||||
-- Attributes:
|
||||
-- { to = ctrl | delta | uart
|
||||
-- body = <string>
|
||||
-- parsed = { <command>, <arg1>, <arg2>, ... }
|
||||
-- encoded = <string>
|
||||
-- received = { raw = <string>, l = <string>, crc = <string>, u = <string> }
|
||||
-- decoded = { l = ..., u = ... }
|
||||
-- reply = <string>
|
||||
-- }
|
||||
--
|
||||
-- @param to The message destination: ctrl | delta | uart.
|
||||
-- @param body The message body.
|
||||
-- @return An spi message object.
|
||||
function new_msg(to, body)
|
||||
return setmetatable({ to = to, body = body }, { __index = modenv })
|
||||
end
|
||||
|
||||
function parse(msg)
|
||||
msg.parsed = {}
|
||||
|
||||
msg.parsed[1] = msg.body:match('^%l%l')
|
||||
for arg in msg.body:gmatch('%d+') do
|
||||
msg.parsed[#msg.parsed + 1] = arg
|
||||
end
|
||||
|
||||
--> TODO: more detailed command syntax checking
|
||||
end
|
||||
|
||||
function encode(msg)
|
||||
if msg.to == 'uart' then
|
||||
msg.encoded = nixio.bin.hexlify(msg.body)
|
||||
return
|
||||
end
|
||||
|
||||
if msg.parsed[1] == 'gd' then
|
||||
msg.encoded = msg.parsed[1]
|
||||
elseif msg.parsed[1] == 'gv' then
|
||||
|
||||
elseif msg.parsed[1] == 'gp' then
|
||||
|
||||
elseif msg.parsed[1] == 'gc' then
|
||||
|
||||
elseif msg.parsed[1] == 'gm' then
|
||||
|
||||
elseif msg.parsed[1] == 'gw' then
|
||||
|
||||
elseif msg.parsed[1] == 'gb' then
|
||||
|
||||
elseif msg.parsed[1] == 'sv' then
|
||||
|
||||
elseif msg.parsed[1] == 'sp' then
|
||||
|
||||
elseif msg.parsed[1] == 'sc' then
|
||||
|
||||
elseif msg.parsed[1] == 'sm' then
|
||||
|
||||
elseif msg.parsed[1] == 'sw' then
|
||||
|
||||
elseif msg.parsed[1] == 'sb' then
|
||||
|
||||
elseif msg.parsed[1] == 'ct' then
|
||||
|
||||
else
|
||||
|
||||
end
|
||||
|
||||
--> TODO msg.encoded = msg.encoded .. dow_crc(msg.encoded)
|
||||
end
|
||||
|
||||
function tx(msg, cdev)
|
||||
if msg.to == 'ctrl' or msg.to == 'delta' then
|
||||
cdev:write('l' .. msg.encoded .. '.\0\0')
|
||||
elseif msg.to == 'uart' then
|
||||
cdev:write('u' .. msg.encoded .. '\0\0')
|
||||
end
|
||||
end
|
||||
|
||||
function rx(msg, cdev)
|
||||
local sequence = {}
|
||||
|
||||
for char in function() return cdev:read(1) end do
|
||||
if char ~= '\0' then
|
||||
table.insert(sequence, char)
|
||||
else
|
||||
-- one more read to let the AVR send a second 0x00
|
||||
-- after which the AVR's state machine toggles to read mode
|
||||
cdev:read(1)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
msg.received = {}
|
||||
msg.received.raw = table.concat(sequence)
|
||||
msg.received.l, msg.received.u = msg.received.raw:match('^l(%w*)%.?u(%w*)%.?$')
|
||||
|
||||
if msg.received.l ~= '' and msg.received.l:sub(1, 2) == msg.parsed[1] then
|
||||
msg.received.crc = msg.received.l:sub(-2, -1)
|
||||
msg.received.l = msg.received.l:sub(1, -3)
|
||||
|
||||
if dow_crc(msg.received.l) ~= msg.received.crc then
|
||||
--> TODO implement crc error counter
|
||||
msg.received.l = ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function decode(msg)
|
||||
msg.decoded = {}
|
||||
|
||||
if msg.received.u ~= '' then
|
||||
msg.decoded.u = nixio.bin.unhexlify(msg.received.u)
|
||||
end
|
||||
|
||||
if msg.received.l ~= '' then
|
||||
msg.decoded.largs = msg.received.l:sub(3, -1)
|
||||
|
||||
if msg.parsed[1] == 'gd' then
|
||||
for i = 1, msg.decoded.largs:len() / 18 do
|
||||
msg.decoded[(i-1)*3 + 1] =
|
||||
tonumber(BinDecHex.Hex2Dec(msg.decoded.largs:sub((i-1)*18 + 1, (i-1)*18 + 2)))
|
||||
msg.decoded[(i-1)*3 + 2] =
|
||||
tonumber(BinDecHex.Hex2Dec(msg.decoded.largs:sub((i-1)*18 + 3, (i-1)*18 + 10)))
|
||||
msg.decoded[(i-1)*3 + 3] =
|
||||
tonumber(BinDecHex.Hex2Dec(msg.decoded.largs:sub((i-1)*18 + 11, (i-1)*18 + 18)))
|
||||
end
|
||||
elseif msg.parsed[1] == 'gv' then
|
||||
|
||||
elseif msg.parsed[1] == 'gp' then
|
||||
|
||||
elseif msg.parsed[1] == 'gc' then
|
||||
|
||||
elseif msg.parsed[1] == 'gm' then
|
||||
|
||||
elseif msg.parsed[1] == 'gw' then
|
||||
|
||||
elseif msg.parsed[1] == 'gb' then
|
||||
|
||||
elseif msg.parsed[1] == 'sv' then
|
||||
|
||||
elseif msg.parsed[1] == 'sp' then
|
||||
|
||||
elseif msg.parsed[1] == 'sc' then
|
||||
|
||||
elseif msg.parsed[1] == 'sm' then
|
||||
|
||||
elseif msg.parsed[1] == 'sw' then
|
||||
|
||||
elseif msg.parsed[1] == 'sb' then
|
||||
|
||||
elseif msg.parsed[1] == 'ct' then
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,78 @@
|
|||
#! /usr/bin/env lua
|
||||
|
||||
--[[
|
||||
|
||||
fluksod.lua - Lua part of fluksod
|
||||
|
||||
Copyright (C) 2011 Bart Van Der Meerssche <bart.vandermeerssche@flukso.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
]]--
|
||||
|
||||
require 'dbg'
|
||||
require 'nixio'
|
||||
require 'nixio.fs'
|
||||
local spi = require 'flukso.spi'
|
||||
|
||||
DAEMON = os.getenv('DAEMON') or 'fluksod'
|
||||
DAEMON_PATH = os.getenv('DAEMON_PATH') or '/var/run/' .. DAEMON
|
||||
|
||||
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.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
|
||||
fdin = fdin,
|
||||
fdout = fdout,
|
||||
events = POLLIN,
|
||||
revents = 0,
|
||||
line = fdin:linesource() }
|
||||
end
|
||||
|
||||
local uart = mkfifos('uart')
|
||||
local ctrl = mkfifos('ctrl')
|
||||
local delta = mkfifos('delta')
|
||||
|
||||
local fds = { uart, ctrl, delta }
|
||||
|
||||
local spidev = nixio.open('/dev/spidev0.0', O_RDWR_NONBLOCK)
|
||||
|
||||
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())
|
||||
msg:parse()
|
||||
msg:encode()
|
||||
msg:tx(spidev)
|
||||
nixio.nanosleep(0, 10e7) --> 10ms
|
||||
msg:rx(spidev)
|
||||
msg:decode()
|
||||
--> dbg.vardump(msg)
|
||||
delta.fdout:write(msg.parsed[1] .. ' ' .. table.concat(msg.decoded, ' ') .. '\n')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,60 +0,0 @@
|
|||
#! /usr/bin/env lua
|
||||
|
||||
--[[
|
||||
|
||||
spid.lua - Lua part of the spi daemon
|
||||
|
||||
Copyright (C) 2011 Bart Van Der Meerssche <bart.vandermeerssche@flukso.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
]]--
|
||||
|
||||
|
||||
require 'nixio.fs'
|
||||
|
||||
ctrl_path = os.getenv('DAEMON_PATH') .. '/ctrl/'
|
||||
|
||||
nixio.fs.mkdirr(ctrl_path)
|
||||
nixio.fs.unlink(ctrl_path .. 'in')
|
||||
nixio.fs.unlink(ctrl_path .. 'out')
|
||||
|
||||
nixio.fs.mkfifo(ctrl_path .. 'in', '644')
|
||||
nixio.fs.mkfifo(ctrl_path .. 'out', '644')
|
||||
|
||||
rdwr_nonblock = nixio.open_flags('rdwr', 'nonblock')
|
||||
|
||||
ctrl_fd_in = nixio.open(ctrl_path .. 'in', rdwr_nonblock)
|
||||
ctrl_fd_out = nixio.open(ctrl_path .. 'out', rdwr_nonblock)
|
||||
|
||||
pfin = nixio.poll_flags('in')
|
||||
|
||||
local fd = {fd = ctrl_fd_in,
|
||||
events = pfin,
|
||||
revents = 0}
|
||||
|
||||
local fds = {fd}
|
||||
|
||||
ctrl_line = ctrl_fd_in:linesource()
|
||||
|
||||
while true do
|
||||
if nixio.poll(fds, 1000) then
|
||||
ctrl_fd_out:write((ctrl_line() or 'nil!') .. '\n')
|
||||
else
|
||||
ctrl_fd_out:write('timeout\n')
|
||||
end
|
||||
end
|
||||
|
||||
nixio.fs.unlink(ctrl_path .. 'in')
|
||||
nixio.fs.unlink(ctrl_path .. 'out')
|
Loading…
Reference in New Issue