Compare commits

..

2 commits

Author SHA1 Message Date
Stephan I. Böttcher
649887021d pipe: fix flash pipe, parity 2026-04-22 15:38:51 +02:00
Stephan I. Böttcher
53de8c0d12 pipe: fix flash write bch
The flash_current_block() was stored redundantly in pipe.status.
The ensuing confusion broke flash write with BCH generation.
2026-04-14 20:01:08 +02:00
5 changed files with 67 additions and 34 deletions

View file

@ -204,7 +204,7 @@ void parse_command(const uint8_t *s, uint8_t n)
case 'B':
if (cmd_flag('@'))
pipe.valid = 0;
r = pipe.valid;
r = pipe.valid | flash_current_block() << 5;
if (have_b) {
if (bflg && cmd_flag('!') || ~r & bflg) {
memcpy(bptr, cmd_buffer, 16);
@ -228,7 +228,6 @@ void parse_command(const uint8_t *s, uint8_t n)
if (~r & bflg)
goto error;
pipe.valid = r &=~ bflg;
r |= pipe.status << 4;
goto send_buffer;
}
break;
@ -257,7 +256,7 @@ void parse_command(const uint8_t *s, uint8_t n)
flash_poll(1);
if (cmd_flag('!'))
pipe_poll();
r = pipe.status;
r = pipe.status | flash_current_block();
break;
#ifdef HAVE_FPGA
case 'O':

View file

@ -169,6 +169,11 @@ class dose_cmd(uart.uart):
r += dd[4:4+nn]
return r
def read_version(self, a="version_str", s=None):
r = read_mem(a, s)
print(r.decode())
return r
_adc_conf = None
_sigrow = None
@ -564,7 +569,7 @@ class dose_cmd(uart.uart):
def pipe(self, source=None, dest=None,
fpga_cmd=4, psize=0, n=0,
page=0, npages=0,
poll=True, stop=False):
poll=True, stop=False, parity=None):
astatus = flags2int(self.PIPE, dest)
astatus |= flags2int(self.PIPE, source)
astatus >>= 8
@ -599,16 +604,19 @@ class dose_cmd(uart.uart):
if not npages:
npages = 1
if parity == "pipe":
status |= 0x30 # PS_BCH
if source & self.PIPE["FLASH"]:
source = self.PIPE["FLASH"]
flash |= 4
status |= 0x30 # PS_528 | PS_BCH
status |= 0x10 # PS_528
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
status |= 0x10 # PS_528
if source == self.PIPE["FPGA"] and not n:
n = (512*npages + psize - 1) // psize
@ -689,7 +697,7 @@ class dose_cmd(uart.uart):
f.close()
return result
def write_pipe(self, data=[], timeout=2, n=None, parity=False, bfill=b'\0', pfill=b'\xff'):
def write_pipe(self, data=[], timeout=2, n=None, parity="pipe", bfill=b'\0', pfill=b'\xff'):
if isinstance(data, str):
f = open(data, "rb")
data = []
@ -700,6 +708,16 @@ class dose_cmd(uart.uart):
i = 0
t = time.time()
s = 1/256
# parity="cmd":
# calculate the parity with the 'B%' command
# parity="data":
# calculate the parity with python, or take it from array `data[]`
# parity="pipe":
# calculate the parity in `pipe_poll()`
# !parity:
# Do not care about parity (same as "pipe")
while True:
if f:
page = f.read(512)
@ -718,13 +736,14 @@ class dose_cmd(uart.uart):
page += (64-j)*bfill
if pfill:
page = (page + 512*pfill)[:512]
if len(page)==512 and parity:
if len(page)==512 and parity == "data":
page += bch.page_parity(page)
page = [page[j:j+64] for j in range(0,len(page),64)]
for b in range(8):
while True:
cc, nn, dd = self.cmd("B")
tt = time.time()
bb = nn>>5
nn &= 0xf
if not nn:
t = tt
@ -740,12 +759,23 @@ class dose_cmd(uart.uart):
s = 1
if nn:
break
if parity and b==7:
self.cmd("B@4", page[8])
if bb != b:
raise ValueError(f"block number mismatch {b=} != {bb=}")
if b >= len(page):
break
if parity == "data" and b==7:
self.cmd("B4@", page[8])
for j in range(4):
self.cmd(f"B{j}", page[b][16*j:16*(j+1)])
B = f"B{j}"
if parity == "cmd":
B += "%"
if not b and not j:
B += "@"
if b==7 and j==3:
B += "!"
ccc,nnn,ddd = self.cmd(B, page[b][16*j:16*(j+1)])
if self._verbose >= 3:
print(f"write_pipe {i=} {b=} {j=} {B=} {nn=}, {ccc=}, {nnn=:#02x}", file=sys.stderr)
if self._verbose >= 2:
self.peek("pipe", 11)
i += 1
@ -774,6 +804,12 @@ class dose_cmd(uart.uart):
raise bch.BCHError("galois module not loaded for Parity Error correction")
return True
def write_file2flash(self, filename, page, npages=None, parity="pipe"):
if npages is None:
npages = (os.stat(filename).st_size + 511) // 512
self.pipe("CMD", "FLASH", page=page, npages=npages, parity=parity)
return self.write_pipe(filename, parity=parity)
def flags2int(FLAGS, flags):
r = 0
if flags is None:

View file

@ -253,9 +253,11 @@ uint8_t flash_poll(uint8_t rr)
if (r & FS_Ready)
goto ready;
if (r & FS_StBsy && flash_status_bytes[0] & 0x80)
if (r & FS_StBsy && flash_status_bytes[0] & 0x80) {
// flash is done burning
fs.block &= ~7;
goto ready;
}
if (r & FS_Write && fs.block == 9) {
// Write or Erase
r |= FS_StBsy;

View file

@ -69,43 +69,43 @@ uint8_t pipe_poll()
// flash did not finish yet, successfully
goto done;
// fpga is OUT when the spi is ready.
// We are done with this buffer
r &=~ PS_OUT;
// Return if next ADC reading is not yet due.
// Come back here, until is is.
if (pipe.source == pipe_adc && !adc_poll(pipe.adc))
goto done;
// fpga is OUT when the spi is ready.
// We are done with this buffer
r &=~ PS_OUT;
// Continue the flash stream.
// PS_BLK is the 64-Bytes buffer number in the page
valid = 0;
if (pipe.source == pipe_flash) {
r &= ~ PS_BLK;
r |= flash_current_block() & PS_BLK;
if (pipe.source == pipe_flash)
flash_poll(1);
}
#ifdef HAVE_FPGA
// Continue the FPGA stream.
else if (pipe.source == pipe_fpga) {
if (!fpga_start_read())
pipe.source = 0;
}
else if (pipe.source == pipe_fpga && !fpga_start_read())
pipe.source = 0;
#endif
goto done;
}
// Waiting for the buffer to fill
// The current block index in the flash page
uint8_t b = flash_current_block();
if (pipe.source == pipe_flash)
// The valid data is from the previous block
b -= 1;
b &= 7;
uint8_t bflgs = 0x0f;
// For 528 bytes pages, the last buffer must be 80 Bytes,
// i.e., five cmd_buffers á 16 Bytes
uint8_t bflgs = 0x0f;
if ((r & PS_5) == PS_5)
if (b==7 && r & PS_528)
bflgs = 0x1f;
// Data from the ADC is in named .bss segments. We send
@ -174,12 +174,12 @@ adc_done:
// The buffer shall include BCH Bytes.
if (r & PS_BCH) {
// First buffer of a page, clear the parity
if (!(r & PS_BLK))
if (!b)
bch4369_init(config.bch_salt);
// Add the current buffer to the parity
uint8_t *bend = bch4369_stri(flash_buffer, 64);
// Last buffer of the page:
if (!(~r & PS_BLK)) {
if (b==7) {
bch4369_fini();
// When the Flash is not the source,
// and cmd did not provide the parity
@ -210,8 +210,6 @@ adc_done:
#endif
// Resume the flash stream
if (dest & pipe_flash) {
r &= ~ PS_BLK;
r |= flash_current_block() & PS_BLK;
flash_poll(1);
if (flash_stream_done())
dest &=~ pipe_flash;

View file

@ -11,8 +11,6 @@ enum pipe_ports {
PS_ERR = 0x40,
PS_BCH = 0x20,
PS_528 = 0x10,
PS_BLK = 0x07,
PS_5 = PS_BLK | PS_528, // need 16 bytes more
AS_CONT = 1,
AS_CONFIG = SPI_CONFIG, // = 2