gw info: Report HW Submodel and USB transfer speed

This commit is contained in:
Keir Fraser
2020-05-21 08:32:49 +01:00
parent adff44c183
commit 08ae2cb6c8
10 changed files with 61 additions and 36 deletions

View File

@@ -110,8 +110,10 @@ struct packed gw_info {
uint8_t max_index;
uint8_t max_cmd;
uint32_t sample_freq;
uint16_t hw_type;
uint8_t hw_model, hw_submodel;
uint8_t usb_speed;
};
extern struct gw_info gw_info;
/* CMD_GET_INFO, index 1 */
#define GETINFO_BW_STATS 1

View File

@@ -15,6 +15,12 @@ from greaseweazle.tools import util
from greaseweazle import usb as USB
from greaseweazle import version
submodel_id = { 1: { 0: 'Basic USB-FS' },
7: { 0: 'Basic USB-FS' } }
speed_id = { 0: 'Full Speed (12 Mbit/s)',
1: 'High Speed (480 Mbit/s)' }
def print_info_line(name, value, tab=0):
print(''.ljust(tab) + (name + ':').ljust(12-tab) + value)
@@ -38,15 +44,31 @@ def main(argv):
sys.exit(0)
port = usb.port_info
if port.device:
print_info_line('Device', port.device, tab=2)
print_info_line('Model', 'F%d' % usb.hw_type, tab=2)
try:
submodel = submodel_id[usb.hw_model][usb.hw_submodel]
except KeyError:
submodel = 'Unknown'
submodel = '%02X (%s)' % (usb.hw_submodel, submodel)
print_info_line('Model', 'F%d' % usb.hw_model, tab=2)
print_info_line('Submodel', submodel, tab=2)
fwver = 'v%d.%d' % (usb.major, usb.minor)
if usb.update_mode:
fwver += ' (Update Bootloader)'
print_info_line('Firmware', fwver, tab=2)
if port.serial_number:
print_info_line('Serial', port.serial_number, tab=2)
print_info_line('Serial', port.serial_number if port.serial_number
else 'Unknown', tab=2)
try:
speed = speed_id[usb.usb_speed]
except KeyError:
speed = 'Unknown (0x%02X)' % usb.usb_speed
print_info_line('USB Rate', speed, tab=2)
if __name__ == "__main__":

View File

@@ -38,9 +38,9 @@ def update_firmware(usb, args):
# Search the catalogue for a match on our Weazle's hardware type.
while dat:
upd_len, hw_type = struct.unpack("<2H", dat[:4])
upd_len, hw_model = struct.unpack("<2H", dat[:4])
upd_type, = struct.unpack("2s", dat[upd_len-4:upd_len-2])
if hw_type == usb.hw_type and upd_type == req_type:
if hw_model == usb.hw_model and upd_type == req_type:
# Match: Pull out the embedded update file.
dat = dat[4:upd_len+4]
break
@@ -48,12 +48,12 @@ def update_firmware(usb, args):
dat = dat[upd_len+4:]
if not dat:
print("%s: No match for hardware type %x" % (filename, usb.hw_type))
print("%s: No match for hardware type %x" % (filename, usb.hw_model))
return
# Check the matching update file's footer.
sig, maj, min, hw_type = struct.unpack("<2s2BH", dat[-8:-2])
if len(dat) & 3 != 0 or sig != req_type or hw_type != usb.hw_type:
sig, maj, min, hw_model = struct.unpack("<2s2BH", dat[-8:-2])
if len(dat) & 3 != 0 or sig != req_type or hw_model != usb.hw_model:
print("%s: Bad update file" % (filename))
return
crc16 = crcmod.predefined.Crc('crc-ccitt-false')
@@ -80,7 +80,7 @@ def update_firmware(usb, args):
return
print("Done.")
if usb.hw_type == 7:
if usb.hw_model == 7:
util.usb_reopen(usb, is_update=False)
else:
print("** Disconnect Greaseweazle and remove the Programming Jumper.")

View File

@@ -152,11 +152,11 @@ def usb_open(devicename, is_update=False, mode_check=True):
print("** %s v%u.%u [F%u], Host Tools v%u.%u"
% (("Greaseweazle", "Bootloader")[usb.update_mode],
usb.major, usb.minor, usb.hw_type,
usb.major, usb.minor, usb.hw_model,
version.major, version.minor))
if usb.update_mode and not is_update:
if usb.hw_type == 7 and not usb.update_jumpered:
if usb.hw_model == 7 and not usb.update_jumpered:
usb = usb_reopen(usb, is_update)
if not usb.update_mode:
return usb
@@ -169,7 +169,7 @@ def usb_open(devicename, is_update=False, mode_check=True):
sys.exit(1)
if is_update and not usb.update_mode:
if usb.hw_type == 7:
if usb.hw_model == 7:
usb = usb_reopen(usb, is_update)
error.check(usb.update_mode, """\
Greaseweazle F7 did not change to Firmware Update Mode as requested.
@@ -182,7 +182,7 @@ If the problem persists, install the Update Jumper (across RX/TX).""")
if not usb.update_mode and usb.update_needed:
print("Firmware is out of date: Require v%u.%u"
% (version.major, version.minor))
if usb.hw_type == 7:
if usb.hw_model == 7:
print("Run \"update <update_file>\"")
else:
print("Install the Update Jumper and \"update <update_file>\"")

View File

@@ -137,12 +137,13 @@ class Unit:
self.reset()
# Copy firmware info to instance variables (see above for definitions).
self._send_cmd(struct.pack("3B", Cmd.GetInfo, 3, GetInfo.Firmware))
x = struct.unpack("<4BIH22x", self.ser.read(32))
x = struct.unpack("<4BI3B21x", self.ser.read(32))
(self.major, self.minor, self.max_index,
self.max_cmd, self.sample_freq, self.hw_type) = x
self.max_cmd, self.sample_freq, self.hw_model,
self.hw_submodel, self.usb_speed) = x
# Old firmware doesn't report HW type but runs on STM32F1 only.
if self.hw_type == 0:
self.hw_type = 1
if self.hw_model == 0:
self.hw_model = 1
# Check whether firmware is in update mode: limited command set if so.
self.update_mode = (self.max_index == 0)
if self.update_mode:

View File

@@ -1,17 +1,17 @@
# mk_update.py <bootloader> <main_firmware> <output> <stm_type>
# mk_update.py <bootloader> <main_firmware> <output> <stm_model>
#
# Convert a raw firmware binary into an update file for our bootloader.
#
# Update Format (Little endian, unless otherwise stated):
# Catalogue Header:
# 2 bytes: <length> (excludes Catalogue Header)
# 2 bytes: <hw_type>
# 2 bytes: <hw_model>
# Payload:
# N bytes: <raw binary data>
# Footer:
# 2 bytes: 'GW' or 'BL'
# 2 bytes: major, minor
# 2 bytes: <hw_type>
# 2 bytes: <hw_model>
# 2 bytes: CRC16-CCITT, seed 0xFFFF (big endian, excludes Catalogue Header)
#
# Written & released by Keir Fraser <keir.xen@gmail.com>
@@ -24,14 +24,14 @@ import re, struct, sys
from greaseweazle import version
def mk_cat_entry(dat, hw_type, sig):
def mk_cat_entry(dat, hw_model, sig):
max_kb = { 1: { b'BL': 8, b'GW': 56 },
7: { b'BL': 16, b'GW': 48 } }
dlen = len(dat)
assert (dlen & 3) == 0, "input is not longword padded"
assert dlen <= max_kb[hw_type][sig]*1024, "input is too long"
header = struct.pack("<2H", dlen + 8, hw_type)
footer = struct.pack("<2s2BH", sig, version.major, version.minor, hw_type)
assert dlen <= max_kb[hw_model][sig]*1024, "input is too long"
header = struct.pack("<2H", dlen + 8, hw_model)
footer = struct.pack("<2s2BH", sig, version.major, version.minor, hw_model)
crc16 = crcmod.predefined.Crc('crc-ccitt-false')
crc16.update(dat)
crc16.update(footer)
@@ -40,11 +40,11 @@ def mk_cat_entry(dat, hw_type, sig):
def main(argv):
out_f = open(argv[3], "wb")
hw_type = int(re.match("f(\d)", argv[4]).group(1))
hw_model = int(re.match("f(\d)", argv[4]).group(1))
with open(argv[2], "rb") as gw_f:
out_f.write(mk_cat_entry(gw_f.read(), hw_type, b'GW'))
out_f.write(mk_cat_entry(gw_f.read(), hw_model, b'GW'))
with open(argv[1], "rb") as bl_f:
out_f.write(mk_cat_entry(bl_f.read(), hw_type, b'BL'))
out_f.write(mk_cat_entry(bl_f.read(), hw_model, b'BL'))
if __name__ == "__main__":
main(sys.argv)

View File

@@ -244,10 +244,10 @@ void floppy_init(void)
_set_bus_type(BUS_NONE);
}
static struct gw_info gw_info = {
struct gw_info gw_info = {
.max_index = 15, .max_cmd = CMD_MAX,
.sample_freq = 72000000u,
.hw_type = STM32F
.hw_model = STM32F
};
static void auto_off_arm(void)

View File

@@ -37,10 +37,10 @@ static uint32_t u_prod;
static bool_t upd_strapped;
static struct gw_info gw_info = {
struct gw_info gw_info = {
/* Max Index == 0 signals that this is the Bootloader. */
.max_index = 0, .max_cmd = CMD_MAX,
.hw_type = STM32F
.hw_model = STM32F
};
static void blink_init(void)

View File

@@ -9,8 +9,6 @@
* See the file COPYING for more details, or visit <http://unlicense.org>.
*/
uint8_t board_id;
#define early_delay_ms(ms) (delay_ticks((ms)*2000))
#define early_delay_us(ms) (delay_ticks((ms)*2))
@@ -69,8 +67,8 @@ static void board_id_init(void)
}
/* Panic if the ID is unrecognised. */
board_id = id;
if (board_id != 0)
gw_info.hw_submodel = id;
if (id != 0)
early_fatal(2);
}

View File

@@ -108,6 +108,8 @@ bool_t cdc_acm_set_configuration(void)
bulk_type = EPT_BULK;
#endif
gw_info.usb_speed = usb_is_highspeed() ? 1 : 0;
/* Notification Element (D->H) */
usb_configure_ep(0x81, EPT_INTERRUPT, 0);
/* Bulk Pipe (H->D) */