主题 : 大家帮我看哈嘛,LED驱动的问题. 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 15135
精华: 0
发帖: 2
金钱: 10 两
威望: 2 点
综合积分: 4 分
注册时间: 2010-03-01
最后登录: 2010-03-02
楼主  发表于: 2010-03-02 00:44

 大家帮我看哈嘛,LED驱动的问题.

我自已在写mini2440上的LED驱动。但我发现,写入GPBDAT口的值,和随后从中读取的值不相等啊。

这样,会出很多问题啊,从GPBDAT口读取的值,和led灯亮的情况不匹配,根本不能反应灯亮的情况。但是我写入的值,和随后灯亮的情况倒是吻合的。代码如下,不长,只花你们一分种。  这是为什么呢,希望能得倒你们工程师的回答。

#define GPBCON        0x56000010
#define GPBDAT        0x56000014
#define GPBUP         0x56000018

#define SETGPBOUT     0x15400      //010101010000000000 用来设输出模式
#define SETGPBIN      0x0      //000000000000000000用来设输入模式
.........................

    //获得i/o内存

    request_mem_region(GPBCON,4,"sss");
    request_region(GPBDAT,1,"ooo");



   //向GPB  data口写入值,oxffff
    void *datAddr=ioremap(GPBDAT,4);
    void *conAddr=ioremap(GPBCON,4);
    __raw_writel(SETGPBOUT, conAddr);
    __raw_writel(0Xffff,datAddr);          //注意,这里写入的是0xffff,LED灯全部被关掉。说明写入的值能正确控制灯。

  

  //取得GPB  data口的值

   __raw_writel(SETGPBIN, conAddr);
   unsigned long tmpvalue=__raw_readl(datAddr);

   printf("value=%d\n");                        //这里不是打印的oxffff, 而是一个变化的值,比如0x7fe    



    release_region(GPBDAT,1);
    release_mem_region(GPBCON,4

级别: 新手上路
UID: 15135
精华: 0
发帖: 2
金钱: 10 两
威望: 2 点
综合积分: 4 分
注册时间: 2010-03-01
最后登录: 2010-03-02
1楼  发表于: 2010-03-02 00:46
我发信问了mini2440的技术支持邮箱. 但回了两次后, 最后说不提供源代码相关的支持.
内容如下......
你好



我们不对源代码提供解释服务,很抱歉。

你可以到arm9之家论坛问问。



发件人: qvbhsskg [mailto:qvbhsskg@163.com]
发送时间: 2010年3月1日 18:49
收件人: capbily
主题: Re:答复: 答复: led驱动中的问题,望能得倒你们耐心的解答。



Hi,

我就是参考了没想明白啊。

光盘中的led驱动,它是调用下面这函数把相应位设成0/1

  s3c2410_gpio_setpin(led_table, 0);



这函数的原型如下.  可以从中看出,它也是从GPBDAT中读出数据,然后再把相应位置0或1,然后把数据写回GPBDAT口。 这函数就说明,从GPBDAT口读出的数据,能够正确返映LED的状态啊。 但正如我最开始所描述的,多从GPBDAT口的读出的数据明显不正确啊。

void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
{
void __iomem *base = S3C2410_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags;
unsigned long dat;

local_irq_save(flags);

dat = __raw_readl(base + 0x04);
dat &= ~(1 << offs);
dat |= to << offs;
__raw_writel(dat, base + 0x04);

local_irq_restore(flags);
}


在2010-03-01 18:39:23,capbily <capbily@163.com> 写道:



你好



你可以参考我们提供的LED驱动,并在BSP包中搜索所有GPB相关的寄存器,查看参考它们的设置



发件人: qvbhsskg [mailto:qvbhsskg@163.com]
发送时间: 2010年3月1日 17:20
收件人: capbily
主题: Re:答复: led驱动中的问题,望能得倒你们耐心的解答。



Hi,

谢谢你的回答先,那我有两个问题

1、   我已经在代码中通过GPBCON口把GPBDAT口设置为输入模式后,再从GPBDAT口中读入的数据。代码中有下面这句话

__raw_writel(SETGPBIN, conAddr);

  

2、那如果从GPB口读入的数据不准确。那么,我从哪里读入的数值,能准确反映LED的状态。





在2010-03-01 07:54:28,capbily <capbily@163.com> 写道:

你好



作为LED驱动,GPB是设置为输出端口,而不是输入,这样读取的数值是不确定的。
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
2楼  发表于: 2010-03-02 10:14
#define SETGPBOUT     0x15400      //010101010000000000 用来设输出模式
...
__raw_writel(SETGPBOUT, conAddr);

你的代码把GPB5,6,7,8设成了OUTPUT,同时把_其他_的GPB0~4,GPB9~10设成了INPUT,因此后面对GPBDAT的写入只影响其中对应于GPB5~8的bit[5:8], 所以你读到的0x7fe和原本写入的0xffff是符合的。记住对GPBDAT寄存器的写入只对配置为OUTPUT的GPIO对应的bit有意义。

另外,从你的代码看,对寄存器写入的方法是不正确的,那样会“覆盖”不是你需要设定的寄存器位。正确的方法是用C语言的位操作符"|"和“&”。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."