GPIO模拟SPI
CLK低有效(CPOL=1),第一个条边沿采集数据(CPHA=0)
#define GPIO_LCM_CLK (66|0x80000000)
#define GPIO_LCM_DATA (68|0x80000000) //MOSI
#define GPIO_LCM_DATA_IN (67|0x80000000) //MISO
#define GPIO_LCM_CS (65|0x80000000)
#define SPI_CS_H mt_set_gpio_mode(GPIO_LCM_CS,GPIO_MODE_00);\
mt_set_gpio_dir(GPIO_LCM_CS,GPIO_DIR_OUT);\
mt_set_gpio_out(GPIO_LCM_CS,GPIO_OUT_ONE)
#define SPI_CS_L mt_set_gpio_mode(GPIO_LCM_CS,GPIO_MODE_00);\
mt_set_gpio_dir(GPIO_LCM_CS,GPIO_DIR_OUT);\
mt_set_gpio_out(GPIO_LCM_CS,GPIO_OUT_ZERO)
#define SPI_CLK_H mt_set_gpio_mode(GPIO_LCM_CLK,GPIO_MODE_00);\
mt_set_gpio_dir(GPIO_LCM_CLK,GPIO_DIR_OUT);\
mt_set_gpio_out(GPIO_LCM_CLK,GPIO_OUT_ONE)
#define SPI_CLK_L mt_set_gpio_mode(GPIO_LCM_CLK,GPIO_MODE_00);\
mt_set_gpio_dir(GPIO_LCM_CLK,GPIO_DIR_OUT);\
mt_set_gpio_out(GPIO_LCM_CLK,GPIO_OUT_ZERO)
#define SPI_DO_H mt_set_gpio_mode(GPIO_LCM_DATA,GPIO_MODE_00);\
mt_set_gpio_dir(GPIO_LCM_DATA,GPIO_DIR_OUT);\
mt_set_gpio_out(GPIO_LCM_DATA,GPIO_OUT_ONE)
#define SPI_DO_L mt_set_gpio_mode(GPIO_LCM_DATA,GPIO_MODE_00);\
mt_set_gpio_dir(GPIO_LCM_DATA,GPIO_DIR_OUT);\
mt_set_gpio_out(GPIO_LCM_DATA,GPIO_OUT_ZERO)
#define SPI_DO_IN mt_set_gpio_mode(GPIO_LCM_DATA_IN,GPIO_MODE_00);\
mt_set_gpio_dir(GPIO_LCM_DATA_IN,GPIO_DIR_IN)
#define SPI_DO_OUT mt_set_gpio_mode(GPIO_LCM_DATA_IN,GPIO_MODE_00);\
mt_set_gpio_dir(GPIO_LCM_DATA_IN,GPIO_DIR_OUT)
void SPI_WriteComm(unsigned int i)
{
unsigned char n,m;
SPI_CS_L;
SPI_CLK_L;
SPI_DO_L; //第一位低代表发送的是地址 应该是内部协议
SPI_CLK_H;
m=i;
for(n=0; n<8; n++)
{
SPI_CLK_L;
if((m&0x80)!=0)
{
SPI_DO_H;
}
else
{
SPI_DO_L;
}
SPI_CLK_H;
m=m<<1;
}
SPI_CS_H;
}
void SPI_WriteData(unsigned int i)
{
unsigned char n,m;
SPI_CS_L;
SPI_CLK_L;
SPI_DO_H; //第一位高代表发送的是数据
SPI_CLK_H;
m=i;
for(n=0; n<8; n++)
{
SPI_CLK_L;
if((m&0x80)!=0)
{
SPI_DO_H;
}
else
{
SPI_DO_L;
}
SPI_CLK_H;
m=m<<1;
}
SPI_CS_H;
}
//上升沿写数据,下降沿读取数据
unsigned char SPI_ReadData(unsigned int cmd)
{
unsigned char n,m,y;
unsigned char value = 0;
SPI_CS_L;
// first send read command
SPI_CLK_L;
SPI_DO_L;
SPI_CLK_H;
m=cmd;
for(n=0; n<8; n++)
{
SPI_CLK_L;
if((m&0x80)!=0)
{
SPI_DO_H;
}
else
{
SPI_DO_L;
}
SPI_CLK_H;
m=m<<1;
}
// second get read data
SPI_DO_IN;
for(y=1; y<6; y++) {
for(n=0; n<8; n++)
{
value <<= 1;
SPI_CLK_H;
printk("[%d]0x%x \n", n, mt_get_gpio_in(GPIO_LCM_DATA_IN));
if (mt_get_gpio_in(GPIO_LCM_DATA_IN))
value |= 0x01;
else
value &= ~0x01;
SPI_CLK_L;
}
printk("[%d]value: 0x%x\n", y, value);
value = 0;
}
SPI_CS_H;
return value;
}
void init_spi_rgb_lcm(void)
{
unsigned char value = 0;
printk("[Jason] init_spi_rgb_lcm\n");
SPI_WriteComm(0x29);
SPI_WriteComm(0x11);
MDELAY(120);
SPI_WriteComm(0x36);
SPI_WriteData(0x00);
SPI_WriteComm(0x3A);
SPI_WriteData(0x70);
SPI_WriteComm(0xB0);
SPI_WriteData(0x00);
//SPI_WriteComm(0xB8);
//SPI_WriteData(0x00);
SPI_WriteComm(0xB8);
SPI_WriteData(0x01);
SPI_WriteComm(0xB9);
SPI_WriteData(0x01);
SPI_WriteData(0xFF);
SPI_WriteComm(0xB0);
SPI_WriteData(0x03);
value = SPI_ReadData(0xA1); //0xA1 returns information from the display
printk("addr: 0xA1, value:0x%x\n", value); //0x04, 0x84, 0x08, 0x00, 0xff
}