Skip to content

Commit ce90eb5

Browse files
committed
debug.superh.aud: queue up all reads before waiting for them
1 parent 2aafb1e commit ce90eb5

File tree

1 file changed

+45
-32
lines changed

1 file changed

+45
-32
lines changed

software/glasgow/applet/debug/superh/aud/__init__.py

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
from glasgow.abstract import AbstractAssembly, GlasgowPin, ClockDivisor
2121
from glasgow.applet import GlasgowAppletV2, GlasgowAppletError
2222

23+
MAX_BS = 1024
24+
2325

2426
class AUDError(GlasgowAppletError):
2527
pass
@@ -86,7 +88,7 @@ def elaborate(self, platform):
8688

8789
# Wait for clock period to pass, then set clock high
8890
with m.State("OUT-CLOCK-0"):
89-
with m.If(timer == self.divisor):
91+
with m.If(timer == self.divisor >> 1):
9092
m.d.sync += self.audck_o.eq(1)
9193
m.d.sync += timer.eq(0)
9294
m.next = "OUT-CLOCK-1"
@@ -95,7 +97,7 @@ def elaborate(self, platform):
9597

9698
# Wait for clock period to pass, then return to command reception
9799
with m.State("OUT-CLOCK-1"):
98-
with m.If(timer == self.divisor):
100+
with m.If(timer == self.divisor >> 1):
99101
m.d.sync += self.audck_o.eq(0)
100102
m.d.comb += self.i_stream.ready.eq(1) # Indicate to AUDComponent we're ready to receive a new command
101103
m.next = "RECV-COMMAND"
@@ -110,7 +112,7 @@ def elaborate(self, platform):
110112

111113
# Wait for clock period to pass, then sample data and set clock high
112114
with m.State("INP-CLOCK-0"):
113-
with m.If(timer == self.divisor):
115+
with m.If(timer == self.divisor >> 1):
114116
m.d.sync += self.audck_o.eq(1)
115117
m.d.sync += timer.eq(0)
116118

@@ -123,7 +125,7 @@ def elaborate(self, platform):
123125

124126
# Wait for clock period to pass, then send data
125127
with m.State("INP-CLOCK-1"):
126-
with m.If(timer == self.divisor):
128+
with m.If(timer == self.divisor >> 1):
127129
m.d.sync += self.audck_o.eq(0)
128130
m.next = "SEND-DATA"
129131
with m.Else():
@@ -323,12 +325,10 @@ async def run(self):
323325
async def out(self, val):
324326
await self._cmd(AUDCommand.Out, val)
325327

326-
async def inp(self, n) -> bytes:
328+
async def inp(self, n):
327329
await self._cmd(AUDCommand.Inp, n)
328330

329-
# This is the only place we need to flush, as we're going to wait for a response
330-
await self._pipe.flush()
331-
331+
async def read(self, n) -> bytes:
332332
data = await self._pipe.recv(n)
333333
data = bytes(data)
334334
self._logger.log(self._level, "AUD: read <%s>", data.hex())
@@ -350,34 +350,47 @@ async def init(self):
350350
for i in range(10):
351351
await self.out(0)
352352

353-
async def read(self, addr: int, sz: Literal[1,2,4 ] = 4, timeout: int = 100):
353+
async def bulk_read(self, addr: int, sz: int, bs: Literal[1,2,4 ] = 4):
354354
assert addr in range(0, 1<<32), "Address must be a 32-bit value"
355-
assert sz in (1, 2, 4), "Size must be one of 1, 2, or 4 bytes"
355+
assert bs in (1, 2, 4), "Block size must be one of 1, 2, or 4 bytes"
356+
357+
# Queue up all the reads
358+
for block_addr in range(addr, addr + sz, bs):
359+
await self.sync(0)
360+
await self.out(0)
361+
362+
# Send the Read command
363+
cmd = _AUDMonitorCommand.Read.value | \
364+
{
365+
1: _AUDMonitorSize.Byte,
366+
2: _AUDMonitorSize.Word,
367+
4: _AUDMonitorSize.LongWord,
368+
}[bs].value
369+
await self.out(cmd)
370+
371+
# Clock out Addr
372+
for i in range(8):
373+
await self.out((block_addr >> (i * 4)) & 0b1111)
356374

357-
await self.sync(0)
358-
await self.out(0)
375+
await self.inp(1 + 2 * bs)
359376

360-
# Send the Read command
361-
cmd = _AUDMonitorCommand.Read.value | \
362-
{
363-
1: _AUDMonitorSize.Byte,
364-
2: _AUDMonitorSize.Word,
365-
4: _AUDMonitorSize.LongWord,
366-
}[sz].value
367-
await self.out(cmd)
377+
# This is the only place we need to flush, as we're going to wait for a response
378+
await self._pipe.flush()
368379

369-
# Clock out Addr
370-
for i in range(8):
371-
await self.out((addr >> (i * 4)) & 0b1111)
380+
# Get all the responses
381+
out = []
382+
for _ in range(addr, addr + sz, bs):
383+
data = await self.read(1 + 2 * bs)
372384

373-
out = await self.inp(1 + 2 * sz)
374-
out = out[1:] # Remove the status code nibble
385+
# Remove the status code nibble
386+
data = data[1:]
375387

376-
# Combine nibbles into bytes and reverse
377-
out = bytes([x << 4 | y for x, y in zip(out[0::2], out[1::2])])
378-
out = out[::-1]
388+
# Combine nibbles into bytes and reverse
389+
data = bytes([y << 4 | x for x, y in zip(data[0::2], data[1::2])])
390+
data = data[::-1]
391+
out.append(data)
379392

380-
return out
393+
return b"".join(out)
381394

382395

383396
class AUDApplet(GlasgowAppletV2):
@@ -467,11 +480,11 @@ async def run(self, args):
467480
await self.aud_iface.init()
468481

469482
self.logger.trace("Reading data")
470-
bs = 4
483+
bs = min(MAX_BS, args.length)
471484

472485
for i in range(args.address, args.address + args.length, bs):
473-
data = await self.aud_iface.read(i, sz=bs)
486+
data = await self.aud_iface.bulk_read(i, bs)
474487
args.file.write(data)
475-
self._show_progress(i - args.address + bs, args.length, f"Read {data.hex()}")
488+
self._show_progress(i - args.address + bs, args.length, f"Read {data[:0x10].hex()}...")
476489

477490
self.logger.trace("Done")

0 commit comments

Comments
 (0)