基于Dragonboard 410c的总线控制之UART(一)

    UART也是一种常用的总线,可以实现异步操作,速率比i2c要块。

    1.标准是4线连接,分别是VCC、GND、RX、TX,但是根据不同的场景及用途,可以有3线和2线连接。

     2.协议

     UART使用的是异步串行通信协议,一步通信以一个字符为传输单位,通信中两个字符之间的时间间隔多少是不固定的,然而在同一个字符中的两个相邻位间的间隔是固定的。

    数据传输速率用波特率来表示,即每秒传送二进制的位数,例如:数据传送速率为120字符/秒,而每一个字符10位(1个起始位,7个数据位,一个校验位,一个结束位),则其传送的波特率为10x120=1200位/秒。

     数据传输格式如下所示:

   

    (1)起始位,先发一个逻辑“0”,表示开始传输

    (2)5-8位逻辑“0”或“1”,如ASCII码7位,扩展BCD码8位,并且是小端传输模式

    (3)校验位,数据位加上这一位后,使得“1“的个数为偶数,表示偶校验;”1“的个数为奇数,表示奇校验

    (4)停止位,一个字符数据传输结束的标志,可以是1位,1.5位,2位的高电平

    (5)空闲状态,高电平,表示当前线路没有数据传输


    基本了解后,就是UART在lk中的配置了。

     首先将debug的宏打开

     路径:bootable/bootloader/lk/project/msm8916.mk

     DEFINES += WITH_DEBUG_UART = 1

     接下来是UART的初始化了

     路径:bootable/bootloader/lk/target/msm8916/init.c

    void target_early_init(void)
{
#if WITH_DEBUG_UART
    uart_dm_init(2, 0, BLSP1_UART1_BASE);
#endif
}

uart_dm_init这个函数中,第一个参数表示BLSP ID(1-12),第二个参数表示是基于GSBI,第三个参数表示UART CORE的物理地址(路径:bootable/bootloader/lk/platform/msm8916/include/platform/iomap.h)

    接下来看一下具体实现:

    路径:bootable/bootloader/lk/platform/msm_shared/uart_dm.c

   void uart_dm_init(uint8_t id, uint32_t gsbi_base, uint32_t uart_dm_base)
{
    static uint8_t port = 0;
    char *data = "Android Bootloader - UART_DM Initialized!!!\n";

    /* Configure the uart clock */
    clock_config_uart_dm(id);
    dsb();

    /* Configure GPIO to provide connectivity between UART block
       product ports and chip pads */
    gpio_config_uart_dm(id);
    dsb();

    /* Configure GSBI for UART_DM protocol.
     * I2C on 2 ports, UART (without HS flow control) on the other 2.
     * This is only on chips that have GSBI block
     */
     if(gsbi_base)
        writel(GSBI_PROTOCOL_CODE_I2C_UART <<
            GSBI_CTRL_REG_PROTOCOL_CODE_S,
            GSBI_CTRL_REG(gsbi_base));
    dsb();

    /* Configure clock selection register for tx and rx rates.
     * Selecting 115.2k for both RX and TX.
     */
    writel(UART_DM_CLK_RX_TX_BIT_RATE, MSM_BOOT_UART_DM_CSR(uart_dm_base));
    dsb();

    /* Intialize UART_DM */
    msm_boot_uart_dm_init(uart_dm_base);

    msm_boot_uart_dm_write(uart_dm_base, data, 44);

    ASSERT(port < ARRAY_SIZE(port_lookup));
    port_lookup[port++] = uart_dm_base;

    /* Set UART init flag */
    uart_init_flag = 1;
}

主要看一下clock_config_uart_dm(id);和gpio_config_uart_dm(id);

路径:bootable/bootloader/lk/platform/msm8916/acpuclock.c

void clock_config_uart_dm(uint8_t id)
{
    int ret;
    char iclk[64];
    char cclk[64];

    snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id);
    snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id);

    ret = clk_get_set_enable(iclk, 0, 1);
    if(ret)
    {
        dprintf(CRITICAL, "failed to set %s ret = %d\n", iclk, ret);
        ASSERT(0);
    }

    ret = clk_get_set_enable(cclk, 7372800, 1);
    if(ret)
    {
        dprintf(CRITICAL, "failed to set %s ret = %d\n", cclk, ret);
        ASSERT(0);
    }
}

iclk 是iface_clock,为BLSP的clock;cclk是core_clock,为UART的clock.

在下面路径中定义
路径:bootable/bootloader/lk/platform/msm8916/include/platform/iomap.h

/* UART */

#define BLSP1_AHB_CBCR              (CLK_CTL_BASE + 0x1008)

路径:bootable/bootloader/lk/platform/msm8916/msm8916-clock.c

static struct clk_lookup msm_clocks_8916[] =
{

     CLK_LOOKUP("uart2_iface_clk", gcc_blsp1_ahb_clk.c),
    CLK_LOOKUP("uart2_core_clk",  gcc_blsp1_uart2_apps_clk.c),

.......

}


static struct vote_clk gcc_blsp1_ahb_clk = {
    .cbcr_reg     = (uint32_t *) BLSP1_AHB_CBCR,
    .vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
    .en_mask      = BIT(10),

    .c = {
        .dbg_name = "gcc_blsp1_ahb_clk",
        .ops      = &clk_ops_vote,
    },
};


static struct clk_ops clk_ops_vote =
{
    .enable     = clock_lib2_vote_clk_enable,
    .disable    = clock_lib2_vote_clk_disable,
};


static struct branch_clk gcc_blsp1_uart2_apps_clk =
{
    .cbcr_reg     = (uint32_t *) BLSP1_UART2_APPS_CBCR,
    .parent       = &blsp1_uart2_apps_clk_src.c,

    .c = {
        .dbg_name = "gcc_blsp1_uart2_apps_clk",
        .ops      = &clk_ops_branch,
    },
};


static struct clk_ops clk_ops_branch =
{
    .enable     = clock_lib2_branch_clk_enable,
    .disable    = clock_lib2_branch_clk_disable,
    .set_rate   = clock_lib2_branch_set_rate,
};

时钟配置到这就完了,接下来看一下引脚配置

路径:bootable/bootloader/lk/platform/msm8916/gpio.c

void gpio_config_uart_dm(uint8_t id)
{
    /* configure rx gpio */
    gpio_tlmm_config(5, 2, GPIO_INPUT, GPIO_NO_PULL,
                GPIO_8MA, GPIO_DISABLE);

    /* configure tx gpio */
    gpio_tlmm_config(4, 2, GPIO_OUTPUT, GPIO_NO_PULL,
                GPIO_8MA, GPIO_DISABLE);
}

到此,UART在lk的配置就结束了


















  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值