i2c接口可以接哪些器件_单片机i2c接口

i2c接口可以接哪些器件_单片机i2c接口高通项目在lk阶段配置I2C6作充电接口

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

项目中I2C6所对应的gpio口为22和23

i2c接口可以接哪些器件_单片机i2c接口 

由上表可以确定以下信息:

        a) QUP ID:BLSP6

        b) QUP BASE Addr:7AF6000

        c) IRQ:300

        d) src clk:clk_gcc_blsp2_qup2_i2c_apps_clk

1、高通在lk阶段已经存在I2C的初始化代码

路径:bootable/bootloader/lk/platform/msm_shard/i2c_qup.c

i2c接口可以接哪些器件_单片机i2c接口

在初始化代码中qup_blsp_i2c_init为i2c接口函数,其中调用了两个重要函数gpio_config_blsp_i2c和clock_config_blsp_i2c,分别用于i2c的gpio和时钟clock的设置,BLSP_QUP_IRQ这个宏用来给中断号赋值。

2、添加中断号定义代码:

diff –git a/platform/msm8952/include/platform/irqs.h b/platform/msm8952/include/platform/irqs.h
index 59408bd87..388be802a 100644
— a/platform/msm8952/include/platform/irqs.h
+++ b/platform/msm8952/include/platform/irqs.h
@@ -60,6 +60,7 @@
 
 #define NR_IRQS                                (NR_MSM_IRQS + NR_GPIO_IRQS + \
                                                NR_BOARD_IRQS)

+//#define BLSP_QUP_IRQ(blsp_id, qup_id)          (GIC_SPI_START + 101 + qup_id)
+#define BLSP_QUP_IRQ(blsp_id, qup_id)          (GIC_SPI_START + 95 + (blsp_id-1)*204 + qup_id)
 #define SMD_IRQ                                (GIC_SPI_START + 168)
 #endif /* __IRQS_MSM8952_H */

其中GIC_SPI_START为一个偏移量,blsp_id为2,qup_id为1,即中断号为300

3、I2C初始化时调用gpio和时钟的配置函数添加如下

gpio设置文件添加函数代码:

diff –git a/platform/msm8952/gpio.c b/platform/msm8952/gpio.c
old mode 100644
new mode 100755
index 05b4977ec..72a3f6919
— a/platform/msm8952/gpio.c
+++ b/platform/msm8952/gpio.c
@@ -70,3 +70,46 @@ void gpio_config_uart_dm(uint8_t id)
     gpio_tlmm_config(4, 2, GPIO_OUTPUT, GPIO_NO_PULL,
                 GPIO_8MA, GPIO_DISABLE);
 }
+void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
+{

+    if(blsp_id == BLSP_ID_1) {

+        switch (qup_id) {

+            case QUP_ID_1:
+                /* configure I2C SDA gpio */
+                gpio_tlmm_config(6, 3, GPIO_OUTPUT, GPIO_NO_PULL,
+                        GPIO_8MA, GPIO_DISABLE);
+
+                /* configure I2C SCL gpio */
+                gpio_tlmm_config(7, 3, GPIO_OUTPUT, GPIO_NO_PULL,
+                    GPIO_8MA, GPIO_DISABLE);
+            break;
+            case QUP_ID_3:
+                /* configure I2C SDA gpio */
+                gpio_tlmm_config(14, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+                        GPIO_8MA, GPIO_DISABLE);
+
+                /* configure I2C SCL gpio */
+                gpio_tlmm_config(15, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+                    GPIO_8MA, GPIO_DISABLE);
+            break;
+            default:
+                dprintf(CRITICAL, “Incorrect QUP id %d\n”,qup_id);
+                ASSERT(0);
+        }
+    } else if (blsp_id == BLSP_ID_2){

+        switch (qup_id) {

+            case QUP_ID_1:
+                gpio_tlmm_config(22, 3, GPIO_OUTPUT, GPIO_NO_PULL,
+                        GPIO_8MA, GPIO_DISABLE);
+                gpio_tlmm_config(23, 3, GPIO_OUTPUT, GPIO_NO_PULL,
+                        GPIO_8MA, GPIO_DISABLE);
+            break;
+            default:
+                dprintf(CRITICAL, “Incorrect QUP id %d\n”,qup_id);
+                ASSERT(0);
+        }
+    } else {

+        dprintf(CRITICAL, “Incorrect BLSP id %d\n”,blsp_id);
+        ASSERT(0);
+    }
+}
\ No newline at end of file

diff –git a/platform/msm8952/include/platform/gpio.h b/platform/msm8952/include/platform/gpio.h
index b4d12e818..4d4dcd1cf 100644
— a/platform/msm8952/include/platform/gpio.h
+++ b/platform/msm8952/include/platform/gpio.h
@@ -69,4 +69,5 @@ void gpio_tlmm_config(uint32_t gpio,
             uint8_t pull,
             uint8_t drvstr,
             uint32_t enable);
+void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);
 #endif

时钟设置文件添加函数代码:

diff –git a/platform/msm8952/acpuclock.c b/platform/msm8952/acpuclock.c
old mode 100644
new mode 100755
index 9efe09b4f..7c9315ba2
— a/platform/msm8952/acpuclock.c
+++ b/platform/msm8952/acpuclock.c
@@ -34,6 +34,7 @@
 #include
 #include
 #include
+#include
 #include
 
 #define MAX_LOOPS    500
@@ -507,3 +508,86 @@ void clock_config_ce(uint8_t instance)
 
     clock_ce_enable(instance);
 }
+void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
+{

+    uint8_t ret = 0;
+    char clk_name[64];
+
+    struct clk *qup_clk;
+
+    if(((qup_id != QUP_ID_1) && (qup_id != QUP_ID_3))) {

+        dprintf(CRITICAL, “Incorrect BLSP-%d or QUP-%d configuration\n”, blsp_id, qup_id);
+        ASSERT(0);
+    }
+    if(blsp_id == BLSP_ID_1){

+        if (qup_id == QUP_ID_1) {

+            snprintf(clk_name, sizeof(clk_name), “blsp1_qup2_ahb_iface_clk”);
+        }
+        else if (qup_id == QUP_ID_3) {

+            snprintf(clk_name, sizeof(clk_name), “blsp1_qup4_ahb_iface_clk”);
+        }
+
+        ret = clk_get_set_enable(clk_name, 0 , 1);
+
+        if (ret) {

+            dprintf(CRITICAL, “Failed to enable %s clock\n”, clk_name);
+            return;
+        }
+
+        if (qup_id == QUP_ID_1) {

+            snprintf(clk_name, sizeof(clk_name), “gcc_blsp1_qup2_i2c_apps_clk”);
+        }
+        else if (qup_id == QUP_ID_3) {

+            snprintf(clk_name, sizeof(clk_name), “gcc_blsp1_qup4_i2c_apps_clk”);
+        }
+
+        qup_clk = clk_get(clk_name);
+
+        if (!qup_clk) {

+            dprintf(CRITICAL, “Failed to get %s\n”, clk_name);
+            return;
+        }
+
+        ret = clk_enable(qup_clk);
+
+        if (ret) {

+            dprintf(CRITICAL, “Failed to enable %s\n”, clk_name);
+            return;
+        }
+    } else if (blsp_id == BLSP_ID_2){

+        if (qup_id == QUP_ID_1) {

+            snprintf(clk_name, sizeof(clk_name), “blsp2_qup2_ahb_iface_clk”);
+        }
+        else if (qup_id == QUP_ID_3) {

+            snprintf(clk_name, sizeof(clk_name), “blsp2_qup4_ahb_iface_clk”);
+        }
+
+        ret = clk_get_set_enable(clk_name, 0 , 1);
+
+        if (ret) {

+            dprintf(CRITICAL, “Failed to enable %s clock\n”, clk_name);
+            return;
+        }
+
+        if (qup_id == QUP_ID_1) {

+            snprintf(clk_name, sizeof(clk_name), “gcc_blsp2_qup2_i2c_apps_clk”);
+        }
+        else if (qup_id == QUP_ID_3) {

+            snprintf(clk_name, sizeof(clk_name), “gcc_blsp2_qup4_i2c_apps_clk”);
+        }
+
+        qup_clk = clk_get(clk_name);
+
+        if (!qup_clk) {

+            dprintf(CRITICAL, “Failed to get %s\n”, clk_name);
+            return;
+        }
+
+        ret = clk_enable(qup_clk);
+
+        if (ret) {

+            dprintf(CRITICAL, “Failed to enable %s\n”, clk_name);
+            return;
+        }
+    }
+}
diff –git a/platform/msm8952/include/platform/clock.h b/platform/msm8952/include/platform/clock.h
index e6734cb27..cbd1ba46f 100644
— a/platform/msm8952/include/platform/clock.h
+++ b/platform/msm8952/include/platform/clock.h
@@ -99,4 +99,5 @@ void gcc_dsi_hs_clocks_enable(uint32_t flags,  bool use_dsi1_pll, uint8_t pclk0_
         uint8_t pclk0_n, uint8_t pclk0_d);
 void gcc_dsi_lp_clock_enable(uint32_t flags);
 void gcc_dsi_clocks_disable(uint32_t flags);
+void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);
 #endif
添加时钟的配置及序列,主要添加三个与时钟相关结构体

diff –git a/platform/msm8952/msm8952-clock.c b/platform/msm8952/msm8952-clock.c
old mode 100644
new mode 100755
index 85d506987..f9bebfe9f
— a/platform/msm8952/msm8952-clock.c
+++ b/platform/msm8952/msm8952-clock.c
@@ -206,6 +206,19 @@ static struct rcg_clk sdcc1_apps_clk_src =
     },
 };
 
+/* BLSP2_QUP2 Clocks */
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup2_i2c_apps_clk_src[] =
+{

+    F(96000,cxo,10,1,2),
+    F(4800000,cxo,4,0,0),
+    F(9600000,cxo,2,0,0),
+    F(16000000,gpll0,10,1,5),
+    F(19200000,gpll0,1,0,0),
+    F(25000000,gpll0,16,1,2),
+    F(50000000,gpll0,16,0,0),
+    F_END
+};
+
 static struct branch_clk gcc_sdcc1_apps_clk =
 {

     .cbcr_reg     = (uint32_t *) SDCC1_APPS_CBCR,
@@ -594,6 +607,37 @@ static struct vote_clk gcc_ce1_axi_clk = {

     },
 };
 
+static struct vote_clk gcc_blsp2_ahb_clk = { 
+        .cbcr_reg     = (uint32_t *) BLSP2_AHB_CBCR,
+        .vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+        .en_mask      = BIT(20),
+
+        .c = { 
+                .dbg_name = “gcc_blsp2_ahb_clk”,
+                .ops      = &clk_ops_vote,
+        },  
+};
+static struct rcg_clk gcc_blsp2_qup2_i2c_apps_clk_src =
+{

+    .cmd_reg      = (uint32_t *) GCC_BLSP2_QUP2_CMD_RCGR,
+    .cfg_reg      = (uint32_t *) GCC_BLSP2_QUP2_CFG_RCGR,
+    .set_rate     = clock_lib2_rcg_set_rate_hid,
+    .freq_tbl     = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src,
+    .current_freq = &rcg_dummy_freq,
+    .c = {

+        .dbg_name = “gcc_blsp2_qup2_i2c_apps_clk_src”,
+        .ops      = &clk_ops_rcg,
+    },
+};
+static struct branch_clk gcc_blsp2_qup2_i2c_apps_clk = {

+    .cbcr_reg = (uint32_t *) GCC_BLSP2_QUP2_APPS_CBCR,
+    .parent   = &gcc_blsp2_qup2_i2c_apps_clk_src.c,
+    .c = {

+        .dbg_name = “gcc_blsp2_qup2_i2c_apps_clk”,
+        .ops      = &clk_ops_branch,
+    },
+};
+

在时钟查找列表中添加如下函数代码:
 /* Clock lookup table */
 static struct clk_lookup msm_clocks_8952[] =
 {

@@ -621,6 +665,9 @@ static struct clk_lookup msm_clocks_8952[] =
     CLK_LOOKUP(“ce1_axi_clk”,  gcc_ce1_axi_clk.c),
     CLK_LOOKUP(“ce1_core_clk”, gcc_ce1_clk.c),
     CLK_LOOKUP(“ce1_src_clk”,  ce1_clk_src.c),
+    CLK_LOOKUP(“blsp2_qup2_ahb_iface_clk”, gcc_blsp2_ahb_clk.c),
+    CLK_LOOKUP(“gcc_blsp2_qup2_i2c_apps_clk_src”, gcc_blsp2_qup2_i2c_apps_clk_src.c),
+    CLK_LOOKUP(“gcc_blsp2_qup2_i2c_apps_clk”, gcc_blsp2_qup2_i2c_apps_clk.c),
 };
 
 void msm8956_clock_override()
diff –git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index c64acf027..57f833189 100755
— a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -634,6 +634,7 @@ DEFINES += DISPLAY_NONE_LK_MENU=1
             $(LOCAL_DIR)/crypto_hash.o \
             $(LOCAL_DIR)/crypto5_eng.o \
             $(LOCAL_DIR)/crypto5_wrapper.o \
+            $(LOCAL_DIR)/i2c_qup.o \
             $(LOCAL_DIR)/mdp5.o \
             $(LOCAL_DIR)/display.o \
             $(LOCAL_DIR)/mipi_dsi.o \

配置I2C的时钟参数:

diff –git a/platform/msm8952/include/platform/iomap.h b/platform/msm8952/include/platform/iomap.h
old mode 100644
new mode 100755
index 057d909f2..3e016fcff
— a/platform/msm8952/include/platform/iomap.h
+++ b/platform/msm8952/include/platform/iomap.h
@@ -101,6 +101,15 @@
 #define  GCC_CRYPTO_CBCR                   (CLK_CTL_BASE + 0x1601C)
 #define  GCC_CRYPTO_AXI_CBCR               (CLK_CTL_BASE + 0x16020)
 #define  GCC_CRYPTO_AHB_CBCR               (CLK_CTL_BASE + 0x16024)
+#define BLSP_QUP_BASE(blsp_id, qup_id)   ((blsp_id == 1) ? (PERIPH_SS_BASE + 0xB5000 \
+                                         + (qup_id * 0x1000)) :\
+                                         (PERIPH_SS_BASE + 0x2f5000 + \
+                                         (qup_id * 0x1000)))
+
+#define BLSP2_AHB_CBCR              (CLK_CTL_BASE + 0xB008)   //0x0B008
+#define GCC_BLSP2_QUP2_APPS_CBCR    (CLK_CTL_BASE + 0xD010)
+#define GCC_BLSP2_QUP2_CFG_RCGR     (CLK_CTL_BASE + 0xD004)
+#define GCC_BLSP2_QUP2_CMD_RCGR     (CLK_CTL_BASE + 0xD000)

4、添加I2C测试程序

diff –git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 16717dee5..87375893e 100755
— a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -95,6 +95,12 @@
 #include
 #include
 #include “fastboot_test.h”
+#include
+#include
+#include
+#include
+#include
+#include
 
 extern  bool target_use_signed_kernel(void);
 extern void platform_uninit(void);
@@ -326,6 +332,8 @@ struct getvar_partition_info {

 #define EXT_MAGIC_OFFSET_SB   0x38
 #define F2FS_MAGIC   0xF2F52010  // F2FS Magic Number
 #define F2FS_MAGIC_OFFSET_SB 0x0
+#define EXTERNCHG_SLAVE_ADDR  0x3b
+#define EXTERNCHG_I2C_VOLTAGE 0x08
 
 typedef enum fs_signature_type {

     EXT_FS_SIGNATURE = 1,
@@ -372,6 +380,79 @@ extern int emmc_recovery_init(void);
 extern int fastboot_trigger(void);
 #endif
 
+static struct qup_i2c_dev  *i2c_dev;
+int externchg_lk_i2c_read(uint8_t addr, uint8_t *reg, uint8_t *buf, uint8_t len) 
+{

+    if (!buf)
+        return ERR_INVALID_ARGS;
+    if(!i2c_dev)
+        return ERR_NOT_VALID;
+    struct i2c_msg rd_buf[] = {

+        {addr, I2C_M_WR, 1, reg},
+        {addr, I2C_M_RD, len, buf}
+    };
+    dprintf(CRITICAL, “#### qup_i2c_xfer\n”);
+    int err = qup_i2c_xfer(i2c_dev, rd_buf, 2);
+    
+    if (err < 0) {

+        dprintf(CRITICAL, “Read reg %x failed err %d\n”, *reg,err);
+        return err;
+    }
+    return NO_ERROR;
+}
+
+int externchg_lk_adapter_present(void)
+{

+    unsigned char buf;
+    unsigned char register_addr = EXTERNCHG_I2C_VOLTAGE;
+    unsigned char slave_addr = EXTERNCHG_SLAVE_ADDR;
+    int ret=-1;
+
+    if(!i2c_dev) {

+        return ERR_NOT_VALID;
+    }
+    ret = externchg_lk_i2c_read(slave_addr, ®ister_addr, &buf, 1);
+    if(ret < 0) {

+        dprintf(CRITICAL, “read externchg adapter_present error\n”);
+        return ret;
+    }
+    dprintf(CRITICAL, “#### read reg[0x8]=%x\n”,buf);
+    return (buf && 0x04) ? 0 : -1;
+}
+int externchg_lk_read_voltage(void)
+{

+    return target_get_battery_voltage();
+}
+
+void check_low_batt_start_system(void){ 
+    uint32_t is_batt_volt = 0;
+    uint32_t cutoff_volt = 3600000;
+
+    i2c_dev = qup_blsp_i2c_init(BLSP_ID_2, QUP_ID_1, 100000, 19200000);
+    is_batt_volt = externchg_lk_read_voltage();
+    if(is_batt_volt < cutoff_volt) {

+        dprintf(CRITICAL,”low battery(%d),forbidy boot\n”,is_batt_volt);
+        mdelay(20);
+        //display_image_on_screen();
+        /* 判断有无充电器插入,有则进行预充电,没有则关机
+         * externchg_lk_adapter_present();
+         */
+        if(!externchg_lk_adapter_present()){

+            //充电IC初始化
+            while(is_batt_volt < cutoff_volt){

+                dprintf(CRITICAL, “charging: batt_volt =%d\n”,is_batt_volt);
+                mdelay(1000);
+                is_batt_volt = externchg_lk_read_voltage();
+            }
+        }else {

+            shutdown_device();
+        }
+
+    }else{

+        dprintf(CRITICAL,”not low-volt battery(%d)\n”,is_batt_volt);
+    }
+}
+
 void target_get_pmic_info(char *pmic_info)
 {

         dprintf(INFO, “PMIC 0 is %d\n”, board_pmic_target(0));
@@ -632,8 +713,9 @@ unsigned char *update_cmdline(const char * cmdline)
         cmdline_len += strlen(loglevel);
     } else if (boot_reason_alarm) {

         cmdline_len += strlen(alarmboot_cmdline);
–    } else if ((target_build_variant_user() || device.charger_screen_enabled)
–            && target_pause_for_battery_charge() && !boot_into_recovery) {

+    } else if (!externchg_lk_adapter_present()){    
+    //} else if ((target_build_variant_user() || device.charger_screen_enabled)
+    //        && target_pause_for_battery_charge() && !boot_into_recovery) {

         pause_at_bootup = 1;
         cmdline_len += strlen(battchg_pause);
     }
@@ -964,6 +1046,7 @@ unsigned char *update_cmdline(const char * cmdline)
             if (have_cmdline) –dst;
             while ((*dst++ = *src++));
         } else if (pause_at_bootup) {

+            dprintf(INFO, “#### enter poweroff `charger\n”);
             src = battchg_pause;
             if (have_cmdline) –dst;
             while ((*dst++ = *src++));
@@ -5427,6 +5510,7 @@ retry_boot:
                     goto fastboot;
             }
 
+            check_low_batt_start_system();
             boot_err_type = boot_linux_from_mmc();
             switch (boot_err_type)
             {

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/180370.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号