Compare commits

..

No commits in common. "c348b6a2717dd09c652f7a4c0e5d57756fe856ac" and "d495bc2db1554dedc2c144593bd052f3aeb8e6bc" have entirely different histories.

10 changed files with 134 additions and 285 deletions

View file

@ -206,11 +206,11 @@ void parse_command(const uint8_t *s, uint8_t n)
pipe.valid = 0; pipe.valid = 0;
r = pipe.valid; r = pipe.valid;
if (have_b) { if (have_b) {
if (bflg && cmd_flag('!') || ~r & bflg) { if (cmd_flag('!') || ~r & bflg) {
memcpy(bptr, cmd_buffer, 16); memcpy(bptr, cmd_buffer, 16);
pipe.valid = r |= bflg; r = pipe.valid |= bflg;
} }
else if (bflg) else
goto error; goto error;
} }
if (cmd_flag('%')) { if (cmd_flag('%')) {
@ -220,15 +220,14 @@ void parse_command(const uint8_t *s, uint8_t n)
if (cmd_flag('!')) { if (cmd_flag('!')) {
bch4369_fini(); bch4369_fini();
memcpy(flash_buffer+64, bch_parity, 16); memcpy(flash_buffer+64, bch_parity, 16);
pipe.valid = r |= 0x10; r = pipe.valid |= 0x10;
} }
} }
if (cmd_flag('<')) { if (cmd_flag('<')) {
if (cmd_flag('!')) goto send_buffer; if (cmd_flag('!')) goto send_buffer;
if (~r & bflg) if (~r & bflg)
goto error; goto error;
pipe.valid = r &=~ bflg; pipe.valid &=~ bflg;
r |= pipe.status << 4;
goto send_buffer; goto send_buffer;
} }
break; break;
@ -241,23 +240,17 @@ void parse_command(const uint8_t *s, uint8_t n)
r = flash_submit_command(cmd_buffer); r = flash_submit_command(cmd_buffer);
else else
r = spi_busy_p(); r = spi_busy_p();
if (cmd_flag('!')) if (cmd_flag('@'))
spi_poll(); spi_poll();
if (cmd_flag('<')) if (cmd_flag('<'))
goto send_buffer; goto send_buffer;
break; break;
case 'P': case 'P':
if (cmd_flag('@')) if (cmd_flag('!'))
pipe.dest = 0; pipe.dest = 0;
if (have_b) if (have_b)
pipe_config((void*)cmd_buffer, (void*)bptr); pipe_config((void*)cmd_buffer, (void*)bptr);
if (cmd_flag('.')) r = pipe_poll();
flash_poll(0);
else if (cmd_flag(','))
flash_poll(1);
if (cmd_flag('!'))
pipe_poll();
r = pipe.status;
break; break;
#ifdef HAVE_FPGA #ifdef HAVE_FPGA
case 'O': case 'O':

View file

@ -38,7 +38,6 @@ enum magic_flags {
MAGIC = 0xC5, MAGIC = 0xC5,
VERSION = 0x00, VERSION = 0x00,
#endif #endif
hold_pipe = 0x01,
}; };
extern const struct config config; extern const struct config config;
@ -159,7 +158,6 @@ void apply_config()
extern struct magic { extern struct magic {
uint8_t magic; uint8_t magic;
uint8_t reset_source; uint8_t reset_source;
uint8_t flags;
} magic; } magic;
#if 0 #if 0

View file

@ -66,16 +66,6 @@ mmap = memmap(map_fn)
class dose_cmd(uart.uart): class dose_cmd(uart.uart):
def parse_line(self, l):
self.responses.append(l)
v = self._verbose
if v>=4 or v and (l[:1]!=b'#' or b'?' in l.split()[0]):
try:
s = l.decode()
print(f"{self.portname}<- {s}", file=sys.stderr)
except:
print(f"{self.portname}<- {repr(l)}", file=sys.stderr)
def cmd(self, c, d=None, timeout=0.2): def cmd(self, c, d=None, timeout=0.2):
if not isinstance(c, bytes): if not isinstance(c, bytes):
c = c.encode() c = c.encode()
@ -93,7 +83,7 @@ class dose_cmd(uart.uart):
e = int(r[-1], 16) e = int(r[-1], 16)
if len(r)==3: if len(r)==3:
d = base85_decode(r[1]) d = base85_decode(r[1])
if self._verbose >= 3: if self._verbose:
print(f"{r[0]}[{r[2]}] {"".join([f"{b:02x}" for b in d])}", file=sys.stderr) print(f"{r[0]}[{r[2]}] {"".join([f"{b:02x}" for b in d])}", file=sys.stderr)
self.last_cmd = c[0:1] self.last_cmd = c[0:1]
return r[0], e, d return r[0], e, d
@ -101,23 +91,18 @@ class dose_cmd(uart.uart):
def poke(self, a, d, s=None, ccp=0): def poke(self, a, d, s=None, ccp=0):
return self.peek(a, s=s, d=d, ccp=ccp) return self.peek(a, s=s, d=d, ccp=ccp)
def peek(self, a=None, s=None, d=None, ccp=0, o=0): def peek(self, a=None, s=None, d=None, ccp=0):
name = None name = None
if isinstance(a, str): if a in SFR:
aa = a.split('+',1) name = a
if aa[1:]: a, ss = SFR[a]
o += int(aa[1], 0)
aa = aa[0]
if aa in SFR:
name = aa
a, ss = SFR[aa]
if s is None: if s is None:
s = ss s = ss
elif aa in mmap: if a in mmap:
a, ss = mmap[aa] a, ss = mmap[a]
if ss and s is None: if ss and s is None:
s = ss s = ss
else: if isinstance(a, str):
print(f"PEEK: unknown addr {a}", file=sys.stderr) print(f"PEEK: unknown addr {a}", file=sys.stderr)
for k in mmap.keys(): for k in mmap.keys():
if a in k: if a in k:
@ -126,7 +111,6 @@ class dose_cmd(uart.uart):
if a in k: if a in k:
print(f"PEEK: IO SFR we have {k}", file=sys.stderr) print(f"PEEK: IO SFR we have {k}", file=sys.stderr)
raise ValueError(a) raise ValueError(a)
a += o
FF = {1: "B", 2: "H", 4:"I"} FF = {1: "B", 2: "H", 4:"I"}
if a is None: if a is None:
cc, nn, dd = self.cmd(b"M=") cc, nn, dd = self.cmd(b"M=")
@ -239,10 +223,7 @@ class dose_cmd(uart.uart):
def flash(self, op=None, resp=False, poll=False, **aa): def flash(self, op=None, resp=False, poll=False, **aa):
c = "F" c = "F"
if poll: if poll:
if poll in ".,!": c = "F@"
c = "F"+poll
else:
c = "F!"
if resp: if resp:
c += "<" c += "<"
if op is None: if op is None:
@ -297,8 +278,10 @@ class dose_cmd(uart.uart):
if min(d) == 255: if min(d) == 255:
print(f"FLASH: page is erased") print(f"FLASH: page is erased")
elif bch.check_page(d): elif bch.check_page(d):
d = self.fix_page(d) if not bch.galois:
return d raise bch.BCHError("galois module not loaded for Parity Error correction")
d = bch.fix_page(d)
return d[:512]
def read_flash(self, page): def read_flash(self, page):
print(f"FLASH: reading from {page=}") print(f"FLASH: reading from {page=}")
@ -372,17 +355,6 @@ class dose_cmd(uart.uart):
self.flash(op, size=s, what=what, byte=i) self.flash(op, size=s, what=what, byte=i)
self.wait_for_spi() self.wait_for_spi()
def make_parity(self, page):
for i in range(32):
if i==0:
c = "B4!%@"
elif i!=31:
c = "B4!%"
else:
c = "B4!%!"
self.cmd(c, page[16*i:16*(i+1)])
return self.cmd("B4<!")
def power(self, on=None): def power(self, on=None):
if on==True: if on==True:
c = 'O1' c = 'O1'
@ -400,6 +372,7 @@ class dose_cmd(uart.uart):
return self.cmd("C@") return self.cmd("C@")
FPGA_FLGS = { FPGA_FLGS = {
"ABORT": 0x01,
"DEAD": 0x10, "DEAD": 0x10,
"BUSY": 0x20, "BUSY": 0x20,
"SUBMITTED": 0x40, "SUBMITTED": 0x40,
@ -423,7 +396,7 @@ class dose_cmd(uart.uart):
c = bytes((n, z)) + c + bytes(14) c = bytes((n, z)) + c + bytes(14)
r, e, d = self.cmd("C", c[:16]) r, e, d = self.cmd("C", c[:16])
s = int2flags(self.FPGA_FLGS, d[0]) s = int2flags(self.FPGA_FLGS, d[0])
if self._verbose >= 2: if self._verbose:
print(f"FPGA cmd status {s!r}", file=sys.stderr) print(f"FPGA cmd status {s!r}", file=sys.stderr)
return d return d
@ -489,7 +462,7 @@ class dose_cmd(uart.uart):
w.extend([0x8001]*(r-1)) w.extend([0x8001]*(r-1))
w.append(0) w.append(0)
d = struct.pack(f">{len(w)}H", *w) d = struct.pack(f">{len(w)}H", *w)
if self._verbose >= 2: if self._verbose:
if mes: if mes:
mes = f"[{mes}]" mes = f"[{mes}]"
else: else:
@ -497,13 +470,13 @@ class dose_cmd(uart.uart):
print(f"icmd{mes}{[f"{ww:04x}" for ww in w]}") print(f"icmd{mes}{[f"{ww:04x}" for ww in w]}")
d = self.fpga_cmd(d) d = self.fpga_cmd(d)
r = struct.unpack(f">{len(w)+1}H", d[:2*len(w)+2]) r = struct.unpack(f">{len(w)+1}H", d[:2*len(w)+2])
if self._verbose >= 2: if self._verbose:
print(f" {mes}{[f"{rr:04x}" for rr in r]}", file=sys.stderr) print(f" {mes}{[f"{rr:04x}" for rr in r]}", file=sys.stderr)
return r return r
def acmd(self, c, v=None, task=None, verb=True): def acmd(self, c, v=None, task=None, verb=True):
_v = self._verbose _v = self._verbose
self._verbose = verb+1 self._verbose = _v
r = self.icmd(c, v, mes=task)[-1] r = self.icmd(c, v, mes=task)[-1]
self._verbose = _v self._verbose = _v
return r return r
@ -527,7 +500,7 @@ class dose_cmd(uart.uart):
nnn -= nn nnn -= nn
d += dd[2:] d += dd[2:]
r = struct.unpack(f">{len(d)//2}H", d)[:n] r = struct.unpack(f">{len(d)//2}H", d)[:n]
if self._verbose >= 2: if self._verbose:
print(f"FIFO[{fifo}] ← {[f"{rr:04x}" for rr in r]}", file=sys.stderr) print(f"FIFO[{fifo}] ← {[f"{rr:04x}" for rr in r]}", file=sys.stderr)
return r return r
@ -549,140 +522,9 @@ class dose_cmd(uart.uart):
else: else:
self.icmd("MCONF_CLR", what) self.icmd("MCONF_CLR", what)
PIPE = {
"CMD" : 1,
"ADC" : 2,
"FLASH" : 4,
"FPGA" : 8,
"CONFIG" : 0x208,
"FPGA_CMD" : 0x408,
}
def pipe(self, source=None, dest=None,
fpga_cmd=4, psize=64, n=0,
page=0, npages=0,
poll=True, stop=False):
astatus = flags2int(self.PIPE, dest)
astatus |= flags2int(self.PIPE, source)
astatus >>= 8
dest = flags2int(self.PIPE, dest) & 0xff
source = flags2int(self.PIPE, source) & 0xff
flash = 0x80 # FS_528
status = 0x80 # PS_OUT
c = 'P'
if astatus & self.PIPE["FPGA_CMD"]:
if not isinstance(fpga_cmd, int):
self.cmd("B4!", fpga_cmd)
fpga_cmd = 4
c = 'P{fpga_cmd}'
if stop:
c += '@'
if poll:
c += '!'
if source & self.PIPE["FLASH"]:
source = self.PIPE["FLASH"]
flash |= 4
status |= 0x30 # PS_528 | PS_BCH
dest &=~ self.PIPE["FLASH"]
if dest & self.PIPE["FPGA"] and not n:
n = 512/64 * npages
if dest & self.PIPE["FLASH"]:
flash |= 8
status |= 0x30 # PS_528 | PS_BCH
if source == self.PIPE["FPGA"] and not n:
n = (512*npages+psize-1) // psize
d = struct.pack("<6BH3B2HB",
source, dest, status, 0, 0,
astatus, n, psize, 0, 0,
page, npages-1, flash)
return self.cmd(c, d)
Sync = False
def read_pipe(self, n=0, file=None, timeout=2, parity=False):
if isinstance(file, str):
f = open(file, "ab")
else:
f = file
result = []
i = 0
page = []
t = time.time()
s = 1/256
while i < n:
cc, nn, dd = self.cmd("B")
if not parity or len(page) < 7:
bflg = 0x0f
else:
bflg = 0x1f
tt = time.time()
if ~nn & bflg:
if tt > t+timeout:
if self._verbose:
print("read_pipe timeout", file=sys.stderr)
break
time.sleep(s)
s *= 2
if s > 1:
s = 1
continue
t = tt
s = 1/256
if len(result) >= n:
break
if nn & 0x10:
p = self.cmd("B4<")[2]
else:
p = None
data = [self.cmd(f"B{i}<")[2] for i in range(4)]
data = b''.join(data)
page.append(data)
if len(page)==8:
if p:
page.append(p)
page = b''.join(page)
i += 1
if parity:
if bch.check_page(page):
print(f"parity error on page {i}", file=sys.stderr)
if parity == "fix":
page = self.fix_page(page)
if f and parity == "fix":
file.write(page[:512])
if not f:
result.append(page)
page = []
if f and parity != "fix":
f.write(data)
if len(page) and parity == "save":
f.write_flash(p)
if f and self.Sync:
f.sync()
if isinstance(file, str):
f.close()
return result
def fix_page(self, page):
if self.load_galois():
page = bch.fix_page(page)
def load_galois(self):
if not bch.galois:
raise bch.BCHError("galois module not loaded for Parity Error correction")
return True
def flags2int(FLAGS, flags): def flags2int(FLAGS, flags):
r = 0 r = 0
if flags is None:
return r
if isinstance(flags, int): if isinstance(flags, int):
return flags return flags
if isinstance(flags, str): if isinstance(flags, str):
@ -704,7 +546,7 @@ def int2flags(FLAGS, flags):
if tty: if tty:
tty = dose_cmd(tty, baud) tty = dose_cmd(tty, baud)
tty._export(globals()) tty._export(globals())
tty._verbose = True tty._verbose = False
import dorn import dorn
from dorn import * from dorn import *
dorn._connect(tty) dorn._connect(tty)

View file

@ -150,7 +150,7 @@ uint8_t flash_cmd(uint16_t mode, uint16_t what, uint16_t page, uint16_t byte)
spi_start_read(csize, flash_cmd_buffer, size, b); spi_start_read(csize, flash_cmd_buffer, size, b);
break; break;
case FM_WAIT: case FM_WAIT:
spi.mask = spi.wait = 0x80; spi.mask = 0x80;
spi_start_read(csize, flash_cmd_buffer, 2, b); spi_start_read(csize, flash_cmd_buffer, 2, b);
break; break;
} }
@ -173,7 +173,7 @@ uint8_t flash_stream_submit(uint16_t mode, uint8_t size)
{ {
uint8_t b = fs.block; uint8_t b = fs.block;
uint16_t p = fs.page; uint16_t p = fs.page;
uint8_t r = fs.status & ~FS_Ready | FS_Busy; uint8_t r = fs.status & ~FS_Ready;
mode |= (uint16_t)config.flash_page_size << 8; mode |= (uint16_t)config.flash_page_size << 8;
if (size) { if (size) {
if (b & 8) { if (b & 8) {
@ -193,9 +193,21 @@ uint8_t flash_stream_submit(uint16_t mode, uint8_t size)
uint8_t e = flash_cmd(mode, size, p, (uint16_t)(b&7) << 6); uint8_t e = flash_cmd(mode, size, p, (uint16_t)(b&7) << 6);
if (e) if (e)
r |= FS_Error; r |= FS_Ready; // FS_Error
r |= FS_Busy;
fs.status = r; fs.status = r;
return r; return e;
}
__attribute__ ((noinline, noclone))
uint8_t flash_stream_done()
{
uint8_t r = fs.status & FS_Error;
if (!r || r == FS_Error)
return 1;
if (fs.npages || !(fs.block & 8))
return 0;
return 1;
} }
static inline static inline
@ -241,50 +253,55 @@ uint8_t flash_burn_page()
uint8_t flash_poll(uint8_t rr) uint8_t flash_poll(uint8_t rr)
{ {
uint8_t r = fs.status; uint8_t r = fs.status;
if (rr)
r |= FS_Ack;
if (spi_busy_p()) if (spi_busy_p())
return r; return r;
if (flash_stream_done()) if ((r & FS_Error) == FS_Error)
return r; return r;
if (r & FS_Ready) if (r & FS_StBsy) {
// status bytes arrived
if (~flash_status_bytes[0] & 0x80)
// flash is still busy burning
goto rd_status;
// not busy any more, move Bsy → Rdy
if (r & FS_Busy)
r |= FS_Ready;
goto ready; goto ready;
if (r & FS_StBsy && flash_status_bytes[0] & 0x80)
// flash is done burning
goto ready;
if (r & FS_Write && fs.block == 9) {
// Write or Erase
r |= FS_StBsy;
flash_status_bytes[0] = 0;
flash_cmd_na(0xd7 | FM_READ, 0xf002);
goto done;
} }
if (r & FS_Dir == FS_Write && fs.block == 8) { if (!(r & FS_Busy))
// Write goto ready;
r = flash_burn_page(); if (rr) {
goto done; r |= FS_Error;
fs.status = r;
return r;
}
if (r & FS_Write) {
if (fs.block == 9) {
rd_status:
// request status bytes for pending Write or Error
r |= FS_StBsy;
fs.status = r;
flash_cmd_na(0xd7 | FM_READ, 0xf002);
return r;
}
} }
ready: ready:
r &= ~(FS_Error | FS_StBsy); r &= ~(FS_Busy | FS_StBsy);
if (!(r & FS_Ack)) { if (rr)
r |= FS_Ready; r |= FS_Ack;
goto done;
}
r &=~ FS_Ack;
if (!fs.npages && fs.block & 8)
goto done;
if ((r & FS_Dir) == FS_Read)
r = flash_read_next_block();
else if ((r & FS_Dir) == FS_Write)
r = flash_write_next_block();
else if ((r & FS_Dir) == FS_Erase)
r = flash_erase_next_page();
done:
fs.status = r; fs.status = r;
return r; if (r & FS_Dir == FS_Write && fs.block == 8)
flash_burn_page();
else if (!flash_stream_done()) {
if (r & (FS_Dir|FS_Ack) == (FS_Read|FS_Ack))
flash_read_next_block();
else if (r & (FS_Dir|FS_Ack) == (FS_Write|FS_Ack))
flash_write_next_block();
else if (r & FS_Dir == FS_Erase)
flash_erase_next_page();
fs.status &=~ FS_Ack;
}
return fs.status;
} }
uint8_t flash_start_stream(uint16_t page, uint16_t npages, uint8_t flags) uint8_t flash_start_stream(uint16_t page, uint16_t npages, uint8_t flags)
@ -293,12 +310,14 @@ uint8_t flash_start_stream(uint16_t page, uint16_t npages, uint8_t flags)
if ((r & FS_Error) == FS_Busy) if ((r & FS_Error) == FS_Busy)
return FS_Error; return FS_Error;
r = flags | FS_Ready; r = flags | FS_Ready;
if (config.flash_page_size != FM_528)
r &=~ FS_528;
fs.page = page; fs.page = page;
fs.npages = npages;
flash_status_bytes[0] = 0;
fs.block = 0; fs.block = 0;
fs.npages = npages;
fs.status = r; fs.status = r;
return r; flash_status_bytes[0] = 0xff;
return flash_poll(0);
} }
static inline static inline

View file

@ -28,6 +28,7 @@ uint8_t flash_cmd(uint16_t mode, uint16_t what, uint16_t page, uint16_t byte);
extern uint8_t flash_buffer[FB_SIZE]; extern uint8_t flash_buffer[FB_SIZE];
uint8_t flash_submit_command(uint8_t *cmd); uint8_t flash_submit_command(uint8_t *cmd);
uint8_t flash_start_stream(uint16_t page, uint16_t npages, uint8_t flags); uint8_t flash_start_stream(uint16_t page, uint16_t npages, uint8_t flags);
uint8_t flash_stream_done();
uint8_t flash_poll(uint8_t rr); uint8_t flash_poll(uint8_t rr);
uint16_t flash_find_free(); uint16_t flash_find_free();
@ -54,7 +55,5 @@ enum {
}; };
static inline uint8_t flash_current_block() { return fs.block; } static inline uint8_t flash_current_block() { return fs.block; }
static inline uint8_t flash_stream_done()
{ return !(fs.status & FS_Error) || !(~fs.status & FS_Error); }
#endif #endif

View file

@ -113,6 +113,7 @@ uint8_t fpga_start_read()
uint8_t n = 64 - pipe.fpga.val; uint8_t n = 64 - pipe.fpga.val;
if (!n) if (!n)
return n; return n;
spi.rdata = flash_buffer + pipe.fpga.val;
n >>= 1; n >>= 1;
if (~pipe.fpga.status & AS_CONT) { if (~pipe.fpga.status & AS_CONT) {
if (!pipe.fpga.count) if (!pipe.fpga.count)
@ -129,10 +130,7 @@ uint8_t fpga_start_read()
pipe.fpga.pos += n; pipe.fpga.pos += n;
if (pipe.fpga.pos == pipe.fpga.size) if (pipe.fpga.pos == pipe.fpga.size)
pipe.fpga.status &=~ AS_CONT; pipe.fpga.status &=~ AS_CONT;
spi.rdata = flash_buffer + pipe.fpga.val;
spi.rsize = n << 1; spi.rsize = n << 1;
spi.zsize += spi.rsize;
pipe.fpga.val += spi.rsize; pipe.fpga.val += spi.rsize;
spi_start(); spi_start();
return n; return n;

View file

@ -18,7 +18,7 @@ uint8_t pipe_busy()
// call this with cli() before sei();sleep() // call this with cli() before sei();sleep()
if (spi_busy_p()) return 1; if (spi_busy_p()) return 1;
if (flash_poll(0) & FS_Busy) return 1; if (flash_poll(0) & FS_Busy) return 1;
if (adc_busy()) return 1; if (adc_poll(0)) return 1;
return 0; return 0;
} }
@ -77,14 +77,14 @@ uint8_t pipe_poll()
// Return if next ADC reading is not yet due. // Return if next ADC reading is not yet due.
// Come back here, until is is. // Come back here, until is is.
if (pipe.source == pipe_adc && !adc_poll(pipe.adc)) if (pipe.source & pipe_adc && !adc_poll(pipe.adc))
goto done; goto done;
// Continue the flash stream. // Continue the flash stream.
// PS_BLK is the 64-Bytes buffer number in the page // PS_BLK is the 64-Bytes buffer number in the page
valid = 0; valid = 0;
if (pipe.source == pipe_flash) { if (pipe.source & pipe_flash) {
r &= ~ PS_BLK; r &= ~ PS_BLK;
r |= flash_current_block() & PS_BLK; r |= flash_current_block() & PS_BLK;
flash_poll(1); flash_poll(1);
@ -92,9 +92,9 @@ uint8_t pipe_poll()
#ifdef HAVE_FPGA #ifdef HAVE_FPGA
// Continue the FPGA stream. // Continue the FPGA stream.
else if (pipe.source == pipe_fpga) { else if (pipe.source & pipe_fpga) {
if (~fpga_start_read()) if (~fpga_start_read())
pipe.source = 0; pipe.source &=~ pipe_fpga;
} }
#endif #endif
goto done; goto done;
@ -109,7 +109,7 @@ uint8_t pipe_poll()
bflgs = 0x1f; bflgs = 0x1f;
// Data from the ADC is in named .bss segments. We send // Data from the ADC is in named .bss segments. We send
// 16, 32, or 64 Bytes from the .bss segement for each ADC reading. // 16, 32, or 64 Bytes from the .bss segement for ead ADC reading.
// The first named .bss segment is `magic`. Observe the link order // The first named .bss segment is `magic`. Observe the link order
// in the Makefile. // in the Makefile.
// //
@ -118,7 +118,7 @@ uint8_t pipe_poll()
// `o` is the addr in the flash_buffer // `o` is the addr in the flash_buffer
// `v` are the currently valid cmd_buffer flags // `v` are the currently valid cmd_buffer flags
// `f` are the fresh valid cmd_buffer flags // `f` are the fresh valid cmd_buffer flags
if (pipe.source == pipe_adc) { if (pipe.source & pipe_adc) {
uint8_t n = pipe.adc & 0x70; uint8_t n = pipe.adc & 0x70;
if (!n) if (!n)
goto adc_done; goto adc_done;
@ -160,11 +160,11 @@ adc_done:
// When the flash is done, flag the buffer valid, // When the flash is done, flag the buffer valid,
// including BCH Bytes. // including BCH Bytes.
if (pipe.source == pipe_flash && fs.status & FS_Ready) if (pipe.source & pipe_flash && fs.status & FS_Ready)
valid = bflgs; valid = bflgs;
#ifdef HAVE_FPGA #ifdef HAVE_FPGA
// The FPGA delivers 64 Bytes. // The FPGA delivers 64 Bytes.
else if (pipe.source == pipe_fpga && fpga_pipe_ready()) else if (pipe.source & pipe_fpga && fpga_pipe_ready())
valid = 0x0f; valid = 0x0f;
#endif #endif
// The buffer is not here, yet. Nothing we can do now. // The buffer is not here, yet. Nothing we can do now.
@ -181,10 +181,10 @@ adc_done:
// Last buffer of the page: // Last buffer of the page:
if (!(~r & PS_BLK)) { if (!(~r & PS_BLK)) {
bch4369_fini(); bch4369_fini();
valid = 0x01f;
// When the Flash is not the source, // When the Flash is not the source,
// and cmd did not provide the parity
// copy the computed parity into the buffer. // copy the computed parity into the buffer.
if (~valid & 0x10) if (~pipe.source & pipe_flash)
_memcopyyz(bend, bch_parity, 16); _memcopyyz(bend, bch_parity, 16);
// When the page as read from flash has invalid parity, // When the page as read from flash has invalid parity,
// stop writing to the FPGA. // stop writing to the FPGA.
@ -192,7 +192,6 @@ adc_done:
dest &=~ pipe_fpga; dest &=~ pipe_fpga;
r |= PS_ERR; r |= PS_ERR;
} }
valid = 0x1f;
} }
} }
// We still do not have all data we need // We still do not have all data we need
@ -204,7 +203,7 @@ adc_done:
#ifdef HAVE_FPGA #ifdef HAVE_FPGA
// Resume the FPGA stream // Resume the FPGA stream
if (dest & pipe_fpga && ~fpga_start_write()) if (dest & pipe_fpga & ~fpga_start_write())
dest &=~ pipe_fpga; dest &=~ pipe_fpga;
else else
#endif #endif
@ -228,7 +227,7 @@ void pipe_config(const struct pipe_config *c, const struct pipe_fpga_cmd *a)
{ {
/************************************************************ /************************************************************
* cmd("B0!", «fpga-cmd») optionally configure an FPGA cmd * cmd("B0!", «fpga-cmd») optionally configure an FPGA cmd
* cmd("P0", «pipe-cfg») with `AS_CMD` in `.status` * cmd("P0:, «pipe-cfg») with `AS_CMD` in `.status`
***********************************************************/ ***********************************************************/
if (c->pipe.dest) { if (c->pipe.dest) {
@ -239,7 +238,6 @@ void pipe_config(const struct pipe_config *c, const struct pipe_fpga_cmd *a)
else { else {
// new source (NOT flash) // new source (NOT flash)
pipe.source = c->pipe.source; pipe.source = c->pipe.source;
pipe.adc = c->pipe.adc;
} }
if (pipe.source & pipe_adc) if (pipe.source & pipe_adc)
adc_start_stream(pipe.adc); adc_start_stream(pipe.adc);
@ -249,7 +247,6 @@ void pipe_config(const struct pipe_config *c, const struct pipe_fpga_cmd *a)
_memcopyzy((void*)&pipe_fpga_cmd, (void*)a, sizeof(*a)); _memcopyzy((void*)&pipe_fpga_cmd, (void*)a, sizeof(*a));
else else
memset(&pipe_fpga_cmd, 0, sizeof(*a)); memset(&pipe_fpga_cmd, 0, sizeof(*a));
pipe.fpga = c->pipe.fpga;
fpga_start_read(); fpga_start_read();
} }
#endif #endif

View file

@ -387,18 +387,23 @@ ISR(SPI0_INT_vect, ISR_NAKED)
"rjmp 4f" "\n" "rjmp 4f" "\n"
"1:" "\n\t" "1:" "\n\t"
"lds r26, %[WAIT]" "\n\t" "lds r26, %[MASK]" "\n\t"
"eor r26, r25" "\n\t" "cpi r26, 0" "\n\t"
"lds r24, %[MASK]" "\n\t" "breq 1f" "\n\t"
"and r26, r24" "\n\t" "and r26, r25" "\n\t"
"breq 2f" "\n\t" "lds r24, %[WAIT]" "\n\t"
"cp r24, r26" "\n\t"
"brne 2f" "\n\t"
"lds r25, %[ZSZ]" "\n\t" "lds r25, %[ZSZ]" "\n\t"
"subi r25, -1" "\n\t" "subi r25, -1" "\n\t"
"sts %[ZSZ], r25" "\n\t" "sts %[ZSZ], r25" "\n\t"
"rjmp 4f" "\n" "rjmp 4f" "\n"
"2:" "\n\t" "2:" "\n\t"
"sts %[MASK], r26" "\n\t" "clr r26" "\n\t"
"sts %[MASK], r26" "\n"
"1:" "\n\t"
"lds r26, %[RSZ]" "\n\t" "lds r26, %[RSZ]" "\n\t"
"subi r26, 1" "\n\t" "subi r26, 1" "\n\t"
"brcs 4f" "\n\t" "brcs 4f" "\n\t"

View file

@ -13,7 +13,6 @@
#include "config.h" #include "config.h"
#include "uart.h" #include "uart.h"
#include "pipe.h" #include "pipe.h"
#include "adc.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// //
@ -41,18 +40,17 @@ int main()
send_hex_byte_eol(magic.reset_source); send_hex_byte_eol(magic.reset_source);
while (1) { while (1) {
// The irq sources may become idle before we reach sleep. // The pipe may become idle before we reach sleep.
// Make sure we have nothing pending before we sleep. // Make sure we have nothing to do before we sleep.
// The sleep command will execute even when an irq becomes // The sleep command will execute even when an irq
// pending after cli(). It will wake us immediately. // is pending. It will wake us immediately.
cli(); cli();
if (!command_pending() || adc_busy() || spi_busy_p()) { if (!command_pending() && (!pipe.dest || pipe_busy())) {
sei(); sei();
sleep_cpu(); sleep_cpu();
} }
sei(); sei();
command(); command();
if (~magic.flags & hold_pipe)
pipe_poll(); pipe_poll();
} }
} }

View file

@ -61,7 +61,7 @@ class uart(threading.Thread):
def parse_line(self, l): def parse_line(self, l):
self.responses.append(l) self.responses.append(l)
if self._verbose >= 4: if self._verbose:
try: try:
s = l.decode() s = l.decode()
print(f"{self.portname}<- {s}", file=sys.stderr) print(f"{self.portname}<- {s}", file=sys.stderr)
@ -92,7 +92,7 @@ class uart(threading.Thread):
c = c.encode() c = c.encode()
if c[-1:] != b'\n': if c[-1:] != b'\n':
c = c + b'\n' c = c + b'\n'
if self._verbose >= 4: if self._verbose:
print(f"{self.portname}-> {c.decode().rstrip()}", file=sys.stderr) print(f"{self.portname}-> {c.decode().rstrip()}", file=sys.stderr)
self.write(c) self.write(c)