module(...,package.seeall)

local schar,slen,sfind,sbyte,ssub = string.char,string.len,string.find,string.byte,string.sub

--[[

uart֡ṹսΧ豸

֡ṹ£
ʼ־1ֽڣ̶Ϊ0x01
ݸ1ֽڣУݸֽ֮ڸ
ָ1ֽ
11ֽ
21ֽ
31ֽ
41ֽ
У룺ݸ4
־1ֽڣ̶Ϊ0xFE
]]


--ID,1Ӧuart1
--Ҫ޸Ϊuart2UART_IDֵΪ2
local UART_ID = 1
--ʼ־
local FRM_HEAD,FRM_TAIL = 0x01,0xFE
--ָ
local CMD_01 = 0x01
--ڶݻ
local rdbuf = ""

--[[
print
  ӡӿڣļедӡtestǰ׺
  
ֵ
]]
local function print(...)
	_G.print("test",...)
end

--ָ1ݽ
local function cmd01(s)
	print("cmd01",common.binstohexs(s),slen(s))
	if slen(s)~=4 then return end
	local i,j,databyte
	for i=1,4 do
		databyte = sbyte(s,i)
		for j=0,7 do
			print("cmd01 data"..i.."_bit"..j..": "..(bit.isset(databyte,j) and 1 or 0))
		end
	end
end

--ַsУ
local function checksum(s)
	local ret,i = 0
	for i=1,slen(s) do
		ret = bit.bxor(ret,sbyte(s,i))
	end
	return ret
end

--[[
parse
  ֡ṹһ֡
  
		dataδ
ֵһֵһ֡ĵĴڶֵδ
]]
local function parse(data)
	if not data then return end
	
	--ʼ־
	local headidx = string.find(data,schar(FRM_HEAD))
	if not headidx then print("parse no head error") return true,"" end
	
	--ݸ
	if slen(data)<=headidx then print("parse wait cnt byte") return false,data end
	local cnt = sbyte(data,headidx+1)
	
	if slen(data)<headidx+cnt+3 then print("parse wait complete") return false,data end
	
	--ָ
	local cmd = sbyte(data,headidx+2)	
	local procer =
	{
		[CMD_01] = cmd01,
	}
	if not procer[cmd] then print("parse cmd error",cmd) return false,ssub(data,headidx+cnt+4,-1) end
	
	--־
	if sbyte(data,headidx+cnt+3)~=FRM_TAIL then print("parse tail error",sbyte(data,headidx+cnt+3)) return false,ssub(data,headidx+cnt+4,-1) end
	
	--У
	local sum1,sum2 = checksum(ssub(data,headidx+1,headidx+1+cnt)),sbyte(data,headidx+cnt+2)
	if sum1~=sum2 then print("parse checksum error",sum1,sum2) return false,ssub(data,headidx+cnt+4,-1) end
	
	procer[cmd](ssub(data,headidx+3,headidx+1+cnt))
	
	return true,ssub(data,headidx+cnt+4,-1)	
end

--[[
proc
  Ӵڶ
  
		dataǰһδӴڶ
ֵ
]]
local function proc(data)
	if not data or string.len(data) == 0 then return end
	--׷ӵ
	rdbuf = rdbuf..data	
	
	local result,unproc
	unproc = rdbuf
	--֡ṹѭδ
	while true do
		result,unproc = parse(unproc)
		if not unproc or unproc == "" or not result then
			break
		end
	end

	rdbuf = unproc or ""
end

--[[
read
  ȡڽյ
  
ֵ
]]
local function read()
	local data = ""
	--ײcoreУյʱ
	--ջΪգжϷʽ֪ͨLuaűյݣ
	--ջΪգ򲻻֪ͨLuaű
	--Luaűյж϶ʱÿζҪѽջеȫܱ֤ײcoreежreadеwhileоͱ֤һ
	while true do		
		data = uart.read(UART_ID,"*l")
		if not data or string.len(data) == 0 then break end
		--Ĵӡʱ
		print("read",common.binstohexs(data))
		proc(data)
	end
end

--[[
write
  ͨڷ
  
		sҪ͵
ֵ
]]
function write(s)
	print("write",s)
	uart.write(UART_ID,s)
end

--ϵͳڻ״̬˴ֻΪ˲ҪԴģûеطpm.sleep("test")ߣ͹״̬
--ڿҪ󹦺ĵ͡ĿʱһҪ취֤pm.wake("test")ڲҪʱpm.sleep("test")
pm.wake("test")
--עᴮڵݽպյݺ󣬻жϷʽreadӿڶȡ
sys.reguart(UART_ID,read)
--òҴ򿪴
uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1)


