regnual: flash write support

This commit is contained in:
NIIBE Yutaka
2012-05-22 17:02:54 +09:00
parent 6c205c3111
commit 84e3a5c1a6
2 changed files with 138 additions and 34 deletions

View File

@@ -28,9 +28,16 @@
#include "types.h"
#include "usb_lld.h"
extern void set_led (int);
extern void *memset (void *s, int c, size_t n);
extern void set_led (int);
extern uint8_t _flash_start, _flash_end;
extern int flash_write (uint32_t dst_addr, const uint8_t *src, size_t len);
extern int flash_erase_page (uint32_t addr);
extern int flash_protect (void);
extern void nvic_system_reset (void);
#define ENDP0_RXADDR (0x40)
#define ENDP0_TXADDR (0x80)
@@ -81,24 +88,24 @@ static const uint8_t regnual_string_serial[] = {
'0', 0, '.', 0, '0', 0,
};
const struct Descriptor Device_Descriptor = {
const struct Descriptor device_desc = {
regnual_device_desc,
sizeof (regnual_device_desc)
};
const struct Descriptor Config_Descriptor = {
const struct Descriptor config_desc = {
regnual_config_desc,
sizeof (regnual_config_desc)
};
const struct Descriptor String_Descriptors[] = {
const struct Descriptor string_descs[] = {
{regnual_string_lang_id, sizeof (regnual_string_lang_id)},
{gnukStringVendor, sizeof (gnukStringVendor)},
{gnukStringProduct, sizeof (gnukStringProduct)},
{regnual_string_serial, sizeof (regnual_string_serial)},
};
#define NUM_STRING_DESC (sizeof (String_Descriptors)/sizeof (struct Descriptor))
#define NUM_STRING_DESC (sizeof (string_descs)/sizeof (struct Descriptor))
static void
regnual_device_reset (void)
@@ -107,7 +114,7 @@ regnual_device_reset (void)
usb_lld_set_configuration (0);
/* Current Feature initialization */
usb_lld_set_feature (Config_Descriptor.Descriptor[7]);
usb_lld_set_feature (config_desc.Descriptor[7]);
usb_lld_reset ();
@@ -124,7 +131,10 @@ regnual_device_reset (void)
#define USB_REGNUAL_PROTECT 5
#define USB_REGNUAL_FINISH 6
static uint8_t mem[1024];
static uint8_t mem[256];
static const uint8_t *const mem_info[] = { &_flash_start, &_flash_end, };
static void regnual_ctrl_write_finish (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index,
@@ -133,16 +143,13 @@ static void regnual_ctrl_write_finish (uint8_t req, uint8_t req_no,
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)
&& USB_SETUP_SET (req) && req_no == USB_REGNUAL_FINISH && len == 0)
&& USB_SETUP_SET (req) && len == 0)
{
(void)value; (void)index;
/* RESET MCU */
}
if (req_no == USB_REGNUAL_FINISH && value == 0 && index == 0)
nvic_system_reset ();
}
}
extern uint8_t _flash_start, _flash_end;
static const uint8_t *const mem_info[] = { &_flash_start, &_flash_end, };
static int
regnual_setup (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len)
@@ -170,21 +177,38 @@ regnual_setup (uint8_t req, uint8_t req_no,
{
if (req_no == USB_REGNUAL_SEND)
{
if (value >= 4 || value * 0x100 + index + len > 1024)
if (value != 0 || index + len > 256)
return USB_UNSUPPORT;
if (value == 0 && index == 0)
memset (mem + value * 0x100, 0xff, 1024);
usb_lld_set_data_to_recv (mem + value * 0x100 + index, len);
if (index != 0)
memset (mem, 0xff, 256);
usb_lld_set_data_to_recv (mem + index, len);
return USB_SUCCESS;
}
else if (req_no == USB_REGNUAL_FLASH && len == 0)
{
uint8_t *addr = (uint8_t *)(0x08000000 + value * 0x400);
uint32_t dst_addr = (0x08000000 + value * 0x100);
/* flash write, verify */
return USB_SUCCESS;
if (flash_write (dst_addr, mem, 256) == 0)
return USB_SUCCESS;
}
else if (req_no == USB_REGNUAL_ERASE && len == 0 && index == 0)
{
uint32_t dst_addr = (0x08000000 + value * 0x100);
if (flash_erase_page (dst_addr))
return USB_SUCCESS;
}
else if (req_no == USB_REGNUAL_PROTECT && len == 0
&& value == 0 && index == 0)
{
if (flash_protect ())
return USB_SUCCESS;
}
else if (req_no == USB_REGNUAL_FINISH && len == 0
&& value == 0 && index == 0)
return USB_SUCCESS;
}
}
@@ -197,14 +221,14 @@ regnual_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
(void)index;
if (desc_type == DEVICE_DESCRIPTOR)
{
usb_lld_set_data_to_send (Device_Descriptor.Descriptor,
Device_Descriptor.Descriptor_Size);
usb_lld_set_data_to_send (device_desc.Descriptor,
device_desc.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == CONFIG_DESCRIPTOR)
{
usb_lld_set_data_to_send (Config_Descriptor.Descriptor,
Config_Descriptor.Descriptor_Size);
usb_lld_set_data_to_send (config_desc.Descriptor,
config_desc.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == STRING_DESCRIPTOR)
@@ -213,8 +237,8 @@ regnual_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
if (desc_index < NUM_STRING_DESC)
{
usb_lld_set_data_to_send (String_Descriptors[desc_index].Descriptor,
String_Descriptors[desc_index].Descriptor_Size);
usb_lld_set_data_to_send (string_descs[desc_index].Descriptor,
string_descs[desc_index].Descriptor_Size);
return USB_SUCCESS;
}
}

View File

@@ -48,6 +48,59 @@ def iso7816_compose(ins, p1, p2, data):
else:
return pack('>BBBBB', cls, ins, p1, p2, data_len) + data
class regnual:
def __init__(self, device):
self.__devhandle = device.open()
def mem_info(self):
mem = self.__devhandle.controlMsg(requestType = 0xc0, request = 0,
value = 0, index = 0, buffer = 8,
timeout = 10000)
start = ((mem[3]*256 + mem[2])*256 + mem[1])*256 + mem[0]
end = ((mem[7]*256 + mem[6])*256 + mem[5])*256 + mem[4]
return (start, end)
def download(self, start, data):
addr = start
addr_end = (start + len(data)) & 0xffffff00
i = (addr - 0x08000000) / 0x100
j = 0
print "start %08x" % addr
print "end %08x" % addr_end
while addr < addr_end:
print "# %08x: %d: %d : %d" % (addr, i, j, 256)
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
value = 0, index = 0,
buffer = data[j*256:j*256+256],
timeout = 10000)
print "flash"
self.__devhandle.controlMsg(requestType = 0x40, request = 3,
value = i, index = 0,
buffer = None,
timeout = 10000)
i = i+1
j = j+1
addr = addr + 256
residue = len(data) % 256
if residue != 0:
print "# %08x: %d : %d" % (addr, i, residue)
print "send"
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
value = 0, index = 0,
buffer = data[j*256:],
timeout = 10000)
if (i % 4) != 0 or residue:
print "flash"
self.__devhandle.controlMsg(requestType = 0x40, request = 3,
value = i, index = 0,
buffer = None,
timeout = 10000)
def finish(self):
self.__devhandle.controlMsg(requestType = 0x40, request = 6,
value = 0, index = 0, buffer = None,
timeout = 10000)
# This class only supports Gnuk (for now)
class gnuk_token:
def __init__(self, device, configuration, interface):
@@ -80,9 +133,9 @@ class gnuk_token:
self.__timeout = 10000
self.__seq = 0
def stop_icc(self):
# XXX: need to disclaim interface and close device and re-open???
# self.__devhandle.setConfiguration(0)
def stop_gnuk(self):
self.__devhandle.releaseInterface()
self.__devhandle.setConfiguration(0)
return
def mem_info(self):
@@ -237,7 +290,7 @@ def compare(data_original, data_in_device):
raise ValueError, "verify failed at %08x" % i
i += 1
def get_device():
def get_ccid_device():
busses = usb.busses()
for bus in busses:
devices = bus.devices
@@ -251,6 +304,21 @@ def get_device():
return dev, config, alt
raise ValueError, "Device not found"
USB_VENDOR_FSIJ=0x234b
USB_PRODUCT_GNUK=0x0000
def get_gnuk_device():
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
if dev.idVendor != USB_VENDOR_FSIJ:
continue
if dev.idProduct != USB_PRODUCT_GNUK:
continue
return dev
raise ValueError, "Device not found"
def to_string(t):
result = ""
for c in t:
@@ -260,7 +328,7 @@ def to_string(t):
def main(passwd, data_regnual, data_upgrade):
data_regnual += pack('<i', binascii.crc32(data_regnual))
dev, config, intf = get_device()
dev, config, intf = get_ccid_device()
print "Device: ", dev.filename
print "Configuration: ", config.value
print "Interface: ", intf.interfaceNumber
@@ -274,15 +342,27 @@ def main(passwd, data_regnual, data_upgrade):
challenge = icc.cmd_get_challenge()
signed = to_string(challenge)
icc.cmd_external_authenticate(signed)
icc.stop_icc() # disable all interfaces but control pipe
icc.stop_gnuk()
mem_info = icc.mem_info()
print "%08x:%08x" % mem_info
print "Downloading flash upgrade program..."
icc.download(mem_info[0], data_regnual)
print "Run flash upgrade program..."
icc.execute(mem_info[1] + len(data_regnual))
del icc
icc = None
#
print "Wait 3 seconds..."
time.sleep(3)
# Then, send upgrade program...
print "NOT YET: Downloading the program"
dev = get_gnuk_device()
print "Device: ", dev.filename
reg = regnual(dev)
mem_info = reg.mem_info()
print "%08x:%08x" % mem_info
print "Downloading the program"
reg.download(mem_info[0]+0x3000, data_upgrade)
reg.finish()
return 0
DEFAULT_PW3 = "12345678"