1
0
Fork 0
forked from len0rd/rockbox

hwstub: Add ajt213x lua interface for DSP block

With this you can upload and run code on DSP core in atj213x.

The files can be produced using as2181. You can download
this assembler from https://github.com/wodz/as2181
You should use extended mode (-x switch) since DSP core
in atj is non standard and uses 24bit operands.
PX register has different meaning as well and is used as MSB
when loading other registers with immediates (immediate field
is 16bit in instruction so to set register to 24bit value
you need to store MSB in PX prior to this).

MAC MR is 56bit accordingly.

HIP interface seems to be mapped at standard addresses
(except that regular 218x doesn't have HIP).

Have a fun!

Change-Id: I9a80ca0dd3718ba8435ae8579bfffa66e067e022
This commit is contained in:
Marcin Bukat 2015-11-17 13:25:28 +01:00
parent 5b7c9d40e7
commit f47f04b65f
2 changed files with 159 additions and 0 deletions

View file

@ -7,3 +7,4 @@ ATJ = {}
hwstub.soc:select("atj213x") hwstub.soc:select("atj213x")
require "atj/gpio" require "atj/gpio"
require "atj/lcm" require "atj/lcm"
require "atj/dsp"

View file

@ -0,0 +1,158 @@
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)
DSP.stop()
DSP.start()
hwstub.mdelay(msec)
DSP.stop()
end
-- Clear DSP program memory
function ATJ.dsp.clearPM()
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()
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
DSP.stop()
for i,opcode in ipairs(opcodes) do
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
DSP.prog(opcodes, addr, type)
opcodes={}
addr = nil
type = nil
end
end
fh:close()
end