GPIO 模拟SPI 通讯接口的驱动 一,某些时候我们会不得不使用GPIO 来模拟SPI,I2C 等通讯接口,如本例中,需要使用SPI 接口发送9 位的数据,如果使用linux 内核提供的SPI 子系统来做这个驱动是无法实现9 位传输数据的。 二,用GPIO 模拟SPI 总的来说是比较简单,把相应的管脚配置成 GPIO 功能,再按需要配置管脚的输入输出方向,然后根据SPI 总线的时序设定 IO 口的电平。 三,驱动代码如下,以备今后作参考: (linux-2.6.28 + TCC8900, 这个驱动是用来控制 LCD 的初始化的(型号为 LW350AC9001)) #include
#include #include #include #include #include #include #include #include #define PDEBUG #ifdef PDEBUG #define PLOG(fmt,args...) printk(fmt,##args) #else #define PLOG(fmt,args...) /*do nothing*/ #endif #define SPI_CMD 0 #define SPI_DATA 1 #define FUN_GPIO 0 #define PIN_SDO 15 //GPIOF[15] #define PIN_SDI 14 #define PIN_SCLK 16 #define PIN_CS 29 //GPIOC[29] #define GPC_BASE 0xF0102080 #define GPF_BASE 0xF0102140 #define OFFSET_DAT 0x0 #define OFFSET_EN 0x4 #define OFFSET_FUN0 0x24 #define OFFSET_FUN1 0x28 #define OFFSET_FUN2 0x2c #define OFFSET_FUN3 0x30 // select pin used for gpio static int tcc_set_pin_fun(int pin, int fun) { if(pin<8) tcc_writel(((tcc_readl(GPF_BASE+OFFSET_FUN0) & ~ (0x0f<<(4*pin))) | (fun<<(4 * pin))), GPF_BASE+OFFSET_FUN0); else if(pin<16) tcc_writel(((tcc_readl(GPF_BASE+OFFSET_FUN1) & ~ (0x0f<<(4*(pin-8)))) | (fun<<(4 * (pin-8)))), GPF_BASE+OFFSET_FUN1); else if(pin<24) tcc_writel(((tcc_readl(GPF_BASE+OFFSET_FUN2) & ~ (0x0f<<(4*(pin-16)))) | (fun<<(4 * (pin-16)))), GPF_BASE+OFFSET_FUN2); else if(pin<32) tcc_writel(((tcc_readl(GPF_BASE+OFFSET_FUN3) & ~ (0x0f<<(4*(pin-24)))) | (fun<<(4 * (pin-24)))), GPF_BASE+OFFSET_FUN3); return 0; } static int tcc_set_cs_fun(void) { tcc_writel(((tcc_re...