龙芯1C300B—GPIO操作

gpio.c : 提供了GPIO初始化、输出、输入操作函数: (参考了勤为本的gpioc封装gpio接口和使用示例,不过我做了非常多的修改和浓缩,原本200多行弄成了50多行)

勤为本:【龙芯1c库】封装gpio接口和使用示例

#include "gpio.h"

#define GPIO_GET_PORT(gpio) ((gpio) / 32)
#define GPIO_GET_PIN(gpio) ((gpio) % 32)

// gpio的工作模式--输入、输出
typedef enum
{
    gpio_mode_output = 0, // 输出
    gpio_mode_input = 1   // 输入
} gpio_mode_t;

//  gpio高低电平值
typedef enum
{
    gpio_level_low = 0, // 低电平
    gpio_level_high = 1 // 高电平
} gpio_level_t;

void gpio_init(unsigned int gpio, gpio_mode_t mode)
{
    volatile unsigned int *gpio_cfgx = (volatile unsigned int *)(LS1C_GPIO_CFG0 + (0x00000004) * GPIO_GET_PORT(gpio));
    volatile unsigned int *gpio_enx = (volatile unsigned int *)(LS1C_GPIO_EN0 + (0x00000004) * GPIO_GET_PORT(gpio));

    *gpio_cfgx |= (1 << GPIO_GET_PIN(gpio));

    if (mode == gpio_mode_output)
        *gpio_enx &= ~(1 << GPIO_GET_PIN(gpio));
    else if (mode == gpio_mode_input)
        *gpio_enx |= (1 << GPIO_GET_PIN(gpio));
}

void gpio_set(unsigned int gpio, gpio_level_t level)
{
    volatile unsigned int *gpio_outx = (volatile unsigned int *)(LS1C_GPIO_OUT0 + (0x00000004) * GPIO_GET_PORT(gpio));

    if (level == gpio_level_high)
        *gpio_outx &= ~(1 << GPIO_GET_PIN(gpio));
    else if (level == gpio_level_low)
        *gpio_outx |= (1 << GPIO_GET_PIN(gpio));
}

gpio_level_t gpio_get(unsigned int gpio)
{
    volatile unsigned int *gpio_inx = (volatile unsigned int *)(LS1C_GPIO_IN0 + (0x00000004) * GPIO_GET_PORT(gpio));

    if ((*gpio_inx >> (GPIO_GET_PIN(gpio)) & 1) == 1)
        return gpio_level_high;
    else if ((*gpio_inx >> (GPIO_GET_PIN(gpio)) & 1) == 1)
        return gpio_level_low;
}

gpio.h : gpio.c头文件

#ifndef __GPIO_H__
#define __GPIO_H__

#define LS1C_GPIO_CFG0 (0xbfd010c0)
#define LS1C_GPIO_EN0 (0xbfd010d0)
#define LS1C_GPIO_IN0 (0xbfd010e0)
#define LS1C_GPIO_OUT0 (0xbfd010f0)

#define LS1C_GPIO_CFG1 (0xbfd010c4)
#define LS1C_GPIO_EN1 (0xbfd010d4)
#define LS1C_GPIO_IN1 (0xbfd010e4)
#define LS1C_GPIO_OUT1 (0xbfd010f4)

#define LS1C_GPIO_CFG2 (0xbfd010c8)
#define LS1C_GPIO_EN2 (0xbfd010d8)
#define LS1C_GPIO_IN2 (0xbfd010e8)
#define LS1C_GPIO_OUT2 (0xbfd010f8)

#define LS1C_GPIO_CFG3 (0xbfd010cc)
#define LS1C_GPIO_EN3 (0xbfd010dc)
#define LS1C_GPIO_IN3 (0xbfd010ec)
#define LS1C_GPIO_OUT3 (0xbfd010fc)

#endif

驱动函数 :点灯 P51 GPIO 每隔300ms 点亮熄灭 ( 驱动随便写的,只是方便自己测试用的 )

#include "driver.h"

#define DRIVER_MAJOR 233         /* 主设备号 */
#define DRIVER_NAME "chrdevbase" /* 设备名 */

static int driver_open(struct inode *inode, struct file *filp)
{
    return 0;
}
static ssize_t driver_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{
    return 0;
}
static ssize_t driver_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
    return 0;
}
static int driver_release(struct inode *inode, struct file *filp)
{
    return 0;
}

static struct file_operations test_fops = {
    .owner = THIS_MODULE,
    .open = driver_open,
    .read = driver_read,
    .write = driver_write,
    .release = driver_release,
};
static int __init driver_module_init(void)
{
    int ret = 0;
    printk("<1> driver_module_init\n");

    gpio_init(51, gpio_mode_output);

    if (DRIVER_MAJOR > 0)
    {
        /* 静态注册字符设备驱动 */
        ret = register_chrdev(DRIVER_MAJOR, DRIVER_NAME, &test_fops);
        if (ret < 0)
        {
            return 0;
        }
    }
    else
    {
    }
    while (1)
    {
        gpio_set(51, 1);
        msleep(300);
        gpio_set(51, 0);
        msleep(300);
    }
    return 0;
}

static void __exit driver_module_exit(void)
{
    printk("<1> driver_module_exit\n");
    /* 注销字符设备驱动 */
    unregister_chrdev(DRIVER_MAJOR, DRIVER_NAME);
}

module_init(driver_module_init);
module_exit(driver_module_exit);
MODULE_AUTHOR("ZTD");                     // 描述模块的作者
MODULE_LICENSE("GPL");                    // 描述模块的许可证
MODULE_DESCRIPTION("driver module test"); // 描述模块的介绍信息
MODULE_ALIAS("alias xxx");                // 描述模块的别名信息

注意点:

        ( 1 )龙芯GPIO操作不需要配置PAD[127:0]复用配置寄存器和时钟频率配置寄存器,只需要上图中的四个GPIO寄存器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爪爪鸡啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值