zoukankan      html  css  js  c++  java
  • uboot移植spi驱动

    记录一下在uboot内移植spi驱动的过程

    芯片:freescale Mpc8308

    uboot版本:u-boot-2009.11-rc1.2

    需求:我们需要在uboot下通过spi配置一个时钟芯片(dpll)用来给fpga提供时钟

    要移植spi驱动,前提是要通过手册了解该cpu的spi的结构和寄存器描述,一般作为cpu的外围设备,spi是有一个spi控制器的

    简单看一下8308的spi模块结构

    spi的四根线,MOSI,MISO,CS,CLK

    CS以外的几根线是从Master上引出来的

    而CS是由cpu的gpio来扮演的

    驱动方面

    uboot中产品的配置文件我的在include/configs/MPC8308EDD.h

    这个是修改过的,

    在u-boot-2009.11-rc1.2/driver/spi中找到mpc8xxx_spi.c文件,我们姑且认为这个就是最相近的驱动了(根据芯片名称与文件名称)

    相关Makefile

    COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o 

    在lib_ppc/board.c(不通uboot,目录不同)中有spi_init()的初始化调用,如下

    #if defined(CONFIG_HARD_SPI)
    static int init_func_spi (void)
    {
            puts ("SPI:   ");
            spi_init ();
            puts ("ready
    ");
            return (0);
    }
    #endif

    将需要的宏添加到MPC8308EDD.h中

    /*
    
     * eSPI - Enhanced SPI
     */
    #define CONFIG_HARD_SPI
    #define CONFIG_FSL_ESPI

    现在spi模块驱动有了,初始化有了,但是我们还需要一个spi的对象,struct spi_slave

    struct spi_slave *spi_slave_init(void)
    {
    
    struct spi_slave *slave;
    unsigned int    bus = 0;
    unsigned int    cs = 3;
    unsigned int    mode = SPI_MODE_0;
    
    slave = spi_setup_slave(bus, cs, 1000000, mode);
    if (!slave) {
    printf("Invalid device %d:%d
    ", bus, cs);
    return NULL;
    }
    
    spi_claim_bus(slave);
    
    return slave;
    }
    static int spi_read_write(struct spi_slave *spi,
    const u8 *cmd, size_t cmd_len,
    const u8 *data_out, u8 *data_in,
    size_t data_len)
    {
    unsigned long flags = SPI_XFER_BEGIN;
    int ret;
    
    if (data_len == 0)
    flags |= SPI_XFER_END;
    
    ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags);
    if (ret) {
    debug("SF: Failed to send command (%zu bytes): %d
    ",
    cmd_len, ret);
    } else if (data_len != 0) {
    ret = spi_xfer(spi, data_len * 8, data_out, data_in, SPI_XFER_END);
    if (ret)
    debug("SF: Failed to transfer %zu bytes of data: %d
    ",
    data_len, ret);
    }
    
    return ret;
    }

    这个spi_read_write是根据我的读写需求后补的
    在lib_ppc/board.c函数board_init_r最后添加spi的slave初始化
            struct spi_slave *slave;

            slave = spi_slave_init();
    目前为止,spi驱动理论上移植完了,一次ok的可能性太小了^_^,后面讲问题

    1.一切配置正常但从设备并没有工作

    初始化正常,从设备也配置了,而且spi的各引脚信号都能测到,从设备是一个时钟芯片,并没有时钟输出

    信号能测到那么检查信号的正确性了,按照时钟芯片的要求,将spi的初始化模式修改

    - spi->mode = SPI_MODE_REV | SPI_MODE_MS | SPI_MODE_EN;
    - spi->mode = (spi->mode & 0xfff0ffff) | (1 << 16); /* Use SYSCLK / 8
    -     (16.67MHz typ.) */
    + spi->mode = 0;
    + spi->mode = SPMODE_INIT_VAL | SPMODE_ENABLE;
    +// spi->mode = (spi->mode & 0xfff0ffff) | (1 << 16); /* Use SYSCLK / 8   (16.67MHz typ.) */
      spi->event = 0xffffffff; /* Clear all SPI events */
      spi->mask = 0x00000000; /* Mask  all SPI interrupts */
      spi->com = 0; /* LST bit doesn't do anything, so disregard */
    + printf("mode = 0x%x ",spi->mode);
      spi->com = 0; /* LST bit doesn't do anything, so disregard */
    + printf("mode = 0x%x ",spi->mode);


    原文链接:https://blog.csdn.net/davion_zhang/article/details/50883806

  • 相关阅读:
    spring常用注解
    P1255 数楼梯
    蓝桥杯 传纸条(动态规划)
    蓝桥杯 数的划分两种解法
    蓝桥杯 数独
    Elasticsearch05-批量增删改查
    Elasticsearch04-正排索引和倒排索引
    Elasticsearch03-Mapping和聚合
    Elasticsearch02-查询语法
    亿级流量多级缓存高并发系统架构实战
  • 原文地址:https://www.cnblogs.com/Ph-one/p/11539827.html
Copyright © 2011-2022 走看看