GPIO和SPI之间有什么关系? [英] What's the relationship between GPIO and SPI?

查看:1194
本文介绍了GPIO和SPI之间有什么关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现内核中的GPIO驱动程序离开/sys/class/gpio来控制gpio,但是我发现GPIO也可以由/dev/mem控制,我发现此映射可以在spi-bcm2708中完成(该调用称为作为平台驱动程序),但是我不了解spi和GPIO之间的关系,它们如何在linux中一起工作?

I found GPIO driver in the kernel leave /sys/class/gpio to control gpio, but I found GPIO can be controlled by /dev/mem as well, I found this mapping may be done in the spi-bcm2708 (which call the __ioremap as a platform driver), but I don't understand the relationship between spi and GPIO,how they work together in the linux?

推荐答案

据我了解,您在谈论驱动程序(例如,在Raspberry Pi中使用).首先,请查看 BCM2835数据表.查看下一部分:

As I understand you are talking about this driver (which is used, for example, in Raspberry Pi). First of all, take a look at BCM2835 datasheet. Review next sections:

  • 1.1概述
  • 6.0通用I/O(GPIO)
  • 6.2替代功能分配(请参阅表6-31)

来自驱动程序代码(请参见 bcm2708_init_pinmode()函数)和数据表(表6-31),我们可以看到SPI引脚实际上是GPIO7..11引脚.这些引脚实际上可以连接到不同的硬件模块(在这种情况下为SPI或SD)

From driver code (see bcm2708_init_pinmode() function) and datasheet (table 6-31), we can see that SPI pins are actually GPIO7..11 pins. Those pins can be actually connected to different hardware modules (either SPI or SD, in this case).

使用 pin muxing 完成选择.因此,基本上,您需要将GPIO7..GPIO11引脚连接到SPI模块.为此,您需要为每个GPIO7..GPIO11引脚选择 ALT0 功能.可以通过将相应的值写入 GPFSEL0 GPFSEL1 寄存器(请参见数据表中的表6-1..6-3)来完成:

Such a selection is done using pin muxing. So basically you need to connect GPIO7..GPIO11 pins to SPI module. To do so you need to select ALT0 function for each of GPIO7..GPIO11 pins. This can be done by writing corresponding values to GPFSEL0 and GPFSEL1 registers (see tables 6-1..6-3 in datasheet):

这是驾驶员实际执行此操作的方式:

And this is how the driver is actually doing this:

/*
 * This function sets the ALT mode on the SPI pins so that we can use them with
 * the SPI hardware.
 *
 * FIXME: This is a hack. Use pinmux / pinctrl.
 */
static void bcm2708_init_pinmode(void)
{
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define SET_GPIO_ALT(g, a) *(gpio+(((g)/10))) |= (((a) <= 3 ? (a)+4 : (a) == 4 ? 3 : 2)<<(((g)%10)*3))

    int pin;
    u32 *gpio = ioremap(GPIO_BASE, SZ_16K);

    /* SPI is on GPIO 7..11 */
    for (pin = 7; pin <= 11; pin++) {
        INP_GPIO(pin);      /* set mode to GPIO input first */
        SET_GPIO_ALT(pin, 0);   /* set mode to ALT 0 */
    }

    iounmap(gpio);

#undef INP_GPIO
#undef SET_GPIO_ALT
}

对我来说似乎是个快速技巧,实际上他们提到了它:正确的方法是使用称为 pinctrl .

which looks like quick hack to me, and they actually mentioned it: the correct way would be to use kernel mechanism called pinctrl.

结论:BCM2708驱动程序实际上并不触发任何GPIO引脚,它只是在进行引脚复用以便将GPIO7..GPIO11引脚连接到SPI模块.为此,该驱动程序将写入GPFSELn寄存器,该寄存器恰好是GPIO寄存器.此驱动程序中的SPI和GPIO之间的关系几乎全部.

Conclusion: BCM2708 driver doesn't actually trigger any GPIO pins, it's just doing pin muxing in order to connect GPIO7..GPIO11 pins to SPI module. And to do so this driver writes to GPFSELn registers, which happen to be GPIO registers. This is pretty much all relationship between SPI and GPIO in this driver.

PS :如果您对SPI和GPIO之间的可能关系感到好奇,请阅读 spi-bitbang.c 驱动程序, Linux内核.

P.S.: if you are curious about possible relationship between SPI and GPIO, read about bit banging. See for example spi-bitbang.c driver in Linux kernel.

这篇关于GPIO和SPI之间有什么关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆