[NXP][imx8mm]How to enable PWM1 on UBOOT
--imx8mm evk環境---
Android OS : android_P9.0.0_2.3.1
----
以下紀錄如何enable uboot PWM1
---
主要要做的事情有
1.enable pwm root clock (enable_pwm_clock()) and setup multiple pads(GPIO alternation function)
2.pwm init, config,and enable.
---
首先先說明一下,在 imx8mm uboot下,我們不採用 DM_PWM 方式(也就是 uclass 與 udevice架構)
原因是 NXP在uboot尚未完成 imx8mm DM_PWM的完整的code. (可留著練功用)
所以我們採取的方式是 "在 include\configs\imx8mm_evk.h設定#define CONFIG_PWM_IMX ,直接設定相關HW register方式".
總共修改的檔案會有
---
modified: arch/arm/include/asm/arch-imx8m/clock_imx8mm.h
modified: arch/arm/include/asm/arch-imx8m/imx-regs-imx8mm.h
modified: arch/arm/mach-imx/imx8m/clock_imx8mm.c
modified: board/freescale/imx8mm_evk/imx8mm_evk.c
modified: configs/imx8mm_evk_android_defconfig
modified: include/configs/imx8mm_evk.h
---
首先我們必須先在 \configs\imx8mm_evk_android_defconfig ,將以下兩個拿掉
# CONFIG_DM_PWM=y
# CONFIG_PWM_IMX=y
並試著 make -j16 bootloader看看,發現會出現很多"not define"的錯誤訊息
所以必須修改檔案 /arch/arm/include/asm/arch-imx8m/imx-regs-imx8mm.h
加上以下內容
--
#define PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4)
#define PWMCR_DOZEEN (1 << 24)
#define PWMCR_WAITEN (1 << 23)
#define PWMCR_DBGEN (1 << 22)
#define PWMCR_CLKSRC_IPG_HIGH (2 << 16)
#define PWMCR_CLKSRC_IPG (1 << 16)
#define PWMCR_EN (1 << 0)
struct pwm_regs {
u32 cr;
u32 sr;
u32 ir;
u32 sar;
u32 pr;
u32 cnr;
};
--
並在檔案 include\configs\imx8mm_evk.h
加上
--
#define CONFIG_PWM_IMX //使之build出 "obj-$(CONFIG_PWM_IMX) += pwm-imx.o pwm-imx-util.o" (from driver/pwm/Makefile)
#define CONFIG_IMX6_PWM_PER_CLK 33000000 //66000000 //drivers/pwm/pwm-imx-util.c的pwm_imx_get_parms會使用到
--
改到這邊,先試著檢查還會不會有build error, 重新 make -j16 bootloader,應該不會有錯誤訊息了.
接著,我們要setup multiple pads,enable pwm1 root clock,與 enable pwm.
imx8mm 周邊的clock設定集中在 arch/arm/mach-imx/imx8m/clock_imx8mm.c,我們加上以下 pwm的 root clock設定
---
int set_clk_pwm(void)
{
/*
*/
clock_enable(CCGR_PWM1,0);
if (is_imx8mm()) {
clock_set_target_val(PWM1_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(0)| CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV64)); // PWM1, 103, 24M hz
}
clock_enable(CCGR_PWM1, 1);
return 0;
}
---
因為新增了int set_clk_pwm(void) 函式,為了讓其他c也可以呼叫,記得要在檔案 arch/arm/include/asm/arch-imx8m/clock_imx8mm.h,加上
--
int set_clk_pwm(void);
--
接著在board/freescale/imx8mm_evk/imx8mm_evk.c,加上 multiple pads setup
--
#ifdef CONFIG_PWM_IMX
#define PWM_PAD_CTRL (PAD_CTL_DSE2 |PAD_CTL_FSEL0| PAD_CTL_HYS) // 0x82
static iomux_v3_cfg_t const pwm_pads[] = {
IMX8MM_PAD_GPIO1_IO01_PWM1_OUT | MUX_PAD_CTRL(PWM_PAD_CTRL),
};
int enable_pwm_clock(void)
{
imx_iomux_v3_setup_multiple_pads(pwm_pads, ARRAY_SIZE(pwm_pads));
debug("[mark]%s,%d \n", __func__,__LINE__);
set_clk_pwm(); // call clock_imx8mm.c set_clk_pwm function to setup pwm root clock
return 0;
}
#endif
--
並在 int board_init(void) 函式內,加上 pwm 初始化設定
--
#ifdef CONFIG_PWM_IMX
#ifdef CONFIG_PWM_IMX
enable_pwm_clock(); // enable pwm1 clock
pwm_init(0,0,0); // PWM1
pwm_config(0, 400, 800); // PWM 1, duty cycle 4000ns, period: 8000ns , 14Khz(CONFIG_IMX6_PWM_PER_CLK 33000000)
pwm_enable(0);
#endif
--
到目前為止,所有的修改都改完,make -j18 bootloader 並更新 u-boot-imx8mm.imx 到板子上 (fastboot flash bootloader0 u-boot-imx8mm.imx)
開機後,讓裝置停在 uboot (adb reboot bootloader 或 在uboot按 space鍵),並使用示波器量測 pwm1的測點
查看線路圖,PWM1可以從 R804這邊量測
查看layout圖,R804在imx8mm evk後方,從這邊量測,應該就可以量到 PWM1訊號.
目前的code量出來為 1.8V 14.5 kHz duty 50的訊號.
以上記錄提供給各位參考.
文章標籤
全站熱搜
留言列表