s3c2440 DM9000网卡移植,RTC时钟使能

本文允许转载,但请注明出处:http://blog.csdn.net/u010944778/article/details/45271117

我原本只是想完成DM9000移植,而后想弄清楚其中base address的数据,继而再又了解了CPU与不同位宽外设间的连接。现在算是稍微了解了一些参数的由来吧。首先贴上看的s3c2440的datasheet以及dm9000的手册图:


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



没注意看手册的可以回去自己看一下手册,通过上面的我们可以知道最基本的三点:(1)DM9000的I/Obase address 300H~370H;(2)我们接了片选,且可以通过CMD的状态来选择发送数据或地址;(3) DM9000的AEN与s3c2440的NGCS4相连。

下面我们来看看S3c2440的手册图:



/************************************************************************************************************************************************/

如图可知:网卡的内存区域在BANK4,也就是从地址0x20000000开始。另外DM9000可以直接与ISA总线相连,也可以与大多数CPU相连。在这里,我们当然是要让DM9000与s3c2440相连接了。DM9000对 外来说只有两个端口——地址口和数据口,地址口用于输入内部寄存器的地址,而数据口则完成对某一寄存器的读写。DM9000的CMD引脚用来区分这两个端 口,当CMD引脚为0时,DM9000的数据线上传输的是寄存器地址,当CMD引脚为1时,传输的是读写数据。我们把DM9000的A8和A9接为高电 平,把A4~A7接为低电平,并且把DM9000的AEN接到s3c2440的nGCS4引脚上,则DM9000的端口基址为0x20000300,如果 再把DM9000的CMD引脚接到s3c2440的ADDR2引脚上,则我们就可以定义DM9000的这两个端口地址,它们分别为:

#define DM_ADDR_PORT (*((volatile unsigned short *) 0x20000300))//地址口

#define DM_DATA_PORT (*((volatile unsigned short *) 0x20000304))//数据口

DM9000网卡通过看datasheet可知他IO基地址有8种基地址,它们分别是300H,310H,320H,330H,340H,350H,360H和370H。遵循datasheet的公式:IO base = (strap pin value of TXD[2:0]) * 10H + 300H
而有些应用场合会用到多片DM9000网卡,因此需要根据每个网卡的基地址来选择需要操作的网卡,SA4—9是s3c2440的地址总线,用来选择DM9000,datasheet说明当SA9和SA8引脚高电平,SA7和AEN处于低电平,SA6~4引脚状态与TXD[2:0](strap pins)引脚状态匹配时,该DM9000网卡就会被选中。

=================================================================================================

注意:我们所说的地址:0x20000000 和 0x20000004 是由ARM芯片的地址引脚决定的,注意,这个地址表示是用的16进制,那么,0x20000004的每一位的值都可以是0~f,它由ARM的4根地址线的电平高,比如最低的一位,就是由 ADDR3~ADDR0 这4个引脚的电平决定,如果 ADDR3~ADDR0 = 1111,则该位为f ,如果 LADDR3~LADDR0 = 0100,则该位为 4。因此,如果将 DM9000的CMD引脚接到s3c2440的ADDR2,由于CMD引脚的高低电平决定地址口和数据口,那么,ADDR2为0时,访问的就是地址口,所以地址口的起始地址为 ARRD2为0的情况,即0x20000000 ;ADDR2为1时,(LADDR3~LADDR0 = 0100)访问的就是数据口,所以数据口的地址即 0x20000004。

下面再上一张图:


可以看到,我们的S3C2440CPU其实可以接不同位宽的外设,CPU认为一个地址对应一个字节的。而我们的外设为16位的DM9000网卡,也就是会说对于网卡来说它认为一个地址线是对应两个字节,倘若外设为SDRAM32位则是4个字节,那么cpu与连接的外设如何通过那一根地址线互相协调获取字节数据呢?

最重要的一点就是:牛逼的内存控制器可以从所获的单元中自动选取所需要的地址。
所以当cpu要获得16位外设地址3的一个字节时,是先获取外设第1个地址单元(两个字节),然后从自动从这个单元的两个字节中选取具体所要的那个字节。而不论是获取地址2(0X0000,0010)或者是地址3(0X0000,0011)这两个字节都存放在同一个地址单元。那么cpu给内存控制器发送(0X0000,0010)(0X0000,0011)获取指令后,内存控制器通过地址线ADDR1,也就是(0x0000,001x)来获取对应的地址单元后再选择即可。所以ADDR0线即第0地址位不论是1或者是0对于内存控制器来说都无所谓,他只要获取到地址单元,再负责把CPU老板告诉他的具体字节(即地址2或者地址3的那个字节)从地址单元中获取出来就完成任务。 同理;对于SDRAM来说,对外是32位的。对于内存控制器来说:0(0x0000,0000)~3(0x0000,0011)为一个单元,所以ADDR0和ADDR1都不用具体获取,CPU与SDRAM之间直接从ADDR2(0x0000,0x00)开始接,选择对应的地址单元后再获取具体的字节即可。

下面是简陋的图解:

具体的可以看韦东山老师的视频《怎么看原理图之内存类接口》,看完肯定会更理解些。

下面的修改驱动程序就很简单了。

--- mach-smdk2440_o.c   2015-04-24 11:39:20.492017397 +0800
+++ mach-smdk2440.c     2015-04-24 12:24:04.000000000 +0800
@@ -22,6 +22,7 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/dm9000.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -46,6 +47,69 @@
 #include <plat/cpu.h>
 
 #include <plat/common-smdk.h>
+#include <sound/s3c24xx_uda134x.h>
+#include <mach/gpio-nrs.h>
+
+#define MACH_SMDK2440_DM9K_BASE (S3C2410_CS4 + 0x300)
+/* audio */
+
+static struct platform_device uda1340_codec = {
+               .name = "uda134x-codec",
+               .id = -1,
+};
+
+
+
+static struct s3c24xx_uda134x_platform_data smdk2440_audio_pins = {
+       .l3_clk = S3C2410_GPB(4),
+       .l3_mode = S3C2410_GPB(2),
+       .l3_data = S3C2410_GPB(3),
+       .model = UDA134X_UDA1341
+};
+
+static struct platform_device smdk2440_audio = {
+       .name           = "s3c24xx_uda134x",
+       //.id           = 0,
+       .dev            = {
+               .platform_data  = &smdk2440_audio_pins,
+       },
+};
+
+
+
+/*dm9000  */
+static struct resource smdk2440_dm9k_resource[] = {
+    [0] = {
+        .start  = MACH_SMDK2440_DM9K_BASE,
+        .end    = MACH_SMDK2440_DM9K_BASE + 3,
+        .flags  = IORESOURCE_MEM
+    },
+    [1] = {
+        .start  = MACH_SMDK2440_DM9K_BASE + 4,
+        .end    = MACH_SMDK2440_DM9K_BASE + 7,
+        .flags  = IORESOURCE_MEM
+    },
+    [2] = {
+        .start  = IRQ_EINT7,
+        .end    = IRQ_EINT7,
+        .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+    }
+};
+
+static struct dm9000_plat_data smdk2440_dm9k_pdata = {
+       .flags          = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device smdk2440_device_eth = {
+       .name           = "dm9000",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(smdk2440_dm9k_resource),
+       .resource       = smdk2440_dm9k_resource,
+       .dev            = {
+               .platform_data  = &smdk2440_dm9k_pdata,
+       },
+};
+
 
 static struct map_desc smdk2440_iodesc[] __initdata = {
        /* ISA IO Space map (memory space selected by A24) */
@@ -155,6 +219,11 @@
        &s3c_device_wdt,
        &s3c_device_i2c0,
        &s3c_device_iis,
+       &smdk2440_device_eth,
+       &smdk2440_audio,
+       &uda1340_codec,
+       &samsung_asoc_dma,
+       &s3c_device_rtc,    //额,RTC时钟使能真的只要添加一句话..加进去后修改内核配置。
 };
 
 static void __init smdk2440_map_io(void)

然后直接make menuconfig中 
Devices Driver->
Network device support->
Ethernet(10 or 10Mbit)->dm9000 surpport


RTC时钟在S3C2440上的添加非常的简单,因为linux平台已经支持了,只要把RTC的platform_deivce进行注册,对内核进行简单配置就好。
<*> Real Time Clock --->
[*] Set system time from RTC on startup and resume
(rtc0) RTC used to set the system time
[*] /sys/class/rtc/rtcN (sysfs)
[*] /proc/driver/rtc (procfs for rtc0)
[*] /dev/rtcN (character devices)
<*> Samsung S3C series SoC RTC


说到时钟,在Linux下的时间分为两种:系统时间与硬件时间(RTC)

粗略的说系统时间就是我们运行系统时,用date命令所能查看到的时间。

硬件时间:就是开发板上RTC芯片上面的时间,开发板上有个特定的电池为其供电,即使总电源断掉也不影响。

linux系统开机时,会从RTC中读取当前时间,作为系统时间,从此以后系统时间独立tick,即使你用date命令修改了系统时间,RTC时间也是不会收到影响的。如果此时关机,下次的系统时间还是不准确。要想将系统时间保存到硬件时间。我们可以通过date和hwclock配合来对时间随心的修改。


通过# hwclock --help   我们可以看到:

hwclock -r   显示硬件时钟

hwclock -s  用RTC时间替换掉当前的系统时间,也就是将RTC时间设置为当前系统的时间。

hwclock -w  将当前系统的时间设置为RTC时间。


Referencehttp://blog.csdn.net/fulinus/article/details/41171879

还一段话的参考链接找不到了,如有要求请博主与我联系。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值