Files
pitts-touchscreen/3B/archive/root_12.bak/secs_i.lua

184 lines
4.9 KiB
Lua

periphery = require('periphery')
Serial = periphery.Serial
Scheduler = require('scheduler')
local T1 = 100 --300
local T2 = 2000 --1000
local T3 = 5000 --3000
local ASCII_EOT = "\x04" -- end of transmission
local ASCII_ENQ = "\x05" -- enquiary
local ASCII_ACK = "\x06" -- acknowledge
local ASCII_NAK = "\x15" -- negative acknowledge
local pending = false
local reading = false
local writing = false
local serial
local onProcessRequest;
-----------------------------------------------------------------------
local function hexDumpString(buf)
if buf then
for i=1,math.ceil(#buf/16) * 16 do
if (i-1) % 16 == 0 then io.stderr:write(string.format('%06X ', i-1)) end
io.stderr:write( i > #buf and ' ' or string.format('%02X ', buf:byte(i)) )
if i % 8 == 0 then io.stderr:write(' ') end
if i % 16 == 0 then io.stderr:write( buf:sub(i-16+1, i):gsub('[^%g]','.'), '\n' ) end
end
io.stderr:write("\n");
end
end
-----------------------------------------------------------------------
function begin(device, baud)
serial = Serial(device,baud)
transactionTimer = Scheduler.Timer(T3)
end
local function discardInput()
hexDumpString(buf);
io.stderr:write("SECS I:\t Discard input: ")
while serial:poll(100) do
c = serial:read(1)
io.stderr:write(string.format('%02X ',c:byte(1)));
end
io.stderr:write("\n")
end
local function sendMsg(buf)
-- hexDumpString(buf)
writing = true
serial:write(ASCII_ENQ)
if serial:poll(T1) then
c = serial:read(1)
if c == ASCII_EOT then
serial:write(string.char(#buf))
local chksum = 0 -- 0 normal, 1 force error
for i=1, #buf do
serial:write(string.char(buf:byte(i)))
chksum = chksum + buf:byte(i);
-- io.stderr:write(string.format('%02X ',buf:byte(i)));
end
serial:write(string.char(math.floor(chksum / 256)))
serial:write(string.char(chksum % 256))
if serial:poll(T1) then
c = serial:read(1)
if not (c == ASCII_ACK) then
io.stderr:write("SECS I:\t NAK Received\n")
--discardInput()
end
else
io.stderr:write("SECS I:\t AKN Timeout\n")
discardInput()
end
writing = false
end
else
io.stderr:write("SECS I:\t EOT Timeout\n")
discardInput()
writing = false
end
end
local function receiveMsg()
serial:write(ASCII_EOT)
reading = true
if serial:poll(T1) then
local cnt = string.byte(serial:read(1))
io.stderr:write("SECS I:\t receiveMsg count: "..cnt.."\n")
local buf = serial:read(cnt+2,10*T1)
local chksum = 0 -- 0 normal, 1 force error
for i=1, #buf-2 do
chksum = chksum + buf:byte(i)
end
local msgChksum = buf:byte(#buf-1)*256 + buf:byte(#buf)
if msgChksum == chksum then
serial:write(ASCII_ACK)
return buf
else
io.stderr:write("SECS I:\t Checksum Error\n")
hexDumpString(buf)
serial:write(ASCII_NAK)
discardInput()
--io.stderr:write(string.format("SECS I:\t Checksum: %04X %04X\n",chksum,msgChksum))
io.stderr:write(string.format("SECS I:\t Bytes: %d Checksum: %04X %04X\n",#buf,chksum,msgChksum))
return ""
end
reading = false
else
io.stderr:write("SECS I:\t Countbyte Timeout\n")
discardInput()
reading = false
return ""
end
end
local function poll()
if ( serial:poll(T1) ) then
c = serial:read(1)
-- io.stderr:write(string.format("C: %02X\n",c:byte()));
if c == ASCII_ENQ then
local buf=receiveMsg()
if #buf >= 11 then
onProcessRequest(buf)
else
io.stderr:write("SECS I:\t Poll error bytes: "..#buf.."\n")
discardInput(buf)
serial:write(ASCII_NAK)
end
elseif c == ASCII_NAK then
io.stderr:write("SECS I:\t Poll NAK received\n")
--discardInput()
pending = false
else
---- TODO: Illegal byte, skip input send NAK ----
io.stderr:write(string.format("SECS I:\t Poll error byte = %02X\n",string.byte(c)))
discardInput()
serial:write(ASCII_NAK)
pending = false
end
else
if pending and transactionTimer.elapsed() then
---- TODO: Timeout, skip input send NAK ----
io.stderr:write("SECS I:\t Poll transaction timeout\n")
discardInput(buf)
serial:write(ASCII_NAK)
pending = false;
end
end
io.stderr:flush();
end
return {
begin = begin;
poll = poll;
sendMsg = sendMsg;
receiveMsg = receiveMsg;
isReading = function() return reading end;
isWriting = function() return writing end;
isPending = function() return pending end;
onProcessRequest = function(cb) onProcessRequest = cb end;
startTransaction = function() transactionTimer.restart(); pending = true end;
stopTransaction = function() pending = false end;
}