Compare commits
6 commits
c348b6a271
...
55f5008540
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55f5008540 | ||
|
|
2575504fce | ||
|
|
1f18bebdd9 | ||
|
|
5bf152eab7 | ||
|
|
68e5849e2a | ||
|
|
190f8741d4 |
6 changed files with 127 additions and 21 deletions
|
|
@ -261,7 +261,7 @@ void parse_command(const uint8_t *s, uint8_t n)
|
|||
break;
|
||||
#ifdef HAVE_FPGA
|
||||
case 'O':
|
||||
r = fpga_power();
|
||||
r = fpga_status();
|
||||
if (bflg & 1)
|
||||
// "O1" power off
|
||||
fpga_power_off();
|
||||
|
|
|
|||
121
src/dose.py
121
src/dose.py
|
|
@ -1,6 +1,6 @@
|
|||
#! /usr/bin/ipython3 --profile=thhor
|
||||
|
||||
import sys, time, getopt, fileinput, struct
|
||||
import sys, os, time, getopt, fileinput, struct
|
||||
import uart
|
||||
from base85 import base85_encode, base85_decode
|
||||
from map import memmap
|
||||
|
|
@ -383,18 +383,21 @@ class dose_cmd(uart.uart):
|
|||
self.cmd(c, page[16*i:16*(i+1)])
|
||||
return self.cmd("B4<!")
|
||||
|
||||
FPGA_STAT = {
|
||||
"POWER": 1,
|
||||
"nCONFIG": 0x40,
|
||||
"nSTATUS": 0x10,
|
||||
"CRCERR": 0x20,
|
||||
}
|
||||
|
||||
def power(self, on=None):
|
||||
if on==True:
|
||||
c = 'O1'
|
||||
elif on==False:
|
||||
c = 'O0'
|
||||
elif on is None:
|
||||
if on is None:
|
||||
c = 'O'
|
||||
else:
|
||||
raise ValueError(f".power expects True or False, got {on!r}")
|
||||
c = f'O{on:d}'
|
||||
r = self.cmd(c)
|
||||
print(f"Power was {("off", "ON")[r[1]]}", file=sys.stderr)
|
||||
return r
|
||||
print(f"Power was {("off", "ON")[r[1]&1]}", file=sys.stderr)
|
||||
return int2flags(self.FPGA_STAT, r[1])
|
||||
|
||||
def fpga_reset(self):
|
||||
return self.cmd("C@")
|
||||
|
|
@ -427,7 +430,7 @@ class dose_cmd(uart.uart):
|
|||
print(f"FPGA cmd status {s!r}", file=sys.stderr)
|
||||
return d
|
||||
|
||||
def fpga_config(self, filename="../fpga/quartus/thhor_crs.rbf"):
|
||||
def fpga_config_c(self, filename="../fpga/quartus/thhor_crs.rbf"):
|
||||
self.fpga_reset()
|
||||
n = 0
|
||||
nn = 0
|
||||
|
|
@ -559,7 +562,7 @@ class dose_cmd(uart.uart):
|
|||
}
|
||||
|
||||
def pipe(self, source=None, dest=None,
|
||||
fpga_cmd=4, psize=64, n=0,
|
||||
fpga_cmd=4, psize=0, n=0,
|
||||
page=0, npages=0,
|
||||
poll=True, stop=False):
|
||||
astatus = flags2int(self.PIPE, dest)
|
||||
|
|
@ -580,6 +583,22 @@ class dose_cmd(uart.uart):
|
|||
if poll:
|
||||
c += '!'
|
||||
|
||||
if n and not psize:
|
||||
if dest & self.PIPE["FPGA"]:
|
||||
psize = (n % 64) & 0xfe
|
||||
n //= 64
|
||||
else:
|
||||
psize = 64
|
||||
|
||||
if n and not npages:
|
||||
if dest & self.PIPE["FPGA"]:
|
||||
npages = (n*64 + psize + 511)//512
|
||||
else:
|
||||
npages = (n*psize + 511)//512
|
||||
|
||||
if not npages:
|
||||
npages = 1
|
||||
|
||||
if source & self.PIPE["FLASH"]:
|
||||
source = self.PIPE["FLASH"]
|
||||
flash |= 4
|
||||
|
|
@ -591,11 +610,11 @@ class dose_cmd(uart.uart):
|
|||
flash |= 8
|
||||
status |= 0x30 # PS_528 | PS_BCH
|
||||
if source == self.PIPE["FPGA"] and not n:
|
||||
n = (512*npages+psize-1) // psize
|
||||
n = (512*npages + psize - 1) // psize
|
||||
|
||||
d = struct.pack("<6BH3B2HB",
|
||||
source, dest, status, 0, 0,
|
||||
astatus, n, psize, 0, 0,
|
||||
astatus, n, psize//2, 0, 0,
|
||||
page, npages-1, flash)
|
||||
return self.cmd(c, d)
|
||||
|
||||
|
|
@ -670,6 +689,82 @@ 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'):
|
||||
if isinstance(data, str):
|
||||
f = open(data, "rb")
|
||||
data = []
|
||||
else:
|
||||
f = None
|
||||
if not isinstance(data, list):
|
||||
data = [data]
|
||||
i = 0
|
||||
t = time.time()
|
||||
s = 1/256
|
||||
while True:
|
||||
if f:
|
||||
page = f.read(512)
|
||||
elif data:
|
||||
page = data[0]
|
||||
data[0:1] = []
|
||||
else:
|
||||
page = None
|
||||
if not page:
|
||||
break
|
||||
if len(page) < 512:
|
||||
j = len(page) % 64
|
||||
if self._verbose:
|
||||
print(f"short page {len(page)} bytes", file=sys.stderr)
|
||||
if j and bfill:
|
||||
page += (64-j)*bfill
|
||||
if pfill:
|
||||
page = (page + 512*pfill)[:512]
|
||||
if len(page)==512 and parity:
|
||||
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()
|
||||
nn &= 0xf
|
||||
if not nn:
|
||||
t = tt
|
||||
s = 1/256
|
||||
break
|
||||
if tt > t+timeout:
|
||||
if self._verbose:
|
||||
print(f"write_pipe timeout {i=} {b=}", file=sys.stderr)
|
||||
break
|
||||
time.sleep(s)
|
||||
s *= 2
|
||||
if s > 1:
|
||||
s = 1
|
||||
if nn:
|
||||
break
|
||||
if parity and b==7:
|
||||
self.cmd("B@4", page[8])
|
||||
if b >= len(page):
|
||||
break
|
||||
for j in range(4):
|
||||
self.cmd(f"B{j}", page[b][16*j:16*(j+1)])
|
||||
if self._verbose >= 2:
|
||||
self.peek("pipe", 11)
|
||||
i += 1
|
||||
if n and i >= n:
|
||||
break
|
||||
if n and i >= n:
|
||||
break
|
||||
if nn:
|
||||
break
|
||||
if f:
|
||||
f.close()
|
||||
return i
|
||||
|
||||
def fpga_config_p(self, filename="../fpga/quartus/thhor_crs.rbf"):
|
||||
self.fpga_reset()
|
||||
n = (os.stat(filename).st_size + 63) // 64
|
||||
self.pipe("CMD", "CONFIG", n=n*64)
|
||||
self.write_pipe(filename, n=n)
|
||||
|
||||
def fix_page(self, page):
|
||||
if self.load_galois():
|
||||
page = bch.fix_page(page)
|
||||
|
|
|
|||
10
src/fpga.c
10
src/fpga.c
|
|
@ -30,7 +30,7 @@ void fpga_reset()
|
|||
nCONFIG_VPORT.OUT &=~ (1<<nCONFIG_PIN);
|
||||
uint8_t n = 10;
|
||||
// nSTATUS will go low within 500ns
|
||||
while (n-- && ~fpga_reset_poll());
|
||||
while (!fpga_reset_poll() && --n);
|
||||
}
|
||||
|
||||
void fpga_cmd(struct fpga_cmd *c)
|
||||
|
|
@ -74,7 +74,12 @@ struct pipe_fpga_cmd pipe_fpga_cmd;
|
|||
|
||||
uint8_t fpga_start_write()
|
||||
{
|
||||
uint8_t s = fpga_status();
|
||||
uint8_t mode = pipe.fpga.status & SPI_CONFIG;
|
||||
if (!mode && s != as_configured)
|
||||
return 0;
|
||||
if (~s & as_rconfig)
|
||||
return 0;
|
||||
spi_select(mode);
|
||||
spi.wdata = flash_buffer;
|
||||
uint8_t n = 32;
|
||||
|
|
@ -163,6 +168,7 @@ uint8_t fpga_pipe_ready()
|
|||
const struct pipe pipe_config_fpga_config = {
|
||||
.source = pipe_flash,
|
||||
.dest = pipe_fpga,
|
||||
.status = PS_BCH | PS_528,
|
||||
.fpga = {
|
||||
.status = AS_CONFIG,
|
||||
},
|
||||
|
|
@ -173,5 +179,5 @@ void fpga_config(uint16_t page, uint16_t count)
|
|||
fpga_reset();
|
||||
pipe = pipe_config_fpga_config;
|
||||
pipe.fpga.count = count;
|
||||
flash_start_stream(page, count>>8, FS_Read|FS_528);
|
||||
flash_start_stream(page, count >> 3, FS_Read|FS_528);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,11 @@ void fpga_config(uint16_t page, uint16_t count);
|
|||
|
||||
static inline uint8_t fpga_power() { return !!(PEN_VPORT.IN & (1<<PEN_PIN)); }
|
||||
static inline void fpga_power_on() { PEN_VPORT.OUT |= 1<<PEN_PIN; }
|
||||
static inline void fpga_power_off() { PEN_VPORT.OUT &=~ (1<<PEN_PIN); }
|
||||
static inline void fpga_power_off()
|
||||
{
|
||||
nCONFIG_VPORT.OUT &=~ (1<<nCONFIG_PIN);
|
||||
PEN_VPORT.OUT &=~ (1<<PEN_PIN);
|
||||
}
|
||||
|
||||
enum fpga_status_values {
|
||||
as_off = 0,
|
||||
|
|
@ -35,6 +39,7 @@ enum fpga_status_values {
|
|||
as_reset = as_on | 1<<CRCERR_PIN,
|
||||
as_configured = as_on | 1<<nCONFIG_PIN | 1<<nSTATUS_PIN,
|
||||
as_crcerror = as_configured | 1<<CRCERR_PIN,
|
||||
as_rconfig = as_on | 1<<nCONFIG_PIN | 1<<nSTATUS_PIN,
|
||||
};
|
||||
|
||||
uint8_t fpga_status();
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ uint8_t pipe_poll()
|
|||
if (pipe_busy() || !dest)
|
||||
return r;
|
||||
#ifdef HAVE_FPGA
|
||||
// we need to wait at least until the FPGA raises nCONFIG
|
||||
// we need to wait at least until the FPGA raises nSTATUS
|
||||
if (dest & pipe_fpga && fpga_reset_poll())
|
||||
return r;
|
||||
#endif
|
||||
|
|
@ -93,7 +93,7 @@ uint8_t pipe_poll()
|
|||
// Continue the FPGA stream.
|
||||
|
||||
else if (pipe.source == pipe_fpga) {
|
||||
if (~fpga_start_read())
|
||||
if (!fpga_start_read())
|
||||
pipe.source = 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -204,7 +204,7 @@ adc_done:
|
|||
|
||||
#ifdef HAVE_FPGA
|
||||
// Resume the FPGA stream
|
||||
if (dest & pipe_fpga && ~fpga_start_write())
|
||||
if (dest & pipe_fpga && !fpga_start_write())
|
||||
dest &=~ pipe_fpga;
|
||||
else
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ uint8_t spi_poll_delay()
|
|||
uint8_t ifg;
|
||||
do {
|
||||
ifg = SPI.INTFLAGS & SPI_RXCIF_bm;
|
||||
} while (~ifg && t--);
|
||||
} while (!ifg && t--);
|
||||
return ifg;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue