initial commit with all the stuff
This commit is contained in:
184
3B/archive/root_3.bak/secs_i.lua
Normal file
184
3B/archive/root_3.bak/secs_i.lua
Normal file
@@ -0,0 +1,184 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user