.section .text .align 4 .global irq_handler #define BUFF_ADDR 0x60800000 irq_handler: stmfd sp!,{r0-r7,ip,lr} /* get interrupt number */ mov r4,#0x18000000 add r4,r4,#0x80000 ldr r5,[r4,#0x104] and r5,r5,#0x1f cmp r5,#0x10 /* UDC interrupt */ bleq udc_irq /* clear pending interrupt */ mov r3,#1 mov r2,r3,LSL r5 str r2,[r4,#0x118] ldmfd sp!,{r0-r7,ip,lr} subs pc,lr,#4 udc_irq: stmfd sp!,{r4-r8,lr} /* handle usb interrupt */ ldr r4,=0x180A0000 ldr r5,[r4,#0x18] /* UDC_INTFLAG */ /* ep0 in intr */ tst r5,#0x04 beq bulk_recv_intr ep0: ldr r5,[r4,#0x40] mov r5,r5,lsr #10 mov r5,r5,lsl #10 /* clear lower 10 bits in TX0STAT */ str r5,[r4,#0x40] /* set buffer addres in UDC_DMA0LM_OADDR */ mov r5,#0x60000000 str r5,[r4, #0x3c] /* write DMA_START in UDC_DMA0CTLO */ mov r5,#1 str r5,[r4,#0x38] ldmfd sp!,{r4-r8,pc} /* bulk out interrupt */ bulk_recv_intr: tst r5,#0x100 ldmeqfd sp!,{r4-r8,pc} /* read UDC_RX1STAT */ ldr r5,[r4,#0x54] mov r5,r5,lsl #21 mov r5,r5,lsr #21 /* r5 = length */ ldr r6,=usb_sz ldr r6,[r6] ldr r7,[r6] /* r7 = total_code_length expected */ subs r7,r7,r5 bne usb_bulk_out1_recv /* copy from buff to the begining of the ram */ ldr r0,=BUFF_ADDR ldr r1,[r0,#-4] /* size */ ldr r1,=0x800000 /* buffer size */ add r1,r1,r0 /* end address */ ldr r2,=0x60000000 /* destination */ 1: cmp r1,r0 ldrhi r3,[r0],#4 strhi r3,[r2],#4 bhi 1b /* execute user code */ ldr r0,=0x60000000 bx r0 /* jump to 0x60000000 */ usb_bulk_out1_recv: str r7,[r6] /* size = size - received */ ldr r6,=usb_write_addr ldr r7,[r6] add r7,r7,r5 str r7,[r6] /* usb_write_addr += length */ str r7,[r4,#0x60] /* DMA1LM_OADDR = usb_write_addr */ mov r5,#1 str r5,[r4,#0x5c] /* DMA1_CTL0 = ENP_DMA_START */ ldmfd sp!,{r4-r8,pc}