打印

在s3c2440a的mon程序中支持SD Card时要注意:在2440addr.h

[复制链接]
2747|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
阿南|  楼主 | 2007-11-23 22:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
中的rSDIDAT寄存器地址定义有误.

最近想在2440a的一个bootloader中增加SD卡的读写功能,该bootloader的原始代码是官方的u2440amon,由于官方的2440a test程序中包含了SD Card的测试代码sdi.c和sdi.h,直接将这两个文件加进工程中,运行时确出现了问题。后来直接对官方的2440a_fw_testcode_rev06_040607和u2440amon_rev03_20040315进行了测试,将sdi.c和sdi.h从前者复制到后者,且加入到工程中,及增加测试调用,结果是前者测试正常,后者出现了问题,如图:
 https://bbs.21ic.com/upfiles/img/200711/2007112322516528.jpg
将相关的时钟、GPIO口、中断等所有能想到的都找了,还是没找出原因!后来没办法,只能对照数据手册上的寄存器说明,跟踪、分析代码,查看运行过程中有关的寄存器值。
程序死循环在Wt_Block函数中的Chk_DATend函数里,如下图:
https://bbs.21ic.com/upfiles/img/200711/2007112322836630.jpg
 
原因是“Data Transfer Finish”位一直都没有置位,即写数据没有完成。原先以为是和时钟、I/O口等有关,但没找到原因,只好单步跟踪写数据的过程,分别跟踪test和mon两个工程的Wt_Block函数,查看寄存器值,后来发现他们有些不一样,特别是每次将数据写入rSDIDAT(SDI数据寄存器)时,umon中的0x5A00003C值就加1,后来终于在反汇编代码中发现,在umon中,rSDIDAT地址居然是0x5A00003C,而test中是0x5A000040,如下图:
https://bbs.21ic.com/upfiles/img/200711/20071123221043789.jpg
 
请看图中的649行的最后一句反汇编代码,就是将数据写入rSDIDAT,在umon中,rSDIDAT地址为r3(0x5a000000)+0x3c;在test中为r3+0x40。所以就分别在mon、test该部分的源程序中双击选rSDIDAT,点右键的”go to macro declaration of rSDIDAT”跳到2440addr.h文件中的该定义出,发现如下图:
 https://bbs.21ic.com/upfiles/img/200711/2007112322141245.jpg
此时将该寄存器地址修改过来,再编译运行就正常了。

相关帖子

沙发
阿南|  楼主 | 2007-11-23 22:15 | 只看该作者

图1

使用特权

评论回复
板凳
阿南|  楼主 | 2007-11-23 22:19 | 只看该作者

图2

使用特权

评论回复
地板
阿南|  楼主 | 2007-11-23 22:19 | 只看该作者

图3

使用特权

评论回复
5
阿南|  楼主 | 2007-11-23 22:20 | 只看该作者

图4

使用特权

评论回复
6
icecut| | 2007-11-24 15:42 | 只看该作者

我的是这个版本的

#ifdef __BIG_ENDIAN  /* edited for 2440A */
#define rSDIDAT    (*(volatile unsigned *)0x5a00004c)    //SDI data
#define SDIDAT     0x5a00004c  
#else  // Little Endian
#define rSDIDAT    (*(volatile unsigned *)0x5a000040)    //SDI data 
#define SDIDAT     0x5a000040  
#endif   //SD Interface

使用特权

评论回复
7
xieqin| | 2007-11-24 18:49 | 只看该作者

2440 手册上有讲到吧

SDIDAT 

0x5A000040, 44, 48,
4C(Li/W, Li/HW, Li/B, Bi/
0x5A000041(Bi/HW),
0x5A000043(Bi/B)

NOTE:
! (Li/W, Li/HW, Li/B): Access by Word/HalfWord//Byte unit when endian mode is Little
! (Bi/W): Access by Word unit when endian mode is Big
! (Bi/HW): Access by HalfWord unit when endian mode is Big
! (Bi/B): Access by Byte unit when endian mode is Big

像2440addr.h这种头文件本身设计就不好,如果想用MMU把寄存器保护起来,都没法用了.

下面这样就好多了:
typedef struct{
    reg32 SDICON     ; //0x5a000000)    //SDI control
    reg32 SDIPRE     ; //0x5a000004)    //SDI baud rate prescaler
    reg32 SDICARG    ; //0x5a000008)    //SDI command argument
    reg32 SDICCON    ; //0x5a00000c)    //SDI command control
    reg32 SDICSTA    ; //0x5a000010)    //SDI command status
    reg32 SDIRSP0    ; //0x5a000014)    //SDI response 0
    reg32 SDIRSP1    ; //0x5a000018)    //SDI response 1
    reg32 SDIRSP2    ; //0x5a00001c)    //SDI response 2
    reg32 SDIRSP3    ; //0x5a000020)    //SDI response 3
    reg32 SDIDTIMER  ; //0x5a000024)    //SDI data/busy timer
    reg32 SDIBSIZE   ; //0x5a000028)    //SDI block size
    reg32 SDIDCON    ; //0x5a00002c)    //SDI data control
    reg32 SDIDCNT    ; //0x5a000030)    //SDI data remain counter
    reg32 SDIDSTA    ; //0x5a000034)    //SDI data status
    reg32 SDIFSTA    ; //0x5a000038)    //SDI FIFO status
    reg32 SDIIMSK    ; //0x5a00003c)    //SDI interrupt mask. edited for 2440A
    
#ifdef __BIG_ENDIAN  /* edited for 2440A */
    reg32 rsvd[3];
    reg32 SDIDAT    ; //0x5a00004c)    //SDI data

#else  
    reg32 SDIDAT    ; //0x5a000040)    //SDI data 
#endif   //SD Interface
}    regSD_CTR;

void Main( void )
{
#define SD_CONTROL_BASE 0x5a000000
  regSD_CTR *pSDCtr = ((regSD_CTR *)SD_CONTROL_BASE)
.....
}


使用特权

评论回复
8
阿南|  楼主 | 2007-11-26 20:34 | 只看该作者

呵呵,尽管2440addr.h设计不好,但还是懒得去改,去换

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5786

主题

10221

帖子

463

粉丝