RK3568笔记五十一:W25Q64测试(spi 标准接口 )

news2024/9/22 13:44:39

若该文为原创文章,转载请注明原文出处。

前面有测试过W25Q64,但那是自己编写的驱动,现在使用内核自带的驱动,只需要通过SPI标准接口,编写应用程序即可以读写W25Q64.

一、硬件原理图

SPI

引脚

功能

MOSI

GPIO3_C1

主设备输出/从设备输入

MISO

GPIO3_C2

主设备输入/从设备输出

CLOCK

CPIO3_C3

时钟信号线

CS0

GPIO3_A1

片选信号线0

CS1

NC

片选信号线1

二、内核和设备树配置

1、内核支持

进入kenel目录,make menuconfig

具体路径如下所示:

> Device Drivers

 > SPI support

2、设备树配置

修改/home/alientek/rk3568_linux_sdk/kernel/arch/arm64/boot/dts/rockchip/目录下的rk3568-atk-evb1-ddr4-v10.dtsi文件,在文件末添加代码,在spi1设备树下添加w25q64节点。

修改完成以后,重新编译一下内核,并烧写boot.img文件

重启板子后,查询,可以看到spidev1.0,其中1是spi1,0是cs0

至此驱动已经完成,前面有测试过回环测试,在那基础上修改程序。

三、测试程序

w25q64App.c

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <linux/spi/spidev.h>
 
#define SPI_DEV_PATH "/dev/spidev1.0"
 

 
int fd = 0;                 					// SPI 控制引脚的设备文件描述符
static unsigned  mode = SPI_MODE_0;                  //用于保存 SPI 工作模式
static uint8_t  bits = 8;        			// 接收、发送数据位数
static uint32_t speed = 10000000;      	// 发送速度
static uint16_t delay = 0;          	    //保存延时时间

#define W25X_JedecDeviceID       0x9F 
#define Dummy_Byte               0xFF 

 
void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
{
  	int ret;

  	struct spi_ioc_transfer tr = {
      	.tx_buf = (unsigned long)tx,
      	.rx_buf = (unsigned long)rx,
      	.len = len,
      	.delay_usecs = delay,
      	.speed_hz = speed,
      	.bits_per_word = bits,
      	.tx_nbits = 1,
      	.rx_nbits = 1
  	};

  	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
  	if (ret < 1)
  	  	printf("can't send spi message\n");
}
 
void spi_init(int fd)
{
  	int ret = 0;

	// spi mode 设置SPI 工作模式
  	ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode);
  	if (ret == -1)
  	  	printf("can't set spi mode\n");

	//  bits per word  设置一个字节的位数
  	ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
  	if (ret == -1)
    	printf("can't set bits per word\n");

	//  max speed hz  设置SPI 最高工作频率
  	ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
  	if (ret == -1)
    	printf("can't set max speed hz\n");

	// 打印
   	printf("spi mode: 0x%x\n", mode);
    printf("bits per word: %d\n", bits);
    printf("max speed: %d Hz (%d KHz)\n", speed, speed / 1000);
}



unsigned long SPI_FLASH_ReadID()
{
  unsigned char tx_buffer[4] = {W25X_JedecDeviceID, Dummy_Byte, Dummy_Byte, Dummy_Byte};
  unsigned char rx_buffer[4];
  
  transfer(fd, tx_buffer, rx_buffer, sizeof(tx_buffer));

  return (rx_buffer[1] << 16) | (rx_buffer[2] << 8) | rx_buffer[3];
}
 
int main(int argc, char *argv[])
{
    unsigned long FlashID = 0x00000000; 
	
	if(argc < 2){
        printf("Wrong use !!!!\n");
        printf("Usage: %s [dev]\n",argv[0]);
        return -1;
    }
	
	/*打开 SPI 设备*/
    fd = open(argv[1], O_RDWR); // open file and enable read and  write
    if (fd < 0){
        printf("Can't open %s \n",argv[1]); // open i2c dev file fail
        exit(1);
    }
 
	/*初始化SPI */
	spi_init(fd);
 
	FlashID = SPI_FLASH_ReadID();
	printf("Flash ID: 0x%08x\n", FlashID);
 
	close(fd);
 
	return 0;
}

程序只是简单的读取ID,要注意数据不能分开传,原因未知,像STM32传4次读不到ID。

如果有人知道,麻烦告知,谢谢。

接下来简单了,编写测试。

编译

 /opt/atk-dlrk356x-toolchain/bin/aarch64-buildroot-linux-gnu-gcc w25q64App.c -o w25q64App

测试

测试前需要保证线是接好的,把生成的可执行文件上传到开发板。

测试正常读取到Flash的ID。

如有侵权,或需要完整代码,请及时联系博主。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1976982.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【java基础】徒手写Hello, World!程序

文章目录 前提&#xff1a;java环境变量配置使用vscode编写helloworld解析 前提&#xff1a;java环境变量配置 https://blog.csdn.net/xzzteach/article/details/140869188 使用vscode编写helloworld code .为什么用code看下图 报错了&#xff01;&#xff01;&#xff01;&…

【MATLAB】Matlab安装包及验证生成器

通过百度网盘分享的文件&#xff1a;Matlab 链接: https://pan.baidu.com/s/1PF8iP31WFJUYRF7PLyiX2A?pwdxkds 提取码&#xff1a;xkds

简单搭建dns服务器

目录 一.安装服务 二.编写子配置文件 三.编写主配置文件 四.编写文件 五.测试 一.安装服务 [rootnode1 ~]# dnf install bind -y 二.编写子配置文件 [rootnode1 ~]# vim /etc/named.rfc1912.zones 三.编写主配置文件 [rootnode1 ~]# vim /etc/named.conf 四.编写文件 …

一款创新的物联网综合业务支撑平台,提供资费、客户、进销存、合同、订单、续费、充值、账单等功能(附源码)

前言 在当今快速发展的物联网时代&#xff0c;企业和开发者面临着很大的挑战和机遇。现有软件在处理物联网设备和数据管理方面常常存在一些痛点&#xff0c;如设备管理分散、数据同步不及时、用户交互体验不佳等。这些问题不仅影响了物联网解决方案的效率&#xff0c;也限制了…

docker部署可执行的jar

1.将项目打包&#xff0c;上传到服务器的指定目录 2.在该目录下创建Dockerfile文件 3.Dockerfile写入如下指令 # 基于哪个镜像 FROM java:8 # 拷贝文件到容器&#xff0c;也可以直接写成ADD xxxxx.jar /app.jar ADD springboot-file-0.0.1.jar file.jar RUN bash -c touch /…

GuLi商城-商品服务-API-新增商品-调试会员等级相关接口

在网关服务中配置路由: 代码: nacos这些服务都要启动: 如果有不是一个命名空间中的,要改成同一个命名空间中 启动商品product服务遇到循环依赖问题,解决:

AVL树在插入时保持平衡的旋转过程

目录 AVL树节点的定义 AVL树的插入 AVL树的旋转 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。于是在这两位俄罗斯的数学家G.M.Adelson-Velskii 和E.M.…

《LeetCode热题100》---<6.①矩阵四道(二维数组)>

本篇博客讲解LeetCode热题100道矩阵篇中的四道题 第一道&#xff1a;矩阵置零&#xff08;中等&#xff09; 第二道&#xff1a;螺旋矩阵&#xff08;中等&#xff09; 第一道&#xff1a;矩阵置零&#xff08;中等&#xff09; 方法一&#xff1a;使用标记数组 class Solutio…

C语言指针(1)

目录 一、内存和地址 1、生活中的例子 2、内存的关系 二、指针变量和地址 1、&符号&#xff0c;%p占位符 2、一个简单的指针代码。 3、理解指针 4、解引用操作符 5、指针变量的大小。 三、指针变量类型的意义 1、指针解引用的作用 2、指针指针 3、指针-指针 4…

Leetcode3224. 使差值相等的最少数组改动次数

Every day a Leetcode 题目来源&#xff1a;3224. 使差值相等的最少数组改动次数 解法1&#xff1a; 想一想&#xff0c;什么情况下答案是 0&#xff1f;什么情况下答案是 1&#xff1f; 如果答案是 0&#xff0c;意味着所有 ∣nums[i]−nums[n−1−i]∣ 都等于同一个数 X。…

【JVM内存】系统性排查JVM内存问题的思路

【JVM内存】系统性排查JVM内存问题的思路 背景 前言 遇到过几次JVM堆外内存泄露的问题&#xff0c;每次问题的排查、修复都耗费了不少时间&#xff0c;问题持续几月、甚至一两年。我们将这些排查的思路梳理成一套系统的方法&#xff0c;希望能给对JVM内存分布、内存泄露问题…

有序矩阵中第K小的元素(LeetCode)

题目 给你一个 n x n 矩阵 matrix &#xff0c;其中每行和每列元素均按升序排序&#xff0c;找到矩阵中第 k 小的元素。 请注意&#xff0c;它是 排序后 的第 k 小元素&#xff0c;而不是第 k 个 不同 的元素。 你必须找到一个内存复杂度优于 的解决方案。 解题 from queue i…

DFS之搜索顺序与剪枝

搜索顺序&#xff1a; 1.https://www.acwing.com/problem/content/1119/ 首先&#xff0c;我们考虑一个贪心&#xff1a; 假如说A的倒数K个字符恰好与B的前K个字符重合&#xff0c;那么我们就连接。 也就是说我们一旦匹配就直接相连而不是继续找更长的重合的一段子串。 因…

秋招突击——算法练习——8/3——马上消费笔试总结——{距离为一的字符串、组合数遍历}

文章目录 引言正文第一题&#xff1a;距离为1的字符串个人实现修正实现 第二题&#xff1a;三角形数个人实现反思实现比较对象使用equalsCollections.sort方法 总结 引言 今天的笔试难度不算大&#xff0c;但是自己的做的很糟糕&#xff0c;发现了很多问题&#xff0c;很多模板…

目标检测,目标跟踪,目标追踪

个人专做目标检测&#xff0c;目标跟踪&#xff0c;目标追踪&#xff0c;deepsort。YOLOv5 yolov8 yolov7 yolov3运行指导、环境配置、数据集配置等&#xff08;也可解决代码bug&#xff09;&#xff0c;cpu&#xff0c;gpu&#xff0c;可直接运行&#xff0c;本地安装或者远程…

JVM-类加载器和双亲委派机制

什么是类加载器&#xff1f; 类加载器是Jvm的重要组成之一&#xff08;类加载器、运行时数据区、执行引擎、本地库接口、本地方法库&#xff09;&#xff0c;负责读取java字节码并将其加载到Jvm中的组件 类加载器的分类 Java中的类加载器可以分为以下几种&#xff1a; 1. 启…

Yolov8在RK3588上进行自定义目标检测(一)

1.数据集和训练模型 项目地址&#xff1a;https://github.com/airockchip/ultralytics_yolov8.git 从github(htps:l/github.com/airockchip/ultralytics_yolov8)上获取yolov8模型。 下载项目&#xff1a; git clone https://github.com/airockchip/ultralytics_yolov8.git …

进程的虚拟内存地址(C++程序的内存分区)

严谨的说法&#xff1a; 一个C、C程序实际就是一个进程&#xff0c;那么C的内存分区&#xff0c;实际上就是一个进程的内存分区&#xff0c;这样的话就可以分为两个大模块&#xff0c;从上往下&#xff0c;也就是0地址一直往下&#xff0c;假如是x86的32位Linux系统&#xff0c…

InstantID节点安装遇到的问题与解决办法

原来在一台没有显卡支持的电脑上安装InstantID节点使用没有问题&#xff0c;将安装好的ComfyUI&#xff08;简称ComfyUI_CPU_OK包&#xff09;复制到一台有显卡支持的电脑上&#xff0c;竟然发现InstantID节点异常不能使用&#xff08;按道理应该能正常运行才对&#xff09;&am…

吴恩达机器学习L1W3L06-逻辑回归的梯度下降

目标 在本实验室&#xff0c;你可以看到 更新逻辑回归的梯度下降。在一个熟悉的数据集上探索梯度下降 import copy, math import numpy as np %matplotlib widget import matplotlib.pyplot as plt from lab_utils_common import dlc, plot_data, plt_tumor_data, sigmoid,…