当前位置: 首页 > news >正文

linux下gpio模拟spi三线时序

目录

    • 前言
    • 一、配置内容
    • 二、驱动代码实现
    • 三、总结

前言

本笔记总结linux下使用gpio模拟spi时序的方法,基于arm64架构的一个SOC,linux内核版本为linux5.10.xxx,以驱动三线spi(时钟线sclk,片选cs,sdata数据读和写使用同一个数据线进行分时复用做半双工)的hmc704x为例;

一、配置内容

设备树配置

1.在芯片的引脚模式寄存器中配置 cs ,sclk , mosi ,miso为 gpio模式;
2.在spi控制器下添加pinctrl-x = 引脚引用,对引脚的模式进行生效

3.在spi控制器的节点下添加spi从设备节点,并定义cs,sclk,mosi,miso的gpio属性:
spics = <引用>;
spiclk = <引用>;
spimiso = <引用>;
spimosi = <引用>;

二、驱动代码实现

1、gpio请求

int spics_gpio = 0;
int spiclk_gpio = 0;
int spimiso_gpio = 0;
int spimosi_gpio = 0;
void  xxx_probe(xxxx)
{spics_gpio = of_get_named_gpio(spi->dev.of_node,"spics",0);if(spics_gpio<0){printk("faild to request gpio!\n");}gpio_request(spics_gpio,NULL);gpio_direction_output(spics_gpio,0);spiclk_gpio = of_get_named_gpio(spi->dev.of_node,"spiclk",0);if(spics_gpio<0){printk("faild to request gpio!\n");}printk("get GPIO%d\n",spiclk_gpio);gpio_request(spiclk_gpio,NULL);gpio_direction_output(spiclk_gpio,0);spimiso_gpio = of_get_named_gpio(spi->dev.of_node,"spimiso",0);
if(spimiso_gpio<0){printk("faild to request gpio!\n");
}
gpio_request(spimiso_gpio,NULL);gpio_direction_output(spimiso_gpio,0);spimosi_gpio = of_get_named_gpio(spi->dev.of_node,"spimosi",0);if(spimosi_gpio<0){printk("faild to request gpio!\n");}
gpio_request(spimosi_gpio,NULL);gpio_direction_output(spimosi_gpio,0);
}

2、读写函数实现
读写时序

在这里插入图片描述

读函数

#define HMC7044_WRITE		(0 << 15)
#define HMC7044_READ		(1 << 15)
#define HMC7044_CNT(x)		(((x) - 1) << 13)
#define HMC7044_ADDR(x)		((x) & 0xFFF)static int xxx_read(unsigned int reg,unsigned int *val)
{u16 cmd,i;u32 data,datatemp;uint8_t tempvalue = 0;cmd = HMC7044_READ | HMC7044_CNT(1) | HMC7044_ADDR(reg);data = cmd; gpio_direction_output(spimosi_gpio,0);gpio_set_value(spics_gpio,1);gpio_set_value(spiclk_gpio,0);gpio_set_value(spimosi_gpio,0);udelay(5);gpio_set_value(spics_gpio,0);for(i=0;i<16;i++){gpio_set_value(spiclk_gpio,0);datatemp = ((data>>(15-i)) & 0x1);if(datatemp>0) gpio_set_value(spimosi_gpio,1);else gpio_set_value(spimosi_gpio,0);udelay(5);gpio_set_value(spiclk_gpio,1);udelay(5);}gpio_direction_input(spimosi_gpio);for(i=0;i<8;i++){gpio_set_value(spiclk_gpio,0);udelay(5);tempvalue<<=1;gpio_set_value(spiclk_gpio,1);if(gpio_get_value(spimosi_gpio)){tempvalue++;}udelay(5);}gpio_set_value(spics_gpio,1);*val = tempvalue;return 0;
}

写函数

static int xxx_write(unsigned int reg,unsigned int val)
{ u16 cmd,i;u32 data,datatemp;cmd = HMC7044_WRITE | HMC7044_CNT(1) | HMC7044_ADDR(reg);data = (cmd << 8) | (val & 0xFF);gpio_direction_output(spimosi_gpio,0);gpio_set_value(spics_gpio,1); gpio_set_value(spiclk_gpio,0);gpio_set_value(spimosi_gpio,0);udelay(5);gpio_set_value(spics_gpio,0);for(i=0;i<24;i++){gpio_set_value(spiclk_gpio,0);datatemp = ((data>>(23-i)) & 0x1);if(datatemp>0) gpio_set_value(spimosi_gpio,1); else gpio_set_value(spimosi_gpio,0);udelay(5);gpio_set_value(spiclk_gpio,1);udelay(5);}gpio_set_value(spics_gpio,1);return 0;
}

三、总结

具体的芯片读写协议不一样,按具体spi时序协议做相应修改即可;


http://www.mrgr.cn/news/58330.html

相关文章:

  • 若依微服务15 - RuoYi-Vue3 实现前端独立运行
  • C#探索之路基础夯实篇(6):C#在Unity中的自定义特性
  • C++基础1
  • yarn的安装与使用以及与npm的区别(安装过程中可能会遇到的问题)
  • MySQL的group_concat函数:将分组中的多个值连接成一个字符串的聚合函数
  • 计算生物学与生物信息学漫谈-1-测序一路走来
  • opencv - py_imgproc - py_geometric_transformations 几何变换
  • 设计师的新宠:7款不容错过的界面设计软件
  • Telegram机器人的手机部署
  • 股市动向背后有哪些因素?我们该如何应对?
  • 网络服务请求流程简单理解
  • uniapp renderjs页面传值
  • springboot大学校园报修管理平台-计算机毕业设计源码90736
  • 华为开放式耳机测评,南卡 、华为、Cleer开放式耳机超深度横评
  • FreeSWITCH JSON API
  • 国产linux系统(银河麒麟,统信uos)使用 PageOffice 在线打开Word文件最简单集成代码
  • 美国颁布史上最严数据安全规定:企业该如何应对网络安全挑战?
  • 企业通过FSC认证后如何保持合规
  • 从安全事故谈信息透明化的重要性
  • 入侵检测算法平台部署LiteAIServer视频智能分析平台行人入侵检测算法
  • 海外盲盒系统搭建:海外市场带来的全新机遇
  • Axure PR 9 多级下拉清除选择器 设计交互
  • Linux中的文件的常用命令
  • 运维工程师的职业发展路径:从零基础到精通,收藏这篇就够了
  • 【机器学习】多项式回归
  • GC.2022.六年级.05.数三角形