写的代码更擂人,呵呵
--
-- nxt2nxp v0.3 (ASkr 9/2009)
--
-- LPC90X ICP programmer (for FlashMagic, until now)
--
-- !!! pbLua >= v18c required !!!
--
-- - USB connection preferred
-- - You may need to download this source in several parts.
-- Otherwise pbLuas byte compiler may run out of memory!
-- Use the "*** for download, only ***" (followed by a garbage-collect)
-- markings as a suggested split indicator.
--
nxt=nil
collectgarbage("collect")
require("nxt_misc")
require("nxt_input")
require("nxt_rs485")
require("nxt_file")
require("nxt_display")
collectgarbage("collect")
-- *** for download, only ***
collectgarbage("collect")
gDisCol=0
gChkSum=0
gBytes=0
gAdrHi=0
gAdrLo=0
gRecType=0
gRec7=0
gTB={}
------------------------------------------------------------------------------------------------------------
-- utilWait()
--
-- Waits (blocks) for <tim> ms.
-----------------------------------------------------------------------------------------------------------
function utilWait(tim)
local stim=nxt.TimerRead()
repeat
until nxt.TimerRead() > stim+tim
end
------------------------------------------------------------------------------------------------------------
-- uWait()
--
-- Waits (blocks) for ~<c> us.
-- Minimum value is ~80us
-- Use this while in a nxt.DisableNXT(1) <-> nxt.DisableNXT(0) loop!
-----------------------------------------------------------------------------------------------------------
function uWait(c)
local i
c=c*10
c=(c/24)-32
for i=1,c do
end
end
------------------------------------------------------------------------------------------------------------
-- ICPloop
--
-----------------------------------------------------------------------------------------------------------
function ICPloop()
local ch;
local i
while 1 do
collectgarbage("collect")
gChkSum=0
repeat
ch=ICPecho()
-- baud rate detection override
if ch=="U" then
nxt.FileWrite(0,"U")
nxt.FileWrite(0,"U")
end
-- try to enter prog mode again
if ch=="'" then
ICPinit()
ICPenter()
end
until ch==":" or ch=="*"
if ch=="*" then break end
gBytes=ICPget2()
gAdrHi=ICPget2()
gAdrLo=ICPget2()
gRecType=ICPget2()
for i=0,gBytes-1 do
gTB[i]=ICPget2()
end
gRec7=gChkSum
if gRec7 ~= ICPget2() then
print("X")
gRecType=999
end
-- *** READ_VERSION ***
if gRecType==1 then
nxt.FileWrite(0,string.format("%02x",0x07))
nxt.FileWrite(0,string.format("%02x",0x07))
print(".")
-- *** PROGRAM ***
elseif gRecType==0 then
ICPprogram()
print(".")
-- *** MISC_WRITE ***
elseif gRecType==2 then
ICPwrite_config()
print(".")
-- *** MISC_READ ***
elseif gRecType==3 then
ICPread_config()
nxt.FileWrite(0,string.format("%02x",gTB[0]))
print(".")
-- *** ERASE ***
elseif gRecType==4 then
if gTB[0]==0 then
ICPerase_page()
print(".")
elseif gTB[0]==1 then
ICPerase_sector()
print(".")
else
print("R")
end
-- *** SECTOR CRC ***
elseif gRecType==5 then
ICPcrcsector()
gRecType=888
-- *** GLOBAL CRC ***
elseif gRecType==6 then
ICPcrcglobal()
gRecType=888
-- *** CHIP_ERASE ***
elseif gRecType==8 then
ICPerase_global()
print(".")
-- *** CONTINUE ***
elseif gRecType==999 then
i=i
-- *** INCORRECT RECORD TYPE ***
elseif 1 then
print("R")
end -- elseif
-- *** PRINT CRC ***
if gRecType==888 then
nxt.FileWrite(0,string.format("%02x",gTB[3]))
nxt.FileWrite(0,string.format("%02x",gTB[2]))
nxt.FileWrite(0,string.format("%02x",gTB[1]))
nxt.FileWrite(0,string.format("%02x",gTB[0]))
print(".")
end
end -- while 1
end
-- *** for download, only ***
collectgarbage("collect")
------------------------------------------------------------------------------------------------------------
-- dp()
--
-- debug print
-----------------------------------------------------------------------------------------------------------
function dp(msg)
nxt.DisplayText(string.format("%02x",msg),gDisCol)
gDisCol=gDisCol+20
if gDisCol >= 100 then
gDisCol=0
nxt.DisplayScroll()
end
end
------------------------------------------------------------------------------------------------------------
-- ICPinit
--
-----------------------------------------------------------------------------------------------------------
function ICPinit()
-- Port 2
-- dig0 -> PDA
-- dig1 -> PCL
-- POWER
nxt.InputSetType(2,0)
nxt.InputSetDir(2,1,1)
nxt.InputSetState(2,0,0)
-- Port 3
-- dig0 -> n.c.
-- dig1 -> VDD
nxt.InputSetType(3,0)
nxt.InputSetDir(3,1,1)
nxt.InputSetState(3,0,0)
-- Port 4
-- dig0 -> n.c.
-- dig1 -> RESET
nxt.InputSetType(4,0)
nxt.InputSetDir(4,1,0)
utilWait(1000)
end
------------------------------------------------------------------------------------------------------------
-- ICPexit
--
-----------------------------------------------------------------------------------------------------------
function ICPexit()
-- damn, someone deleted this ;)
end
------------------------------------------------------------------------------------------------------------
-- ICPenter
--
-- PureMagic ;)
-----------------------------------------------------------------------------------------------------------
function ICPenter()
local dat=string.char(0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0)
local i
local j
nxt.DisableNXT(1)
nxt.RS485Enable(230000) -- works fine...
-- nxt.RS485Enable(460000) -- NORMAL !!!
-- nxt.RS485Enable(921600)
nxt.InputSetState(4,1,1)
utilWait(1500)
nxt.InputSetState(3,1,1)
uWait(1000)
nxt.RS485SendData(dat)
nxt.InputSetState(4,1,0)
-- for 460000 bit/s: 45
-- for 230000 bit/s: 90
for i=1,90 do
j=i
end
nxt.InputSetState(2,0,0)
nxt.InputSetType(4,0)
nxt.DisableNXT(0)
end
------------------------------------------------------------------------------------------------------------
-- ICPwait128
--
-----------------------------------------------------------------------------------------------------------
function ICPwait128()
local i
repeat
ICPmultishiftout({0x0f})
i=ICPshift_in()
-- emergency exit
if nxt.ButtonRead() ~= 0 then
break
end
until(i>127)
end
------------------------------------------------------------------------------------------------------------
-- ICPecho
--
-----------------------------------------------------------------------------------------------------------
function ICPecho()
local ch
ch=nxt.FileRead(0,1)
ch=string.upper(ch)
nxt.FileWrite(0,ch)
return ch
end
-- *** for download, only ***
collectgarbage("collect")
------------------------------------------------------------------------------------------------------------
-- ICPascii2hex
--
-----------------------------------------------------------------------------------------------------------
function ICPascii2hex(ch)
-- alternative:
local i
ch=string.byte(ch)
if ch > 0x3f then
ch=ch+9
end
i=ch/16 -- shift right and snip
i=i*16 -- shift snipped val left
ch=ch-i
-- ch=string.byte(ch)
-- if nxt.band(ch,0x40) ~= 0 then
-- ch=ch+9
-- end
-- ch=nxt.band(ch,0x0f)
return ch
end
------------------------------------------------------------------------------------------------------------
-- ICPget2
--
-----------------------------------------------------------------------------------------------------------
function ICPget2()
local ch
ch=ICPascii2hex(ICPecho())*(2^4)
ch=ch+ICPascii2hex(ICPecho())
gChkSum=gChkSum-ch
if gChkSum < 0 then
gChkSum=gChkSum+256
end
return ch
end
------------------------------------------------------------------------------------------------------------
-- ICPmultishiftout
--
-- DIG0 -> PDA
-- DIG1 -> PCL
-----------------------------------------------------------------------------------------------------------
function ICPmultishiftout(ch)
local i,j
local byte
for _,byte in ipairs(ch) do
nxt.DisableNXT(1)
for i=1,8 do
nxt.InputSetState(2,0,0) -- PCL low (NEW: was low before)
if byte%2 == 1 then
j=1
else
j=0
end
nxt.InputSetState(2,j,0) -- set PDA (and keep PCL)
nxt.InputSetState(2,j,1) -- PCL high (but keep PDA)
byte=byte/2
end
nxt.InputSetState(2,0,0) -- PCL and PDA low
nxt.DisableNXT(0)
end -- end for whole table
end
------------------------------------------------------------------------------------------------------------
-- ICPshift_in
--
-- DIG0 -> PDA
-- DIG1 -> PCL
-----------------------------------------------------------------------------------------------------------
function ICPshift_in()
local i,rbit
local di=0
nxt.DisableNXT(1)
nxt.InputSetState(2,0,0) -- PCL low
nxt.InputSetDir(2,0,1) -- PDA input
for i=1,8 do
di=di/2
nxt.InputSetState(2,nil,1) -- PCL high
_,rbit=nxt.InputGetStatus(2)
if rbit == 1 then
di=di+128
end
nxt.InputSetState(2,nil,0) -- PCL low
end
nxt.InputSetState(2,0,0) -- keep both low
nxt.DisableNXT(0)
return di
end
-- *** for download, only ***
collectgarbage("collect")
------------------------------------------------------------------------------------------------------------
-- ICPprogram
--
-----------------------------------------------------------------------------------------------------------
function ICPprogram()
local i
for i=0,gBytes-1 do
ICPmultishiftout({0x08,gAdrLo,0x0a,gAdrHi,0x0e,0x00,0x0c,gTB[i],0x0e,0x48})
ICPwait128()
gAdrLo=gAdrLo+1
if gAdrLo>255 then
gAdrLo=0
gAdrHi=gAdrHi+1
end
end -- end for
end
------------------------------------------------------------------------------------------------------------
-- ICPcrcsector
--
-----------------------------------------------------------------------------------------------------------
function ICPcrcsector()
local i
ICPmultishiftout({0x0a,gTB[0],0x0e,0x19})
ICPwait128()
for i=0,3 do
ICPmultishiftout({0x05})
gTB[i]=ICPshift_in()
end
end
------------------------------------------------------------------------------------------------------------
-- ICPcrcglobal
--
-----------------------------------------------------------------------------------------------------------
function ICPcrcglobal()
local i
ICPmultishiftout({0x0e,0x1a})
ICPwait128()
for i=0,3 do
ICPmultishiftout({0x05})
gTB[i]=ICPshift_in()
end
end
------------------------------------------------------------------------------------------------------------
-- ICPwrite_config
--
-----------------------------------------------------------------------------------------------------------
function ICPwrite_config()
local i=0
if gTB[0] == 0x10 then
ICPmultishiftout({0x0e,0x67,0x0c,0x96 })
else
ICPmultishiftout({0x0e,0x6c,0x08,gTB[0],0x0c,gTB[1]})
end
ICPwait128()
end
------------------------------------------------------------------------------------------------------------
-- ICPread_config
--
-----------------------------------------------------------------------------------------------------------
function ICPread_config()
ICPmultishiftout({0x0e,0x6c,0x08,gTB[0],0x0d})
gTB[0]=ICPshift_in()
end
------------------------------------------------------------------------------------------------------------
-- ICPerase_global
--
-----------------------------------------------------------------------------------------------------------
function ICPerase_global()
local i
ICPmultishiftout({0x0e,0x72})
-- NEW
for i=1,5 do
ICPmultishiftout({0x05})
ICPshift_in()
end
ICPwait128()
end
-- *** for download, only ***
collectgarbage("collect")
------------------------------------------------------------------------------------------------------------
-- ICPerase_page
--
-----------------------------------------------------------------------------------------------------------
function ICPerase_page()
local i
ICPmultishiftout({0x08,gTB[2],0x0a,gTB[1],0x0e,0x70})
ICPwait128()
end
------------------------------------------------------------------------------------------------------------
-- ICPerase_sector
--
-----------------------------------------------------------------------------------------------------------
function ICPerase_sector()
local i
ICPmultishiftout({0x0a,gTB[1],0x0e,0x71})
ICPwait128()
end
------------------------------------------------------------------------------------------------------------
-- kill
--
-- On larger programs, like this, you may experience download problems of
-- changed functions because luas byte compiler needs too much memory...
-- Usually, there is no other way than rebooting you NXT.
-- Here's my strategy to empty the memory ;)
-----------------------------------------------------------------------------------------------------------
function kill()
utilWait=nil
uWait=nil
ICPloop=nil
dp=nil
ICPinit=nil
ICPexit=nil
ICPenter=nil
ICPwait128=nil
ICPecho=nil
ICPascii2hex=nil
ICPget2=nil
ICPmultishiftout=nil
ICPshift_in=nil
ICPprogram=nil
ICPcrcsector=nil
ICPcrcglobal=nil
ICPwrite_config=nil
ICPread_config=nil
ICPerase_global=nil
ICPerase_page=nil
ICPerase_sector=nil
t=nil
collectgarbage("collect")
print(collectgarbage("count"))
end
------------------------------------------------------------------------------------------------------------
-- run
--
-- Leaves programming mode and "starts" your LPC90X.
-- !!! Be aware of potential short-circuit conditions if you use it for more than
-- !!! programming test firmware!
-- !!! Reset and PCL pins are always outputs on NXT2NXP!
-----------------------------------------------------------------------------------------------------------
function run()
-- hold in reset (low)
nxt.InputSetDir(4,1,1)
nxt.InputSetState(4,0,1)
-- power off
nxt.InputSetDir(3,1,1)
nxt.InputSetState(3,0,0)
utilWait(1500)
-- power on
nxt.InputSetState(3,0,1)
-- go...
nxt.InputSetState(4,0,0)
end
------------------------------------------------------------------------------------------------------------
-- prog
--
-- Starts programming mode.
-- Disconnect from your port and start FlashMagic afterwards...
-----------------------------------------------------------------------------------------------------------
function prog()
local i
for i=1,8 do
nxt.DisplayScroll()
end
ICPinit()
ICPenter()
ICPloop()
ICPexit()
end
-- *** for download, only ***
collectgarbage("collect") |