summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2015-11-17 13:25:28 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2015-11-17 13:35:09 +0100
commitf47f04b65fc7603ec5926dd5f941d6690a0daf91 (patch)
treedfb19cbe3eb22552df68f3d96aff62a6947bf489
parent5b7c9d40e749e96bd382e332ab9e25b6a18435b2 (diff)
downloadrockbox-f47f04b65fc7603ec5926dd5f941d6690a0daf91.tar.gz
rockbox-f47f04b65fc7603ec5926dd5f941d6690a0daf91.zip
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
-rw-r--r--utils/hwstub/tools/lua/atj.lua1
-rw-r--r--utils/hwstub/tools/lua/atj/dsp.lua158
2 files changed, 159 insertions, 0 deletions
diff --git a/utils/hwstub/tools/lua/atj.lua b/utils/hwstub/tools/lua/atj.lua
index 1f59a141fc..a1ad0c7505 100644
--- a/utils/hwstub/tools/lua/atj.lua
+++ b/utils/hwstub/tools/lua/atj.lua
@@ -7,3 +7,4 @@ ATJ = {}
7hwstub.soc:select("atj213x") 7hwstub.soc:select("atj213x")
8require "atj/gpio" 8require "atj/gpio"
9require "atj/lcm" 9require "atj/lcm"
10require "atj/dsp"
diff --git a/utils/hwstub/tools/lua/atj/dsp.lua b/utils/hwstub/tools/lua/atj/dsp.lua
new file mode 100644
index 0000000000..93c80e36ef
--- /dev/null
+++ b/utils/hwstub/tools/lua/atj/dsp.lua
@@ -0,0 +1,158 @@
1ATJ.dsp = {}
2
3-- Ungate DSP clock
4function ATJ.dsp.init()
5 HW.CMU.DEVCLKEN.write(bit32.bor(HW.CMU.DEVCLKEN.read(), 0x10010))
6end
7
8-- Connect memory to DSP bus
9-- Start DSP core
10function ATJ.dsp.start()
11 HW.SRAMOC.CTL.write(0) -- connect memory to DSP bus
12 HW.DSP.CTL.write(0x187) -- reset DSP
13 hwstub.mdelay(100)
14 HW.DSP.CTL.write(0x18f) -- run DSP from PM@0 clocked from HOSC
15end
16
17-- Stop DSP core
18-- Connect memory to MIPS bus
19function ATJ.dsp.stop()
20 HW.DSP.CTL.write(0x107)
21 HW.DSP.CTL.write(0x0f)
22 HW.SRAMOC.CTL.write(0xf0) -- connect memory to MIPS bus
23end
24
25function ATJ.dsp.setclock(mhz)
26 local dpck = math.floor(mhz/6)
27 if dpck < 2 then dpck = 2 end
28
29 HW.DSP.CTL.write(0x0f) -- stop DSP clock
30 HW.CMU.DSPPLL.DPCK.write(dpck) -- setup pll
31 HW.CMU.DSPPLL.DPEN.write(1) -- enable pll
32 hwstub.mdelay(10) -- wait for PLL to settle
33 HW.DSP.CTL.write(0x10f) -- run DSP again clocked from DSP PLL
34end
35
36-- Start the execution of DSP program and wait
37-- specified number of miliseconds before stoping DSP
38-- Then you can inspect DSP memories from MIPS side
39function ATJ.dsp.run(msec)
40 DSP.stop()
41 DSP.start()
42 hwstub.mdelay(msec)
43 DSP.stop()
44end
45
46-- Clear DSP program memory
47function ATJ.dsp.clearPM()
48 DSP.stop()
49 for i=0,16*1024-1,4 do DEV.write32(0xb4040000+i, 0) end
50end
51
52-- Clear DSP data memory
53function ATJ.dsp.clearDM()
54 DSP.stop()
55 for i=0,16*1024-1,4 do DEV.write32(0xb4050000+i, 0) end
56end
57
58-- write single 24bit value to DSP memory
59-- 0xb4040000 is start address of PM
60-- 0xb4050000 is start address of DM
61function ATJ.dsp.write(addr,val)
62 DEV.write8(addr+0, bit32.band(val, 0xff))
63 DEV.write8(addr+1, bit32.band(bit32.rshift(val, 8), 0xff))
64 DEV.write8(addr+2, bit32.band(bit32.rshift(val, 16), 0xff))
65end
66
67-- This function takes array of opcodes/values and writes it DSP memory
68function ATJ.dsp.prog(opcodes, base, type)
69 if base > 0x3fff then
70 print(string.format("Invalid address 0x%x", base))
71 return
72 end
73
74 if type == 'p' then
75 -- DSP program memory
76 base = base + 0xb4040000
77 elseif type == 'd' then
78 -- DSP data memory
79 base = base + 0xb4050000
80 else
81 print(string.format("Invalid memory type: %c", type))
82 return
83 end
84
85 local offset=0
86 DSP.stop()
87 for i,opcode in ipairs(opcodes) do
88 DSP.write(base+4*offset, opcode)
89 offset=offset+1
90 end
91end
92
93-- This function reads the file produced by as2181 and
94-- uploads it to the DSP memory
95function ATJ.dsp.progfile(path)
96 local opcodes={}
97 local addr=nil
98 local type=nil
99
100 local fh=io.open(path)
101 if fh == nil then
102 print(string.format("Unable to open %s", path))
103 return
104 end
105
106 while true do
107 line = fh:read()
108 if line == nil then
109 break
110 end
111
112 -- Search for header describing target memory
113 if string.find(line, '@PA') ~= nil then
114 type = 'p'
115 elseif string.find(line, '@PD' ~= nil) then
116 type = 'd'
117 end
118
119 if type ~= nil then
120 -- Next line after the header is the address
121 addr = fh:read()
122 if addr ~= nil then
123 addr = tonumber(addr, 16)
124 else
125 break;
126 end
127
128 while true do
129 line = fh:read()
130 if line == nil then
131 break
132 end
133
134 -- Check ending clause
135 -- We don't check embedded checksum
136 if string.find(line, '#123') then
137 break
138 end
139
140 -- Read operand and store in array
141 opcodes[#opcodes+1] = tonumber(line,16)
142 end
143
144 if (type == 'p') then
145 print(string.format("Writing %d opcodes PM @ 0x%0x", #opcodes, addr))
146 elseif (type == 'd') then
147 print(string.format("Writing %d values DM @ x0%0x", #opcodes, addr))
148 end
149
150 -- Write to DSP memory
151 DSP.prog(opcodes, addr, type)
152 opcodes={}
153 addr = nil
154 type = nil
155 end
156 end
157 fh:close()
158end