From 719f9d4d4bb09fee612abae97b28d630b6d7cfdc Mon Sep 17 00:00:00 2001 From: Rick Bronson Date: Sun, 20 Nov 2011 22:22:56 -0800 Subject: [PATCH 1/1] Add USB download capability. Signed-off-by: Rick Bronson --- board/igep00x0/config.mk | 4 +- board/omap3530beagle/config.mk | 6 +- board/omap3evm/config.mk | 4 +- board/overo/config.mk | 4 +- cpu/omap3/start.S | 17 ++- drivers/Makefile | 2 +- drivers/usb.c | 141 ++++++++++++ drivers/usb.h | 63 ++++++ include/common.h | 1 + include/configs/omap3530beagle.h | 2 + lib/board.c | 5 + scripts/Makefile | 18 ++ scripts/omap3_usbload.c | 442 ++++++++++++++++++++++++++++++++++++++ scripts/signGP.c | 2 +- 14 files changed, 696 insertions(+), 15 deletions(-) create mode 100644 drivers/usb.c create mode 100644 drivers/usb.h create mode 100644 scripts/Makefile create mode 100644 scripts/omap3_usbload.c diff --git a/board/igep00x0/config.mk b/board/igep00x0/config.mk index 864b7d0..48f1f4b 100644 --- a/board/igep00x0/config.mk +++ b/board/igep00x0/config.mk @@ -14,6 +14,6 @@ # For XIP in 64K of SRAM or debug (GP device has it all availabe) # SRAM 40200000-4020FFFF base # initial stack at 0x4020fffc used in s_init (below xloader). -# The run time stack is (above xloader, 2k below) +# The run time stack is within xloader (2k) # If any globals exist there needs to be room for them also -TEXT_BASE = 0x40200800 +TEXT_BASE = 0x40200000 diff --git a/board/omap3530beagle/config.mk b/board/omap3530beagle/config.mk index f271b14..c7100cb 100644 --- a/board/omap3530beagle/config.mk +++ b/board/omap3530beagle/config.mk @@ -10,11 +10,11 @@ # 8000'0000 (bank0) # For use if you want X-Loader to relocate from SRAM to DDR -#TEXT_BASE = 0x80e80000 +#TEXT_BASE = 0x40200000 # For XIP in 64K of SRAM or debug (GP device has it all availabe) # SRAM 40200000-4020FFFF base # initial stack at 0x4020fffc used in s_init (below xloader). -# The run time stack is (above xloader, 2k below) +# The run time stack is within xloader (2k) # If any globals exist there needs to be room for them also -TEXT_BASE = 0x40200800 +TEXT_BASE = 0x40200000 diff --git a/board/omap3evm/config.mk b/board/omap3evm/config.mk index a45ec22..7b4d870 100644 --- a/board/omap3evm/config.mk +++ b/board/omap3evm/config.mk @@ -14,6 +14,6 @@ # For XIP in 64K of SRAM or debug (GP device has it all availabe) # SRAM 40200000-4020FFFF base # initial stack at 0x4020fffc used in s_init (below xloader). -# The run time stack is (above xloader, 2k below) +# The run time stack is within xloader (2k) # If any globals exist there needs to be room for them also -TEXT_BASE = 0x40200800 +TEXT_BASE = 0x40200000 diff --git a/board/overo/config.mk b/board/overo/config.mk index 7ee3014..3ce87c3 100644 --- a/board/overo/config.mk +++ b/board/overo/config.mk @@ -15,6 +15,6 @@ # For XIP in 64K of SRAM or debug (GP device has it all availabe) # SRAM 40200000-4020FFFF base # initial stack at 0x4020fffc used in s_init (below xloader). -# The run time stack is (above xloader, 2k below) +# The run time stack is within xloader (2k) # If any globals exist there needs to be room for them also -TEXT_BASE = 0x40200800 +TEXT_BASE = 0x40200000 diff --git a/cpu/omap3/start.S b/cpu/omap3/start.S index 4cbf437..983b065 100644 --- a/cpu/omap3/start.S +++ b/cpu/omap3/start.S @@ -142,9 +142,7 @@ copy_loop: /* Set up the stack */ stack_setup: - ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub sp, r0, #128 /* leave 32 words for abort-stack */ - and sp, sp, #~7 /* 8 byte alinged for (ldr/str)d */ + ldr sp, _abort_stack /* Clear BSS (if any). Is below tx (watch load addr - need space) */ clear_bss: @@ -161,7 +159,18 @@ clbss_l: _start_armboot: .word start_armboot - +/* we can't have the stack at the beginning of SRAM, reset needs to be there */ + .align 3 + .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */ + .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */ + .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */ + .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */ + .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */ + .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */ + .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */ + .octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 256 bytes */ +abort_stack: +_abort_stack: .word abort_stack /* ************************************************************************* * diff --git a/drivers/Makefile b/drivers/Makefile index bd620c2..807beb5 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -37,7 +37,7 @@ COBJS += k9f1g08r0a.o endif ifeq ($(BOARD), omap3530beagle) -COBJS += k9f1g08r0a.o +COBJS += k9f1g08r0a.o usb.o endif ifeq ($(BOARD), omap3evm) diff --git a/drivers/usb.c b/drivers/usb.c new file mode 100644 index 0000000..cd77f17 --- /dev/null +++ b/drivers/usb.c @@ -0,0 +1,141 @@ +/* + * USB bootloader + * + * Copyright (C) 2011 Rick Bronson + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include /* get chip and board defs */ +#include "usb.h" + +extern void udelay (unsigned long usecs); + +typedef int boot_os_fn (void); + +/* send a buffer via USB */ +int usb_send(unsigned char *buffer, unsigned int buffer_size) + { + int ret = 0; + + if (!(*peri_txcsr & MUSB_TXCSR_TXPKTRDY)) + { + unsigned int cntr; + + for (cntr = 0; cntr < buffer_size; cntr++) + *bulk_fifo = buffer[cntr]; + + *peri_txcsr |= MUSB_TXCSR_TXPKTRDY; + + ret = buffer_size; + } + return ret; + } + +//////////////////// + +static int usb_recv (u8 *buffer, int size) +{ + int cntr; + u16 count = 0; + + if (*peri_rxcsr & MUSB_RXCSR_RXPKTRDY) + { + count = *rxcount; + for (cntr = 0; cntr < count; cntr++) + { + *buffer++ = *bulk_fifo; + } + /* Clear the RXPKTRDY bit */ + *peri_rxcsr &= ~MUSB_RXCSR_RXPKTRDY; + } + return count; /* FIXME */ +} + +static unsigned char usb_outbuffer[64]; + +static void usb_msg (unsigned int cmd, const char *msg) + { + unsigned char *p_char = usb_outbuffer; + + * (int *) p_char = cmd; + p_char += sizeof (cmd); + if (msg) + { + while (*msg) + *p_char++= *msg++; + *p_char++= 0; + } + usb_send (usb_outbuffer, p_char - usb_outbuffer); + } + +static void usb_code (unsigned int cmd, u32 code) + { + unsigned int *p_int = (unsigned int *) usb_outbuffer; + + *p_int++ = cmd; + *p_int++ = code; + usb_send (usb_outbuffer, ((unsigned char *) p_int) - usb_outbuffer); + } + +void do_usb (void) + { + boot_os_fn *boot_fn; + int res; + u32 usb_inbuffer[16]; + u32 total; + u8 *addr; + u32 bytes; + int size; + int cntr; + + usb_msg (USBLOAD_CMD_FILE_REQ, "file req"); + for (cntr = 0; cntr < 100000; cntr++) /* try for 1 second then bail out */ + { + res = usb_recv ((u8 *) usb_inbuffer, sizeof (usb_inbuffer)); + switch (usb_inbuffer[0]) + { + case USBLOAD_CMD_FILE: + printf ("USBLOAD_CMD_FILE total = %d addr = 0x%x val = 0x%x val = 0x%x\n", res, usb_inbuffer[0], usb_inbuffer[1], usb_inbuffer[2]); + total = usb_inbuffer[1]; /* get size and address */ + addr = (u8 *) usb_inbuffer[2]; + usb_code (USBLOAD_CMD_ECHO_SZ, total); + + bytes = 0; + while (bytes < total) + { + size = usb_recv ((u8 *) usb_inbuffer, sizeof (usb_inbuffer)); + memcpy(addr, usb_inbuffer, size); + addr += size; + bytes += size; + } + usb_code (USBLOAD_CMD_REPORT_SZ, total); /* tell him we got this many bytes */ + printf ("got file addr = 0x%x\n", addr); + usb_msg (USBLOAD_CMD_FILE_REQ, "file req"); /* see if they have another file for us */ + break; + case USBLOAD_CMD_JUMP: + printf ("USBLOAD_CMD_JUMP total = %d addr = 0x%x val = 0x%x\n", res, usb_inbuffer[0], usb_inbuffer[1]); + boot_fn = (boot_os_fn *) usb_inbuffer[1]; + boot_fn(); /* go to u-boot and maybe kernel */ + break; + default: + break; + } + udelay(10); /* delay 10 us */ + } + } diff --git a/drivers/usb.h b/drivers/usb.h new file mode 100644 index 0000000..ba8f495 --- /dev/null +++ b/drivers/usb.h @@ -0,0 +1,63 @@ +/* + * USB bootloader + * + * Copyright (C) 2011 Rick Bronson + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _USB_H_ +#define _USB_H_ + +#define OMAP34XX_USB_BASE (OMAP34XX_CORE_L4_IO_BASE + 0xAB000) + +#define OMAP34XX_USB_EP(n) (OMAP34XX_USB_BASE + 0x100 + 0x10*(n)) + +#define MUSB_RXCSR 0x06 +#define MUSB_RXCOUNT 0x08 +#define MUSB_TXCSR 0x02 +#define MUSB_FIFOSIZE 0x0F +#define OMAP34XX_USB_RXCSR(n) (OMAP34XX_USB_EP(n) + MUSB_RXCSR) +#define OMAP34XX_USB_RXCOUNT(n) (OMAP34XX_USB_EP(n) + MUSB_RXCOUNT) +#define OMAP34XX_USB_TXCSR(n) (OMAP34XX_USB_EP(n) + MUSB_TXCSR) +#define OMAP34XX_USB_FIFOSIZE(n) (OMAP34XX_USB_EP(n) + MUSB_FIFOSIZE) +#define OMAP34XX_USB_FIFO(n) (OMAP34XX_USB_BASE + 0x20 + ((n) * 4)) + +/* memory mapped registers */ +#define BULK_ENDPOINT 1 +static volatile u16 *peri_rxcsr = (volatile u16 *) OMAP34XX_USB_RXCSR(BULK_ENDPOINT); +#define MUSB_RXCSR_RXPKTRDY 0x0001 +static volatile u16 *rxcount = (volatile u16 *) OMAP34XX_USB_RXCOUNT(BULK_ENDPOINT); +static volatile u16 *peri_txcsr = (volatile u16 *) OMAP34XX_USB_TXCSR(BULK_ENDPOINT); +#define MUSB_TXCSR_TXPKTRDY 0x0001 +static volatile u8 *bulk_fifo = (volatile u8 *) OMAP34XX_USB_FIFO(BULK_ENDPOINT); + +/* In high speed mode packets are 512 + In full speed mode packets are 64 */ +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) + +#define MIN(a,b) ( ((a) < (b)) ? (a) : (b)) + +#define PACK4(a,b,c,d) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) +#define USBLOAD_CMD_FILE PACK4('U', 'S', 'B', 's') /* send file size */ +#define USBLOAD_CMD_JUMP PACK4('U', 'S', 'B', 'j') /* go where I tell you */ +#define USBLOAD_CMD_FILE_REQ PACK4('U', 'S', 'B', 'f') /* file request */ +#define USBLOAD_CMD_ECHO_SZ PACK4('U', 'S', 'B', 'n') /* echo file size */ +#define USBLOAD_CMD_REPORT_SZ PACK4('U', 'S', 'B', 'o') /* report file size */ +#define USBLOAD_CMD_MESSAGE PACK4('U', 'S', 'B', 'm') /* message for debug */ + +#endif diff --git a/include/common.h b/include/common.h index a3c5092..e21cc23 100644 --- a/include/common.h +++ b/include/common.h @@ -111,6 +111,7 @@ void hang (void) __attribute__ ((noreturn)); extern int do_load_serial_bin (ulong offset, int baudrate); extern u32 get_mem_type(void); extern int mmc_init(int verbose); +extern void do_usb(void); extern int misc_init_r(void); extern int sprintf (char *__s, const char *__format, ...); diff --git a/include/configs/omap3530beagle.h b/include/configs/omap3530beagle.h index 5625417..76e3261 100644 --- a/include/configs/omap3530beagle.h +++ b/include/configs/omap3530beagle.h @@ -42,6 +42,8 @@ #define CONFIG_BEAGLE_REV2 1 +/* Enable the below macro if you want to use omap3_usbload to download u-boot and linux via USB */ +#define CONFIG_USB 1 /* Enable the below macro if MMC boot support is required */ #define CONFIG_MMC 1 #if defined(CONFIG_MMC) diff --git a/lib/board.c b/lib/board.c index 0f6b960..2f1d288 100644 --- a/lib/board.c +++ b/lib/board.c @@ -93,6 +93,11 @@ void start_armboot (void) misc_init_r(); +#ifdef CONFIG_USB + printf("Trying load from USB\n"); + do_usb(); /* check for usb download */ +#endif + buf = (uchar*) CFG_LOADADDR; *(int *)buf = 0xffffffff; diff --git a/scripts/Makefile b/scripts/Makefile new file mode 100644 index 0000000..04c1e55 --- /dev/null +++ b/scripts/Makefile @@ -0,0 +1,18 @@ +CC = gcc +INCLUDES = +CFLAGS = -Wall -O2 -g $(INCLUDES) +LIBS = -lusb +LDFLAGS = -g $(LIBS) +APP_NAME = omap3_usbload + +OBJS = omap3_usbload.o + +all: $(APP_NAME) + +$(APP_NAME): $(OBJS) + $(CC) $(LDFLAGS) -o $@ $^ + +clean: + rm -r $(APP_NAME) *.o + +.PHONY: all clean diff --git a/scripts/omap3_usbload.c b/scripts/omap3_usbload.c new file mode 100644 index 0000000..4666111 --- /dev/null +++ b/scripts/omap3_usbload.c @@ -0,0 +1,442 @@ +/* $Id: Exp $ + * + * omap3_usbload, an USB download application for OMAP3 processors + * Copyright (C) 2008 Martin Mueller + * Modified by Rick Bronson 2011 + * + * 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 2, 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 paparazzi; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +/* + + OMAP USB loader. Using the version of x-loader with CONFIG_USB, you can +now boot up the BeagleBoard completely into Linux with a ramdisk via USB. + + Steps: + +1. You will need libusb-dev on your host box: + +sudo apt-get install libusb-dev + +2. Modify u-boot to boot directly if it can't find mmc: + +change "run nandboot;" to "run ramboot;" + +and add: + +"ramboot=setenv bootargs console=ttyO2,115200n8 mem=256M no_console_suspend ramdisk_size=80000 root=/dev/ram0; bootm\0" + + in this file u-boot/include/configs/omap3_beagle.h + +3. Run minicom to the serial port, unplug USB OTG and brick power to + the BeagleBoard, remove the SD Card and then run this program like this: + +cd scripts +sudo omap3_usbload/omap3_usbload -f ../tftpboot/x-load.bin \ + -a 0x80008000 -f ../tftpboot/u-boot.bin \ + -a 0x82000000 -f ../tftpboot/uMulti -j 0x80008000 -v + + Then plug in the USB OTG cable to your host to power the board. + +Usage: omap3_usbload -f file1 [-a addr2 -f file2] [-a addr3 -f file3] [etc] [-j addr] [-v] + + NOTE: first file (file1) has no addr + Load address MUST come before each file2-N + + uMulti is a combined kernel/filesystem. You can substitute +uImage for uMulti and it will at least boot into the kernel, +but you won't have a filesystem. + + Tested on BeagleBoardXM Rev C and Beagleboard Rev B4 + + The Rev B4 Beagleboard saves u-boot environment var's in NAND so you will have to interrupt u-boot +and correct them. Also on Rev B4 you will have to use an older kernel, this one won't work, then +interrupt u-boot and do: + +setenv bootargs console=ttyS2,115200n8 mem=128M no_console_suspend ramdisk_size=80000 root=/dev/ram0; bootm 0x82000000 + + You could load uImage at one address, then the ramdisk file at yet another address (at say 0x830000000) and do: + +setenv bootargs console=ttyS2,115200n8 mem=128M no_console_suspend ramdisk_size=80000 root=/dev/ram0 initrd=0x830000000,8M; bootm 0x82000000 + +*/ + +#include +#include +#include +#include +#include + +#define VERSION "1.1" + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define cpu_to_le32(x) (x) +# define le32_to_cpu(x) (x) +#else +# define cpu_to_le32(x) bswap_32 (x) +# define le32_to_cpu(x) bswap_32 (x) +#endif + +#define VENDOR_ID_TI 0x0451 +#define DEVICE_ID 0xD000 +#define DEVICE_ID_MASK 0xff00 + +#define OMAP3_BOOT_CMD 0xF0030002 /* see page 3515 sprugn4c.pdf */ + +#define PACK4(a,b,c,d) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) +#define USBLOAD_CMD_FILE PACK4('U', 'S', 'B', 's') /* send file size */ +#define USBLOAD_CMD_JUMP PACK4('U', 'S', 'B', 'j') /* go where I tell you */ +#define USBLOAD_CMD_FILE_REQ PACK4('U', 'S', 'B', 'f') /* file request */ +#define USBLOAD_CMD_ECHO_SZ PACK4('U', 'S', 'B', 'n') /* echo file size */ +#define USBLOAD_CMD_REPORT_SZ PACK4('U', 'S', 'B', 'o') /* report file size */ +#define USBLOAD_CMD_MESSAGE PACK4('U', 'S', 'B', 'm') /* message for debug */ + +#define EP_BULK_IN 0x81 +#define EP_BULK_OUT 0x01 +#define BUF_LEN 128 +#define BUF_LEN_SM 256 /* we seem to need this exact size ?? */ + +#define USB_TIMEOUT 1000 /* time in ms */ + +#define MAX_FILES 10 /* the max addr/file pairs */ +struct UPLOAD_DATA + { + int file_cntr; + unsigned long addrs[MAX_FILES]; + int fd[MAX_FILES]; + int filesize[MAX_FILES]; + const char *filename[MAX_FILES]; /* file names */ + unsigned long jump_addr; + usb_dev_handle *udev; + int verbose; /* be verbose? */ + char *p_file; + }; + +struct UPLOAD_DATA upload_data = + { + .verbose = 0, /* be verbose? */ + .filename[0] = NULL, + .jump_addr = 0x80008000, + .p_file = NULL, + }; + + + /* A string listing valid short options letters. */ +const char* const short_options = "a:f:j:v"; + /* An array describing valid long options. */ +const struct option long_options[] = { + { "load_addr", 1, NULL, 'a' }, + { "file", 1, NULL, 'f' }, + { "jump", 1, NULL, 'j' }, + { "verbose", 0, NULL, 'v' }, + { NULL, 0, NULL, 0 } /* Required at end of array. */ + }; + +/* send a value to x-loader */ +static int send_val (struct UPLOAD_DATA *p_data, unsigned int code, unsigned int val1, unsigned int val2) +{ + int res; + int buffer[3]; + + buffer[0]= code; + buffer[1] = cpu_to_le32 (val1); + buffer[2] = cpu_to_le32 (val2); + + if (p_data->verbose) + printf ("send_val code = 0x%x, val1 = 0x%x, val2 = 0x%x\n",(int) buffer[0], (int) buffer[1], (int) buffer[2]); + res= usb_bulk_write (p_data->udev, EP_BULK_OUT, (const char *) buffer, sizeof (buffer), USB_TIMEOUT); + if (res < sizeof (buffer)) + { + printf ("Error in usb_bulk_write1: %d/8\n", res); + return 1; + } + + return 0; +} + +void print_usage (FILE* stream, int exit_code) + { + fprintf (stream, "Usage: omap3_usbload -f file1 [-a addr2 -f file2] [-a addr3 -f file3] [etc] [-j addr] [-v]\n"); + fprintf (stream, + " -f --file file File to load, first file (file1) has no addr\n" + " -a --load_addr addr Load address, MUST come before each file2-N\n" + " -j --jump addr Jump address[0x80008000]\n"); + exit (exit_code); +} + +enum { /* subroutine return codes */ + RET_OK, + RET_ERR, + RET_IN_LOOP +}; + +int do_files(struct UPLOAD_DATA *p_data) + { + int res, sz, file_cnt, file_len, size, usb_cnt; + int dat_buf[BUF_LEN]; + unsigned int command; + int this_file = 1; /* start with the 2nd file */ + char *p_file; + + file_cnt = usb_bulk_read(p_data->udev, EP_BULK_IN, (char *) dat_buf, sizeof (dat_buf), USB_TIMEOUT); + if (file_cnt <= 0) + { + printf("could not get ASIC ID\n"); + return(-1); + } + + command = OMAP3_BOOT_CMD; + if (sizeof(command) != usb_bulk_write(p_data->udev, EP_BULK_OUT, (char*) &command, sizeof(command), USB_TIMEOUT)) + { + printf("could not send peripheral boot command\n"); + return(-1); + } + + file_len = p_data->filesize[0]; + if (sizeof(file_len) != usb_bulk_write(p_data->udev, EP_BULK_OUT, (char*) &file_len, sizeof(file_len), USB_TIMEOUT)) + { + printf("could not send length\n"); + return(-1); + } + + do + { + file_cnt = read(p_data->fd[0], dat_buf, sizeof (dat_buf)); + if (file_cnt > 0) + { + usb_cnt = usb_bulk_write(p_data->udev, EP_BULK_OUT, (char *) dat_buf, file_cnt, USB_TIMEOUT); + + if (usb_cnt != file_cnt) + { + printf("could not write to usb usb_cnt = %d file_cnt = %d\n", usb_cnt, file_cnt ); + return(-1); + } + } + } while (file_cnt > 0); + + if (p_data->verbose) + printf("download ok\n"); + close(p_data->fd[0]); + p_data->fd[0] = 0; /* mark as closed */ + + /* now wait for x-loader */ + while ((size = p_data->filesize[this_file]) > 0) + { + if (p_data->verbose) + printf ("while loop size = %d\n", size); + p_file = p_data->p_file = malloc (p_data->filesize[this_file]); + if (p_file == NULL) + { + printf ("Out of memory requesting %d bytes\n", p_data->filesize[this_file]); + return 1; + } + /* read whole file in */ + if ((p_data->filesize[this_file] = read (p_data->fd[this_file], p_file, p_data->filesize[this_file])) < 0) + { + perror ("read file"); + return 1; + } + if (p_data->verbose) + printf ("filesize = %d\n", p_data->filesize[this_file]); + close (p_data->fd[this_file]); + + while (size > 0) + { + res= usb_bulk_read (p_data->udev, EP_BULK_IN, (char *) dat_buf, sizeof (dat_buf), USB_TIMEOUT); + if (res < 0) + { + printf("Error in usb_bulk_read: %d\n", res); + return 1; + } + if (res < 8) + continue; + + switch (dat_buf[0]) + { + case USBLOAD_CMD_FILE_REQ: + if (p_data->verbose) + printf("f: size = %d, addr = 0x%x\n", size, (int) p_data->addrs[this_file]); + if (send_val (p_data, USBLOAD_CMD_FILE, size, p_data->addrs[this_file])) + size= -1; + break; + + case USBLOAD_CMD_REPORT_SZ: /* he tells us how many btyes are left */ + size -= le32_to_cpu (dat_buf[1]); + if (size > 0) + size= -1; + break; + + case USBLOAD_CMD_ECHO_SZ: /* he echo's the file size */ + sz = le32_to_cpu (dat_buf[1]); + if (p_data->verbose) + printf("sending file, size %d %d\n", sz, res); + while (sz > 0) + { + res = usb_bulk_write(p_data->udev, EP_BULK_OUT, p_file, BUF_LEN_SM, USB_TIMEOUT); + if (res != BUF_LEN_SM) { + printf("Error in usb_bulk_write3: %d/%d\n", res, sz); + size = -1; + break; + } + p_file += res; + sz -= res; + } + break; + + case USBLOAD_CMD_MESSAGE: + printf("Message: %s\n", (char *) &dat_buf[1]); + break; + + default: + printf("Unknown packet type '%s'\n", (char *) dat_buf[1]); + break; + } + } + if (size == 0 && p_data->verbose) + printf("Program stored in memory: %d bytes\n", p_data->filesize[this_file]); + this_file++; /* next */ + free (p_data->p_file); + p_data->p_file = NULL; /* mark as freed */ + } + if (p_data->jump_addr) + { + send_val (p_data, USBLOAD_CMD_JUMP, p_data->jump_addr, 0); /* go to address */ + if (p_data->verbose) + printf("Sending jump 0x%x\n", (int) p_data->jump_addr); + } + return 0; + } + +enum { /* need to have at least one file to load */ + ARG_PROGNAME, + ARG_BINFILE, + NUM_ARGS +}; + +int main(int argc, char **argv) + { + struct UPLOAD_DATA *p_data; + int next_option; + struct usb_bus *bus; + int file_cntr = 0, res = RET_IN_LOOP; + + p_data = &upload_data; + do + { + next_option = getopt_long (argc, argv, short_options, + long_options, NULL); + switch (next_option) + { + case 'a': /* -a or --load_addr */ + /* This option takes an argument, the address to load the file into. */ + p_data->addrs[file_cntr] = strtoul (optarg, NULL, 0); + break; + case 'f': /* -f or --file */ + /* This option takes an argument, the name of the file. */ + p_data->filename[file_cntr] = optarg; + p_data->fd[file_cntr] = open(p_data->filename[file_cntr], O_RDONLY); + if (p_data->fd[file_cntr] < 0) + { + perror("Can't open file"); + return 1; + } + p_data->filesize[file_cntr] = lseek (p_data->fd[file_cntr], 0, SEEK_END); + if (p_data->filesize[file_cntr] < 0 || lseek (p_data->fd[file_cntr], 0, SEEK_SET) < 0) + { + perror ("lseek binfile"); + close (p_data->fd[file_cntr]); + return 1; + } + if (p_data->verbose) + printf("Opening %s fd = %d, size = %d\n", p_data->filename[file_cntr], p_data->fd[file_cntr], p_data->filesize[file_cntr]); + file_cntr++; /* go to next file */ + break; + case 'j': /* -j or --jump */ + /* This option takes an argument, the jump address. */ + p_data->jump_addr = strtoul (optarg, NULL, 0); + break; + case 'v': /* -v or --verbose */ + p_data->verbose = 1; + break; + case '?': /* The user specified an invalid option. */ + /* Print usage information to standard error, and exit with exit + code one (indicating abonormal termination). */ + print_usage (stderr, 1); + break; + case -1: /* Done with options. */ + break; + default: /* Something else: unexpected. */ + print_usage (stderr, 1); + } + } + while (next_option != -1); + + if (argc < NUM_ARGS) { + print_usage (stderr, 1); + return(-1); + } + + usb_init(); + usb_find_busses(); + + while (res == RET_IN_LOOP) + { + printf("."); + fflush(stdout); + + if (usb_find_devices()) + { + for (bus = usb_get_busses(); bus; bus = bus->next) + { + struct usb_device *dev; + + for (dev = bus->devices; dev; dev = dev->next) + { + if (dev->descriptor.idVendor == VENDOR_ID_TI && + (dev->descriptor.idProduct & DEVICE_ID_MASK) == DEVICE_ID) + { + p_data->udev = usb_open(dev); + + if (p_data->udev) + { + if (p_data->verbose) + printf("\n\nfound device 0x%04x:0x%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct); + + if (usb_set_configuration(p_data->udev, 1) < 0) + { + printf("could not set configuration\n"); + res = RET_ERR; + } + if (do_files(p_data)) /* if an error occurred */ + res = RET_ERR; + else + res = RET_OK; + } + } + } + } + } + usleep(500 * 1000); /* wait until we put another dot */ + } + for (file_cntr = 0; file_cntr < MAX_FILES; file_cntr++) /* close all files */ + if (p_data->fd[file_cntr]) + close(p_data->fd[file_cntr]); + if (p_data->p_file) + free (p_data->p_file); + usb_close(p_data->udev); + return(res); + } diff --git a/scripts/signGP.c b/scripts/signGP.c index ab4715c..a11b533 100644 --- a/scripts/signGP.c +++ b/scripts/signGP.c @@ -255,7 +255,7 @@ int main(int argc, char *argv[]) /* Default to x-load.bin and 0x40200800. */ strcpy(ifname, "x-load.bin"); - loadaddr = 0x40200800; + loadaddr = 0x40200000; if ((argc == 2) || (argc == 3) || (argc == 4)) strcpy(ifname, argv[1]); -- 1.7.7.3