diff --git a/src/cmd.c b/src/cmd.c index 01204ed..7efaed5 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -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': diff --git a/src/dose.py b/src/dose.py index 2707e61..f5f1c92 100755 --- a/src/dose.py +++ b/src/dose.py @@ -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: diff --git a/src/flash.c b/src/flash.c index d52ca11..ffa85b6 100644 --- a/src/flash.c +++ b/src/flash.c @@ -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; diff --git a/src/pipe.c b/src/pipe.c index e89cac9..0429f97 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -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; diff --git a/src/pipe.h b/src/pipe.h index 9d9c3f7..11519cf 100644 --- a/src/pipe.h +++ b/src/pipe.h @@ -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