在i.MX8M Mini的U-Boot SPL阶段启用PWM需要以下几个关键步骤:
1. 确认硬件配置
首先确认你的PWM引脚对应的控制器(如PWM1/PWM2)和通道号,并记录对应的IOMUX配置参数。例如PWM1的某个引脚可能需要以下配置:
/* 硬件复用模式 */
#define PWM_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE)
#define PWM_MUX_MODE 0x0F /* 具体值参考i.MX8MM手册 */
2. 配置设备树
确保设备树中已启用PWM控制器(可能需要拆分SPL专用设备树):
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
};
3. 修改SPL代码
在你的verdin-imx8mm/spl.c中添加以下内容:
#include
#include
static void enable_pwm_controller(void)
{
/* 1. 配置IOMUX引脚复用为PWM功能 */
imx8m_iomux_setup_pad(IMX8MM_PAD_GPIO1_IO01__PWM1_OUT | MUX_PAD_CTRL(PWM_PAD_CTRL));
/* 2. 启用PWM时钟(以PWM1为例) */
imx8m_ccgr_clock_enable(IMX8M_CCGR_PWM1);
/* 3. 初始化PWM控制器 */
struct udevice *pwm_dev;
if (pwm_init(0, PWM1_PIN, &pwm_dev)) { // 0表示PWM1通道号
printf("PWM init failedn");
return;
}
/* 4. 配置PWM参数 */
pwm_config(pwm_dev, 500, 1000); // 占空比50%(500/1000)
pwm_enable(pwm_dev);
}
然后在board_init_f()中调用这个函数:
void board_init_f(ulong dummy)
{
enable_pwm_controller(); // 添加在这里
...
}
4. 配置U-Boot编译选项
在configs/verdin-imx8mm_defconfig中确保启用:
CONFIG_PWM=y
CONFIG_PWM_IMX=y
CONFIG_SPL_PWM=y
CONFIG_SPL_PWM_IMX=y
5. 关键注意事项
- 时钟配置:i.MX8MM的PWM控制器需要来自CCM的时钟,确认使用的时钟根(如24MHz OSC)
- SPL代码限制:SPL阶段可能无法使用完整驱动,建议参考
drivers/pwm/pwm-imx.c移植必要函数
- 引脚冲突:确保没有其他驱动(如GPIO)正在控制同一引脚
调试建议
- 使用示波器测量PWM引脚波形
- 在SPL中添加
printf调试时钟使能状态
- 检查
pwm_init返回值确认驱动加载状态
如果遇到时钟配置问题,可以尝试在enable_pwm_controller()中添加以下时钟初始化代码:
/* 设置PWM时钟根(示例值,需根据实际需求计算) */
clock_set_target_val(IMX8MM_PWM1_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(2));
最终效果应该是SPL阶段即可产生PWM波形,LED呈现呼吸灯效果而非简单的亮/灭。
在i.MX8M Mini的U-Boot SPL阶段启用PWM需要以下几个关键步骤:
1. 确认硬件配置
首先确认你的PWM引脚对应的控制器(如PWM1/PWM2)和通道号,并记录对应的IOMUX配置参数。例如PWM1的某个引脚可能需要以下配置:
/* 硬件复用模式 */
#define PWM_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE)
#define PWM_MUX_MODE 0x0F /* 具体值参考i.MX8MM手册 */
2. 配置设备树
确保设备树中已启用PWM控制器(可能需要拆分SPL专用设备树):
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
};
3. 修改SPL代码
在你的verdin-imx8mm/spl.c中添加以下内容:
#include
#include
static void enable_pwm_controller(void)
{
/* 1. 配置IOMUX引脚复用为PWM功能 */
imx8m_iomux_setup_pad(IMX8MM_PAD_GPIO1_IO01__PWM1_OUT | MUX_PAD_CTRL(PWM_PAD_CTRL));
/* 2. 启用PWM时钟(以PWM1为例) */
imx8m_ccgr_clock_enable(IMX8M_CCGR_PWM1);
/* 3. 初始化PWM控制器 */
struct udevice *pwm_dev;
if (pwm_init(0, PWM1_PIN, &pwm_dev)) { // 0表示PWM1通道号
printf("PWM init failedn");
return;
}
/* 4. 配置PWM参数 */
pwm_config(pwm_dev, 500, 1000); // 占空比50%(500/1000)
pwm_enable(pwm_dev);
}
然后在board_init_f()中调用这个函数:
void board_init_f(ulong dummy)
{
enable_pwm_controller(); // 添加在这里
...
}
4. 配置U-Boot编译选项
在configs/verdin-imx8mm_defconfig中确保启用:
CONFIG_PWM=y
CONFIG_PWM_IMX=y
CONFIG_SPL_PWM=y
CONFIG_SPL_PWM_IMX=y
5. 关键注意事项
- 时钟配置:i.MX8MM的PWM控制器需要来自CCM的时钟,确认使用的时钟根(如24MHz OSC)
- SPL代码限制:SPL阶段可能无法使用完整驱动,建议参考
drivers/pwm/pwm-imx.c移植必要函数
- 引脚冲突:确保没有其他驱动(如GPIO)正在控制同一引脚
调试建议
- 使用示波器测量PWM引脚波形
- 在SPL中添加
printf调试时钟使能状态
- 检查
pwm_init返回值确认驱动加载状态
如果遇到时钟配置问题,可以尝试在enable_pwm_controller()中添加以下时钟初始化代码:
/* 设置PWM时钟根(示例值,需根据实际需求计算) */
clock_set_target_val(IMX8MM_PWM1_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(2));
最终效果应该是SPL阶段即可产生PWM波形,LED呈现呼吸灯效果而非简单的亮/灭。
举报