SPI子系统
一、SPI子系统模型

三个组成部分:
SPI核心:连通了SPI客户驱动、SPI主控制器驱动
SPI控制器驱动:驱动芯片中的SPI控制器
SPI的FLASH(客户驱动)
二、SPI控制器驱动分析
- static int __init s3c24xx_spi_probe(struct platform_device *pdev)
- {
- struct s3c2410_spi_info *pdata;
- struct s3c24xx_spi *hw;
- struct spi_master *master;
- struct resource *res;
- int err = 0;
- master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));
- if (master == NULL) {
- dev_err(&pdev->dev, "No memory for spi_master\n");
- err = -ENOMEM;
- goto err_nomem;
- }
- hw = spi_master_get_devdata(master);
- memset(hw, 0, sizeof(struct s3c24xx_spi));
- hw->master = spi_master_get(master);
- hw->pdata = pdata = pdev->dev.platform_data;
- hw->dev = &pdev->dev;
- if (pdata == NULL) {
- dev_err(&pdev->dev, "No platform data supplied\n");
- err = -ENOENT;
- goto err_no_pdata;
- }
- platform_set_drvdata(pdev, hw);
- init_completion(&hw->done);
- /* setup the master state. */
- master->num_chipselect = hw->pdata->num_cs;
- master->bus_num = pdata->bus_num;
- /* setup the state for the bitbang driver */
- hw->bitbang.master = hw->master;
- hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer;
- hw->bitbang.chipselect = s3c24xx_spi_chipsel;
- hw->bitbang.txrx_bufs = s3c24xx_spi_txrx;
- hw->bitbang.master->setup = s3c24xx_spi_setup;
- dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
- /* find and map our resources */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
- err = -ENOENT;
- goto err_no_iores;
- }
- hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1,
- pdev->name); //设置硬件资源
- if (hw->ioarea == NULL) {
- dev_err(&pdev->dev, "Cannot reserve region\n");
- err = -ENXIO;
- goto err_no_iores;
- }
- hw->regs = ioremap(res->start, (res->end - res->start)+1); //获取映射地址
- if (hw->regs == NULL) {
- dev_err(&pdev->dev, "Cannot map IO\n");
- err = -ENXIO;
- goto err_no_iomap;
- }
- hw->irq = platform_get_irq(pdev, 0); //获取中断号
- if (hw->irq < 0) {
- dev_err(&pdev->dev, "No IRQ specified\n");
- err = -ENOENT;
- goto err_no_irq;
- }
- err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw); //注册中断
- if (err) {
- dev_err(&pdev->dev, "Cannot claim IRQ\n");
- goto err_no_irq;
- }
- hw->clk = clk_get(&pdev->dev, "spi");
- if (IS_ERR(hw->clk)) {
- dev_err(&pdev->dev, "No clock for device\n");
- err = PTR_ERR(hw->clk);
- goto err_no_clk;
- }
- /* setup any gpio we can */
- if (!pdata->set_cs) {
- if (pdata->pin_cs < 0) {
- dev_err(&pdev->dev, "No chipselect pin\n");
- goto err_register;
- }
- err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev));
- if (err) {
- dev_err(&pdev->dev, "Failed to get gpio for cs\n");
- goto err_register;
- }
- hw->set_cs = s3c24xx_spi_gpiocs;
- gpio_direction_output(pdata->pin_cs, 1);
- } else
- hw->set_cs = pdata->set_cs;
- s3c24xx_spi_initialsetup(hw); //初始化部分
- /* register our spi controller */
- err = spi_bitbang_start(&hw->bitbang); //完成注册
- if (err) {
- dev_err(&pdev->dev, "Failed to register SPI master\n");
- goto err_register;
- }
- return 0;
- err_register:
- if (hw->set_cs == s3c24xx_spi_gpiocs)
- gpio_free(pdata->pin_cs);
- clk_disable(hw->clk);
- clk_put(hw->clk);
- err_no_clk:
- free_irq(hw->irq, hw);
- err_no_irq:
- iounmap(hw->regs);
- err_no_iomap:
- release_resource(hw->ioarea);
- kfree(hw->ioarea);
- err_no_iores:
- err_no_pdata:
- spi_master_put(hw->master);;
- err_nomem:
- return err;
- }
s3c24xx_spi_initialsetup:
- static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw)
- {
- /* for the moment, permanently enable the clock */
- clk_enable(hw->clk);
- /* program defaults into the registers */
- writeb(0xff, hw->regs + S3C2410_SPPRE);
- writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);
- writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); //设置成中断触发方式
- if (hw->pdata) {
- if (hw->set_cs == s3c24xx_spi_gpiocs)
- gpio_direction_output(hw->pdata->pin_cs, 1);
- if (hw->pdata->gpio_setup)
- hw->pdata->gpio_setup(hw->pdata, 1);
- }
- }
中断函数s3c24xx_spi_irq:
- static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
- {
- struct s3c24xx_spi *hw = dev;
- unsigned int spsta = readb(hw->regs + S3C2410_SPSTA);
- unsigned int count = hw->count;
- if (spsta & S3C2410_SPSTA_DCOL) {
- dev_dbg(hw->dev, "data-collision\n");
- complete(&hw->done);
- goto irq_done;
- }
- if (!(spsta & S3C2410_SPSTA_READY)) {
- dev_dbg(hw->dev, "spi not ready for tx?\n");
- complete(&hw->done);
- goto irq_done;
- }
- hw->count++;
- if (hw->rx)
- hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);
- count++;
- if (count < hw->len) //判断长度来收发?
- writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT);
- else
- complete(&hw->done);
- irq_done:
- return IRQ_HANDLED;
- }
SPI子系统的更多相关文章
- spi子系统之驱动SSD1306 OLED
spi子系统之驱动SSD1306 OLED 接触Linux之前,曾以为读源码可以更快的学习软件,于是前几个博客都是一边读源码一边添加注释,甚至精读到每一行代码,实际上效果并不理想,看过之后就忘记了.主 ...
- [国嵌攻略][159][SPI子系统]
SPI 子系统架构 1.SPI core核心:用于连接SPI客户驱动和SPI主控制器驱动,并且提供了对应的注册和注销的接口. 2.SPI controller driver主控制器驱动:用来驱动SPI ...
- SPI子系统分析之二:数据结构【转】
转自:http://www.cnblogs.com/jason-lu/articles/3164901.html 内核版本:3.9.5 spi_master struct spi_master用来描述 ...
- SPI子系统分析之四:驱动模块
内核版本:3.9.5 SPI控制器层(平台相关) 上一节讲了SPI核心层的注册和匹配函数,它是平台无关的.正是在核心层抽象了SPI控制器层的相同部分然后提供了统一的API给SPI设备层来使用.我们这一 ...
- SPI子系统分析之三:驱动模块
内核版本:3.9.5 SPI核心层(平台无关) SPI子系统初始化的第一步就是将SPI总线注册进内核,并且在/sys下创建一个spi_master的类,以后注册的从设备都将挂接在该总线下. 下列函数位 ...
- SPI子系统分析之二:数据结构
内核版本:3.9.5 spi_master struct spi_master用来描述一个SPI主控制器,我们一般不需要自己编写spi控制器驱动. /*结构体master代表一个SPI接口,或者叫一个 ...
- SPI子系统分析之一:框架
内核版本:3.9.5 SPI子系统概述: 一个SPI主控制器对应一条SPI总线,当然在系统中有唯一的总线编号. SPI总线上有两类设备: 其一是主控端,通常作为SOC系统的一个子模块出现,很多嵌入式M ...
- spi 子系统
http://blog.csdn.net/ropenyuan/article/details/42269641 http://blog.chinaunix.net/uid-27406766-id-33 ...
- Linux内核中SPI/I2c子系统剖析
Linux内核中,SPI和I2C两个子系统的软件架构是一致的,且Linux内核的驱动模型都以bus,driver,device三种抽象对象为基本元素构建起来.下文的分析将主要用这三种抽象对象的创建过程 ...
随机推荐
- JS中数据结构之链表
1.链表的基本介绍 数组不总是组织数据的最佳数据结构,在很多编程语言中,数组的长度是固定的,所以当数组已被数据填满时,再要加入新的元素就会非常困难.在数组中,添加和删除元素也很麻烦,因为需要将数组中的 ...
- 洛谷 P3806 (点分治)
题目:https://www.luogu.org/problem/P3806 题意:一棵树,下面有q个询问,问是否有距离为k的点对 思路:牵扯到树上路径的题都是一般都是点分治,我们可以算出所有的路径长 ...
- Nuget-Doc:NuGet 介绍
ylbtech-Nuget-Doc:NuGet 介绍 NuGet 是适用于 .NET 的包管理器. 它使开发人员能够创建.共享和使用有用的 .NET 库. NuGet 客户端工具可生成这些库并将其作为 ...
- 建站手册-浏览器信息:Mozilla 项目
ylbtech-建站手册-浏览器信息:Mozilla 项目 1.返回顶部 1. http://www.w3school.com.cn/browsers/browsers_mozilla.asp 2. ...
- jmeter添加自定义扩展函数之String---base64加密
1,打开eclipse,新建maven工程,在pom中引用jmeter核心jar包,具体请看---https://www.cnblogs.com/guanyf/p/10863033.html---,这 ...
- gradle 国内加速,修改镜像源
为什么慢 由于默认情况下执行 gradle 各种命令是去国外的 gradle 官方镜像源获取需要安装的具体软件信息,所以在不使用代理.不翻墙的情况下,从国内访问国外服务器的速度相对比较慢 如何修改镜像 ...
- C++内存修改器开源代码
我们玩单机游戏时,游戏难度可能过大, 或者游戏已经比较熟练,想要增加游戏的玩法,这时候可以使用修改器. 内存式游戏修改器主要对游戏内存修改 修改时有两种方式,一是定时对内存数值进行修改.实现类似锁定的 ...
- jQ无法设置checkbox变成选中状态
设置以后checkbox并没有变成选中状态,用chrome调试看了一下,checkbox中确实有checked属性,针对这个问题,大家可以参考下本文 代码如下: $("input" ...
- 使用matplotlib画出log的图像
以下内容是学习笔记,若有侵权,立即删除! import math import matplotlib.pyplot as plt import numpy as np if __name__ == ' ...
- web编程非常实用的在线工具大全---转载
代码对比/归并: http://www.matools.com/compare 正则表达式: http://www.matools.com/regex js/css压缩: http://www.mat ...