参考资料http://chxxxyg.blog.163.com/blog/static/1502811932010813115518537/
http://blog.chinaunix.net/u3/105764/showart_2144192.html
1。在drivers/usb/下面建立新目录
mkdir /drivers/usb/slave
拷贝那个chxxxyg给的源代码。
2。修改uboot根目录下的Makefeils,添加红色部分代码
LIBS += drivers/usb/musb/libusb_musb.a
LIBS += drivers/usb/slave/libusb_slave.a
LIBS += drivers/video/libvideo.a
3。修改lib_arm/board.c文件,添加红色部分代码,增加USB_SLAVE初始化函数。
/* enable exceptions */
enable_interrupts ();
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
#ifdef CONFIG_USB_DEVICE
usb_init_slave();
#endif
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
4。修改平台头文件,include/configs/smdk2440.h,添加红色部分
#define CONFIG_USB_DEVICE 1
#ifdef CONFIG_USB_DEVICE
#define CONFIG_USE_IRQ 1
#endif
//#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
5。修改cpu/arm920t/s3c24x0/interrupts.c 文件,添加arch_interrupt_init函数定义
添加头文件 #include <asm/io.h>
添加
int arch_interrupt_init (void)
{
return 0;
}
6。修改arch/arm/cpu/arm920t/start.S,文件
#ifdef CONFIG_USE_IRQ
.align 5
irq:
//此处开始修改
/*
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs
*/
/* use IRQ for USB and DMA */
sub lr, lr, #4 @ the return address
ldr sp, IRQ_STACK_START @ the stack for irq
stmdb sp!, { r0-r12,lr } @ save registers
ldr lr, =int_return @ set the return addr
ldr pc, =IRQ_Handle @ call the isr
int_return:
ldmia sp!, { r0-r12,pc }^ @ return from interrupt
//,修改结束
7。修改arch/arm/include/asm/arch-s3c24x0.h,文件
#else /* little endian */
u8FUNC_ADDR_REG;
u8res1[3];
u8PWR_REG;
u8res2[3];
u8EP_INT_REG;
u8res3[15];
u8USB_INT_REG;
u8res4[3];
u8EP_INT_EN_REG;
u8res5[15];
u8USB_INT_EN_REG;
u8res6[3];
u8FRAME_NUM1_REG;
u8res7[3];
u8FRAME_NUM2_REG;
u8res8[3];
u8INDEX_REG;
u8res9[7];
u8MAXP_REG;
//u8res10[7];
u8res10[3]; //by cheny
u8EP0_CSR_IN_CSR1_REG;
u8res11[3];
u8IN_CSR2_REG;
//u8res12[3];
u8res12[7]; //by cheny
u8OUT_CSR1_REG;
//u8res13[7];
u8res13[3];//by cheny
u8OUT_CSR2_REG;
u8res14[3];
u8OUT_FIFO_CNT1_REG;
u8res15[3];
u8OUT_FIFO_CNT2_REG;
u8res16[3];
#endif /* __BIG_ENDIAN */
u32res17[8]; //by cheny
struct s3c24x0_usb_dev_fifosfifo[5];
u32res18[11]; //by cheny
struct s3c24x0_usb_dev_dmasep1;//by cheny
struct s3c24x0_usb_dev_dmasep2; //by cheny
u8res19[16];//by cheny
struct s3c24x0_usb_dev_dmasep3; //by cheny
struct s3c24x0_usb_dev_dmasep4; //by cheny
//struct s3c24x0_usb_dev_dmasdma[5];
};
8。添加usbslave命令
在common目录下创建cmd_usbslave.c
#include <common.h>
#include <command.h>
#include <asm/byteorder.h>
#ifdef CONFIG_USB_DEVICE
#ifdef CONFIG_USE_IRQ
#define IRQ_STACK_START (_armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4)
#define FIQ_STACK_START (IRQ_STACK_START - CONFIG_STACKSIZE_IRQ)
#define FREE_RAM_END (FIQ_STACK_START - CONFIG_STACKSIZE_FIQ - CONFIG_STACKSIZE)
#define FREE_RAM_SIZE (FREE_RAM_END - PHYS_SDRAM_1)
#else
#define FREE_RAM_END (_armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4 - CONFIG_STACKSIZE)
#define FREE_RAM_SIZE (FREE_RAM_END - PHYS_SDRAM_1)
#endif
int g_bUSBWait = 1;
u32 g_dwDownloadLen = 0;
extern int download_run;
extern volatile unsigned int dwUSBBufBase;
extern volatile unsigned int dwUSBBufSize;
extern __u32 usb_receive(char *buf, size_t len, unsigned int wait);
int do_usbslave (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int i;
size_t len = ~0UL;
char buf[32];
download_run = 1;
switch (argc) {
case 1:
{
break;
}
case 2:
{
g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
break;
}
case 3:
{
g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
load_addr = simple_strtoul(argv[2], NULL, 16);
download_run = 0;
break;
}
default:
{
printf ("Usage:/n%s/n", cmdtp->usage);
return 1;
}
}
dwUSBBufBase = load_addr;
dwUSBBufSize = (FREE_RAM_SIZE&(~(0x80000-1)));
if (g_bUSBWait)
len = FREE_RAM_SIZE;
g_dwDownloadLen = usb_receive(dwUSBBufBase, len, g_bUSBWait);
sprintf(buf, "%X", g_dwDownloadLen);
setenv("filesize", buf);
return 0;
}
U_BOOT_CMD(
usbslave, 3, 0, do_usbslave,
"usbslave - get file from host(PC)/n",
"[wait] [loadAddress]/n"
"/"wait/" is 0 or 1, 0 means for return immediately, not waits for the finish of transferring/n"
);
#endif
COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
#+
COBJS-$(CONFIG_USB_DEVICE) += cmd_usbslave.o
# -
10。修改USB_EN gpio设置
vi board/smdk2440/smdk2440.c
gpio->GPFCON = 0x000055AA;
gpio->GPFUP = 0x000000FF;
//gpio->GPGCON = 0xFF95FFBA;
//gpio->GPGUP = 0x0000FFFF;
gpio->GPGCON = 0xFD95FFBA; //USB_EN by cheny
gpio->GPGUP = 0x0000EFFF; //by cheny
gpio->GPGDAT &= ~(1 << 12);//disable USB Device by cheny
11。下载命令
usbslave 1 0x32000000
nand erase 0x200000 0x300000
nand write 0x32000000 0x200000 0x300000