mtk-GPIO设置与应用

2018/06/14 18:58
阅读数 889

一.block Dragram

一般来说,GPIO引脚功能复用,可作为EINT、GPIO、或I2C、SPI等,通过GPIO_MODE进行选择

GPIO_DIR:控制输入输出的方向,为0作为input,为1作为output,默认状态为0

GPIO_DIN:通过访问寄存器可以得知输入的是高电平还是低电平

GPIO_OUT:控制输出高低电平

GPIO_PULLEN:是否支持上下拉

mtk的文档给的block dragram中并没有标全,还有设置上下拉,SMT,slew rate这些属性

 

 

二.dws中的配置

依次来看下GPIO的配置项:

  • EintMode:中断模式
  • M0~M7:GPIO支持的模式选择
  • Def.Mode:默认的模式,根据后面勾选的M0~M7中选择默认模式
  • InPull En:是否支持上下拉
  • InPull Sel High:选择上拉还是下拉,勾选表示上拉
  • Def.Dir:input还是output
  • In:input
  • Out:output
  • OutHigh:输出为高电平还是低电平
  • SMT#:SMT group
  • SMT:是否支持SMT(schmitt trigger)功能,波形过滤,输出方波或者脉冲波,延迟滞后具有消噪的功能。一般不用勾选

最终生成cust_gpio_boot.h和cust_gpio_usage.h两个头文件,取GPIO8看下实际内容,还是比较一目了然的

cust_gpio_boot.h
//Configureation for Pin 8
#define GPIO8_MODE      GPIO_MODE_00
#define GPIO8_DIR       GPIO_DIR_OUT
#define GPIO8_PULLEN    GPIO_PULL_DISABLE
#define GPIO8_PULL      GPIO_PULL_DOWN
#define GPIO8_DATAOUT   GPIO_OUT_ZERO
#define GPIO8_SMT       GPIO_SMT_DISABLE
cust_gpio_usage.h
#define GPIO_FLASH_LED_EN         (GPIO8 | 0x80000000)
#define GPIO_FLASH_LED_EN_M_GPIO  GPIO_MODE_00
#define GPIO_FLASH_LED_EN_M_PWM  GPIO_MODE_01
#define GPIO_FLASH_LED_EN_M_PCC_PPC_IO   GPIO_MODE_02
#define GPIO_FLASH_LED_EN_M_CONN_MCU_TRST_B   GPIO_MODE_04
#define GPIO_FLASH_LED_EN_M_C2K_DM_JTINTP   GPIO_MODE_05
#define GPIO_FLASH_LED_EN_M_IO_JTAG_TRSTN   GPIO_MODE_06
#define GPIO_FLASH_LED_EN_M_DBG_MON_A   GPIO_MODE_07

lk阶段中对gpio进行初始化

void mt_gpio_set_default(void)
{
    //mt_gpio_set_avoid_leakage();
    mt_gpio_set_default_chip();
    //mt_gpio_set_driving();
    //mt_gpio_set_power();
    mutex_init(&gpio_mutex);
    return;
}

void mt_gpio_set_default_chip(void)
{
unsigned pin = 0;
    for (pin = 0; pin < MT_GPIO_BASE_MAX; pin++) {
        /* set GPIOx_MODE*/
        mt_set_gpio_mode(0x80000000+pin ,gpio_array[pin].mode);

        /* set GPIOx_DIR*/
        mt_set_gpio_dir(0x80000000+pin ,gpio_array[pin].dir);
        //GPIOVER("fwq2..........\n");

        /* set GPIOx_PULLEN*/
        mt_set_gpio_pull_enable(0x80000000+pin ,gpio_array[pin].pullen);
        //GPIOVER("fwq3..........\n");

        /* set GPIOx_PULL*/
        mt_set_gpio_pull_select(0x80000000+pin ,gpio_array[pin].pull);

        /* set GPIOx_DATAOUT*/
        mt_set_gpio_out(0x80000000+pin ,gpio_array[pin].dataout);

        //GPIOVER("fwq5..........\n");
        /* set GPIO0_SMT */
        mt_set_gpio_smt(0x80000000+pin ,gpio_array[pin].smt);
}

三.shell下调试GPIO

//可以cat查看pin脚状态,分析gpio是否与预期值一致
cat /sys/devices/virtual/misc/mtgpio/pin

 具体细节可以看mt_gpio_store_pin这个函数

四.MTK 旧时API(MTK不推荐这种方法)

设置mode >> 设置dir >>设置上下拉使能 >>设置上下拉

GPIO设置为中断:mode0 >> input >> 根据实际连接设置上下拉

mt-plat/mt-gpio.h
/*direction*/
int mt_set_gpio_dir(unsigned long pin, unsigned long dir);
int mt_get_gpio_dir(unsigned long pin);

/*pull enable*/
int mt_set_gpio_pull_enable(unsigned long pin, unsigned long enable);
int mt_get_gpio_pull_enable(unsigned long pin);

/*schmitt trigger*/
int mt_set_gpio_smt(unsigned long pin, unsigned long enable);
int mt_get_gpio_smt(unsigned long pin);

/*IES*/
int mt_set_gpio_ies(unsigned long pin, unsigned long enable);
int mt_get_gpio_ies(unsigned long pin);

/*pull select*/
int mt_set_gpio_pull_select(unsigned long pin, unsigned long select);
int mt_get_gpio_pull_select(unsigned long pin);

/*data inversion*/
int mt_set_gpio_inversion(unsigned long pin, unsigned long enable);
int mt_get_gpio_inversion(unsigned long pin);

/*input/output*/
int mt_set_gpio_out(unsigned long pin, unsigned long output);
int mt_get_gpio_out(unsigned long pin);
int mt_get_gpio_in(unsigned long pin);

/*mode control*/
int mt_set_gpio_mode(unsigned long pin, unsigned long mode);
int mt_get_gpio_mode(unsigned long pin);

五.pinctrl的方法

dts中设置pinctrl的方式如下

&device{ 
  ......
  pinctrl-names = "aaa","bbb","ccc";
  pinctrl-0 = <&xxx>;
  pinctrl-1 = <&yyy>;
   pinctrl-2 = <&zzz>;
  ......
};
&pio {
    xxx: config0 {
        pins_cmd_dat {
        pins = <PINMUX_GPIO1__FUNC_GPIO1>;  ----设置GPIO mode,在boot/dts/中mtxxxx-pinfunc.h里有定义
        slew-rate = <0>;  ----设置GPIO dir,0为input,1为output
        bias-pull-down = <11>;  ----设置pull enable,下拉,后面的11并无影响,写00也可以
        input-schmitt-enable = <0>;   ----设置SMT enable        
        };
    };
    yyy: config1 {
        pins_cmd_dat {
        pins = <PINMUX_GPIO1__FUNC_GPIO1>;
        slew-rate = <1>;
        bias-pull-up = <11>;
        output-low;  ----设置低电平输出,只有在slew-rate设置为1时才有效,output-high就是设置为高电平输出
        input-schmitt-enable = <0>;         
        };
    };
    zzz: config2 {
        pins_cmd_dat {
        pins = <PINMUX_GPIO1__FUNC_GPIO1>;
        slew-rate = <1>;
        bias-disable;  ----无上下拉设置,不能与bias-pull-down/up共存
        output-low;
        input-schmitt-enable = <0>;         
        };
    };
};

 

驱动中获取pinctrl并进行配置

struct pinctrl* pinctrl0;
struct pinctrl_state* config0, *config1, *config2;

//获取pinctrl句柄
pinctrl0 = devm_pinctrl_get(&pdev->dev);

//根据句柄得到gpio的配置,根据pinctrl-name属性进行匹配
config0 = pinctrl_lookup_state(pinctrl0, "aaa");
config1 = pinctrl_lookup_state(pinctrl0, "bbb");
config2 = pinctrl_lookup_state(pinctrl0, "ccc");

//配置生效
pinctrl_select_state(pinctrl0, config0);

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部