uboot命令行pwm.c代码

15 篇文章 3 订阅
6 篇文章 0 订阅

之前在uboot命令行验证一些小IP的寄存器,发现某款板子u-boot/cmd下面并没有pwm.c代码,补充一份。

#include <common.h>
#include <command.h>
#include <dm.h>
#include <pwm.h>

enum pwm_cmd {
	PWM_SET_INVERT,
	PWM_SET_CONFIG,
	PWM_SET_ENABLE,
	PWM_SET_DISABLE,
};

static int do_pwm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	const char *str_cmd, *str_channel = NULL, *str_enable = NULL;
	const char *str_pwm = NULL, *str_period = NULL, *str_duty = NULL;
	enum pwm_cmd sub_cmd;
	struct udevice *dev;
	u32 channel, pwm_enable, pwm_dev, period_ns = 0, duty_ns = 0;
	int ret;

	if (argc < 4) //参数个数argc < 4是因为在U_BOOT_CMD中所有命令最少的参数个数就是4个, 包括命令名本身, 例如pwm config 1 2 5000000 2500000  就是6个参数 。
show_usage:
		return CMD_RET_USAGE;
	str_cmd = argv[1];
	argc -= 2;
	argv += 2;

	str_pwm = *argv;
	argc--;
	argv++;

	//printf("str_pwm 0x%p\n", str_pwm);
	if (!str_pwm) {
		goto show_usage;
	}
	/* parse the behavior */
	switch(*str_cmd) {
	case 'i':
		sub_cmd = PWM_SET_INVERT;
		if (argc != 2)
			goto show_usage;
		break;
	case 'c':
		sub_cmd = PWM_SET_CONFIG;
		if (argc != 3) //剩余参数个数
			goto show_usage;
		break;
	case 'e':
		sub_cmd = PWM_SET_ENABLE;
		if (argc != 1)
			goto show_usage;
		break;
	case 'd':
		sub_cmd = PWM_SET_DISABLE;
		if (argc != 1)
			goto show_usage;
		break;
	default:
		goto show_usage;
	}

	pwm_dev = simple_strtoul(str_pwm, NULL, 10);
	ret = uclass_get_device(UCLASS_PWM, pwm_dev, &dev);
	if (ret) {
		printf("pwm '%s' not found\n", str_pwm);
		return cmd_process_error(cmdtp, ret);
	}

	str_channel = *argv;
	channel = simple_strtoul(str_channel, NULL, 10);
	argc--;
	argv++;

	if (sub_cmd == PWM_SET_INVERT) {
		str_enable = *argv;
		pwm_enable = simple_strtoul(str_enable, NULL, 10);
		ret = pwm_set_invert(dev, channel, pwm_enable);
	} else if (sub_cmd == PWM_SET_CONFIG) {
		str_period = *argv;
		argc--;
		argv++;
		period_ns = simple_strtoul(str_period, NULL, 10);

		str_duty = *argv;
		duty_ns = simple_strtoul(str_duty, NULL, 10);

		ret = pwm_set_config(dev, channel, period_ns, duty_ns);
	} else if (sub_cmd == PWM_SET_ENABLE) {
		ret = pwm_set_enable(dev, channel, 1);
	} else if(sub_cmd == PWM_SET_DISABLE) {
		ret = pwm_set_enable(dev, channel, 0);
	}

	if (ret) {
		printf("error(%d)\n", ret);
		return CMD_RET_FAILURE;
	}

	return CMD_RET_SUCCESS;
}

U_BOOT_CMD(pwm, 6, 0, do_pwm,  //参数6代表下所有输入的命令中最大参数为6个
	   "control pwm channels",
	   "pwm invert <pwm_dev_num> <channel> <polarity> - invert polarity\n"
	   "pwm config <pwm_dev_num> <channel> <period_ns> <duty_ns> - config PWM\n"
	   "pwm enable <pwm_dev_num> <channel> - enable PWM output\n"
	   "pwm disable <pwm_dev_num> <channel> - disable PWM output\n"
	   "Note: All input values are in decimal");

整套验证流程符合u-boot DM模型,即从u-boot/cmd/pwm.c调用到u-boot/drivers/pwm/下面的uclass的driver pwm-uclass.c,进而再通过pwm_ops结构体调用到u-boot/cmd/pwm/下面的udevice的driver xx_pwm.c去操作相关寄存器。也可以不用u-boot的这套DM模型,直接从u-boot/cmd/pwm.c调用到xx_pwm.c驱动。

在u-boot命令行敲ctrl+c进入命令行后如果发现没有pwm命令,则要在u-boot/configs/下面的xx_defconfig(xx一般是板子编号)文件中添加一个宏:CONFIG_CMD_PWM=y。再重新编译u-boot烧写进板子。

一共需要在xx_defconfig中添加三个宏:
1.CONFIG_CMD_PWM=y ,此宏对应cmd/pwm.c同路径的makefile,编译pwm.c文件
2.CONFIG_DM_PWM=y ,此宏对应pwm-uclass.c同路径的makefile,编译pwm-uclass.c文件
3.CONFIG_PWM_xx=y,此宏对应xx_pwm.c同路径的makefile,编译xx_pwm.c文件

如果某个板子默认进入uboot命令行的时间为0,宏CONFIG_BOOTDELAY=0一般定义在u-boot/configs的xx_defconfig中,可以将其改为CONFIG_BOOTDELAY=5,方便进入命令行。

在调试uboot命令行pwm命令的时候主要出现两个问题:
1、是在pwm.c的U_BOOT_CMD()中定义的嘴一个_help参数无法在串口打印出来,是因为在pwm.c中少加了一个头文件#include <common.h>
2、在rk3588_defconfig中定义了CONFIG_CMD_PWM=y,在u-boot/cmd/makefile中定义了obj-$(CONFIG_CMD_PWM) += pwm.o,但是这个宏CONFIG_CMD_PWM并没有起作用,即在u-boot/cmd/下面添加的pwm.c文件没有被编译到。所以还要在u-boot/cmd/Kconfig中定义PWM如下:
config CMD_PWM
bool “pwm”
default y
help
PWM support.
这样CONFIG_CMD_PWM才会起作用,当然也可以obj-y += pwm.o。
=> pwm config指令
pwm config 1 2 5000000 25000000

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值