rockbox/utils/hwstub/tools/lua/atj/dsp.lua
Marcin Bukat ad5e5c42fb hwstub: fix atj213x dsp lua code
Change-Id: I5fbd1799b958bedbe74f91bdcdd8a544e15d2a78
2015-11-17 22:40:31 +01:00

158 lines
4.2 KiB
Lua

ATJ.dsp = {}
-- Ungate DSP clock
function ATJ.dsp.init()
HW.CMU.DEVCLKEN.write(bit32.bor(HW.CMU.DEVCLKEN.read(), 0x10010))
end
-- Connect memory to DSP bus
-- Start DSP core
function ATJ.dsp.start()
HW.SRAMOC.CTL.write(0) -- connect memory to DSP bus
HW.DSP.CTL.write(0x187) -- reset DSP
hwstub.mdelay(100)
HW.DSP.CTL.write(0x18f) -- run DSP from PM@0 clocked from HOSC
end
-- Stop DSP core
-- Connect memory to MIPS bus
function ATJ.dsp.stop()
HW.DSP.CTL.write(0x107)
HW.DSP.CTL.write(0x0f)
HW.SRAMOC.CTL.write(0xf0) -- connect memory to MIPS bus
end
function ATJ.dsp.setclock(mhz)
local dpck = math.floor(mhz/6)
if dpck < 2 then dpck = 2 end
HW.DSP.CTL.write(0x0f) -- stop DSP clock
HW.CMU.DSPPLL.DPCK.write(dpck) -- setup pll
HW.CMU.DSPPLL.DPEN.write(1) -- enable pll
hwstub.mdelay(10) -- wait for PLL to settle
HW.DSP.CTL.write(0x10f) -- run DSP again clocked from DSP PLL
end
-- Start the execution of DSP program and wait
-- specified number of miliseconds before stoping DSP
-- Then you can inspect DSP memories from MIPS side
function ATJ.dsp.run(msec)
ATJ.dsp.stop()
ATJ.dsp.start()
hwstub.mdelay(msec)
ATJ.dsp.stop()
end
-- Clear DSP program memory
function ATJ.dsp.clearPM()
ATJ.dsp.stop()
for i=0,16*1024-1,4 do DEV.write32(0xb4040000+i, 0) end
end
-- Clear DSP data memory
function ATJ.dsp.clearDM()
ATJ.dsp.stop()
for i=0,16*1024-1,4 do DEV.write32(0xb4050000+i, 0) end
end
-- write single 24bit value to DSP memory
-- 0xb4040000 is start address of PM
-- 0xb4050000 is start address of DM
function ATJ.dsp.write(addr,val)
DEV.write8(addr+0, bit32.band(val, 0xff))
DEV.write8(addr+1, bit32.band(bit32.rshift(val, 8), 0xff))
DEV.write8(addr+2, bit32.band(bit32.rshift(val, 16), 0xff))
end
-- This function takes array of opcodes/values and writes it DSP memory
function ATJ.dsp.prog(opcodes, base, type)
if base > 0x3fff then
print(string.format("Invalid address 0x%x", base))
return
end
if type == 'p' then
-- DSP program memory
base = base + 0xb4040000
elseif type == 'd' then
-- DSP data memory
base = base + 0xb4050000
else
print(string.format("Invalid memory type: %c", type))
return
end
local offset=0
ATJ.dsp.stop()
for i,opcode in ipairs(opcodes) do
ATJ.dsp.write(base+4*offset, opcode)
offset=offset+1
end
end
-- This function reads the file produced by as2181 and
-- uploads it to the DSP memory
function ATJ.dsp.progfile(path)
local opcodes={}
local addr=nil
local type=nil
local fh=io.open(path)
if fh == nil then
print(string.format("Unable to open %s", path))
return
end
while true do
line = fh:read()
if line == nil then
break
end
-- Search for header describing target memory
if string.find(line, '@PA') ~= nil then
type = 'p'
elseif string.find(line, '@PD') ~= nil then
type = 'd'
end
if type ~= nil then
-- Next line after the header is the address
addr = fh:read()
if addr ~= nil then
addr = tonumber(addr, 16)
else
break;
end
while true do
line = fh:read()
if line == nil then
break
end
-- Check ending clause
-- We don't check embedded checksum
if string.find(line, '#123') then
break
end
-- Read operand and store in array
opcodes[#opcodes+1] = tonumber(line,16)
end
if (type == 'p') then
print(string.format("Writing %d opcodes PM @ 0x%0x", #opcodes, addr))
elseif (type == 'd') then
print(string.format("Writing %d values DM @ x0%0x", #opcodes, addr))
end
-- Write to DSP memory
ATJ.dsp.prog(opcodes, addr, type)
opcodes={}
addr = nil
type = nil
end
end
fh:close()
end