mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Implement debugging over CDC
This commit is contained in:
parent
62a213522d
commit
754cce406c
@ -1 +1 @@
|
||||
Subproject commit 077eefd22d8e8e2db2fb49617a66820a936a1533
|
||||
Subproject commit 640d2e639f2c94b40762c1b8314fef91ab0756ff
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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):
|
||||
|
||||
156
usr/openmv.py
156
usr/openmv.py
@ -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()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user