SPI接口调试

本文记录了复旦微fmql45t900 SPI裸核和linux系统下spi接口的调试步骤。

问题描述:

复旦微fmql45t900 SPI接口片选信号无法拉低控制。

原因分析:

为了排除硬件问题,创建spi裸核测试工程进行单步调试,spi发送数据时用示波器可以正常量到spi发送的数据和片选拉低信号,数据发送完后片选自动拉高。

当procise将相关MIO端口配置成spi功能时,对应的MIO30口默认配置为spi0的片选,当spi发送fifo非空时会自动拉低,无法作为通用GPIO口进行控制。

解决措施:修改spi测试工程中ps_init.c文件,将MIO30口配置成普通GPIO口,修改如下:

SPI接口调试_第1张图片

注意:在线调试时如果先加载了fsbl工程再加载的话,最好将fsbl工程和spi测试工程中的ps_init.c都进行修改,如果只修改fsbl工程后面再加载spi测试工程时再次初始化端口可能会覆盖之前的配置。

测试验证:

裸核测试验证

在spi测试工程fmsh_gpio_exampl.c中增加以下片选设置代码:

/*功能:片选设置
参数:
port:片选对应gpio口,共32个口,spi0片选对应端口30
value:gpio值,0拉低 1拉高
*/
u8 FGpioPs_cs_set(int port, int value)
{
    FGpioPs_T gpioDevA;
    FGpioPs_init(&gpioDevA, FGpioPs_LookupConfig(GPIO_DeviceID));
    static unsigned int staus = 0xFFFFFFFF;

    FGpioPs_setDirection(&gpioDevA, 0xFFFFFFFF);    /*set gpio direction all output */
    
    if(value)
    {
      staus |= (1 << port);
      FGpioPs_writeData(&gpioDevA, staus);       /*output high level to gpio pins*/ 
    }
    else
    {
      staus &= (~(1 << port)); 
      FGpioPs_writeData(&gpioDevA, staus);       /*output low level to gpio pins*/
    }

    return 0;
}
在spi测试工程fmsh_spi_exampl.c中修改spi测试函数FSpiPs_example如下:
int FSpiPs_example(void)
{
    FSpiPs_T* spi0Ptr;
    FSpiPs_T* spi1Ptr;
    int status = FMSH_SUCCESS;
    u32 data;
    spi0Ptr = &spi0;
    
    /* spi0 master, spi1 slaver */
    FSpiPs_Initialize(spi0Ptr, FPS_SPI0_DEVICE_ID);
    FSpiPs_Reset(spi0Ptr);
    FSpiPs_Initialize_Master(spi0Ptr);
    /*将spi0片选拉低*/       
    FGpioPs_cs_set(30, 0);
    /*发送数据*/
    FSpiPs_Send(spi0Ptr, 0xf3); 
    /*将spi0片选拉高*/    
    FGpioPs_cs_set(30, 1);
    return status;
}

Linux系统下使用spi步骤:

a、将上述修改后的fsbl工程编译生成FSBL.out文件

b、修改dts设备树文件添加spi设备节点,修改如下:

spi@e0001000 {

//spi控制器名称,和spi主控制器驱动匹配

compatible = "fmsh,dw-apb-ssi", "snps,dw-apb-ssi";

#address-cells = <0x1>;

#size-cells = <0x0>;

reg = <0xe0001000 0x1000>; //spi控制器寄存器地址、长度

interrupts = <0x0 0x16 0x4>;

num-cs = <0x2>;  //支持两个片选

clocks = <0x1 0x27 0x1 0x29>;

clock-names = "clk_ref", "pclk";

reg-io-width = <0x4>;

spi-max-frequency = <0xf4240>;

status = "okay";

//片选信号,0xb表示GPIO,对应porta,0x1e表示对应MIO30端口,0表示低电平有效

cs-gpios = <0xb 0x1e 0x0 0xb 0x1f 0x0>;

// spi控制器连接的设备0

spidev0:dh2228@0 {

compatible = "rohm,dh2228fv"; //设备名称,和spi设备驱动匹配

reg = <0x0>; //片选0

spi-max-frequency = <0x1000000>;

};

// spi控制器连接的设备1

spidev1:dh2228@1 {

compatible = "rohm,dh2228fv";

reg = <0x1>;//片选1

spi-max-frequency = <0x1000000>;

};

};

上述节点中的片选gpio设备树节点由procise将MIO配置成GPIO后自动生成,如下所示:

gpio@e0003000 {

compatible = "snps,dw-apb-gpio";

reg = <0xe0003000 0x100>;

#address-cells = <0x1>;

#size-cells = <0x0>;

clocks = <0x1 0x2d>;

status = "okay";

gpio-controller@0 {

compatible = "snps,dw-apb-gpio-port";

bank-name = "porta";

gpio-controller;

#gpio-cells = <0x2>;

snps,nr-gpios = <0x20>;

reg = <0x0>;

interrupt-controller;

#interrupt-cells = <0x2>;

interrupts = <0x0 0x11 0x4>;

linux,phandle = <0xb>;

phandle = <0xb>;

};

};

c、用dtc工具将步骤b修改后的dts编译成dtb, dtc工具使用命令如下(xxx表示对应dtb和dts文件名):

dtc  -I  dts -O  dtb  -o xxx.dtb  xxx.dts  

d、用dtb编译对应的uboot.elf文件,将uboot.elf和FSBL.out生成BOOT.bin

e、配置内核,增加spi驱动相关配置,重新编译内核(复旦微提供的内核默认已经配置相关项):

SPI接口调试_第2张图片

 

其中CONFIG_SPI_DW_FMSH对应复旦微spi主控制器驱动, CONFIG_SPI_SPIDEV对应spi外接设备驱动,其他为spi驱动框架涉及的核心和片选控制驱动代码。

完成上述步骤、进入系统后会在/dev目录下生成对应的spi设备文件,应用程序可以对设备文件进行读写操作。

 

你可能感兴趣的:(linux,c语言)