1.Linux主机驱动和外设驱动分离思想(I2C驱动里有)
SPI驱动总线架构:SPI核心层(x),SPI控制器驱动层(x),SPI设备驱动层(√)。前面两个设备驱动搞明白了可以去看
2.教程中介绍:SPI函数接口(API):
简单介绍SPI协议,硬件原理(4412datasheet)
3.教程中介绍:SPI函数接口(API):
简单介绍SPI协议,硬件原理(4412datasheet)
SDI(数据输入),SDO(数据输出),SCLK(时钟),CS(片选)
SPI(rfid模块)的硬件基础知识(增加reset)
SPI CLK管脚复用:Android4.0(wifi不能用)
rfid的驱动配置:
Device Drivers
→SPI support
→SPI_RC522
can的驱动配置:
Networking support
→CAN bus subsystem support
→CAN Device Drivers
Platform CAN drivers with Netlink support(默认配置,不用动)
CAN_MCP251X
设备注册:spi_board_info,spi_register_board_info
驱动注册函数和结构体:spi_register_driver/spi_unregister_driver,spi_driver
读写函数和结构体:spi_transfer和spi_message结构体,spi_async
1.驱动“设备注册,驱动注册,probe,数据下传,数据上传”的小结
虚拟平台:
①因为LED,蜂鸣器等等,因为这些驱动本身不是总线。所以都注册在虚拟平台总线上(platform_device)。
②然后platfrom_driver_register就是在驱动程序中使用了,注册时的platfrom_driver结构体中有name成员对应platform_device的名字。此结构当然还有probe,remove,suspend,resume等配套的功能接口。
③然后对LED来说,GPIO的操作基本是在probe中初始化。
④然后应用层如果需要调用,那么在probe里就需要注册杂项设备、字符设备等。
I2C:
①I2C的设备注册和平台注册类似,都是在arc/arm/mach-exynos/mach-itop4412.c中完成的
②和平台设备类似,I2C使用的函数不一样罢了,而且结构体也是i2c_driver了
③I2C对硬件的传输,使用i2c_transfer结合i2c_msg
④然后应用层如果需要调用,那么需要注册杂项设备,和虚拟平台类似。
SPI:
基本和I2C类似不同的是操作硬件的函数,spi_transfer要配置一下,然后传输用spi_sync。SPI让应用层调用使用字符设备。
2.设备-SPI设备注册一级设备注册之后的查询方法
配置SPI的内核之后可以用,查询到
[root@iTOP-4412]# cat sys/bus/spi/devices/spi2.0/modalias
rc522
SPI_board_info参数
spi_board_info参数
.modalias = "rc522", //初始化设备的名称
.platform_data = NULL,
.max_speed_hz = 10*1000*1000, //初始化传输速率
.bus_num = 2, //控制器编号
.chip_select = 0, //控制器片选的编号
.mode = SPI_MODE_0, //spi的模式
.controller_data = &spi2_csi[0], //片选IO的信息
spi2_board_info设备描述结构体,设备注册函数spi_register_board_info
增加一个spi设备my_rc522,然后去掉rfid和can驱动
mach-itop4412.c
/* add by cym 20141222 for RC522 RFID */
#ifdef CONFIG_SPI_RC522
{
.modalias = "rc522",
.platform_data = NULL,
.max_speed_hz = 10*1000*1000,
.bus_num = 2,
.chip_select = 0,
.mode = SPI_MODE_0,
.controller_data = &spi2_csi[0],
}
#endif
/* end add */
/* add by ct 2018825 */
{
.modalias = "my_rc522",
.platform_data = NULL,
.max_speed_hz = 10*1000*1000,
.bus_num = 2,
.chip_select = 0,
.mode = SPI_MODE_0,
.controller_data = &spi2_csi[0],
}
/* end add */
cat sys/bus/spi/devices/spi2.0/modalias
rfid的设备名称my_rc522
3.驱动-spi驱动注册和卸载。I2C设备初始化完成-进入probe函数。(不能加载wifi驱动)
my_rc522.c
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int __devinit my_rc522_probe(struct spi_device *spi) { /* reset */ printk(KERN_EMERG "my_rc522_probe!n"); return 0; } static int __devexit my_rc522_remove(struct spi_device *spi) { printk(KERN_EMERG "my_rc522_remove!n"); return 0; } static struct spi_driver my_rc522_spi_driver = { .driver = { .name = "my_rc522", .owner = THIS_MODULE, }, .probe = my_rc522_probe, .remove = __devexit_p(my_rc522_remove), }; static int __init my_rc522_init(void) { spi_register_driver(&my_rc522_spi_driver); return 0; } static void __exit my_rc522_exit(void) { spi_unregister_driver(&my_rc522_spi_driver); } module_init(my_rc522_init); module_exit(my_rc522_exit); MODULE_AUTHOR("topeet: ct"); MODULE_LICENSE("GPL"); 4.驱动-spi数据的传输(rfid模块,不能加载wifi驱动) 1.本节实验需要RFID的硬件模块 2.1平台文件中RC522的设备名称直接改为my_rc522 2.2需要配置rfid对应的menuconfig 2.3 drivers/spi/Makefile中注释掉rc522.c文件的编译 3.从rc522驱动中提取spi传输的核心代码 4.直接在probe中做复位,读,写测试 写:rc522_write→rc522_sync_write→rc522_sync→spi_async 读:rc522_read→rc522_sync_read→rc522_sync→spi_async my_rc522 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "spidev_test.h" #include "spidev.h" struct spi_device *my_spi; #define RC522_RESET_PIN EXYNOS4_GPK1(0) void my_rc522_reset() { //printk("************************ %sn", __FUNCTION__); if(gpio_request_one(RC522_RESET_PIN, GPIOF_OUT_INIT_HIGH, "RC522_RESET")) pr_err("failed to request GPK1_0 for RC522 reset controln"); s3c_gpio_setpull(RC522_RESET_PIN, S3C_GPIO_PULL_UP); gpio_set_value(RC522_RESET_PIN, 0); mdelay(5); gpio_set_value(RC522_RESET_PIN, 1); gpio_free(RC522_RESET_PIN); } static int write_test(unsigned char *buffer, int len) { int status; struct spi_transfer t = { .tx_buf = buffer, .len = len, }; struct spi_message m; spi_message_init(&m); spi_message_add_tail(&t, &m); DECLARE_COMPLETION_ONSTACK(done); m.complete = complete; m.context = &done; printk("spi_async send begin!n"); status = spi_async(my_spi,&m); if(status == 0){ wait_for_completion(&done); status = m.status; if (status == 0) status = m.actual_length; } return status; } static int read_test(unsigned char *buffer, int len) { int status; struct spi_transfer t = { .rx_buf = buffer, .len = len, }; struct spi_message m; spi_message_init(&m); spi_message_add_tail(&t, &m); DECLARE_COMPLETION_ONSTACK(done); m.complete = complete; m.context = &done; printk("spi_async read begin!n"); status = spi_async(my_spi,&m); if(status == 0){ wait_for_completion(&done); status = m.status; if (status == 0) status = m.actual_length; } return status; } static unsigned char ReadRawRC(int addr) { int ret; unsigned char ReData; unsigned char Address; Address = (unsigned char)addr << 1; Address |= (1 << 7); Address &= ~(1 << 0); ret = write_test(&Address, 1); if (ret < 0) printk("spi:SPI Write errorn"); udelay(100); ret = read_test(&ReData, 1); if (ret < 0) printk("spi:SPI Read errorn"); return ReData; } static int WriteRawRC(int addr, int data) { int ret; unsigned char TxBuf[2]; //bit7:MSB=0,bit6~1:addr,bit0:RFU=0 TxBuf[0] = ((unsigned char)addr << 1)&0x7E; //TxBuf[0] &= 0x7E; TxBuf[1] = (unsigned char)data; ret = write_test(TxBuf, 2); if (ret < 0) printk("spi:SPI Write errorn"); udelay(10); return ret; } static int rc522_init() { int ret; char version = 0; //reset WriteRawRC(CommandReg, PCD_RESETPHASE); udelay(10); WriteRawRC(ModeReg, 0x3D); WriteRawRC(TReloadRegL, 30); WriteRawRC(TReloadRegH, 0); WriteRawRC(TModeReg, 0x8D);
上一篇:4412 Linux定时器
下一篇:4412 i2c驱动
推荐阅读最新更新时间:2024-11-10 12:52
推荐帖子
- 13、Beaglebone外围电路设计第四周:关于AM335x 的浮点型使用的心得体会!!
- 设计来到了第四周,这一周,我用StellarisGraphicsLibrary设计了数据采集的LCD界面,这个会在下一个帖子里和大家分享!我这次要讲的是关于AM335x的浮点型使用的心得体会,我的设计里面要加入显示倾角的表盘,这个我在M4的活动里做过这个界面https://bbs.eeworld.com.cn/viewthread.php?tid=330039,所以我以为会很容易实现的!!可是调程序就是这样,你永远不会知道自己会碰到什么!!这次我就碰到了!!首先,我是在程序里面
- anananjjj DSP 与 ARM 处理器
- 脉冲功率装置能源计算机控制技术
- 脉冲功率装置能源计算机控制技术摘要介绍一种多分布传式MARX发生器能源计算机监控系统.详细叙述了系统的硬件构成,计算机与各能源系统之间的通讯原理和通讯协议,以及系统的软件实现,同时简要说明了系统抗干扰解决办法。关键词MARX发生器程控电源RS485总线VisualBasic脉冲功率装置能源计算机控制技术
- mdreamj 工控电子
- 大家谈谈都用什么板子啊?(被坑的分数要回来了,散分!)
- 我想了解一下大家现在都在用什么开发板啊,将来准备用什么开发板呢?能总是谈技术,总要看看未来吧,想做个统计,看看啥是当前主流,将来的趋向是什么。另外,也欢迎大家谈谈对CE前景的看法大家谈谈都用什么板子啊?(被坑的分数要回来了,散分!)最初用了下三星SMDK2450的开发板了解了一下,然后直接拿的产品demo板做东西。以后有机会的话找块6410的板子玩玩。2440我还是去年买的优龙的2440具体要看做什么用了!!!引用4楼ankye的回复:具体要看做什么用了!!!
- yuexiaomei 嵌入式系统
- 国外老师用microbit教逻辑门
- 国外一个老师使用microbit教学生学习逻辑门电路。Iwantedahandsonwaytoteachlogicgatesandtruthtablestomystudents,soIdecidedtoprogramasetofmicrobitstoactlikelogicgates.Theselogicgatescouldthenbeconnectedtoswitchesandoutputsusing
- dcexpert MicroPython开源版块
- 拆解一个WSN的节点设备,看看如何选料?
- 物联网的兴起带旺了很多新兴的技术和产品,无线传感网络(WirelessSensorNetwork,简称WSN)就是其中之一。对于WSN最简单的理解就是,将传统的传感器技术和网络通讯融合在一起,让物联网节点同时具备感知和通信能力,使无处不在的传感器不再是各自为战的数据孤岛,而是构成一个可靠、高效、智能的数据生产和传输体系,因此WSN也被认为是物联网的核心支撑技术之一。不过WSN这个概念说起来简单,但在实际设计过程中并不是将已有功能电路和模块简单地拼凑在一起,还是会遇到很多新的挑战。
- ohahaha RF/无线
- 从零开始仿制工业PLC
- 从零开始仿制工业PLC不错的想法,不过PLC没有必要用这么高级的芯片。zhaojun_xf发表于2015-8-2212:23不错的想法,不过PLC没有必要用这么高级的芯片。 打算后期增加新功能,当然,量产时看实际情况了。这个主意不错的这个好我要支持点个赞,加油!“我要参与”,本人对工业控制和PLC比较熟悉,多年从事工业控制,设计过多款工业控制板。谢谢大家支持做PLC,顺便自带工业屏!我要支持我要支持@boming建议最好简单介绍一下你自己的项
- boming stm32/stm8
设计资源 培训 开发板 精华推荐
- 混频模块
- 使用 STMicroelectronics 的 R5970AD 的参考设计
- LT3091MPDE 具有 LDO 输入至输出控制的高效低噪声单电感正负转换器的典型应用
- LTC2164、16 位、105Msps 低功耗 ADC 的典型应用
- STM32F405RGT6最小系统板
- IC卡NFC合集(会更新)
- LT3506 双路单片式 1.6A 降压型开关稳压器的典型应用电路
- 课设作业
- DC1241B-BA,用于 LTM9001-BA LVDS 输出的演示板,16 位,160Msps,DC-300MHz LPF,8dB 增益
- LTC3100EUD 演示板、1.5MHz 同步双通道 DC/DC 转换器和 100mA LDO