mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-04-21 12:27:27 +03:00
usb boot working again
This commit is contained in:
@@ -1,140 +0,0 @@
|
||||
# Iris: micro-kernel for a capability-based operating system.
|
||||
# mips/nanonote/Makefile.arch: nanonote-specific parts of the build rules
|
||||
# Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
start_load = 0x80400000
|
||||
load = 0x80000000
|
||||
# Uncomment exactly one of these to select the boot method for the image.
|
||||
UDC_BOOT = yes
|
||||
#SD_BOOT = yes
|
||||
#UNBRICK = yes
|
||||
|
||||
arch_iris_sources = mips/interrupts.cc mips/arch.cc
|
||||
boot_sources = mips/init.cc mips/nanonote/board.cc
|
||||
arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh mips/nand.hh
|
||||
udc_boot_programs = udc
|
||||
sd_boot_programs = sd+mmc partition fat
|
||||
unbrick_boot_programs = nand sd+mmc usb-mass-storage
|
||||
standard_boot_programs = bootinit
|
||||
|
||||
# use sort to remove duplicates.
|
||||
programs = $(sort init gpio font lcd bsquare ball buzzer metronome elfrun alarm rtc gui test boot booter $(udc_boot_programs) $(sd_boot_programs) $(unbrick_boot_programs) $(standard_boot_programs))
|
||||
|
||||
ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
|
||||
CROSS = mipsel-linux-gnu-
|
||||
OBJDUMP = $(CROSS)objdump
|
||||
junk = mdebug.abi32 reginfo comment pdr
|
||||
OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk))
|
||||
|
||||
ifneq ($(UDC_BOOT),)
|
||||
boot_threads = $(standard_boot_programs) $(udc_boot_programs)
|
||||
ARCH_CXXFLAGS = -DNUM_THREADS=2
|
||||
BOOT_CPPFLAGS = -DUDCBOOT
|
||||
all: mips/nanonote/nand-boot.raw test
|
||||
mips/start.o: TARGET =
|
||||
else
|
||||
ifneq ($(SD_BOOT),)
|
||||
boot_threads = $(standard_boot_programs) $(sd_boot_programs)
|
||||
ARCH_CXXFLAGS = -DNUM_THREADS=4
|
||||
BOOT_CPPFLAGS = -DSDBOOT
|
||||
all: mips/nanonote/nand-boot.raw iris-sd.tar
|
||||
mips/start.o: TARGET = -DWRAPPED
|
||||
iris-sd.tar: $(addprefix fs/,$(addsuffix .elf,$(programs))) mips/start.raw.gz fs/init.config
|
||||
mkimage -A mips -T kernel -a $(start_load) -e $(shell /bin/sh -c '$(OBJDUMP) -t mips/start.elf | grep __start$$ | cut -b1-8') -n Iris -d mips/start.raw.gz fs/uimage | sed -e 's/:/;/g'
|
||||
cd fs && tar cvf ../$@ uimage init.config $(addsuffix .elf,$(programs)) --dereference
|
||||
else
|
||||
ifneq ($(UNBRICK),)
|
||||
boot_threads = $(standard_boot_programs) $(unbrick_boot_programs) sd+mmc
|
||||
ARCH_CXXFLAGS = -DNUM_THREADS=3
|
||||
BOOT_CPPFLAGS = -DUNBRICK
|
||||
all: mips/start.raw
|
||||
mips/start.o: TARGET =
|
||||
else
|
||||
error Please define your boot method.
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
iris.elf: LDFLAGS = --omagic -Ttext $(load)
|
||||
mips/start.elf: LDFLAGS = --omagic -Ttext $(start_load)
|
||||
mips/nanonote/nand-boot.elf: LDFLAGS = --omagic -Ttext 0x80000000
|
||||
mips/nanonote/nand-boot.o: mips/nand.hh
|
||||
source/nand.o: mips/nand.hh
|
||||
|
||||
mips/start.o:mips/start.S Makefile Makefile.arch iris.raw
|
||||
$(CC) $(CPPFLAGS) $(TARGET) -DSTART=0x$(shell /bin/sh -c '$(OBJDUMP) -t iris.elf | grep __start$$ | cut -b1-8') -c $< -o $@
|
||||
|
||||
test: mips/start.raw mips/start.elf mips/nanonote/server/usb-server mips/nanonote/sdram-setup.raw $(addsuffix .elf,$(addprefix fs/,$(programs))) fs/init.config
|
||||
echo "reboot $(start_load) 0x$(shell /bin/sh -c '$(OBJDUMP) -t mips/start.elf | grep __start$$ | cut -b1-8') $<" | nc localhost 5050
|
||||
|
||||
mips/nanonote/server/usb-server: mips/nanonote/server/usb-server.ccp mips/nanonote/server/Makefile.am mips/nanonote/server/configure.ac devices.hh
|
||||
$(MAKE) -C mips/nanonote/server
|
||||
echo "shutdown" | nc localhost 5050
|
||||
sleep 1
|
||||
|
||||
%.elf: %.o
|
||||
$(LD) $(LDFLAGS) -o $@ $<
|
||||
|
||||
%.raw: %.elf
|
||||
$(OBJCOPY) -S $(OBJCOPYFLAGS) -Obinary $< $@
|
||||
|
||||
%.raw.gz: %.raw
|
||||
gzip < $< > $@
|
||||
|
||||
nanonote-boot: mips/nanonote/nanonote-boot.cc mips/nanonote/sdram-setup.raw
|
||||
g++ `pkg-config --cflags --libs shevek` $< -o $@ -lusb
|
||||
|
||||
mips/nanonote/sdram-setup.elf: mips/nanonote/sdram-setup.ld
|
||||
mips/nanonote/sdram-setup.elf: LDFLAGS = --omagic -T mips/nanonote/sdram-setup.ld
|
||||
mips/nanonote/threadlist.o: $(addprefix fs/,$(addsuffix .elf,$(boot_threads)))
|
||||
mips/boot.o: TARGET_FLAGS = -DMEMORY_SIZE="32 << 20"
|
||||
mips/init.o: TARGET_FLAGS = -I/usr/mipsel-linux-gnu/include
|
||||
source/bootinit.o: TARGET_FLAGS = -I/usr/mipsel-linux-gnu/include
|
||||
source/elfrun.o: TARGET_FLAGS = -I/usr/mipsel-linux-gnu/include
|
||||
source/gpio.ccp: source/nanonote-gpio.ccp
|
||||
ln -s $(subst source/,,$<) $@
|
||||
$(addprefix fs/,$(addsuffix .elf,$(boot_threads))): TARGET_FLAGS = -I.
|
||||
$(addprefix fs/,$(addsuffix .elf,$(boot_threads))): LDFLAGS = -EL
|
||||
$(addprefix fs/,$(addsuffix .elf,$(programs))): LDFLAGS = -EL
|
||||
source/lcd.o: source/charset.data
|
||||
|
||||
source/charset.data: source/charset
|
||||
$< > $@
|
||||
|
||||
%.o:%.S Makefile Makefile.arch mips/arch.hh
|
||||
$(CC) $(CPPFLAGS) $(BOOT_CPPFLAGS) $(TARGET_FLAGS) -DKERNEL_STACK_SIZE=0x1000 -c $< -o $@
|
||||
|
||||
# entry.o must be the first file. threadlist.o must be the first of the init objects (which can be freed after loading).
|
||||
iris.elf: mips/entry.o $(subst .cc,.o,$(iris_sources)) mips/nanonote/threadlist.o mips/boot.o $(subst .cc,.o,$(boot_sources))
|
||||
$(LD) $(LDFLAGS) $^ -o $@
|
||||
|
||||
mips/start.elf: mips/start.o
|
||||
$(LD) $(LDFLAGS) $^ -o $@
|
||||
|
||||
server:
|
||||
while mips/nanonote/server/usb-server ; do : ; done
|
||||
|
||||
servers:
|
||||
while : ; do $(MAKE) server ; done
|
||||
|
||||
setup:
|
||||
x-terminal-emulator -e make debug &
|
||||
x-terminal-emulator -e make servers &
|
||||
|
||||
ARCH_CLEAN_FILES = $(boot_sources) $(addsuffix .elf,$(boot_threads)) $(arch_headers) devices.hh keys.hh mips/*.o mips/nanonote/*.o source/charset.data iris.elf iris.raw mips/nanonote/sdram-setup.elf mips/nanonote/sdram-setup.raw mips/start.elf mips/start.raw
|
||||
|
||||
.PRECIOUS: mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
|
||||
.PHONY: test all monitor server servers setup
|
||||
@@ -11,7 +11,7 @@ SECTIONS
|
||||
.text : { *(.text*) } > ram
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata*) } > ram
|
||||
.rodata : { *(.rodata*) *(.note*) } > ram
|
||||
|
||||
. = ALIGN(4);
|
||||
.sdata : { *(.sdata*) } > ram
|
||||
@@ -28,4 +28,3 @@ SECTIONS
|
||||
.bss : { *(.bss*) } > ram
|
||||
. = ALIGN (4);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# Iris: micro-kernel for a capability-based operating system.
|
||||
# mips/nanonote/server/Makefile.am: build rules
|
||||
# Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
bin_PROGRAMS = usb-server
|
||||
|
||||
usb_server_SOURCES = usb-server.cc
|
||||
usb_server_CPPFLAGS = $(SHEVEK_CFLAGS) -DSTAGE1_FILE=\"mips/nanonote/sdram-setup.raw\" -I../../.. -DCOPYRIGHT_YEARS=\"2009-2012\" -DCOPYRIGHT_AUTHOR=\"Bas\ Wijnen\" -DCOPYRIGHT_EMAIL=\"wijnen@debian.org\"
|
||||
usb_server_LDFLAGS = $(SHEVEK_LIBS) -lusb
|
||||
|
||||
PYPP = /usr/bin/pypp
|
||||
%.cc: %.ccp
|
||||
$(PYPP) --name $< < $< > $@
|
||||
|
||||
run:
|
||||
$(top_buiddir)/usb-server
|
||||
|
||||
BUILT_SOURCES = usb-server.cc
|
||||
@@ -1,9 +0,0 @@
|
||||
AC_INIT(usb-server, 1.0, wijnen@debian.org)
|
||||
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
|
||||
|
||||
AC_PROG_CXX
|
||||
|
||||
PKG_CHECK_MODULES(SHEVEK, shevek,, AC_MSG_ERROR(You need libshevek to compile AC_PACKAGE_NAME))
|
||||
|
||||
AC_CONFIG_FILES(Makefile)
|
||||
AC_OUTPUT
|
||||
@@ -1,347 +0,0 @@
|
||||
#pypp 0
|
||||
// Iris: micro-kernel for a capability-based operating system.
|
||||
// mips/nanonote/server/usb-server.ccp: Host-side helper for USB.
|
||||
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <unistd.h>
|
||||
#include <usb.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cstring>
|
||||
#include <shevek/mainloop.hh>
|
||||
#include <shevek/server.hh>
|
||||
#include <shevek/args.hh>
|
||||
#include <shevek/dir.hh>
|
||||
#include <shevek/error.hh>
|
||||
#include "devices.hh"
|
||||
|
||||
struct client
|
||||
|
||||
struct data:
|
||||
Glib::RefPtr <shevek::server <client, data *> > server
|
||||
usb_dev_handle *handle
|
||||
static int const boot_vendor = 0x601a
|
||||
static int const boot_product = 0x4740
|
||||
static int const run_vendor = 0xfffe
|
||||
static int const run_product = 0x0002
|
||||
static unsigned const timeout = 10000
|
||||
void boot (std::string const &filename, unsigned load, unsigned entry)
|
||||
data (std::string const &port):
|
||||
handle = NULL
|
||||
server = shevek::server <client, data *>::create ()
|
||||
server->data () = this
|
||||
server->open (port)
|
||||
|
||||
private:
|
||||
static unsigned const STAGE1_LOAD = 0x80003000
|
||||
static unsigned const STAGE1_ENTRY = STAGE1_LOAD
|
||||
enum requests:
|
||||
VR_GET_CPU_INFO = 0
|
||||
VR_SET_DATA_ADDRESS = 1
|
||||
VR_SET_DATA_LENGTH = 2
|
||||
VR_FLUSH_CACHES = 3
|
||||
VR_PROGRAM_START1 = 4
|
||||
VR_PROGRAM_START2 = 5
|
||||
POLL = 10
|
||||
void request (requests num, unsigned data = 0)
|
||||
void send_file (unsigned address, unsigned size, char const *data)
|
||||
void reboot ():
|
||||
char buffer[8]
|
||||
if usb_control_msg (handle, USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, VR_GET_CPU_INFO, 0, 0, buffer, 8, timeout) < 0:
|
||||
std::cerr << "unable to send reboot message to device: " << usb_strerror () << std::endl
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
void get_device (unsigned vendor, unsigned product, unsigned tries)
|
||||
void poll ()
|
||||
|
||||
static std::string files ("fs")
|
||||
struct Name:
|
||||
char name[16]
|
||||
std::string full
|
||||
std::string content
|
||||
Name (std::string const &n):
|
||||
full = files + '/' + n
|
||||
memset (name, 0, 16)
|
||||
memcpy (name, n.data (), n.size () > 16 ? 16 : n.size ())
|
||||
std::ifstream f (full.c_str ())
|
||||
std::ostringstream s
|
||||
s << f.rdbuf ()
|
||||
content = s.str ()
|
||||
static std::vector <Name> dir
|
||||
unsigned lock (0)
|
||||
|
||||
void data::poll ():
|
||||
while true:
|
||||
unsigned buffer[2]
|
||||
int s = usb_control_msg (handle, USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, POLL, 0, 0, (char *)buffer, 8, timeout)
|
||||
if s != 8:
|
||||
std::cerr << "unable to send poll message to device: " << usb_strerror () << std::endl
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
return
|
||||
switch buffer[0] & 0xffff:
|
||||
case ~0 & 0xffff:
|
||||
// Log character.
|
||||
std::cout << (char)buffer[1] << std::flush
|
||||
continue
|
||||
case ~1 & 0xffff:
|
||||
// No event.
|
||||
break
|
||||
case Iris::Directory::GET_SIZE:
|
||||
unsigned long long size = dir.size ()
|
||||
std::cerr << "sending dir size\n"
|
||||
std::cerr << Iris::Directory::GET_SIZE << '\n'
|
||||
char *str = (char *)&size
|
||||
for unsigned i = 0; i < 8; ++i:
|
||||
std::cerr << " " << (unsigned)(str[i] & 0xff)
|
||||
std::cerr << '\n'
|
||||
if usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, Iris::Directory::GET_SIZE, 0, 0, (char *)&size, 8, timeout) != 8:
|
||||
std::cerr << "unable to send size to device: " << usb_strerror () << std::endl
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
return
|
||||
continue
|
||||
case Iris::Directory::GET_NAME:
|
||||
if buffer[1] >= dir.size ():
|
||||
std::cerr << "invalid file name requested" << std::endl;
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
return
|
||||
std::cerr << "sending filename " << dir[buffer[1]].full << "\n"
|
||||
if usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, Iris::Directory::GET_NAME, 0, 0, dir[buffer[1]].name, 16, timeout) != 16:
|
||||
std::cerr << "unable to send name to device: " << usb_strerror () << std::endl
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
return
|
||||
continue
|
||||
case Iris::Directory::LOCK_RO:
|
||||
std::cerr << "lock\n"
|
||||
lock++
|
||||
std::cerr << "freezing file list\n"
|
||||
shevek::dir d (files)
|
||||
dir.clear ()
|
||||
for shevek::dir::const_iterator i = d.begin (); i != d.end (); ++i:
|
||||
if !i->name.empty () && i->name[0] != '.':
|
||||
dir.push_back (Name (i->name))
|
||||
continue
|
||||
case Iris::Directory::UNLOCK_RO:
|
||||
std::cerr << "unlock\n"
|
||||
if !lock:
|
||||
std::cerr << "unlocking without lock" << std::endl
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
return
|
||||
if !--lock:
|
||||
dir.clear ()
|
||||
continue
|
||||
case Iris::Block::GET_BLOCK:
|
||||
if buffer[1] >= dir.size ():
|
||||
std::cerr << "reading invalid file" << std::endl
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
return
|
||||
unsigned pos = buffer[0] >> 16
|
||||
std::cerr << "getting data from " << pos << '\n'
|
||||
std::string page
|
||||
if dir[buffer[1]].content.size () <= pos << 12:
|
||||
page = std::string (1 << 12, 0)
|
||||
else:
|
||||
page = (dir[buffer[1]].content.substr (pos << 12, 1 << 12) + std::string (1 << 12, 0)).substr (0, 1 << 12)
|
||||
for unsigned i = 0; i < (1 << 12); i += 64:
|
||||
if usb_bulk_write (handle, 1 | USB_ENDPOINT_OUT, &page.data ()[i], 64, timeout) != 64:
|
||||
std::cerr << "unable to send file to device: " << usb_strerror () << std::endl
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
return
|
||||
continue
|
||||
case Iris::Block::GET_SIZE:
|
||||
if buffer[1] >= dir.size ():
|
||||
std::cerr << "reading invalid file size " << buffer[1] << " >= " << dir.size () << std::endl
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
return
|
||||
unsigned long long size = dir[buffer[1]].content.size ()
|
||||
std::cerr << "sending file size " << size << "\n"
|
||||
if usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, Iris::String::GET_SIZE, 0, 0, (char *)&size, 8, timeout) != 8:
|
||||
std::cerr << "unable to send size to device: " << usb_strerror () << std::endl
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
return
|
||||
continue
|
||||
default:
|
||||
std::cerr << "invalid request " << buffer[0] << std::endl
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
return
|
||||
// If the code reaches this point, break out of the loop. The loop continues if a continue statement is reached.
|
||||
break
|
||||
(shevek::absolute_time () + shevek::relative_time (0, 100000000)).schedule (sigc::mem_fun (*this, &data::poll))
|
||||
|
||||
struct client : public shevek::server <client, data *>::connection:
|
||||
static Glib::RefPtr <client> create ():
|
||||
return Glib::RefPtr <client> (new client ())
|
||||
bool keep
|
||||
void pickup (bool is_stdio):
|
||||
keep = is_stdio
|
||||
void read (std::string const &line):
|
||||
shevek::ristring l (line)
|
||||
unsigned load, entry
|
||||
std::string filename
|
||||
if l ("reboot %x %x %a%", load, entry, filename):
|
||||
get_server ()->data ()->boot (filename, load, entry)
|
||||
else if l ("shutdown%"):
|
||||
std::cerr << "shutting down\n"
|
||||
shevek::end_loop ()
|
||||
else:
|
||||
out->write ("invalid command\n")
|
||||
if !keep:
|
||||
out->write_block ()
|
||||
disconnect ()
|
||||
|
||||
void data::request (requests r, unsigned data):
|
||||
std::cerr << shevek::ostring ("requesting %08x with data %08x\n", r, data)
|
||||
if usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, r, (data >> 16) & 0xffff, data & 0xffff, NULL, 0, timeout) < 0:
|
||||
std::cerr << "unable to send control message to NanoNote: " << usb_strerror () << ".\n"
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
|
||||
void data::send_file (unsigned address, unsigned size, char const *data):
|
||||
std::cerr << shevek::ostring ("setting data address to 0x%08x\n", address)
|
||||
request (VR_SET_DATA_ADDRESS, address)
|
||||
char const *ptr = data
|
||||
while ptr - data < size:
|
||||
int ret = usb_bulk_write (handle, 1, ptr, size - (ptr - data), timeout)
|
||||
if ret <= 0:
|
||||
std::cerr << "failed to write to NanoNote.\n"
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
return
|
||||
ptr += ret
|
||||
std::cerr << shevek::ostring ("sent %d bytes\n", size)
|
||||
|
||||
void data::get_device (unsigned vendor, unsigned product, unsigned tries):
|
||||
for unsigned i = 0; i < tries; ++i:
|
||||
usb_find_busses ()
|
||||
usb_find_devices ()
|
||||
for struct usb_bus *bus = usb_busses; bus; bus = bus->next:
|
||||
for struct usb_device *dev = bus->devices; dev; dev = dev->next:
|
||||
if dev->descriptor.idProduct != product || dev->descriptor.idVendor != vendor:
|
||||
//std::cerr << shevek::ostring ("Not using %04x:%04x when looking for %04x:%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product)
|
||||
continue
|
||||
handle = usb_open (dev)
|
||||
if usb_claim_interface (handle, 0) < 0:
|
||||
std::cerr << "unable to claim interface: " << usb_strerror () << "\n"
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
continue
|
||||
(shevek::absolute_time () + shevek::relative_time (0, 100000000)).schedule (sigc::mem_fun (*this, &data::poll))
|
||||
return
|
||||
if i + 1 < tries:
|
||||
//std::cerr << "failed to find device, still trying...\n"
|
||||
sleep (1)
|
||||
std::cerr << shevek::ostring ("giving up finding device %04x:%04x\n", vendor, product)
|
||||
|
||||
void data::boot (std::string const &filename, unsigned load, unsigned entry):
|
||||
std::cerr << "booting " << shevek::ostring ("%s from %x@%x", Glib::ustring (filename), load, entry) << "\n"
|
||||
if handle:
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
get_device (boot_vendor, boot_product, 1)
|
||||
if !handle:
|
||||
get_device (run_vendor, run_product, 1)
|
||||
if !handle:
|
||||
std::cerr << "unable to find device\n"
|
||||
return
|
||||
reboot ()
|
||||
get_device (boot_vendor, boot_product, 5)
|
||||
if !handle:
|
||||
std::cerr << "unable to reboot device\n"
|
||||
return
|
||||
std::cerr << "sending stage 1\n"
|
||||
std::ifstream file (STAGE1_FILE)
|
||||
std::ostringstream stage1
|
||||
stage1 << file.rdbuf ()
|
||||
send_file (STAGE1_LOAD, stage1.str ().size (), stage1.str ().data ())
|
||||
std::cerr << "running stage 1\n"
|
||||
request (VR_PROGRAM_START1, STAGE1_ENTRY)
|
||||
usleep (100)
|
||||
std::ostringstream stage2
|
||||
file.close ()
|
||||
file.open (filename.c_str ())
|
||||
stage2 << file.rdbuf ()
|
||||
std::cerr << shevek::ostring ("sending Iris (size 0x%x)\n", stage2.str ().size ())
|
||||
send_file (load, stage2.str ().size (), stage2.str ().data ())
|
||||
std::cerr << "flushing caches\n"
|
||||
request (VR_FLUSH_CACHES)
|
||||
std::cerr << "running Iris\n"
|
||||
request (VR_PROGRAM_START2, entry)
|
||||
usb_release_interface (handle, 0)
|
||||
usb_close (handle)
|
||||
handle = NULL
|
||||
get_device (run_vendor, run_product, 5)
|
||||
if !handle:
|
||||
std::cerr << "unable to open booted device\n"
|
||||
return
|
||||
std::cerr << "(re)booted NanoNote\n"
|
||||
|
||||
static void dump_devices ():
|
||||
std::cerr << std::hex << "String: " << Iris::String::ID
|
||||
std::cerr << "\nBlock: " << Iris::Block::ID
|
||||
std::cerr << "\nWString: " << Iris::WString::ID
|
||||
std::cerr << "\nWBlock: " << Iris::WBlock::ID
|
||||
std::cerr << "\nBoot: " << Iris::Boot::ID
|
||||
std::cerr << "\nDevice: " << Iris::Device::ID
|
||||
std::cerr << "\nEvent: " << Iris::Event::ID
|
||||
std::cerr << "\nElfrun: " << Iris::Elfrun::ID
|
||||
std::cerr << "\nParent: " << Iris::Parent::ID
|
||||
std::cerr << "\nKeyboard: " << Iris::Keyboard::ID
|
||||
std::cerr << "\nBuzzer: " << Iris::Buzzer::ID
|
||||
std::cerr << "\nDisplay: " << Iris::Display::ID
|
||||
std::cerr << "\nFont: " << Iris::Display::ID
|
||||
std::cerr << "\nSetting: " << Iris::Setting::ID
|
||||
std::cerr << "\nDirectory: " << Iris::Directory::ID
|
||||
std::cerr << "\nWDirectory: " << Iris::WDirectory::ID
|
||||
std::cerr << "\nStream: " << Iris::Stream::ID
|
||||
std::cerr << "\nUI: " << Iris::UI::ID
|
||||
std::cerr << "\n"
|
||||
|
||||
int main (int argc, char **argv):
|
||||
usb_init ()
|
||||
std::string port ("5050")
|
||||
shevek::args::option opts[] = {
|
||||
shevek::args::option ('p', "port", "port to listen for commands", true, port)
|
||||
}
|
||||
shevek::args args (argc, argv, opts, 0, 0, "device server for testing Iris on NanoNote")
|
||||
data d (port)
|
||||
dump_devices ()
|
||||
shevek::loop ()
|
||||
return 0
|
||||
Reference in New Issue
Block a user