ITOP4412裸机编程-串口驱动

文章目录

  • 前言:
  • 原理分析:
  • 源码:
    •        修改main.S
    •        修改exynos4412.h
    •        修改Makefile
    •        修改uart.lds
  • 烧录SD卡:
  • 现象:
  • 源码获取:

前言:

       看过我文章的小伙伴有的可能会有疑问,为什么用汇编,用C语言不好吗?我在这里说明一下,因为后面可能要移植UBoot最新的程序,而UBoot的程序在最初的一段是用汇编写的,所以我们这里也用汇编写,后期移植UBoot就很方便了。烧录SD的脚本和第一章点亮LED灯的一样,这里不再贴出来了,而是直接用了。

原理分析:

       在STM32单片机里,在编写驱动前做的一件很重要的事情就是时钟树配置,这里串口驱动也是,要先配置时钟树才能配置串口,不然波特率无法计算。
ITOP4412裸机编程-串口驱动_第1张图片
       从上面图可以看出,配置时钟树要先配置DMC的时钟,之后在选择左右总线。
ITOP4412裸机编程-串口驱动_第2张图片
       从上面的图片可以看出,UART挂载在PERI-L时钟分支下面。
ITOP4412裸机编程-串口驱动_第3张图片
       由上面图可以看出,先配置SCLKmpll时钟来源,经过锁相环电路,分频电路最终到达PERIL,而UART就挂载在这个时钟分支下面,有的小伙伴会问,那干嘛配置DMC,请看下图。
ITOP4412裸机编程-串口驱动_第4张图片
       内核的时钟树下面蓝色部分有个锁相环,这个锁相环决定了SCLKmpll时钟的来源,而前面还有一个MPLL配置电路,不属于该内核。而锁相环和DMC在一个时钟树中,所以后面需要配置这个锁相环在DMC相关的寄存器中。这里还有一个问题,就是FOUTmpll怎么会配置成的800Mhz,外部时钟来源是24Mhz的有源晶振。
ITOP4412裸机编程-串口驱动_第5张图片
ITOP4412裸机编程-串口驱动_第6张图片
       从上述图片可以看出来,MPLL_CON0寄存器可以配置FOUT的值,它的值决定于下面的FOUT公式,而这个公式和MPS的设置有关,而从上面MPS表可以查得,P=3,M=100,S=0时FOUT的值就是800了。
       OK!总结一下配置的流程:
先配置MPLL_CON0寄存器让FOUT的值为800,在配置CLK_SRC_DMC寄存器使锁相环选定FOUTmpll为时钟来源,再配置CLK_SRC_TOP1寄存器使MUXmpll_ctrl_user_T锁相环选定SCLKmpll为时钟来源,再配置CLK_SRC_PERIL0寄存器使时钟作用于想用的UART,再配置CLK_DIV_PERIL0寄存器使DIVACLK_100把MPLL的8分频后作用于对应的UART,时钟配置到这里就结束了。之后再设置UART的触发方式,数据格式,波特率等就简单了。这里不再叙述UART的配置方法,根据源码去三星的手册中查寄存器即可。

源码:

       新建文件夹及文件

mkdir uart
cd uart
touch main.S exynos4412.h uart.lds Makefile

       修改main.S

#include "exynos4412.h"
.global _start

.word 0x2000
.word 0x0
.word 0x0
.word 0x0

_start:
   ldr r10, =0x1002330c
   ldr r11, [r10]
   orr r11, r11,#0x300
   str r11, [r10]
       
   ldr r10, =0x11000c08
   ldr r11, =0x0
   str r11, [r10]

   ldr r10, =GPA1CON
   ldr r11, =0x222222
   str r11, [r10]

   ldr r10, =MPLL_CON0
   ldr r11, =0x80640300
   str r11, [r10]

   ldr r10, =CLK_SRC_DMC
   ldr r11, =0x00011000
   str r11, [r10]

   ldr r10, =CLK_SRC_TOP1
   ldr r11, =0x01111000
   str r11, [r10]
   
   ldr r10, =CLK_SRC_PERIL0
   ldr r11, =0x66666
   str r11, [r10]
   
   ldr r10, =CLK_DIV_PERIL0
   ldr r11, =0x777777
   str r11, [r10]

   ldr r10, =UFCON2
   ldr r11, =0x111
   str r11, [r10]

   ldr r10, =ULCON2
   ldr r11, =0x3
   str r11, [r10]
   
   ldr r10, =UCON2
   ldr r11, =0x3c5
   str r11, [r10]
   
   ldr r10, =UBRDIV2
   ldr r11, =0x35
   str r11, [r10]
   
   ldr r10, =UFRACVAL2
   ldr r11, =0x4
   str r11, [r10]
   
   ldr r10, =UTXH2	
   ldr r11, =0x55
   str r11, [r10]
   
   ldr r11, =0x61
   str r11, [r10]
   
   ldr r11, =0x72
   str r11, [r10]
   
   ldr r11, =0x74
   str r11, [r10]
   
   ldr r11, =0xA
   str r11, [r10]
   
   ldr r11, =0xD
   str r11, [r10]

loop:	
   ldr r10, =GPL2CON
   mov r11, #(0x01<<0)
   str r11, [r10]
   ldr r10, =GPL2DAT
   mov r11, #0x01
   str r11, [r10]

   b	loop

       修改exynos4412.h

#ifndef EXYNOS4412_H
#define EXYNOS4412_H

#define GPX1CON (0x11000000+0x0c20)
#define GPX1DAT (0x11000000+0x0c24)
#define GPX1PUD (0x11000000+0x0c28)
#define GPX1DRV (0x11000000+0x0c2c)

#define GPK1CON (0x11000000+0x0060)
#define GPK1DAT (0x11000000+0x0064)
#define GPK1PUD (0x11000000+0x0068)
#define GPK1DRV (0x11000000+0x006c)

#define GPL2CON (0x11000000+0x0100)
#define GPL2DAT (0x11000000+0x0104)
#define GPL2PUD (0x11000000+0x0108)
#define GPL2DRV (0x11000000+0x010c)


//uart
// GPIO
#define GPA1CON (0x11400020)
// MPLL
#define MPLL_CON0 (0x10040108)
#define CLK_SRC_DMC (0x10040200)
#define CLK_SRC_TOP1 (0x1003C214)
// system clock
#define CLK_SRC_PERIL0 (0x1003C250)
#define CLK_DIV_PERIL0 (0x1003C550)
// UART
#define UFCON2 (0x13820008)
#define ULCON2 (0x13820000)
#define UCON2 (0x13820004)
#define UBRDIV2 (0x13820028)
#define UFRACVAL2 (0x1382002c)
#define UTXH2 (0x13820020)
#define URXH2 (0x13820024)

#define UTRSTAT2 (0x13820010)

#endif

       修改Makefile

CROSS_COMPILE = arm-linux-gnueabihf-
%.o : %.S
	$(CROSS_COMPILE)gcc -o $@ $< -c

%.o : %.c
	$(CROSS_COMPILE)gcc -o $@ $< -c

.PHONY: all
all :	uart.elf

uart.elf : main.o uart.lds
	$(CROSS_COMPILE)ld -T uart.lds -o uart.elf $^
	$(CROSS_COMPILE)objcopy -O binary uart.elf uart.bin
	$(CROSS_COMPILE)objdump -D uart.elf > uart.dis

.PHONY : clean
clean:
	rm -rf *.o *.elf *.bin *.dis

       修改uart.lds

SECTIONS
{
	. = 0x02023400;
	.text : {
		main.o
		* (.text)
	}
	.rodata ALIGN(4) : {
		* (.rodata*)
	}
	
	.data ALIGN(4) : {
		* (.data*)
	}
	.bss ALIGN(4) : {
		* (.bss)
		* (COMMON)
	}
}

修改完上诉文件使用指令make生成uart.bin下面要用到

烧录SD卡:

我这里的SD卡的设备节点是sdb,请根据自己的实际情况改正后烧录

cd sd_fuse/itop4412
./sd_fusing.sh /dev/sdb ../../uart.bin

现象:

       这里现象就不发图片了,现象就是连接串口之后,串口助手会显示Uart四个字母,开发板有一个LED灯亮。如果有疑问,请加群讨论。

源码获取:

可以加入群聊:667039215找群主获取
CSDN获取:uart压缩包
github下载:git clone https://github.com/HOU1354696096/ITOP4412.git

你可能感兴趣的:(嵌入式linux系统)