1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
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)
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
|