[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
    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這邊量測
image
 
查看layout圖,R804在imx8mm evk後方,從這邊量測,應該就可以量到 PWM1訊號.
目前的code量出來為 1.8V 14.5 kHz duty 50的訊號.
image
 
以上記錄提供給各位參考.
 
 
 

    CuteParrot 發表在 痞客邦 留言(0) 人氣()