刘启明2010-5-3
  FL2440的开发板提供了DM9000A的驱动源码,在开发板上测试通过,能正常上网。将驱动移到公司的机器上,由于公司的硬件电路和FL2440上连接有一些差别,所以移起来并不是那么一帆风顺。
  对比飞凌开发板和公司产品的硬件电路,区别如下:
  一:飞凌开发板的DM9000A,中断脚即34脚连到了2440的GPF7,而公司产品连到了GPF3.
  二:FL2440的DM9000A选择脚CS脚,即37脚连到了2440的NGCS4,而公司产品连到了NGCS1.
  三:FL2440的DM9000A的CMD脚,即第32脚连到了2440地址总线的ADDR2,而公司产品却连到了ADDR11.
  四:网口,FL2440用的HR911105A,而公司产品为了省钱,这么昂贵的东西舍不得啊,不过对编程这个没有影响。
  这里我们只关心前面三点,第一点,中断脚。在整个DM9000A的源码中,找不到中断脚的任何配置,首先这个就难住了一片人。我们仔细分析,发现在Dm9isa.cpp的开头处,有这么一个结构数组:
  CONFIG_PARAMETER g_szDm9ConfigParams[] =
  {
  { CID_CONNECTION_TYPE, -1, NDIS_STRING_CONST("ConnectionType") },
  { CID_SLOT_NUMBER, -1, NDIS_STRING_CONST("SlotNumber")},
  { CID_BUFFER_PHYSICAL_ADDRESS, 0, NDIS_STRING_CONST("BufferPhysicalAddress")},
  { CID_TXBUFFER_NUMBER, 0x20, NDIS_STRING_CONST("XmitBuffer")},
  { CID_RXBUFFER_NUMBER, 0x10, NDIS_STRING_CONST("RecvBuffer")},
  { CID_ADAPTER_NUMBER, 0, NDIS_STRING_CONST("AdapterNumber")},
  { CID_IO_BASE_ADDRESS, 0x08300000/*0x08000300*/, NDIS_STRING_CONST("IoAddress")},// 这样应该就改成nGCS1了吧!!!
  //{ CID_IO_BASE_ADDRESS, 0x20300000, NDIS_STRING_CONST("IoAddress")},
  { CID_IO_RANGE, 0x10, NDIS_STRING_CONST("IoRange")},
  //{ CID_IRQ_NUMBER, 0X23, NDIS_STRING_CONST("IrqNumber")},
  { CID_IRQ_NUMBER, 0x3, NDIS_STRING_CONST("IrqNumber")},// 这里是物理中断号.K390硬件接GPF3.lqm:10-04-30
  { -1,-1,NULL}
  };
  这里CID_IRQ_NUMBER表示DM9000A所连接的物理中断号,FL2440默认为0x23,转化为十进制为35,在s3c2440a_intr.h里面,不然发现,原来35表示IRQ_EINT7,其定义如下:
  #define IRQ_EINT7 35
  这就是定义DM9000A的中断所在!由于公司产品使用的是GPF3,同样看s3c2440a_intr.h里面的定义,发现IRQ_EINT3=3,于是我们顺理成章的将0x23改成了0x3。
  上面数组中还有一个数字很重要,0x20300000。打开三星的内存映射表,具体如下:
  可以看到,上面的地址在bank4的范围内,而bank4是通过nGCS4选择的!这一点与FL2440的硬件连接不谋而合,这也正是为什么飞凌DM9000A驱动使用这个地址的原因所在!由于公司产品使用的nGCS1,于是我将地址改成了0x80000300。
  也许你认为两处差异,一下子就在这里解决了,其实事情远没有这么简单!难道中断,就只用在一个数组里面定义就OK了吗?仔细看驱动源代码,不然发现程序是通过读取注册表的键值来决定中断,IP地址等的。打开注册表,platform.reg,相关代码如下:
  IF BSP_DM9000 !
  [HKEY_LOCAL_MACHINE/Comm/DM9CE]
  "DisplayName"="DM9000A/9010 ISA Fast Ethernet Adapter"
  "Group"="NDIS"
  "ImagePath"="dm9isa.dll"
  [HKEY_LOCAL_MACHINE/Comm/DM9CE/Linkage]
  "Route"=multi_sz:"dm9ce1"
  [HKEY_LOCAL_MACHINE/Comm/DM9CE1]
  "DisplayName"="DM9000A/9010 ISA Fast Ethernet Adapter"
  "Group"="NDIS"
  "ImagePath"="dm9isa.dll"
  [HKEY_LOCAL_MACHINE/Comm/Tcpip/Linkage]
  "Bind"="dm9ce1"
  [HKEY_LOCAL_MACHINE/Comm/DM9CE1/Parms]
  "BusNumber"=dword:0
  "BusType"=dword:0
  "XmitBuffer"=dword:20
  "RecvBuffer"=dword:20
  ;"IrqNumber"=dword:23
  "IrqNumber"=dword:3 ;lqm changed for K390.
  "MACAddress" =hex:00,0A,EB,FD,7A,00
  [HKEY_LOCAL_MACHINE/Comm/DM9CE1/Parms/TcpIp]
  "EnableDHCP"=dword:0
  "UseZeroBroadcast"=dword:0
  "DefaultGateway"="192.168.1.1"
  "IpAddress"="192.168.1.227" "Subnetmask"="255.255.255.0" "DNS"="202.96.134.133" ENDIF BSP_DM9000 ! 将上面的IrqNumber值改成0x3,将IP地址,子网掩码,DNS等全照你电脑上的设置(通过ipconfig /all命令查看)。
  再看第三点,CMD。该管脚为高电平时,表示访问数据端口,为低电平时,表示访问INDEX端口。在Dm9isa.h的最前面,有如下定义:
  #define DM9000_ADDR_OFFSET 0x00//(SMSC_ETHERNET_BASE_U_VIRTUAL+0x300)
  //#define DM9000_DATA_OFFSET 0x04
  #define DM9000_DATA_OFFSET 0x800 //lqm changed for K390
  飞凌的板CMD接到了ADDR2上,拿起指甲数数,是不是0x04?再看公司接的是ADDR11上,再数下,是不是0x800了?如果这里设置错误,读取到的DM9000A的ID号会读成地址值,即0x28292a2b。
  理论上,到此,程序已经改完了。但是还有一点我们绝对不能忽视,那就是中断的实现机制。在E:/WINCE500/PLATFORM/SMDK2440A/Src/Kernel/Oal中目录下,打开intr.c文件,将默认的GPF7中断全改为GPF3,包括EXTINT0寄存器。具体更改后的代码如下:
  BOOL BSPIntrInit()
  {
  S3C2440A_IOPORT_REG *pOalPortRegs;
  ULONG value;
  OALMSG(OAL_INTR&&OAL_FUNC, (L"+BSPIntrInit/r/n"));
  // Then get virtual address for IO port
  pOalPortRegs = OALPAtoVA(S3C2440A_BASE_REG_PA_IOPORT, FALSE);
  // Set GPF7 as EINT7
  value = INREG32(&pOalPortRegs->GPFCON);
  //OUTREG32(&pOalPortRegs->GPFCON, (value & ~(3 << 14))|(2 << 14));
  OUTREG32(&pOalPortRegs->GPFCON, (value & ~(3 << 6))|(2 << 6));// lqm changed to GPF3 for K390.
  // Disable pullup
  value = INREG32(&pOalPortRegs->GPFUP);
  //OUTREG32(&pOalPortRegs->GPFUP, value | (1 << 7));
  OUTREG32(&pOalPortRegs->GPFUP, value | (1 << 3));// lqm changed to GPF3 for K390.
  // High level interrupt
  value = INREG32(&pOalPortRegs->EXTINT0);
  //OUTREG32(&pOalPortRegs->EXTINT0, (value & ~(0xf << 28))|(0x1 << 28));
  OUTREG32(&pOalPortRegs->EXTINT0, (value & ~(0xf << 12))|(0x1 << 12));// lqm changed to GPF3 for K390.
  // Set GPG1 as EINT9
  value = INREG32(&pOalPortRegs->GPGCON);
  OUTREG32(&pOalPortRegs->GPGCON, (value & ~(3 << 2))|(2 << 2));
  // Disable pullup
  value = INREG32(&pOalPortRegs->GPGUP);
  OUTREG32(&pOalPortRegs->GPGUP, value | (1 << 1));
  // High level interrupt
  value = INREG32(&pOalPortRegs->EXTINT1);
  OUTREG32(&pOalPortRegs->EXTINT1, (value & ~(0xf << 4))|(0x4 << 4));
  // Add static mapping for Built-In OHCI
  OALIntrStaticTranslate(SYSINTR_OHCI, IRQ_USBH);
  // OALIntrStaticTranslate(SYSINTR_USBFN, IRQ_USBFN);
  OALMSG(OAL_INTR&&OAL_FUNC, (L"-BSPIntrInit(rc = 1)/r/n"));
  return TRUE;
  }
  注意,如果DM9000A的EECK脚悬空或是下拉,那么中断脚一定要设置为高电平触发中断,如果EECK脚上拉,那么中断脚一定要设置为低电平触发!
  再打开E:/WINCE500/PLATFORM/SMDK2440A/Src/Common/Intr的intr.c文件,仔细查看里面的每一个函数的实现,如果没有对GPF3设置,需要修改!这里我对OALIntrEnableIrqs函数做了如下修改:
  BOOL OALIntrEnableIrqs(UINT32 count, const UINT32 *pIrqs)
 {

BOOL rc = TRUE;
 UINT32 i, mask, irq;

OALMSG(OAL_INTR&&OAL_FUNC, (
  L"+OALIntrEnableIrqs(%d, 0x%08x)/r/n", count, pIrqs
 ));

for (i = 0; i < count; i++) {
#ifndef OAL_BSP_CALLBACKS
  irq = pIrqs[i];
#else
  // Give BSP chance to enable irq on subordinate interrupt controller
  irq = BSPIntrEnableIrq(pIrqs[i]);
#endif
  if (irq == OAL_INTR_IRQ_UNDEFINED) continue;
  // Depending on IRQ number use internal or external mask register
  if (irq <= IRQ_ADC) {
   // Use interrupt mask register
   CLRREG32(&g_pIntrRegs->INTMSK, 1 << irq);
  } else if (irq <= IRQ_EINT7) {
   // Use external mask register
   CLRREG32(&g_pIntrRegs->INTMSK, 1 << IRQ_EINT4_7);
   CLRREG32(&g_pPortRegs->EINTMASK, 1 << (irq - IRQ_EINT4 + 4));
  } else if (irq <= IRQ_EINT23) {
   // Use external mask register
   mask = 1 << (irq - IRQ_EINT4 + 4);
   OUTREG32(&g_pPortRegs->EINTPEND, mask);
   CLRREG32(&g_pPortRegs->EINTMASK, mask);
   mask = 1 << IRQ_EINT8_23;
   if ((INREG32(&g_pIntrRegs->INTPND) & mask) != 0) {
    OUTREG32(&g_pIntrRegs->INTPND, mask);
   }
   CLRREG32( &g_pIntrRegs->INTMSK, 1 << IRQ_EINT8_23);
  } else {
   rc = FALSE;
  }
 }

OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrEnableIrqs(rc = %d)/r/n", rc));
 return rc;

}

查看S3C2440的EINTMASK寄存器,发现EINT0到EINT3是保留的,不知三星出于什么目的。如果三星规格书没有错,使用GPF3做中断脚时,EINTMASK应该可以不设置,即这个函数可以不作修改。
  最后一步,在整个BSP包中搜索关于GPF3,GPA12(即nGCS1)的设置情况,如果发现有错误设置的,一定要屏掉,否则无法正常上网!在FL2440的包中,流水灯使用了GPF3,OAL的init.c中误设置了GPF3,更正过来后,编译common下的intr文件夹,编译kernel,make。到此为止,DM9000A驱动移植告一段落。

基于S3C2440A的DM9000A的调试笔记相关推荐

  1. Rockchip基于RK3566/RK3568 WiFi AP6256调试笔记

    1.开发平台 CPU:RK3566 编译环境:Ubuntu18.04 内核版本:kernel 4.19 2.目的 因为RK3566/RK3568支持SDIO3.0并且向下兼有SDIO2.0接口,由于核 ...

  2. FL2440(S3C2440A 芯片) 开发板开发笔记

    FL2440(S3C2440A 芯片) 开发板开发笔记 开发板的拨码开关指南: FL2440 改 vnfg 飞凌嵌入式 www. witech. com. cn 09. 8. 22 1 开发板使用手册 ...

  3. keil4怎么移植其他人的程序_【调试笔记】韦东山:在100ask_imx6ull上移植使用六轴传感器ICM20608...

    之前发了LCD调试笔记,大家很感兴趣,所以这次再来一篇:六轴传感器ICM20608驱动移植笔记,大家还需要什么移植笔记?可以留言.我们尽量满足. 1.1 移植思路 先找到驱动:也许内核里已经有,也许需 ...

  4. qcc514x-qcc304x调试笔记

    QCC514X-QCC304X系列调试笔记,用的高通QCC5141芯片,基于qcc514x-qcc304x-src-1-0_qtil_standard_oem_earbud-ADK-21.1-CS2- ...

  5. OMAPL138调试笔记

    title: Linux 嵌入式使用 tags: 新建,模板,小书匠 grammar_cjkRuby: true Copyright (C) @2018 Widic Filename:File-fun ...

  6. ARM+Movidius VPU 目标识别调试笔记(一)

    写在前面 Movidius 是一家被Intel收购的计算机视觉创业公司.Intel收购Movidius之后,在AI和边缘计算方面的布局又增加了一支生力军.Movidius的AI芯片分为Myriad x ...

  7. 【调试笔记】韦东山:在100ask_imx6ull上移植使用六轴传感器ICM20608

    在线课堂:https://www.100ask.net/index(课程观看) 论  坛:http://bbs.100ask.net/(学术答疑) 开 发 板:https://100ask.taoba ...

  8. HSC490控制器调试笔记(一)

    HSC490控制器调试笔记 HSC490控制器 1.硬件信息 2.设备连接 3.问题及解决方法 HSC490控制器 C490是一款基于CoDesysV2.3软件平台开发的可现场编辑控制器.控制器编程符 ...

  9. Arduino驱动QMC6308地磁传感器调试笔记(1)

    一.QMC地磁传感器介绍(矽睿科技) QMC6308是三轴磁传感器,它将磁传感器和信号环境ASIC集成到一个硅芯片中. 该晶片级芯片级封装(WLCSP)适用于移动和可穿戴设备中的电子罗盘,地图旋转,游 ...

  10. 基于Solr的空间搜索学习笔记

    基于Solr的空间搜索学习笔记 在Solr中基于空间地址查询主要围绕2个概念实现: (1) Cartesian Tiers 笛卡尔层 Cartesian Tiers是通过将一个平面地图的根据设定的层次 ...

最新文章

  1. c语言 switch案例,C语言程序设计 2. switch语句的运用 案例 switch条件语句.docx
  2. struts1 几种Action父类的比较
  3. c++ 多个字符串排序_Python小白干货宝典:sorted()函数:列表元素排序
  4. ES 集中式日志分析平台 Elastic Stack(介绍)
  5. Tomcat新版本旧版本下载(Windows和Linux)
  6. 检查手机是否安装外置SD卡
  7. linux下加载ISO镜像的方法
  8. 程序上下文切换,什么是上下文?
  9. 顶隙计算公式_齿轮参数计算公式
  10. C++ 依赖倒置原则
  11. mac接收gmail邮件_如何从您的Gmail帐户发送和接收Hotmail
  12. html的css雪花动效,《前端每日实战》第171号作品:用纯 CSS 绘制一朵美丽的雪花...
  13. android 麦克风录音输出
  14. 杭电OJ 1181(C++)
  15. 选择游戏服务器需要什么配置?
  16. 绍兴14岁女孩被德云社录取,她究竟有什么来历呢?
  17. 想练八段锦?扔掉可爱漫画版吧,现在出真人教练版了!
  18. @Hello, I'm Tiw.@
  19. pymongo.errors.ConfigurationError: incompatible_err
  20. JAVA读取文本文件内容以流的形式返回到前端

热门文章

  1. 服务器远程ghost,神奇Ghost 轻松远程安装软件
  2. OpenEuler编译、安装与挂载f2fs文件系统
  3. 四阶龙格库塔matlab计算例题,四阶龙格库塔法matlab实现
  4. 【Python】numpy库和scipy库的安装与使用
  5. PostgreSQL column cryptographic use pgcrypto extension and optional openssl lib
  6. log4j2配置文件详解
  7. IAT-Hook 劫持进程Api调用
  8. C语言栈括号匹配算法
  9. 基于51单片机的电子时钟
  10. 网站服务器 开放端口扫描,端口扫描之开放端口扫描方式