以下裸机程序基于GT2440,编译器为arm-linux-gcc-4.4.3。
程序结构:本程序只有一个spi.S文件。
程序流程:首先上电复位进入复位异常,在复位异常里依次调用子程序关闭看门狗、初始化系统时钟、初始化串口,最后调用spi发送数据,spi发送的数据在程序里指定,对于本程序发送数据为一个字节的字符‘A’,最后spi将接收到的数据发送到串口,在终端上显示出来。
spi.S:
1 //寄存器物理地址宏定义 2 #define WTCON 0x53000000 3 4 #define LOCKTIME 0x4C000000 5 #define MPLLCON 0x4C000004 6 #define UPLLCON 0x4C000008 7 #define CLKDIVN 0x4C000014 8 #define CAMDIVN 0x4C000018 9 10 #define ULCON0 0x50000000 11 #define UCON0 0x50000004 12 #define UFCON0 0x50000008 13 #define UTRSTAT0 0x50000010 14 #define UTXH0 0x50000020 15 #define URXH0 0x50000024 16 #define UBRDIV0 0x50000028 17 //for uart IO 18 #define GPHCON 0x56000070 19 20 #define SPICON0 0x59000000 21 #define SPSTA0 0x59000004 22 #define SPPRE0 0x5900000C 23 #define SPTDAT0 0x59000010 24 #define SPRDAT0 0x59000014 25 //for spi0 IO 26 #define GPECON 0x56000040 27 28 29 .global _start 30 _start: 31 b reset 32 33 //复位异常处理 34 reset: 35 bl disable_watchdog 36 bl init_clock 37 bl init_uart 38 bl spi_send 39 loop: 40 b loop 41 42 //关闭看门狗 43 disable_watchdog: 44 ldr r0,=WTCON 45 bic r1,r0,#0x20 46 str r1,[r0] 47 48 mov pc,lr 49 50 51 //初始化时钟 52 //FCLK=400MHZ,HCLK=100MHZ,PCLK=50MHZ 53 //UCLK=48MHZ 54 init_clock: 55 ldr r0,=LOCKTIME 56 ldr r1,=0x00ffffff 57 str r1,[r0] 58 ldr r0,=CLKDIVN 59 ldr r1,=0x05 60 str r1,[r0] 61 //设为异步总线模式(因为FCLK不等于HCLK) 62 mrc p15,0,r1,c1,c0,0 63 orr r1,r1,#0xc0000000 64 mcr p15,0,r1,c1,c0,0 65 66 ldr r0,=MPLLCON 67 ldr r1,=0x5c011 68 str r1,[r0] 69 ldr r0,=UPLLCON 70 ldr r1,=0x38022 71 str r1,[r0] 72 73 mov pc,lr 74 75 76 //初始化串口 77 init_uart: 78 //IO口设置为串口功能 79 ldr r0,=GPHCON 80 ldr r1,=0xa0 81 str r1,[r0] 82 //无检验位,1位停止位,8位数据位 83 ldr r0,=ULCON0 84 ldr r1,=0x03 85 str r1,[r0] 86 //PCLK作为时钟源(50MHZ) 87 ldr r0,=UCON0 88 ldr r1,=0x05 89 str r1,[r0] 90 //115200bps 91 ldr r0,=UBRDIV0 92 ldr r1,=0x1a 93 str r1,[r0] 94 95 mov pc,lr 96 97 spi_send: 98 //设置IO为SPI模式 99 ldr r0,=((0x2<<26)|(0x2<<24)|(0x2<<22)) 100 ldr r1,=GPECON 101 str r0,[r1] 102 //时钟分频数(PCLK/2/(249+1)) 103 ldr r0,=SPPRE0 104 ldr r1,=0xf9 105 str r1,[r0] 106 //polling模式,主机模式,使能SCLK,自动发送垃圾模式 107 ldr r0,=SPICON0 108 ldr r1,=0x19 109 str r1,[r0] 110 111 wait_send: 112 //检查状态寄存器是否已经准备好 113 ldr r2,=SPSTA0 114 ldr r1,[r2] 115 ldr r3,=0x01 116 and r3,r1,r3 117 cmp r3,#0x01 118 bne wait_send 119 //发送一个字节 120 ldr r0,=SPTDAT0 121 ldr r1,=0x41 //字符A 122 str r1,[r0] 123 124 wait_read: 125 //检查状态寄存器是否已经准备好 126 ldr r1,[r2] 127 ldr r3,=0x01 128 and r3,r1,r3 129 cmp r3,#0x01 130 bne wait_read 131 //读接收到的数据到r5 132 ldr r0,=SPRDAT0 133 ldr r5,[r0] 134 //调用串口将接收到的数据发送到终端 135 bl aurt_send_one_byte 136 137 mov pc,lr 138 139 140 aurt_send_one_byte: 141 wait_se: 142 //读发送状态位 143 ldr r0,=UTRSTAT0 144 ldr r1,[r0] 145 and r1,r1,#0x4 146 cmp r1,#0x4 147 //如果发送状态位不为0则不断读状态位 148 bne wait_se 149 //写入要发送的数据 150 ldr r3,=UTXH0 151 str r5,[r3] 152 153 mov pc,lr
Makefile:
1 spi.bin: 2 arm-linux-gcc -g -c -o spi.o spi.S 3 arm-linux-ld -Ttext 0x00000000 -g spi.o -o spi_elf 4 arm-linux-objcopy -O binary -S spi_elf spi.bin 5 rm -f uart_elf spi.o 6 7 clean: 8 rm -f spi.bin
执行make后将生成的spi.bin文件通过BIOS烧写到nand flash,将MOSI和MISO两个引脚短接,从nand flash启动。