RT Thread SPI设备 使用
之前,我把SPI的片选在Cubemx中配置成了SPI_NSS。
现在我给它改为了GPIO_OUTPUT. 同时参考了别人的类似的一个操作无线模块(采用SPI设备驱动)的例子程序(清楚了RTT的系统API的调用流程)。
年初第一天上班,有空回过头来看这个问题,就成功解决了。
------Sx1278.h-----------------------------------------------------------------------------------------------------
#ifndef __SX1278_H__
#define __SX1278_H__
#include "drv_gpio.h"
struct spi_sx1278_device
{
struct rt_device sx1278_device;
struct rt_spi_device * rt_spi_device;
struct rt_mutex lock;
void * user_data;
};
typedef struct spi_sx1278_device * rt_spi_sx1278_device_t;
// 引脚定义
#define Sx1278_IRQ_PIN GET_PIN(C, 8)
#define Sx1278_nCS_PIN GET_PIN(B, 12)
#define Sx1278_RST_PIN GET_PIN(C, 9)
// 引脚状态
#define ST_SX1278_IRQ() rt_pin_read(Sx1278_IRQ_PIN)
// 引脚输出
#define SX1278_SPI_NCS_H() rt_pin_write(Sx1278_nCS_PIN, PIN_HIGH);
#define SX1278_SPI_NCS_L() rt_pin_write(Sx1278_nCS_PIN, PIN_LOW);
#define SX1278_SPI_RST_H() rt_pin_write(Sx1278_RST_PIN, PIN_HIGH);
#define SX1278_SPI_RST_L() rt_pin_write(Sx1278_RST_PIN, PIN_LOW);
typedef rt_uint8_t u8;
typedef rt_uint16_t u16;
typedef rt_uint32_t u32;
void test(void);
#endif
------Sx1278.c-----------------------------------------------------------------------------------------------------
#include "board.h"
#include "drv_spi.h"
#include "Sx1278.h"
#define SPI_BUS_NAME "spi2"
#define SPI_SX1278_DEVICE_NAME "spi20"
void hdr_callback(void *args)// 回调函数
{
char *a = args; // 获取参数
rt_kprintf("KEY_PIN down! %s\n",a);
}
//struct stm32_hw_spi_cs
//{
// rt_uint32_t pin;
//}; 不自己定义了,新的STM32 BSP 的drv_spi.h 有如下定义
// drv_spi.h 内定义:
//struct stm32_hw_spi_cs
//{
// GPIO_TypeDef* GPIOx;
// uint16_t GPIO_Pin;
//};
static struct stm32_hw_spi_cs spi_cs; /* SPI设备CS片选引脚 */
static struct spi_sx1278_device spi_sx1278_device;
#define CS_PIN 28 // Sx1278_nCS_PIN
static u8 SX1278_spiReadWriteByte(const u8 Sdata)
{
u8 Rdata[13] = {0};
// rt_pin_write(CS_PIN, PIN_LOW); /* 先 低电平 */
// rt_spi_send_then_recv第一个形参:struct rt_spi_device *device;
rt_spi_send_then_recv( spi_sx1278_device.rt_spi_device, &Sdata, (rt_size_t)1, Rdata, (rt_size_t)1);
// rt_spi_send(spi_sx1278_device.rt_spi_device, &Sdata, 1);
return Rdata[0];
}
int rt_hw_spi2_config(const char * spi_device_name) // 这里填的就是"spi20"为参数。这里应该直接直接命名参数为const char * device name
{ // spi_device_name是spi总线设备的意思, 对应的是"spi2"总线。
rt_err_t res;
struct rt_spi_device * rt_spi_device;
rt_pin_mode(CS_PIN, PIN_MODE_OUTPUT);
// 这个不用根据SPI设备名字 来 查找 设备
//res = rt_spi_bus_attach_device(spi_sx1278_device.rt_spi_device, SPI_SX1278_DEVICE_NAME, SPI_BUS_NAME, (void*)&spi_cs);
spi_cs.GPIOx = GPIOB;
spi_cs.GPIO_Pin = GPIO_PIN_12;
// 这个要根据SPI设备名字 来 查找 设备 功能1: 把spi20挂到spi2上
res = rt_hw_spi_device_attach(SPI_BUS_NAME, SPI_SX1278_DEVICE_NAME, spi_cs.GPIOx, spi_cs.GPIO_Pin);
if( res == RT_EOK )
{
rt_kprintf("\n rt_hw_spi_device_attach(), OK! \r\n");
}
rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
spi_sx1278_device.rt_spi_device = rt_spi_device;
if(spi_sx1278_device.rt_spi_device == RT_NULL)
rt_kprintf("\n Wrong ! \r\n");
/* config spi */
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
cfg.max_hz = 1 * 1000 *1000; /* 20M,SPI max 42MHz,ssd1351 4-wire spi */
res = rt_spi_configure(spi_sx1278_device.rt_spi_device, &cfg);
if( res == RT_EOK )
{
rt_kprintf("\n rt_spi_configure(), OK! \r\n");
}
}
return RT_EOK;
}
rt_err_t rt_hw_SX1278_config(const char * sx1278_device_name, const char * spi_device_name)
{
rt_hw_spi2_config(sx1278_device_name);
return RT_EOK;
}
static int rt_hw_SX1278_init(void)
{
// rt_hw_SX1278_config( "spi2", "spi20"); 参数填写错误
rt_hw_SX1278_config( "spi20", "spi2"); // 参数填写正确
// SX1278 部分
// IO 方向
rt_pin_mode(Sx1278_IRQ_PIN, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(Sx1278_RST_PIN, PIN_MODE_OUTPUT);
// SX1278中断
rt_pin_attach_irq(Sx1278_IRQ_PIN, PIN_IRQ_MODE_FALLING, hdr_callback, (void*)"CallBack args"); // 绑定中断,下降沿模式,回调函数
rt_pin_irq_enable(Sx1278_IRQ_PIN, PIN_IRQ_DISABLE); // PIN_IRQ_DISABLE、PIN_IRQ_ENABLE
// IO初值设置
rt_pin_write(Sx1278_nCS_PIN, PIN_HIGH);
rt_pin_write(Sx1278_RST_PIN, PIN_HIGH);
return 0;
}
INIT_PREV_EXPORT(rt_hw_SX1278_init); /* 使用RT-Thread的组件自动初始化机制 */
u8 WirelessInit(u8 channel, u8 pa)
{
u8 result=0;
// SX1278_DisableInt();
// SX1278_SetLoRaPA(pa);
// SX1278_Init(channel); // 初始化
//
// sG_RfState = ST_RF_RECE; // 接收状态
//
// SX1278_EnableInt();
return result;
}
void Delay_1ms(u8 x)
{
//rt_thread_mdelay(x);
rt_thread_delay(x);
}
void SX1278_Reset(void)
{
static int sPowerUpFlag=1;
SX1278_SPI_RST_H();
Delay_1ms(2);
SX1278_SPI_RST_L(); // 至少100us
Delay_1ms(2);
SX1278_SPI_RST_H(); // 至少5ms
if(sPowerUpFlag)
{
sPowerUpFlag = 0;
Delay_1ms(12); // 第一次上电,延时时间长一点
}
else
{
Delay_1ms(7);
}
}
static u8 SX1278Read(u8 adr)
{
u8 tmp;
SX1278_SPI_NCS_L();
SX1278_spiReadWriteByte(adr); // Send address first
tmp = SX1278_spiReadWriteByte(0xFF);
SX1278_SPI_NCS_H();
return tmp;
}
void test(void)
{
u8 TempReg;
u8 timeOutCnt=0;
SX1278_Reset(); rt_thread_mdelay(500);
while(1)
{
TempReg = SX1278Read(0x06);
//rt_kprintf("Hard SPI TempReg = %d \r\n", TempReg);
rt_thread_delay(50);
}
}
RT Thread SPI设备 使用的更多相关文章
- RT Thread的SPI设备驱动框架的使用以及内部机制分析
注释:这是19年初的博客,写得很一般,理解不到位也不全面.19年末得空时又重新看了RTThread的SPI和GPIO,这次理解得比较深刻.有时间时再整理上传. -------------------- ...
- RT Thread 通过ENV来配置SFUD,操作SPI Flash
本实验基于正点原子stm32f4探索者板子 请移步我的RT Thread论坛帖子. https://www.rt-thread.org/qa/forum.php?mod=viewthread& ...
- imx6 生成 spi设备节点
开发板需要使用spi接口,但是spi接口被touch占用,使用event进行操作.所以需要更改配置,生成spi设备节点. 参考链接 https://community.nxp.com/thread/3 ...
- linux spi 设备节点 读写
本文记录spi设备节点的操作方法. SPI总线设备文件名通常为/dev/spidevN.P(N=0.1.2--,P=0.1.2--), 其中N表示第几路SPI总线,而P表示在该路SPI总线中使用哪个C ...
- Linux kernel 有关 spi 设备树参数解析
一.最近做了一个 spi 设备驱动从板级设备驱动升级到设备树设备驱动,这其中要了解 spi 设备树代码的解析. 二. 设备树配置如下: 503 &spi0 { 504 status = &qu ...
- RT-thread 设备驱动组件之SPI设备
本文主要介绍RT-thread中的SPI设备驱动,涉及到的文件主要有:驱动框架文件(spi_dev.c,spi_core.c,spi.h),底层硬件驱动文件(spi_hard.c,spi_hard.h ...
- SPI设备的驱动
主要包括两个SPI设备步骤:register_chrdevspi_register_driver关键点1:spi_board_info可以去已经运行的板子下面找例子:/sys/bus/spi/driv ...
- RTT学习之SPI设备
SPI分为主.从.设备:具体又分标准SPI/DUAL SPI/QUAD SPI(用80字节的RAMrt_err_t rt_spi_take_bus(struct rt_spi_device *devi ...
- RT thread 设备驱动组件之USART设备
本文以stm32f4xx平台介绍串口驱动,主要目的是:1.RTT中如何编写中断处理程序:2.如何编写RTT设备驱动接口代码:3.了解串行设备的常见处理机制.所涉及的主要源码文件有:驱动框架文件(usa ...
随机推荐
- php实现无限极分类(多维数组 / 二维数组)形式
<?php // 测试数组数据$array = array( array('id'=>'1','title'=>'父级分类1','pid'=>'0'), array('id'= ...
- 【pytest】(三) pytest运行多个文件
1.运行多个测试文件 pytest 会运行 test_ 开头 或者 _test 结尾的文件,在当前目录和子目录中 2. 一个类下的多个用例的运行, pytest会找到 test_ 开头的方法 impo ...
- steam 数据转换
目录 数组和集合互转 数组转集合 方法一 遍历 方法二 asList 方法三 steam 集合转数组 方法一 循环 方法二 toArray 方法三 steam 小结 string转为Character ...
- CMOS设计手册—基础篇
模拟CMOS 衬底噪声:由于相邻的电阻互相注入电流而产生的衬底噪声.解决方法:在两个电阻之间加入一个P+注入区(作为P衬底晶圆的衬底接触).P+注入区保护电路免受载流子的影响,由于注入区是一个环形,所 ...
- 使用vuepress搭建GitHub pages静态博客页面
vuepress官网 vuepress是尤大开发来写文档的静态页面.可以用Markdown 语法,并且也可以使用vue模块化的方式开发页面. vuepress-theme-reco 是另外的开发者开发 ...
- DVWA_sql injection(low)
这里主要记录下做题时的思路以及步骤,不查看源码也不对源码进行分析.(我这个dvwa是一个在线靶场,所以我也不确定是否与本地靶场有些许出入) 1.Low 将难度调为Low级别后,来到如下界面 首先输入一 ...
- shell小技巧(6)修改一批文件后缀
当前目录下后缀为sh的文件,改为后缀shell. 这里列出两种方法,先看第一种.方法1:#!/bin/bash str=`find ./ -name \*.sh` # 会产生一个列表 file=&q ...
- 163net邮箱,对商务办公人士有哪些帮助?
在职场当中,无论是沟通交流,还是文档对接,电子邮箱都是是必不可少的办公助手,163net付费邮箱作为很多人的首选工作邮箱,相较于免费邮箱而言,究竟有哪些优势呢? 1. 专属网络空间,有容 ...
- jmeter中接口测试出现乱码或不识别中文解决办法
在查看结果是中出现乱码时:jmeter的bin目录下的jmeter.properties下最下面添加sampleresult.default.encoding=UTF-8后重新打开工具就好了 在接口的 ...
- access数据库一般注入方法及偏移注入
1.access数据库与mysql数据库的差别 access没有数据库,access数据库每个数据都是单个文件,每个access只有表结构 mysql : 库名,表名,列名,字段内容 access:表 ...