am5728通过DM框架配置GPIO管脚
来源:互联网 发布:cdp 知乎 编辑:程序博客网 时间:2024/06/05 02:49
以配置gpio3_31为例:
查看芯片手册:
这里gpio3_31为复用管脚,首先要配置寄存器将此管脚设置为gpio功能。
vim board/ti/am57xx/mux_data.h 所有多路复寄存器信息都在此定义:
const struct pad_conf_entry core_padconf_array_essential_x15[] = { {GPMC_AD0, (M2 | PIN_INPUT | MANUAL_MODE)}, /*gpmc_ad0.vin3a_d0 */ {GPMC_AD1, (M2 | PIN_INPUT | MANUAL_MODE)}, /* gpmc_ad1.vin3a_d1 */ {GPMC_AD2, (M2 | PIN_INPUT | MANUAL_MODE)}, /* gpmc_ad2.vin3a_d2 */ {GPMC_AD3, (M2 | PIN_INPUT | MANUAL_MODE)}, /* gpmc_ad3.vin3a_d3 */ {GPMC_AD4, (M2 | PIN_INPUT | MANUAL_MODE)}, /* gpmc_ad4.vin3a_d4 */ ... {VIN2A_FLD0, (M14 | PIN_INPUT_PULLUP)}, /* vin2a_fld0.gpio3_30 */ {VIN2A_HSYNC0, (M14 | PIN_INPUT_PULLUP)}, /* vin2a_hsync0.gpio 3_31 */ {VIN2A_VSYNC0, (M14 | PIN_INPUT)}, /* vin2a_vsync0.gpio4_0 */ {VIN2A_D0, (M11 | PIN_INPUT)}, /* vin2a_d0.pr1_uart0_rxd */ {VIN2A_D1, (M11 | PIN_OUTPUT)}, /* vin2a_d1.pr1_uart0_txd */ ...
接下来看看uboot代码中如何设置多路复用的:
vim board/ti/am57xx/board.c
512 *ctrl = &dra7xx_ctrl;660 pconf = core_padconf_array_essential_x15;661 pconf_sz =ARRAY_SIZE(core_padconf_array_essential_x15);678 /* Do the muxing here */679 do_set_mux32((*ctrl)->control_padconf_core_base, pconf, pconf_sz);
照猫画虎,自己的代码这样写:
1.定义结构体:
const struct pad_conf_entry my_gpio3_31[] = { {VIN2A_HSYNC0, (M14 | PIN_OUTPUT_PULLDOWN)}, };
2.设置参数:
struct omap_sys_ctrl_regs const **ctrl = NULL;*ctrl = &dra7xx_ctrl;const struct pad_conf_entry *pconf = my_gpio3_31;nt pconf_sz = ARRAY_SIZE(my_gpio3_31);
3.调用do_set_mux32()函数设置多路复用
do_set_mux32((*ctrl)>control_padconf_core_base,pconf,pconf_sz);
这下用多路复用就设置好了。
配置好多路复用后,就可以调用gpio接口函数设置管脚的高低了。
虽然像gpio_request,gpio_direction_output 这样的老接口还可以用,这里用新的DM框架来配置GPIO口。
1)在设备树文件下添加节点
vim .config, 找到CONFIG_DEFAULT_DEVICE_TREE=”am57xx-beagle-x15”,说am5728用到的设备树文件为am57xx-beagle-x15.dts,在设备树文件下添加如下节点:
88 /* my code start*/ 89 set_gpio { 90 compatible = "set_gpio,test"; 91 gpios = <&gpio3 31 GPIO_ACTIVE_HIGH>; 92 }; 93 /*my code end*/
2.通过fdt_node_offset_by_compatible函数找到该节点
struct gpio_desc gpio3_31_desc;int node;node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "set_gpio,test");
该函数通过”set_gpio,test”与设备树的compatible字段进行匹配,如果找到则返回相应的节点。
3.申请GPIO资源
int res = gpio_request_by_name_nodev(gd->fdt_blob, node, "gpios", 0, &gpio3_31_desc, GPIOD_IS_OUT)
该函数通过node节点和gpios字段最终找到gpio3_31,并将这些信息保存到gpio3_31_desc结构体中。
4.设置gpio引脚
dm_gpio_set_value(&gpio3_31_desc, 0)
将此gpio管脚配置为高或低。
至此gpio3_31的配置完成。
可以在uboot中添加命令,通过参数配置任意一个gpio引脚,这里只将配置此引脚的命令添加到uboot中:
在cmd文件下创建setgpio.c文件:
static int do_setgpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]){ const struct pad_conf_entry my_gpio3_31[] = { {VIN2A_HSYNC0, (M14 | PIN_OUTPUT_PULLDOWN)}, }; struct omap_sys_ctrl_regs const **ctrl = NULL; *ctrl = &dra7xx_ctrl; const struct pad_conf_entry *pconf = my_gpio3_31; int pconf_sz = ARRAY_SIZE(my_gpio3_31); do_set_mux32((*ctrl)->control_padconf_core_base, pconf, pconf_sz); /*老版本GPIO接口*//* if(gpio_request(95, "gpio3_31")){ printf("request resource error!\n"); return 0; } if(!strcmp(argv[1], "down")){ gpio_direction_output(95, 0); } else{ gpio_direction_output(95, 1); } gpio_free(95);*/ /*新版本GPIO接口*/ struct gpio_desc gpio3_31_desc; int node; struct udevice *dev = NULL; node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "set_gpio,test"); if(node < 0){ printf("#################\n"); printf("node cannot find\n"); printf("##################\n"); return -1; } int res = gpio_request_by_name_nodev(gd->fdt_blob, node, "gpios", 0, &gpio3_31_desc, GPIOD_IS_OUT); if(res){ printf("##################\n"); printf("request GPIO resource failure!\n"); printf("##################\n"); return -1; } dm_gpio_set_value(&gpio3_31_desc, (*argv[1] - '0')); dm_gpio_free(dev, &gpio3_31_desc); return 0;}U_BOOT_CMD( setgpio, 2, 0, do_setgpio, "set gpio3_31 pin", "setgpio 0 - set the pins to low\n" "setgpio 1 - set the pins to high\n");
在Makefile中添加:obj-y += setgpio.o
编译uboot便会有setgpio命令:
setgpio 0:将gpio3_31配置为低电平。
setgpio 1:将gpio3_31配置为高电平。
附录:DM框架下的GPIO接口
int gpio_request_by_name(struct udevice *dev, const char *list_name, int index, struct gpio_desc *desc, int flags)
通过对应的udevice找到其dtsi节点中属性名为list_name的GPIO属性并转化为gpio_desc,并且request。
int gpio_request_by_name_nodev(const void *blob, int node, const char *list_name, int index, struct gpio_desc *desc, int flags)
通过对应的dtsi节点中属性名为list_name的GPIO属性并转化为gpio_desc,并且request。
int dm_gpio_request(struct gpio_desc *desc, const char *label)
申请gpio_desc描述的GPIO
int dm_gpio_get_value(const struct gpio_desc *desc)
获取gpio_desc描述的GPIO的值
int dm_gpio_set_value(const struct gpio_desc *desc, int value)
设置gpio_desc描述的GPIO的值
int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
设置gpio_desc描述的GPIO的输入输出方向,带标志
int dm_gpio_set_dir(struct gpio_desc *desc)
设置gpio_desc描述的GPIO的输入输出方向
static inline bool dm_gpio_is_valid(const struct gpio_desc *desc)
判断gpio_desc是否可用
- am5728通过DM框架配置GPIO管脚
- zynq gpio管脚配置
- STM32 GPIO管脚配置意思说明
- freescale飞思卡尔Imux6 GPIO管脚配置思路
- MT7628/MT7688平台上如何配置任何一个管脚为GPIO模式
- MT7628/MT7688平台上如何配置任何一个管脚为GPIO模式,试用各种平台
- 树莓派2B的GPIO管脚分布
- 今天在弄openwrt gpio管脚输出
- Quartus II 管脚配置
- 2-1-1 管脚配置
- GPIO配置
- GPIO 配置
- STM32 GPIO管脚模式的设置及使用方法
- STM32:GPIO基础与对应管脚操作库函数
- STM32 GPIO管脚工作模式和输出速度总结笔记
- [uboot] (番外篇)uboot dm-gpio使用方法以及工作流程
- [uboot] (番外篇)uboot dm-gpio使用方法以及工作流程
- Linux 内核设备驱动之GPIO驱动之GPIO 管脚描述
- 获取对话框句柄 对话框指针
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- OI中的常用数据生成
- Linux-CentOS7.x的安装步骤图文详情
- list排序,list去重
- am5728通过DM框架配置GPIO管脚
- c++ namespace 实验
- Android 多线程 线程池原理 封装线程池
- httpd 系统错误 无法启动此程序,因为计算机中丢失VCRUNTIME140.dll
- Vue 2.0 制作列表组件,实现分页、搜索、批量操作等
- MFC里面RC资源编辑器不能打开的解决办法
- Beahshell的使用方法
- 实现权限树样式的插件
- 几个你需注意的数据库设计原则(新手必看)