Firefly开源社区

打印 上一主题 下一主题

W25Q128FV SPI 读ID不稳定

582

积分

10

威望

8

贡献

技术大神

Rank: 3Rank: 3

积分
582
QQ

W25Q128FV SPI 读ID不稳定

发表于 2017-3-23 00:24:01      浏览:12831 | 回复:7        打印      只看该作者   [复制链接] 楼主
本帖最后由 54zw 于 2017-3-23 00:29 编辑

使用firefly spi demo 读id,会有下面这样的日志,间断性无法读到ID

[ 1108.239354] firefly-spi spi0.0: firefly_spi_read_w25x_id_0: ID = ef 40 18 00 00
[ 1108.239449] firefly-spi spi0.0: firefly_spi_read_w25x_id_1: ID = ef 40 18 00 00
[ 1113.247362] firefly-spi spi0.0: firefly_spi_read_w25x_id_0: ID = ff ff ff ff ff
[ 1113.247447] firefly-spi spi0.0: firefly_spi_read_w25x_id_1: ID = ff ff ff ff ff
[ 1118.255374] firefly-spi spi0.0: firefly_spi_read_w25x_id_0: ID = ef 40 18 00 00
[ 1118.255494] firefly-spi spi0.0: firefly_spi_read_w25x_id_1: ID = ef 40 18 00 00
[ 1123.263382] firefly-spi spi0.0: firefly_spi_read_w25x_id_0: ID = ff ff ff ff ff
[ 1123.263501] firefly-spi spi0.0: firefly_spi_read_w25x_id_1: ID = ff ff ff ff ff
[ 1128.271376] firefly-spi spi0.0: firefly_spi_read_w25x_id_0: ID = ef 40 18 00 00
[ 1128.271497] firefly-spi spi0.0: firefly_spi_read_w25x_id_1: ID = ef 40 18 00 00
[ 1133.279384] firefly-spi spi0.0: firefly_spi_read_w25x_id_0: ID = ef 40 18 00 00
[ 1133.279504] firefly-spi spi0.0: firefly_spi_read_w25x_id_1: ID = ef 40 18 00 00
[ 1138.287380] firefly-spi spi0.0: firefly_spi_read_w25x_id_0: ID = ff ff ff ff ff
[ 1138.287500] firefly-spi spi0.0: firefly_spi_read_w25x_id_1: ID = ff ff ff ff ff
[ 1143.295380] firefly-spi spi0.0: firefly_spi_read_w25x_id_0: ID = ef 40 18 00 00
[ 1143.295500] firefly-spi spi0.0: firefly_spi_read_w25x_id_1: ID = ef 40 18 00 00




代码在原有基础上用定时器不断读取ID

static void timeout_handler(unsigned long tdata)
{
    struct spi_device *spi = (struct spi_device *)tdata;

   g_sds.timer.expires = jiffies + EXPIRES_PERIOD;
    add_timer(&g_sds.timer);
    firefly_spi_read_w25x_id_0(spi);
    firefly_spi_read_w25x_id_1(spi);
}

static int firefly_spi_probe(struct spi_device *spi)
{
    int ret = 0;
    struct device_node __maybe_unused *np = spi->dev.of_node;

    dev_dbg(&spi->dev, "Firefly SPI demo program\n");

    if(!spi)
        return -ENOMEM;

    dev_dbg(&spi->dev, "firefly_spi_probe: setup mode %d, %s%s%s%s%u bits/w, %u Hz max\n",
            (int) (spi->mode & (SPI_CPOL | SPI_CPHA)),
            (spi->mode & SPI_CS_HIGH) ? "cs_high, " : "",
            (spi->mode & SPI_LSB_FIRST) ? "lsb, " : "",
            (spi->mode & SPI_3WIRE) ? "3wire, " : "",
            (spi->mode & SPI_LOOP) ? "loopback, " : "",
            spi->bits_per_word, spi->max_speed_hz);

    /* init timer */
    init_timer(&g_sds.timer);

    /* setup the timer */
    g_sds.timer.expires = jiffies + EXPIRES_PERIOD;
    g_sds.timer.function = timeout_handler;
    g_sds.timer.data = (unsigned long)spi;

    /* add to system */
    add_timer(&g_sds.timer);


    return ret;
}

硬件连接图如下:

snap0000.png (202.55 KB, 下载次数: 704)

snap0000.png
回复

使用道具 举报

582

积分

10

威望

8

贡献

技术大神

Rank: 3Rank: 3

积分
582
QQ
发表于 2017-5-7 10:17:56        只看该作者  沙发
已解决,看这里W25Q128FV SPI 驱动
回复

使用道具 举报

459

积分

0

威望

0

贡献

技术达人

Rank: 2

积分
459
发表于 2017-5-8 15:40:53        只看该作者  板凳
你也是 牛了   给个联系方式  让我们好好学习下
回复

使用道具 举报

56

积分

0

威望

0

贡献

技术小白

积分
56
发表于 2017-6-8 10:08:30        只看该作者  地板
你好 , 我最近要测试一下spi, 我们自己下的的linux版本 , /dev/下没有spidev,是需要我们自己去注册设备节点还是在make menuconfig中没有注册设备节点,下面是官方自带的.config文件,如果要改这方面驱动,你能不能给一点指导

QQ图片20170608100726.png (43.5 KB, 下载次数: 647)

QQ图片20170608100726.png
回复

使用道具 举报

582

积分

10

威望

8

贡献

技术大神

Rank: 3Rank: 3

积分
582
QQ
发表于 2017-6-8 15:22:30        只看该作者  5#
chenqian 发表于 2017-6-8 10:08
你好 , 我最近要测试一下spi, 我们自己下的的linux版本 , /dev/下没有spidev,是需要我们自己去注册设备 ...

/dev/spidev是内核里的一个驱动,可以不使用这个,到我github上看下如何写一个spi驱动

https://github.com/54shady/kerne ... ly_RK3399/debug/spi
回复

使用道具 举报

56

积分

0

威望

0

贡献

技术小白

积分
56
发表于 2017-6-20 11:32:37        只看该作者  6#
#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>
/*
*  write a file to spi_flash
  */
#define W25_WRITE_ENABLE                0x06
#define W25_WRITE_DISABLE                0x04
#define W25_READ_STATUS_1                0x05
#define W25_READ_STATUS_2                0x35
#define W25_WRITE_STATUS                0x01
#define W25_READ_DATA                        0x03
#define W25_ERASE_SECTOR                0x20
#define W25_ERASE_BLOCK                0xD8
#define W25_PAGE_PROGRAM                0x02
#define W25_CHIP_ID                         0x9F

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

static const char* spi_device = "/dev/spidev2.2";
static unsigned char mode;
static unsigned char bits = 8;
static unsigned int speed = 1000000;

/*
* 打印出buf的内容
* @parm info 前面的提示信息
  */
static void dis_array(const char* info , const unsigned char* buf, unsigned int len){
        int i =  0;
        printf("%s      :",info);
        for(i = 0; i< len ; i++){
                printf("%02x " , buf[i]);
        }
        printf("\n");
}
/*
*  write and read
*/
static int w25_write_read(int fd , const char* wbuf,unsigned int wlen,
        const char* rbuf , unsigned int rlen){

        int ret = 0;
        struct spi_ioc_transfer tr[2] = {
                {
                        .tx_buf = (unsigned long)wbuf,
                        .rx_buf = 0,
                        .len = wlen,
                        .speed_hz = speed,
                },
                {
                        .tx_buf = 0,
                        .rx_buf = (unsigned long)rbuf,
                        .len = rlen,
                        .speed_hz = speed,
                },
        };

        ret = ioctl(fd , SPI_IOC_MESSAGE(2) , tr);

        return ret;
}

/*
* write no read
*/
static int w25_write(int fd , const char* wbuf,unsigned int wlen){

        int ret = 0;
        struct spi_ioc_transfer tr[1] = {
                {
                        .tx_buf = (unsigned long)wbuf,
                        .rx_buf = 0,
                        .len = wlen,
                        .speed_hz = speed,
                }
        };

        ret = ioctl(fd , SPI_IOC_MESSAGE(1) , tr);

        return ret;
}


int main(int argc , char* argv[]){
        int ret = 0;
        int fd;
        unsigned char tempcmd = 0;
        unsigned char cmd[8] = {0};
        unsigned char buf[8] = {0};

        fd = open(spi_device , O_RDWR);
        if (fd < 0){
                printf("open /dev/spidev error\n ");
        }

        /*
        * spi mode
         */
         ret = ioctl(fd , SPI_IOC_WR_MODE , &mode);
        if (ret == -1){
                printf("set spi mode error\n");
        }
        ret = ioctl(fd , SPI_IOC_RD_MODE , &mode);
        if (ret == -1){
                printf("get spi mode error\n");
        }

        /*
        *  bits per word
        */
        ret = ioctl(fd , SPI_IOC_WR_BITS_PER_WORD , &bits);
        if (ret == -1){
                printf("set bits per word error\n");
        }
        ret = ioctl(fd , SPI_IOC_RD_BITS_PER_WORD , &bits);
        if (ret == -1){
                printf("get bits per word error\n");
        }
       
        /*
        * max speed hz
        */
        ret = ioctl(fd , SPI_IOC_WR_MAX_SPEED_HZ , &speed);
        if (ret == -1){
                printf("set max speed error\n");
        }
        ret = ioctl(fd , SPI_IOC_RD_MAX_SPEED_HZ , &speed);
        if (ret == -1){
                printf("get max speed error\n");
        }

        /*
        * print useful info
        */
        printf("spi mode: %d\n",mode);
        printf("spi bits per words : %d \n" , bits);
        printf("spi max speed : %dhz (%dkHz)\n",speed , speed/1000);

        //get chip id
        tempcmd = W25_CHIP_ID;
        ret = w25_write_read(fd, &tempcmd ,  sizeof(tempcmd ), buf , 3 );
        printf("w25_flash chip ID : %x , %x , %x\n" , buf[0] , buf[1] , buf[2] );
       
        //erase first sector
        tempcmd = W25_WRITE_ENABLE;
        w25_write( fd, &tempcmd , 1 );
        cmd[0] = W25_ERASE_SECTOR;
        cmd[1] = 0;
        cmd[2] = 0;
        cmd[3] = 0;
        ret = w25_write(fd, cmd , 4);
        printf("frist sector erase done ..\n");
       
        //read data
        cmd[0] = W25_READ_DATA;
        cmd[1] = 0;
        cmd[2] = 0;
        cmd[3] = 0;
        ret = w25_write_read(fd, cmd , 4 , buf , sizeof(buf));
        dis_array("before write: ",  buf , sizeof(buf));
       
        //write
        w25_write( fd, &tempcmd , 1 );
        cmd[0] = W25_PAGE_PROGRAM;
        cmd[1] = 0;
        cmd[2] = 0;
        cmd[3] = 0;
        cmd[4] = 0x88;
        ret = w25_write( fd, cmd ,  5);
        printf("0x88 write ok \n");
               
        //read data
        cmd[0] = W25_READ_DATA;
        cmd[1] = 0;
        cmd[2] = 0;
        cmd[3] = 0;
        ret = w25_write_read(fd, cmd , 4 , buf , sizeof(buf));
        dis_array("after write: ",  buf , sizeof(buf));
       
        close(fd);

        return ret;
}

回复

使用道具 举报

56

积分

0

威望

0

贡献

技术小白

积分
56
发表于 2017-6-20 11:34:25        只看该作者  7#
你好 ,我要用spi写W25q64v这个flash芯片,我根据它的手册和网上的一些资料写了一些测试代码,但是一直读不到数据,打印的数据全部是默认的拉高值ff,你可以把你的demo给我发一份或者看看我代码哪里有问题吗
回复

使用道具 举报

582

积分

10

威望

8

贡献

技术大神

Rank: 3Rank: 3

积分
582
QQ
发表于 2017-6-21 17:18:54        只看该作者  8#
本帖最后由 54zw 于 2017-6-21 17:20 编辑
chenqian 发表于 2017-6-20 11:34
你好 ,我要用spi写W25q64v这个flash芯片,我根据它的手册和网上的一些资料写了一些测试代码,但是一直读不 ...

http://developer.t-firefly.com/thread-12059-1-1.html

所有代码都在github上 https://github.com/54shady/kerne ... ly_RK3399/debug/spi
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表