一、415行-421行
uart_asm_init:
/* set GPIO to enable UART0-UART4 */
mov r0, r8
ldr r1, =0x22222222
str r1, [r0, #0x0] @ S5PC100_GPIO_A0_OFFSET
ldr r1, =0x00002222
str r1, [r0, #0x20] @ S5PC100_GPIO_A1_OFFSET
r8 = 0xE0200000,为GPA0CON寄存器。上面的代码将GPA0CON配置为UART功能。
二、423行-425行
/* Check S5PC100 */
cmp r7, r8
bne 110f
跳转到110f。
三、444行-463行
110:
/*
* Note that the following address
* 0xE020'0360 is reserved address at S5PC100
*/
/* UART_SEL MP0_5[7] at S5PC110 */
add r0, r8, #0x360 @ S5PC110_GPIO_MP0_5_OFFSET
ldr r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET
bic r1, r1, #(0xf << 28) @ 28 = 7 * 4-bit
orr r1, r1, #(0x1 << 28) @ Output
str r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET
110:
/*
* Note that the following address
* 0xE020'0360 is reserved address at S5PC100
*/
/* UART_SEL MP0_5[7] at S5PC110 */
add r0, r8, #0x360 @ S5PC110_GPIO_MP0_5_OFFSET
ldr r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET
bic r1, r1, #(0xf << 28) @ 28 = 7 * 4-bit
orr r1, r1, #(0x1 << 28) @ Output
str r1, [r0, #0x0] @ S5PC1XX_GPIO_CON_OFFSET
ldr r1, [r0, #0x8] @ S5PC1XX_GPIO_PULL_OFFSET
bic r1, r1, #(0x3 << 14) @ 14 = 7 * 2-bit
orr r1, r1, #(0x2 << 14) @ Pull-up enabled
str r1, [r0, #0x8] @ S5PC1XX_GPIO_PULL_OFFSET
ldr r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET
orr r1, r1, #(1 << 7) @ 7 = 7 * 1-bit
str r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET
配置MP0_5寄存器。
查看原理图:
发现在原理图中MP0_5没有作为ADDR引脚使用。没有特殊的用途。
四、串口UART Line Control Register手册:
自己配置UART0,8个数据位,1个停止位,无校验。添加的代码:
ldr r0,=0xE2900000
ldr r1,=3
str r1,[r0] @ULCON0=3
五、Uart Control Register
ldr r1,=0x305 //此处代码需查看手册,确定寄存器的功能
str r1,[r0,#0x4] @UCON0=0x305
ldr r1,=1
str r1,[r0,#0x8] @UFCON0=0 //此处代码需查看手册,确定寄存器的功能
ldr r1,=0
str r1,[r0,#0xc] @UMCON0=0 //此处代码需查看手册,确定寄存器的功能
六、UART 时钟频率配置,需要配置下面UBRDIVn和UDIVSLOT两个寄存器。
UBRDIVn和UDIVSLOT的取值计算方法如上图中框起来的公式:
DIV_VAL=UBRDIVn+(num of 1’s in UDIVSLOTn)/16 = (PCLK/(bps*16))-1。
其中,UDIVSLOTn的取值如下表所示:
比如,当UDIVSLOTn取0x0080时,则num of 1‘s = 1.
**公式计算举例:**取bps = 115200。PCLK = 66M。当UDIVSLOTn=0x0080,num of 1‘s = 1。
此时:UBRDIVn+1/16 = (66M/(11520016))-1,计算得到UBRDIVn = (66M/(11520016))-1-1/16 =34.8072917-0.0625 = 34.74479≈35。当一次发送的报文过长,则34.74479≈35这一过程的偏差累积,就会影响到数据传送的准确性。因此,尽量使这个误差减小。推荐使用值:UDIVSLOTn = 0xDFDD,此时num of 1‘s = 13,UBRDIVn = 33.99479≈34。这样误差会小很多。
写入到程序里:
ldr r1,=34
str r1,[r0,#0x28] @UBRDIV0=34
ldr r1,0xDFDD
str r1,[r0,#0x2C] @UDIVSLOT0=0XDFDD,num of 1‘s = 13
七、使用串口发送数据,将数据写进发送数据寄存器
代码:
ldr r0,=0xE2900020
ldr r1,=0x55 @UART0='U',使用UART0发送'U'
str r1,[r0]
ldr r1,=0x61 @UART0='U',使用UART0发送'a'
str r1,[r0]
ldr r1,=0x72 @UART0='U',使用UART0发送'r'
str r1,[r0]
ldr r1,=0x74 @UART0='U',使用UART0发送't'
str r1,[r0]
ldr r1,=0xA @UART0='U',使用UART0发送'\r'
str r1,[r0]
ldr r1,=0xD @UART0='U',使用UART0发送'\n'
str r1,[r0]
WINDOWS中换行是:’\r\n’,’\r’=0xA,’\n’=0xD;
LINUX中换行是:’\n’。
八、前面这段UART配置代码,是为了测试在IRAM中运行BL1阶段16K程序的时候,通过UART发送数据,但是此时在链接阶段,lowlevel_init.S生成的.o文件被链接在uboot.bin的末尾,当生成uboot.16K文件的时候,此部分代码并不能被包含进去。
所以此时需要修改Makefile文件,此.o文件链接在start.o文件后面,修改内容如下:
重新编译即可。