vSE1901A安全芯片调试

vSE1901A安全芯片调试,使用通用的spi协议接口。

电路图

DTS配置

&iomuxc {
    pinctrl-names = "default";

    imx8mm-evk {

        pinctrl_ecspi2: ecspi2grp {
            fsl,pins = <
                MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK        0x82 
                MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI        0x82 
                MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO        0x82 
            >;
        };

        pinctrl_ecspi2_cs: ecspi2cs {
            fsl,pins = <
                MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13          0x40000 
            >;
        };

    };
};

&ecspi2 {
    #address-cells = <1>;
    #size-cells = <0>;
    fsl,spi-num-chipselects = <1>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_ecspi2 &pinctrl_ecspi2_cs>;
    cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
    status = "okay";

    spidev1: vse1901aspi@0 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "vecentek,vSE1901A";
        spi-max-frequency = <1000000>;
        reg = <0>;
    };
};

驱动修改

内核配置:CONFIG_SPI_SPIDEV=y

代码修改:drivers/spi$ vi spidev.c +667

static const struct of_device_id spidev_dt_ids[] = {
    { .compatible = "rohm,dh2228fv" },
    { .compatible = "lineartechnology,ltc2488" },
    { .compatible = "ge,achc" },
    { .compatible = "semtech,sx1301" },
    { .compatible = "siliconlabs,si3210" },
	{ .compatible = "vecentek,vSE1901A" },
    {},
};
MODULE_DEVICE_TABLE(of, spidev_dt_ids);

启动打印

[    1.489045] spi_imx 30830000.ecspi: dma setup error -19, use pio
[    1.495512] spi_imx 30830000.ecspi: probed

查看节点

root@OpenWrt:/# ls /sys/class/spi_master/spi1/
device      power       statistics  uevent
of_node     spi1.0      subsystem

root@OpenWrt:/# ls /sys/class/spidev/spidev1.0/
dev        device     power      subsystem  uevent

root@OpenWrt:/# cat /sys/class/spi_master/spi1/uevent 
OF_NAME=ecspi
OF_FULLNAME=/ecspi@30830000
OF_COMPATIBLE_0=fsl,imx8mm-ecspi
OF_COMPATIBLE_1=fsl,imx51-ecspi
OF_COMPATIBLE_N=2
OF_ALIAS_0=spi1

root@OpenWrt:/# ls /dev/spidev1.0 -l
crw-------    1 root     root      153,   0 Jan  1  1970 /dev/spidev1.0

回环测试

spidev_test.c,代码来源:http://blog.chinaunix.net/uid-23065002-id-5191012.html?tdsourcetag=s_pcqq_aiomsg

/* 
     * SPI testing utility (using spidev driver) 
     * 
     * Copyright (c) 2007 MontaVista Software, Inc. 
     * Copyright (c) 2007 Anton Vorontsov <avorontsov@ru.mvista.com> 
     * 
     * This program is free software; you can redistribute it and/or modify 
     * it under the terms of the GNU General Public License as published by 
     * the Free Software Foundation; either version 2 of the License. 
     * 
     * Cross-compile with cross-gcc -I/path/to/cross-kernel/include 
     */ 
      
    #include <stdint.h> 
    #include <unistd.h> 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <getopt.h> 
    #include <fcntl.h> 
    #include <sys/ioctl.h> 
    #include <linux/types.h> 
    #include <linux/spi/spidev.h> 
      
    #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 
      
    static void pabort(const char *s) 
    { 
            perror(s); 
            abort(); 
    } 
      
    static const char *device = "/dev/spidev1.0"; 
    static uint8_t mode; 
    static uint8_t bits = 8; 
    static uint32_t speed = 500000; 
    static uint16_t delay; 
      
    static void transfer(int fd) 
    { 
            int ret; 
            uint8_t tx[] = { 
                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
                    0x40, 0x00, 0x00, 0x00, 0x00, 0x95, 
                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
                    0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 
                    0xF0, 0x0D, 
            }; 
            uint8_t rx[ARRAY_SIZE(tx)] = {0, }; 
            struct spi_ioc_transfer tr = { 
                    .tx_buf = (unsigned long)tx, 
                    .rx_buf = (unsigned long)rx, 
                    .len = ARRAY_SIZE(tx), 
                    .delay_usecs = delay, 
                    .speed_hz = speed, 
                    .bits_per_word = bits, 
            }; 
      
            ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); 
            if (ret == 1) 
                    pabort("can't send spi message"); 
      
            for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { 
                    if (!(ret % 6)) 
                            puts(""); 
                    printf("%.2X ", rx[ret]); 
            } 
            puts(""); 
    } 
      
    static void print_usage(const char *prog) 
    { 
            printf("Usage: %s [-DsbdlHOLC3]\n", prog); 
            puts(" -D --device device to use (default /dev/spidev1.1)\n" 
                 " -s --speed max speed (Hz)\n" 
                 " -d --delay delay (usec)\n" 
                 " -b --bpw bits per word \n" 
                 " -l --loop loopback\n" 
                 " -H --cpha clock phase\n" 
                 " -O --cpol clock polarity\n" 
                 " -L --lsb least significant bit first\n" 
                 " -C --cs-high chip select active high\n" 
                 " -3 --3wire SI/SO signals shared\n"); 
            exit(1); 
    } 
      
    static void parse_opts(int argc, char *argv[]) 
    { 
            while (1) { 
                    static const struct option lopts[] = { 
                            { "device", 1, 0, 'D' }, 
                            { "speed", 1, 0, 's' }, 
                            { "delay", 1, 0, 'd' }, 
                            { "bpw", 1, 0, 'b' }, 
                            { "loop", 0, 0, 'l' }, 
                            { "cpha", 0, 0, 'H' }, 
                            { "cpol", 0, 0, 'O' }, 
                            { "lsb", 0, 0, 'L' }, 
                            { "cs-high", 0, 0, 'C' }, 
                            { "3wire", 0, 0, '3' }, 
                            { "no-cs", 0, 0, 'N' }, 
                            { "ready", 0, 0, 'R' }, 
                            { NULL, 0, 0, 0 }, 
                    }; 
                    int c; 
      
                    c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL); 
      
                    if (c == -1) 
                            break; 
      
                    switch (c) { 
                    case 'D': 
                            device = optarg; 
                            break; 
                    case 's': 
                            speed = atoi(optarg); 
                            break; 
                    case 'd': 
                            delay = atoi(optarg); 
                            break; 
                    case 'b': 
                            bits = atoi(optarg); 
                            break; 
                    case 'l': 
                            mode |= SPI_LOOP; 
                            break; 
                    case 'H': 
                            mode |= SPI_CPHA; 
                            break; 
                    case 'O': 
                            mode |= SPI_CPOL; 
                            break; 
                    case 'L': 
                            mode |= SPI_LSB_FIRST; 
                            break; 
                    case 'C': 
                            mode |= SPI_CS_HIGH; 
                            break; 
                    case '3': 
                            mode |= SPI_3WIRE; 
                            break; 
                    case 'N': 
                            mode |= SPI_NO_CS; 
                            break; 
                    case 'R': 
                            mode |= SPI_READY; 
                            break; 
                    default: 
                            print_usage(argv[0]); 
                            break; 
                    } 
            } 
    } 
      
    int main(int argc, char *argv[]) 
    { 
            int ret = 0; 
            int fd; 
      
            parse_opts(argc, argv); 
      
            fd = open(device, O_RDWR); 
            if (fd < 0) 
                    pabort("can't open device"); 
      
            /* 
             * spi mode 
             */ 
            ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); 
            if (ret == -1) 
                    pabort("can't set spi mode"); 
      
            ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); 
            if (ret == -1) 
                    pabort("can't get spi mode"); 
      
            /* 
             * bits per word 
             */ 
            ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); 
            if (ret == -1) 
                    pabort("can't set bits per word"); 
      
            ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); 
            if (ret == -1) 
                    pabort("can't get bits per word"); 
      
            /* 
             * max speed hz 
             */ 
            ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); 
            if (ret == -1) 
                    pabort("can't set max speed hz"); 
      
            ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); 
            if (ret == -1) 
                    pabort("can't get max speed hz"); 
      
            printf("spi mode: %d\n", mode); 
            printf("bits per word: %d\n", bits); 
            printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); 
      
            transfer(fd); 
      
            close(fd); 
      
            return ret; 
    }

短接MOSI和MISO,测试结果PASS

root@OpenWrt:/# /tmp/spidev_test 
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

FF FF FF FF FF FF 
40 00 00 00 00 95 
FF FF FF FF FF FF 
FF FF FF FF FF FF 
FF FF FF FF FF FF 
DE AD BE EF BA AD 
F0 0D 

应用测试

使用厂家提供的测试用例程序,修改对应的参数,主要修改有下面几点:

1、spi设备信息

#define SPI_DEVICE      "/dev/spidev1.0"
#define SPI_MODE        0
#define SPI_BITS        8
#define SPI_SPEED       (500*1000)

2、复位GPIO管脚,对应电路图的SE_RST引脚,高复位

static const char *gpio_path[GPIO_PIN_MAX] = {
    NULL, /* GPIO_PIN_NONE */
    "/sys/class/gpio/gpio50", /* GPIO_SE_RST */
};

static const uint8_t gpio_pins[GPIO_PIN_MAX] = {
    255, /* GPIO_PIN_NONE */
    50, /* GPIO_SE_RST */
};

3、打开SPI_DEBUG_EN,打印原始收发数据

#define SPI_DEBUG_EN
#define SPI_STR_END                 "\r\n"
#define SPI_PRINTF(fmt, ...)        printf(fmt SPI_STR_END, ##__VA_ARGS__)
#ifdef  SPI_DEBUG_EN
#define SPI_BUFFER(desc,buf,len)    do { \
                                        uint16_t n; \
                                        printf(desc SPI_STR_END); \
                                        for (n=0;n<len;++n) \
                                            printf("0x%02X ", buf[n]); \
                                        printf(SPI_STR_END); \
                                    } while (0);
#else
#define SPI_BUFFER(desc,buf,len)    
#endif

测试结果PASS

root@OpenWrt:/# /tmp/vse_test-debug 
VSE test count ....................................0.
SPI - Open Succeed. Start Init SPI ....
spi mode: 0.
bits per word: 8.
max speed: 500 KHz (0 MHz).
SPI TX:
0x03 0x00 0x03 
SPI TX:
0xD3 0x00 0xD3 
SPI RX:
0xFF 0xFF 0xFF 
SPI RX:
0x03 0x00 0x03 
SPI RX:
0xD3 0x00 0xD3 
SPI TX:
0x03 0x00 0x03 
SPI TX:
0xE2 0x01 0xE3 
SPI RX:
0xFF 0xFF 0xFF 
SPI RX:
0x03 0x00 0x0B 
SPI RX:
0x3B 0x17 0x01 0x81 0x3D 0x00 0x00 0x40 0x00 0x0A 0xD3 
SPI TX:
0x0E 0x00 0x0A 
SPI TX:
0x80 0xF2 0x01 0x00 0x04 0x04 0x1F 0x01 0x00 0x69 
SPI RX:
0xFF 0xFF 0xFF 
SPI RX:
0xFF 0xFF 0xFF 
SPI RX:
0xFF 0xFF 0xFF 
SPI RX:
0xFF 0xFF 0xFF 
SPI RX:
0x0E 0x00 0x47 
SPI RX:
0x60 0x20 0x80 0xB1 0x07 0x3C 0xF4 0xBF 0x00 0x3A 0x19 0xF5 0x91 0x5D 0xBA 0x4E 
SPI RX:
0x43 0xF0 0xBF 0xE3 0xE9 0x7A 0xFE 0xDA 0xA4 0x02 0x44 0x8D 0xE0 0x91 0x67 0x73 
SPI RX:
0xB2 0x3B 0x61 0x20 0x73 0x55 0x3F 0x57 0xD3 0x53 0x5D 0x1E 0x5F 0x68 0x3E 0xE7 
SPI RX:
0x60 0x87 0x34 0xF0 0x57 0x65 0x90 0x81 0xCE 0xE2 0xB1 0x55 0x76 0x28 0xBF 0x05 
SPI RX:
0xAA 0xE2 0x1E 0xD6 0x90 0x00 0x63 

测试通过正常下不会有打印,测试失败会有异常打印信息提示。

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值