读书人

U-boot移植 (v2012.04.1 S3C2440平台)

发布时间: 2012-08-31 12:55:03 作者: rapoo

U-boot移植 (v2012.04.1 S3C2440平台) (四) usbslave 下载功能实现

8 usbslave 下载功能实现

网上有很多关于在u-boot中添加usbslave功能的教程,我主要是参照了一位叫tekkamanninja的网友的实现,在u-boot-v2012.04上实现了usbslave下载功能。下面是我移植的步骤:

1) 添加driver/usb/slave目录:

这个目录里的代码是usbslave的驱动具体实现,我是从tekkamanninja的github上下载的代码,将driver/usb/slave里的代码拷贝过来的。由于新u-boot里2440寄存器结构体的变量名全部改成小写了,所以需要将slave目录下关于寄存器的变量全改成小写的。具体代码可以查看我的github目录。

然后再修改顶层Makefile,加入对usbslave驱动的编译:

LIBS += drivers/usb/phy/libusb_phy.o

LIBS += drivers/usb/slave/libusb_slave.o

LIBS += drivers/usb/ulpi/libusb_ulpi.o

LIBS += drivers/video/libvideo.o


2) 修改arch/arm/cpu/arm920t/s3c24x0/interrupts.c,加入arch_interrupt_init

的实现:

void do_irq (struct pt_regs *pt_regs)

{

struct s3c24x0_interrupt *irq = s3c24x0_get_base_interrupt();

readl(&irq->intpnd);

}


int arch_interrupt_init (void)

{

return 0;

}


3) 修改arch/arm/cpu/arm920t/start.S:

#ifdef CONFIG_USE_IRQ


.align5

irq:

/*

get_irq_stack

irq_save_user_regs

bl do_irq

irq_restore_user_regs

*/

sub lr, lr, #4

ldr sp, IRQ_STACK_START

stmdb sp!, {r0-r12, lr}


ldr lr, =int_return

ldr pc, =IRQ_Handle

int_return:

ldmia sp!, {r0-r12, pc}^


.align5

fiq:

get_fiq_stack

/* someone ought to write a more effiction fiq_save_user_regs */

irq_save_user_regs

bl do_fiq

irq_restore_user_regs

#else


4) 修改arch/arm/lib/board.c,在init_board_r函数中加入usbslave的初始化操作:

/* set up exceptions */

interrupt_init();

/* enable exceptions */

enable_interrupts();

#ifdef CONFIG_USB_DEVICE

usb_init_slave();

#endif


5) 修改board/samsung/micro2440/micro2440.c中的gpio初始化部分,设置gpc5引脚为usb_en功能:

/* set up the I/O ports */

writel(0x007FFFFF, &gpio->gpacon);

writel(0x00044555, &gpio->gpbcon);

writel(0x000007FF, &gpio->gpbup);

writel(0xAAAAA6AA, &gpio->gpccon);

writel(0x0000FFFF, &gpio->gpcup);

writel(readl(&gpio->gpcdat)&~(1<<5), &gpio->gpcdat);

writel(0xAAAAAAAA, &gpio->gpdcon);

writel(0x0000FFFF, &gpio->gpdup);

writel(0xAAAAAAAA, &gpio->gpecon);

writel(0x0000FFFF, &gpio->gpeup);

writel(0x000055AA, &gpio->gpfcon);

writel(0x000000FF, &gpio->gpfup);

writel(0xFF95FFBA, &gpio->gpgcon);

writel(0x0000FFFF, &gpio->gpgup);

writel(0x002AFAAA, &gpio->gphcon);

writel(0x000007FF, &gpio->gphup);


6) 加入cmd_usbslave支持:

修改common/Makefile,添加COBJS-$(CONFIG_USB_DEVICE) += cmd_usbslave.o,cmd_usbslave.c的具体实现可以查看我的github.


7) 修改micro2440.h,加入IRQ和usb device的配置:

/* input clock of PLL (the MICRO2440 has 12MHz input clock) */

#define CONFIG_SYS_CLK_FREQ 12000000


//#undef CONFIG_USE_IRQ/* we don't need IRQ/FIQ stuff */


#define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */

/************************************************************

* USB support (currently only works with D-cache off)

************************************************************/

#define CONFIG_USB_OHCI

#define CONFIG_USB_KEYBOARD

#define CONFIG_USB_STORAGE

#define CONFIG_DOS_PARTITION

#define CONFIG_USB_DEVICE 1

#ifdef CONFIG_USB_DEVICE

#define CONFIG_USE_IRQ 1

#endif


8) 最后是对头文件s3c24x0.h的修改:

这里需要注意的是新版的u-boot s3c2440的struct s3c24x0_dma的定义是有问题的,我们需要对该结构体的定义针对2440加以修改。我最开始时参照网上的教程移植好usbslave后,发现usb传输的dma中断怎么也收不到,调试了好久才发现的这个问题。

/* DMAS (see manual chapter 8) */

struct s3c24x0_dma {

u32 disrc;

#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

u32 disrcc;

#endif

u32 didst;

#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

u32 didstc;

#endif

u32 dcon;

u32 dstat;

u32 dcsrc;

u32 dcdst;

u32 dmasktrig;

#if defined(CONFIG_S3C2400)

u32 res[1];

#endif

#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)

u32 res[7];

#endif

};

struct s3c24x0_usb_device {

#else /* little endian */

u8 func_addr_reg;

u8 res1[3];

u8 pwr_reg;

u8 res2[3];

u8 ep_int_reg;

u8 res3[15];

u8 usb_int_reg;

u8 res4[3];

u8 ep_int_en_reg;

u8 res5[15];

u8 usb_int_en_reg;

u8 res6[3];

u8 frame_num1_reg;

u8 res7[3];

u8 frame_num2_reg;

u8 res8[3];

u8 index_reg;

u8 res9[7];

u8 maxp_reg;

u8 res10[3];

u8 ep0_csr_in_csr1_reg;

u8 res11[3];

u8 in_csr2_reg;

u8 res12[7];

u8 out_csr1_reg;

u8 res13[3];

u8 out_csr2_reg;

u8 res14[3];

u8 out_fifo_cnt1_reg;

u8 res15[3];

u8 out_fifo_cnt2_reg;

u8 res16[3];

#endif /* __BIG_ENDIAN */

u32 res17[8];

struct s3c24x0_usb_dev_fifos fifo[5];

u32 res18[11];

//struct s3c24x0_usb_dev_dmas dma[5];

struct s3c24x0_usb_dev_dmas ep1;

struct s3c24x0_usb_dev_dmas ep2;

u8 res19[16];

struct s3c24x0_usb_dev_dmas ep3;

struct s3c24x0_usb_dev_dmas ep4;

};

读书人网 >移动开发

热点推荐