1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
.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}
|