CubieBoard中文论坛

 找回密码
 立即注册
搜索
热搜: unable
楼主: WindLand

[教程]Cubieboard GPIO成功点亮LED[My first step on GPIO of Cubieboard]

[复制链接]
 楼主| 发表于 2013-3-28 13:45:32 | 显示全部楼层
gongstar 发表于 2013-3-26 14:15
请问有人编译过ubuntu 12.04 linaro 内核3.4.24-a10-aufs+的  sun4i-gpio.ko驱动没有?有的话,能否发一个 ...

木有,自己编译吧,找不到对应版本的源码的话,就只有编译整个内核然后替换内核
回复 支持 反对

使用道具 举报

发表于 2013-3-28 16:02:57 | 显示全部楼层
这个 sun4i-gpio ugly已经过时了, 大家可以试用 gpio-sunxi, 更标准一些gpio驱动
回复 支持 反对

使用道具 举报

发表于 2013-6-6 11:16:50 | 显示全部楼层
本帖最后由 freechinaren 于 2013-6-6 11:21 编辑

本人参考sun4i-gpio写了一个控制LED驱动的程序,但是加载编译好的驱动后,系统会重启。
本人用的GPIO的是PE4,PE5,PE6,PE7配置成输出口,控制四个LED灯,PE8,PE9,PE10,PE11 配置成输入口,控制四个按键,
下面为本人写的驱动代码,请大虾指点,不胜感激!!!
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <linux/pm.h>
#include <linux/sysdev.h>
#include <linux/slab.h>
#include <linux/earlysuspend.h>
#include <linux/device.h>

//  定义设备文件名
#define DEVICE_NAME "cbio"

#define SW_PA_PORTC_IO_BASE               0x01c20800
/*
*
*                           GPIO(PIN) Operations
*
*/
//#define CSP_OSAL_PHY_2_VIRT(phys, size) SW_VA_PORTC_IO_BASE

//#define    CSP_PIN_PHY_ADDR_BASE    SW_PA_PORTC_IO_BASE
//#define    CSP_PIN_PHY_ADDR_SIZE    0x1000

//u32  gpio_g_pioMemBase;//=SW_PA_PORTC_IO_BASE ;

#define PIOC_REGS_BASE SW_PA_PORTC_IO_BASE

//extern char sys_cofig_data[];
//extern char sys_cofig_data_end[];
#define __REG(x)                        (*(volatile unsigned int *)(x))

#define PIO_REG_CFG(n, i)               ((volatile unsigned int *)(PIOC_REGS_BASE + ((n)-1)*0x24 + ((i)<<2) + 0x00))
#define PIO_REG_DLEVEL(n, i)            ((volatile unsigned int *)(PIOC_REGS_BASE + ((n)-1)*0x24 + ((i)<<2) + 0x14))
#define PIO_REG_PULL(n, i)              ((volatile unsigned int *)(PIOC_REGS_BASE + ((n)-1)*0x24 + ((i)<<2) + 0x1C))
#define PIO_REG_DATA(n)                   ((volatile unsigned int *)(PIOC_REGS_BASE + ((n)-1)*0x24 + 0x10))

#define PIO_REG_CFG_VALUE(n, i)          __REG(PIOC_REGS_BASE + ((n)-1)*0x24 + ((i)<<2) + 0x00)
#define PIO_REG_DLEVEL_VALUE(n, i)       __REG(PIOC_REGS_BASE + ((n)-1)*0x24 + ((i)<<2) + 0x14)
#define PIO_REG_PULL_VALUE(n, i)         __REG(PIOC_REGS_BASE + ((n)-1)*0x24 + ((i)<<2) + 0x1C)
#define PIO_REG_DATA_VALUE(n)            __REG(PIOC_REGS_BASE + ((n)-1)*0x24 + 0x10)
//end

//static unsigned int led_key_status; // 保存4个Leds的设置状态(d4-d7)和保存4个Buttons的状态(d8-d11)
static unsigned char mem[1];                                    //
static ssize_t cbio_read(struct file *file, char __user *buf,
        size_t count, loff_t *ppos)
{
//        unsigned char temp[4];
        unsigned char temp=0;
        //读PE DATA Register
        unsigned int led_key_status=PIO_REG_DATA_VALUE(4);
        //read led status
        temp =(led_key_status>>4)&0x01;//led0
        temp|=((led_key_status>>5)&0x01)<<1;//led1
        temp|=((led_key_status>>6)&0x01)<<2;//led2
        temp|=((led_key_status>>7)&0x01)<<3;//led3
        //read key status
        temp|=((led_key_status>>8)&0x01)<<4; //key0
        temp|=((led_key_status>>9)&0x01)<<5; //key1
        temp|=((led_key_status>>10)&0x01)<<6;//key2
        temp|=((led_key_status>>11)&0x01)<<7;//key3
      
      
        //temp[0] = led_key_status >> 24;
        //temp[1] = led_key_status >> 16;   
        //temp[2] = led_key_status >> 8;
        //temp[3] = led_key_status;
        if (copy_to_user(buf, (void*) &temp, 1))
        {
                return -EINVAL;
        }
        printk("read:status of cbio:%d", (int) count);

        return count;
}

static ssize_t cbio_write(struct file *file, const char __user *buf,
        size_t count, loff_t *ppos)
{
        ssize_t written = count;
        unsigned int tmp;  
        unsigned char c;
        volatile __u32     *tmp_addr;
        if(written!=1)
        {
          printk("write:data len invalid\n");
            return -EINVAL;
        }

        if (copy_from_user(mem, buf, count))
        {
                return -EINVAL;
        }
        //mem[count] = '\0';
        //目前只设置低四位为灯得状态
              
        tmp=PIO_REG_DATA_VALUE(4);
        //设置灯的状态
        
        c=mem[0];        
        //led0->pin34
        if(c&0x01)//led0
         tmp|=0x10;        
        else
         tmp&=0xffffffef;      
        //led1->pin36
         if(c&0x01)//led1
         tmp|=0x20;        
        else
         tmp&=0xffffffdf;         
        //led2->pin38
         if(c&0x01)//led2
         tmp|=0x40;        
        else
         tmp&=0xffffffbf;
        //led3->pin40
         if(c&0x01)//led3
         tmp|=0x80;        
        else
         tmp&=0xffffff7f;
        //tmp|=0xf0;//LED灯全亮或全熄灭
        tmp_addr=PIO_REG_DATA(4);
        *tmp_addr=tmp;        


        printk("write:status word count:%d\n", (int)count);

        return written;
}

//  描述与设备文件触发的事件对应的回调函数指针
static struct file_operations dev_fops =
{ .owner = THIS_MODULE, .read = cbio_read, .write = cbio_write };

//  描述设备文件的信息   
static struct miscdevice misc =
{ .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops };


//  初始化Linux驱动
static int __init cbio_init(void)
{
        int ret;
        volatile __u32     *tmp_addr;
        unsigned int  tmp;
        //  建立设备文件
        ret = misc_register(&misc);
        //printk(KERN_INFO "Init eGon pin module V2.0\n");
        //gpio_g_pioMemBase = (u32)CSP_OSAL_PHY_2_VIRT(CSP_PIN_PHY_ADDR_BASE , CSP_PIN_PHY_ADDR_SIZE);
         
       //初始化配置寄存器
        //使用PE_CFG0(offset:0x90)
        //LED0-LED3:输出pin
        
         //save the PE_CFG0 register's value
         //debug
         tmp=ioread32(PIOC_REGS_BASE + ((4)-1)*0x24 + ((0)<<2) + 0x00));
         printk("Get PE CFG0:%d\n",tmp);
         //end
         tmp=PIO_REG_CFG_VALUE(4,0);
         printk("Get PE CFG0:%d\n",tmp);
         //modify PE4(18:16)        :001         
         //modify PE5(22:20)        :001
         //modify PE6(26:24)        :001
         //modify PE7(30:28)        :001
         tmp&=0x9999ffff;
         tmp|=0x11110000;
         //使用修改后的配置cfg0
         tmp_addr=PIO_REG_CFG(4,0);         
            *tmp_addr=tmp;
           
        //KEY0-KEY3:输入pin
        //使用PE_CFG1(offset:0X94)
         tmp=PIO_REG_CFG_VALUE(4,1);
         printk("Get PE CFG1:%d\n",tmp);
         //modify PE8(2:0)        :000
         //tmp&=0xfffffff8;
         //modify PE9(6:4)        :000
         //tmp&=0xffffff8f;
         //modify PE10(10:8)        :000
         //tmp&=0xfffff8ff;
         //modify PE11(14:12)        :000
         //tmp&=0xffff8fff;
            tmp&=0xffff8888;
         //使用修改后的配置cfg1
         tmp_addr=PIO_REG_CFG(4,1);
         *tmp_addr=tmp;

         //set led default value
         tmp=PIO_REG_DATA_VALUE(4);
         tmp|=0xf0;//LED灯全亮或全熄灭
         tmp_addr=PIO_REG_DATA(4);
         *tmp_addr=tmp;
         

        //  输出日志信息
        printk("cbio_init_success\n");


        return ret;
}

// 卸载Linux驱动
static void __exit cbio_exit(void)
{
        //  删除设备文件  
        misc_deregister(&misc);

        //  输出日志信息
        printk("cbio_init_exit_success\n");
}

//  注册初始化Linux驱动的函数
module_init( cbio_init);
//  注册卸载Linux驱动的函数
module_exit( cbio_exit);

MODULE_DESCRIPTION("gpio of cubieboard.");
MODULE_ALIAS("led and button module.");
MODULE_LICENSE("GPL");
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-6-7 14:57:40 | 显示全部楼层
freechinaren 发表于 2013-6-6 11:16
本人参考sun4i-gpio写了一个控制LED驱动的程序,但是加载编译好的驱动后,系统会重启。
本人用的GPIO的是PE4 ...

驱动方面的可以咨询hipboi,我不太了解.抱歉
回复 支持 反对

使用道具 举报

发表于 2013-6-7 15:56:12 | 显示全部楼层
WindLand ,再次感谢您的回复!
请问怎样联系hipboi,能给联系方式吗?
谢谢!!!
回复 支持 反对

使用道具 举报

发表于 2013-7-1 20:55:57 | 显示全部楼层
gpio_sunxi  需要 开启pin

echo x > /sys/class/gpio/export 这个x 是你fex定义的号码

执行上面一行以后,会在 /sys/class/gpio/目录下多出了一个目录 gpio1_ 开头的目录。 操作 目录里面的value,可以改变状态

例子如下

echo 1 > /sys/class/gpio/export
echo 1 > /sys/class/gpio/gpio1_pd0/value 那么pd0 输出电平了
回复 支持 反对

使用道具 举报

发表于 2013-7-21 09:44:25 | 显示全部楼层
请教斑竹,我现在cb上的平台是  官网的 android tvbox2.2,我现在想在这个android上写一个app来控制下面某几个gpio口的高低电平,我该怎么做呢?


能给点思路吗?谢谢!
回复 支持 反对

使用道具 举报

发表于 2013-7-21 09:44:52 | 显示全部楼层
或者说,这整个流程,我需要做哪些工作呢?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-21 13:52:05 | 显示全部楼层
醉月 发表于 2013-7-21 09:44
请教斑竹,我现在cb上的平台是  官网的 android tvbox2.2,我现在想在这个android上写一个app来控制下面某 ...

android不太清楚。
tvbox我不知道他带不带gpio驱动,如果没有,那就要用android的源码来重新编译和打包镜像,重新刷入。
应该需要ndk编写.so文件,然后app中调用。

你可以问问@matson 版主
回复 支持 反对

使用道具 举报

发表于 2013-7-21 14:29:39 | 显示全部楼层
WindLand 发表于 2013-7-21 13:52
android不太清楚。
tvbox我不知道他带不带gpio驱动,如果没有,那就要用android的源码来重新编译和打包镜 ...

谢谢!

听你说起来还挺麻烦的...
我该怎么呼叫@matson班主呢? 搜索栏似乎没有啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|粤ICP备13051116号|cubie.cc---深刻的嵌入式技术讨论社区

GMT+8, 2024-11-22 23:47 , Processed in 0.025516 second(s), 13 queries .

Powered by Discuz! X3.4

© 2001-2012 Comsenz Inc. | Style by Coxxs

返回顶部