Implement debugging over CDC

This commit is contained in:
iabdalkader 2015-02-08 11:12:24 +02:00
parent 62a213522d
commit 754cce406c
6 changed files with 151 additions and 154 deletions

@ -1 +1 @@
Subproject commit 077eefd22d8e8e2db2fb49617a66820a936a1533
Subproject commit 640d2e639f2c94b40762c1b8314fef91ab0756ff

View File

@ -24,6 +24,10 @@ static vstr_t script;
static int script_ready=0;
mp_obj_t mp_const_ide_interrupt = MP_OBJ_NULL;
extern void usbd_cdc_tx_buf_flush();
extern uint32_t usbd_cdc_tx_buf_len();
extern uint8_t *usbd_cdc_tx_buf(uint32_t bytes);
void usbdbg_init()
{
vstr_init(&script, 64);
@ -51,6 +55,22 @@ void usbdbg_clr_script()
void usbdbg_data_in(void *buffer, int length)
{
switch (cmd) {
case USBDBG_TX_BUF_LEN: {
uint32_t tx_buf_len = usbd_cdc_tx_buf_len();
memcpy(buffer, &tx_buf_len, length);
cmd = USBDBG_NONE;
break;
}
case USBDBG_TX_BUF: {
uint8_t *tx_buf = usbd_cdc_tx_buf(length);
memcpy(buffer, tx_buf, length);
if (xfer_bytes == xfer_length) {
cmd = USBDBG_NONE;
}
break;
}
case USBDBG_FRAME_SIZE:
memcpy(buffer, fb, length);
cmd = USBDBG_NONE;
@ -102,10 +122,22 @@ void usbdbg_data_out(void *buffer, int length)
break;
case USBDBG_TEMPLATE_SAVE: {
int res;
image_t image;
image.w = fb->w; image.h = fb->h; image.bpp = fb->bpp; image.pixels = fb->pixels;
if ((res=imlib_save_image(&image, "1:/template.pgm", (rectangle_t*)buffer)) != FR_OK) {
image_t image ={
.w = fb->w,
.h = fb->h,
.bpp = fb->bpp,
.pixels = fb->pixels
};
// null terminate the path
length = (length == 64) ? 63:length;
((char*)buffer)[length] = 0;
rectangle_t *roi = (rectangle_t*)buffer;
char *path = (char*)buffer+sizeof(rectangle_t);
int res=imlib_save_image(&image, path, roi);
if (res != FR_OK) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res)));
}
// raise a flash IRQ to flush image
@ -114,9 +146,21 @@ void usbdbg_data_out(void *buffer, int length)
}
case USBDBG_DESCRIPTOR_SAVE: {
image_t image;
image.w = fb->w; image.h = fb->h; image.bpp = fb->bpp; image.pixels = fb->pixels;
py_image_descriptor_from_roi(&image, "1:/desc.freak", (rectangle_t*)buffer);
image_t image ={
.w = fb->w,
.h = fb->h,
.bpp = fb->bpp,
.pixels = fb->pixels
};
// null terminate the path
length = (length == 64) ? 63:length;
((char*)buffer)[length] = 0;
rectangle_t *roi = (rectangle_t*)buffer;
char *path = (char*)buffer+sizeof(rectangle_t);
py_image_descriptor_from_roi(&image, path, roi);
break;
}
default: /* error */
@ -124,7 +168,7 @@ void usbdbg_data_out(void *buffer, int length)
}
}
void usbdbg_control(void *buffer, uint8_t request, uint16_t length)
void usbdbg_control(void *buffer, uint8_t request, uint32_t length)
{
cmd = (enum usbdbg_cmd) request;
switch (cmd) {
@ -135,7 +179,7 @@ void usbdbg_control(void *buffer, uint8_t request, uint16_t length)
case USBDBG_FRAME_DUMP:
xfer_bytes = 0;
xfer_length =((uint32_t)length)<<2;
xfer_length = length;
break;
case USBDBG_FRAME_LOCK:
@ -175,8 +219,8 @@ void usbdbg_control(void *buffer, uint8_t request, uint16_t length)
case USBDBG_ATTR_WRITE: {
/* write sensor attribute */
int val = (int8_t)(length&0xff);
int attr= length>>8;
int16_t attr= *((int16_t*)buffer);
int16_t val = *((int16_t*)buffer+1);
switch (attr) {
case ATTR_CONTRAST:
sensor_set_contrast(val);
@ -206,6 +250,12 @@ void usbdbg_control(void *buffer, uint8_t request, uint16_t length)
NVIC_SystemReset();
break;
case USBDBG_TX_BUF:
case USBDBG_TX_BUF_LEN:
xfer_bytes = 0;
xfer_length = length;
break;
default: /* error */
cmd = USBDBG_NONE;
break;

View File

@ -10,19 +10,21 @@
#define __USBDBG_H__
enum usbdbg_cmd {
USBDBG_NONE=0,
USBDBG_FRAME_SIZE,
USBDBG_FRAME_DUMP,
USBDBG_FRAME_LOCK,
USBDBG_FRAME_UPDATE,
USBDBG_SCRIPT_EXEC,
USBDBG_SCRIPT_STOP,
USBDBG_SCRIPT_SAVE,
USBDBG_TEMPLATE_SAVE,
USBDBG_DESCRIPTOR_SAVE,
USBDBG_ATTR_READ,
USBDBG_ATTR_WRITE,
USBDBG_SYS_RESET,
USBDBG_BOOT
USBDBG_FRAME_SIZE =0x81,
USBDBG_FRAME_DUMP =0x82,
USBDBG_FRAME_LOCK =0x83,
USBDBG_FRAME_UPDATE =0x04,
USBDBG_SCRIPT_EXEC =0x05,
USBDBG_SCRIPT_STOP =0x06,
USBDBG_SCRIPT_SAVE =0x07,
USBDBG_TEMPLATE_SAVE =0x08,
USBDBG_DESCRIPTOR_SAVE =0x09,
USBDBG_ATTR_READ =0x8A,
USBDBG_ATTR_WRITE =0x0B,
USBDBG_SYS_RESET =0x0C,
USBDBG_BOOT =0x0D,
USBDBG_TX_BUF_LEN =0x8E,
USBDBG_TX_BUF =0x8F
};
void usbdbg_init();
int usbdbg_script_ready();

View File

@ -412,7 +412,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
<property name="text" translatable="yes">desc.freak</property>
<property name="text" translatable="yes">/desc.freak</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
@ -504,7 +504,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
<property name="text" translatable="yes">template.pgm</property>
<property name="text" translatable="yes">/template.pgm</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>

View File

@ -206,48 +206,31 @@ class OMVGtk:
sleep(wait)
def connect(self):
init = False
for i in range(0, 5):
# init openmv
init = openmv.init()
if init:
break
sleep(0.200)
if init == False:
self.show_message_dialog(gtk.MESSAGE_ERROR, "Failed to connect to OpenMV")
return
# interrupt any running code
openmv.stop_script()
try:
# open VCP and configure the terminal
self.serial = serial.Serial(self.config.get("main", "serial_port"), 115200, timeout=0.001)
self.serial = serial.Serial(self.config.get("main", "serial_port"), 115200, timeout=0.1)
gobject.gobject.idle_add(omvgtk.update_terminal)
except Exception as e:
self.show_message_dialog(gtk.MESSAGE_ERROR, "Failed to open serial port (check prefernces)\n%s"%e)
return
openmv.init(self.serial)
# interrupt any running code
openmv.stop_script()
self.connected = True
self._update_title()
self.connect_button.set_sensitive(False)
map(lambda x:x.set_sensitive(True), self.controls)
def disconnect(self):
#reset terminal
#self.terminal.set_pty(-1)
#self.terminal.reset(True, True)
try:
# stop running code
openmv.stop_script();
except:
pass
# release OpenMV
openmv.release()
self.serial.close()
self.connected = False
self._update_title()
self.connect_button.set_sensitive(True)
@ -438,12 +421,14 @@ class OMVGtk:
adj.set_value(adj.upper - adj.page_size)
def update_terminal(self):
if (self.serial.readable()):
buffer = self.terminal.get_buffer()
try:
buffer.insert(buffer.get_end_iter(), self.serial.readline())
except:
return False
buf_len = openmv.tx_buf_len()
buf = openmv.tx_buf(buf_len)
buffer = self.terminal.get_buffer()
try:
buffer.insert(buffer.get_end_iter(), buf)
except:
return False
return True
def update_drawing(self):

View File

@ -7,96 +7,55 @@
import struct
import sys,time
import usb.core
import usb.util
import serial
import pydfu
import platform
from array import array
from PIL import Image
__dev = None
__serial = None
# VID/PID
__VID=0xf055
__PID=0x9800
# Debug __INTERFACE
__INTERFACE =3
__IN_EP =0x81
__OUT_EP =0x01
__TIMEOUT =3000
__FB_HDR_SIZE =12
# USB Debug commands
__USBDBG_FRAME_SIZE =1
__USBDBG_FRAME_DUMP =2
__USBDBG_FRAME_LOCK =3
__USBDBG_FRAME_UPDATE =4
__USBDBG_SCRIPT_EXEC =5
__USBDBG_SCRIPT_STOP =6
__USBDBG_SCRIPT_SAVE =7
__USBDBG_TEMPLATE_SAVE =8
__USBDBG_DESCRIPTOR_SAVE=9
__USBDBG_ATTR_READ =10
__USBDBG_ATTR_WRITE =11
__USBDBG_SYS_RESET =12
__USBDBG_SYS_BOOT =13
__USBDBG_CMD = 48
__USBDBG_FRAME_SIZE = 0x81
__USBDBG_FRAME_DUMP = 0x82
__USBDBG_FRAME_LOCK = 0x83
__USBDBG_FRAME_UPDATE = 0x04
__USBDBG_SCRIPT_EXEC = 0x05
__USBDBG_SCRIPT_STOP = 0x06
__USBDBG_SCRIPT_SAVE = 0x07
__USBDBG_TEMPLATE_SAVE = 0x08
__USBDBG_DESCRIPTOR_SAVE= 0x09
__USBDBG_ATTR_READ = 0x8A
__USBDBG_ATTR_WRITE = 0x0B
__USBDBG_SYS_RESET = 0x0C
__USBDBG_SYS_BOOT = 0x0D
__USBDBG_TX_BUF_LEN = 0x8E
__USBDBG_TX_BUF = 0x8F
ATTR_CONTRAST =0
ATTR_BRIGHTNESS =1
ATTR_SATURATION =2
ATTR_GAINCEILING=3
def init():
global __dev
# find USB device
__dev = usb.core.find(idVendor=__VID, idProduct=__PID)
if __dev is None:
return False
try:
# This will soft-disconnect the device.
__dev.ctrl_transfer(0x41, 0xFF, 2, __INTERFACE, None, __TIMEOUT)
except:
pass
__dev = usb.core.find(idVendor=__VID, idProduct=__PID)
if __dev is None:
return False
try:
# claim the debug interface
usb.util.claim_interface(__dev, __INTERFACE)
except:
return False
def release():
try:
# release the debug interface
usb.util.release_interface(__dev, __INTERFACE)
# This will soft-disconnect the device.
__dev.ctrl_transfer(0x41, 0xFF, 1, __INTERFACE, None, __TIMEOUT)
# release device
usb.util.dispose_resources(__dev)
except:
pass
def init(serial):
global __serial
__serial = serial
__serial.baudrate =12000000
def _rgb(rgb):
return struct.pack("BBB", ((rgb & 0xF800)>>11)*255/31, ((rgb & 0x07E0)>>5)*255/63, (rgb & 0x001F)*255/31)
def fb_size():
# read fb header
__dev.ctrl_transfer(0xC1, __USBDBG_FRAME_SIZE, __FB_HDR_SIZE, __INTERFACE, 0, __TIMEOUT)
buff = __dev.read(__IN_EP, __FB_HDR_SIZE, __TIMEOUT)
size = struct.unpack("III", buff)
return size
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_FRAME_SIZE, __FB_HDR_SIZE))
return struct.unpack("III", __serial.read(12))
def fb_lock():
__dev.ctrl_transfer(0xC1, __USBDBG_FRAME_LOCK, __FB_HDR_SIZE, __INTERFACE, 0, __TIMEOUT)
buff = __dev.read(__IN_EP, __FB_HDR_SIZE, __TIMEOUT)
return struct.unpack("III", buff)
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_FRAME_LOCK, __FB_HDR_SIZE))
return struct.unpack("III", __serial.read(12))
def fb_dump():
size = fb_lock()
@ -111,14 +70,14 @@ def fb_dump():
num_bytes = size[0]*size[1]*size[2]
# read fb data
__dev.ctrl_transfer(0xC1, __USBDBG_FRAME_DUMP, num_bytes/4, __INTERFACE, 0, __TIMEOUT)
buff = __dev.read(__IN_EP, num_bytes, __TIMEOUT)
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_FRAME_DUMP, num_bytes))
buff = __serial.read(num_bytes)
if size[2] == 1: # Grayscale
s = buff.tostring()
s = buff
buff = ''.join([y for yyy in zip(s, s, s) for y in yyy])
elif size[2] == 2: #RGB565
arr = array('H', buff.tostring())
arr = array('H', buff)
arr.byteswap()
buff = ''.join(map(_rgb, arr))
else: # JPEG
@ -134,45 +93,45 @@ def fb_dump():
return (size[0], size[1], buff)
def fb_update():
__dev.ctrl_transfer(0x41, __USBDBG_FRAME_UPDATE, 0, __INTERFACE, None, __TIMEOUT)
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_FRAME_UPDATE, 0))
def exec_script(buf):
__dev.ctrl_transfer(0x41, __USBDBG_SCRIPT_EXEC, len(buf), __INTERFACE, None, __TIMEOUT)
__dev.write(__OUT_EP, buf, __TIMEOUT)
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_SCRIPT_EXEC, len(buf)))
__serial.write(buf)
def stop_script():
__dev.ctrl_transfer(0x41, __USBDBG_SCRIPT_STOP, 0, __INTERFACE, None, __TIMEOUT)
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_SCRIPT_STOP, 0))
def save_template(x, y, w, h, path):
buf = struct.pack("IIII", x, y, w, h) + path
__dev.ctrl_transfer(0x41, __USBDBG_TEMPLATE_SAVE, len(buf), __INTERFACE, None, __TIMEOUT)
__dev.write(__OUT_EP, buf, __TIMEOUT)
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_TEMPLATE_SAVE, len(buf)))
__serial.write(buf)
def save_descriptor(x, y, w, h, path):
buf = struct.pack("IIII", x, y, w, h) + path
__dev.ctrl_transfer(0x41, __USBDBG_DESCRIPTOR_SAVE, len(buf), __INTERFACE, None, __TIMEOUT)
__dev.write(__OUT_EP, buf, __TIMEOUT)
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_DESCRIPTOR_SAVE, len(buf)))
__serial.write(buf)
def set_attr(attr, value):
buf = struct.unpack(">H", struct.pack("bb", attr, value))[0]
__dev.ctrl_transfer(0x41, __USBDBG_ATTR_WRITE, buf, __INTERFACE, None, __TIMEOUT)
__serial.write(struct.pack("<BBIhh", __USBDBG_CMD, __USBDBG_ATTR_WRITE, 0, attr, value))
def get_attr(attr):
return 0
__serial.write(struct.pack("<BBIh", __USBDBG_CMD, __USBDBG_ATTR_READ, 1, attr))
return __serial.read(1)
def enter_dfu():
try:
# This will timeout.
__dev.ctrl_transfer(0x41, __USBDBG_SYS_BOOT, 0, __INTERFACE, None, __TIMEOUT)
except:
pass
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_SYS_BOOT, 0))
def reset():
try:
# This will timeout.
__dev.ctrl_transfer(0x41, __USBDBG_SYS_RESET, 0, __INTERFACE, None, __TIMEOUT)
except:
pass
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_SYS_RESET, 0))
def tx_buf_len():
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_TX_BUF_LEN, 4))
return struct.unpack("I", __serial.read(4))[0]
def tx_buf(bytes):
__serial.write(struct.pack("<BBI", __USBDBG_CMD, __USBDBG_TX_BUF, bytes))
return __serial.read(bytes)
if __name__ == '__main__':
if len(sys.argv)!= 2:
@ -180,10 +139,11 @@ if __name__ == '__main__':
sys.exit(1)
with open(sys.argv[1], 'r') as fin:
buf = fin.read()
init()
exec_script(buf)
def __write_img(buff, path):
with open(path, "wb") as f:
f.write(buff)
f.close()
s = serial.Serial("/dev/openmvcam", 115200, timeout=1)
init(s)
exec_script(buf)
tx_len = tx_buf_len()
if (tx_len):
print(tx_buf(tx_len))
s.close()