首先看几种不同下lcd序列的代码,一般都是上升沿发送数据,下降沿读数据。
一、发送数据之前有个d/c bit 0标志着写,1标志着读
写法一:
void lcd_send_cmd(unsigned char cmd)
{
unsigned char shift, i;
gpio_set(spi_cs, 0);
udelay(1);
//send D/C bit
gpio_set(spi_sclk, 0);
gpio_set(spi_sdo, 0);
udelay(1);
gpio_set(spi_sclk, 1);
udelay(1);
//end of send D/C
//send byte start from high bit
shift = 0x80;
for (i = 0; i < 8; i++)
{
gpio_set(spi_sclk, 0); //set SCL Low
if (cmd & shift)
{
gpio_set(spi_sdo, 1);
}
else
{
gpio_set(spi_sdo, 0);
}
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
shift = shift >> 1;
}
//send byte end
gpio_set(spi_cs, 1);
gpio_set(spi_sclk, 1);
gpio_set(spi_sdo, 1);
}
void lcd_send_param(unsigned char index)
{
unsigned char shift, i;
gpio_set(spi_cs, 0);
udelay(1);
//send D/C bit
gpio_set(spi_sclk, 0);
gpio_set(spi_sdo, 1);
udelay(1);
gpio_set(spi_sclk, 1);
udelay(1);
//end of send D/C
//send byte start
shift = 0x80;
for (i = 0; i < 8; i++)
{
gpio_set(spi_sclk, 0); //set SCL Low
if (index & shift)
{
gpio_set(spi_sdo, 1);
}
else
{
gpio_set(spi_sdo, 0);
}
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
shift = shift >> 1;
}
//send byte end
gpio_set(spi_cs, 1);
gpio_set(spi_sclk, 1);
gpio_set(spi_sdo, 1);
}
写法二:
static spi_write_byte(char dc, unsigned char data)
{
int bit;
int bnum;
gpio_set(GPIO_SPI_CLK, 0); /* clk low */
/* dc: 0 for command, 1 for parameter */
gpio_set(GPIO_SPI_MOSI, dc);
udelay(1); /* at least 20 ns */
gpio_set(GPIO_SPI_CLK, 1); /* clk high */
udelay(1); /* at least 20 ns */
bnum = 8; /* 8 data bits */
bit = 0x80;
while(bnum) {
gpio_set(GPIO_SPI_CLK, 0); /* clk low */
if (data & bit)
gpio_set(GPIO_SPI_MOSI, 1);
else
gpio_set(GPIO_SPI_MOSI, 0);
udelay(1);
gpio_set(GPIO_SPI_CLK, 1); /* clk high */
udelay(1);
bit >>= 1;
bnum--;
}
}
static int spi_write(char cmd, char *data, int num)
{
int i;
gpio_set(GPIO_SPI_CS0_N, 0); /* cs low */
/* command byte first */
truly_spi_write_byte(0, cmd);
/* followed by parameter bytes */
for(i = 0; i < num; i++)
{
if(data)
truly_spi_write_byte(1, data[i]);
}
gpio_set(GPIO_SPI_MOSI, 1); /* mosi high */
gpio_set(GPIO_SPI_CS0_N, 1); /* cs high */
udelay(10);
return 0;
}
二:下寄存器地址和序列之前,需要初始化sdo
void SIO_gpio_writereg(unsigned char cmd)
{
unsigned char shift, i;
gpio_set(spi_cs, 0);
udelay(1);
//'0'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 0);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'1'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 1);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'1'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 1);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'1'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 1);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'0'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 0);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'ID'= '0'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 0);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'RS'= '0'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 0);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'RW'= '0'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 0);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//send byte start
shift = 0x80;
for (i = 0; i < 8; i++)
{
gpio_set(spi_sclk, 0); //set SCL Low
if (cmd & shift)
{
gpio_set(spi_sdo, 1);
}
else
{
gpio_set(spi_sdo, 0);
}
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
shift = shift >> 1;
}
//send byte end
gpio_set(spi_cs, 1);
gpio_set(spi_sclk, 1);
gpio_set(spi_sdo, 1);
}
void SIO_gpio_writedat(unsigned char cmd)
{
unsigned char shift, i;
gpio_set(spi_cs, 0);
udelay(1);
//'0'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 0);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'1'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 1);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'1'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 1);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'1'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 1);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'0'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 0);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'ID'= '0'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 0);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'RS'= '1'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 1);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//'RW'= '0'
gpio_set(spi_sclk, 0); //set SCL Low
gpio_set(spi_sdo, 0);
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
//send byte start
shift = 0x80;
for (i = 0; i < 8; i++)
{
gpio_set(spi_sclk, 0); //set SCL Low
if (cmd & shift)
{
gpio_set(spi_sdo, 1);
}
else
{
gpio_set(spi_sdo, 0);
}
udelay(1);
gpio_set(spi_sclk, 1); //set SCL High
udelay(1);
shift = shift >> 1;
}
//send byte end
gpio_set(spi_cs, 1);
gpio_set(spi_sclk, 1);
gpio_set(spi_sdo, 1);
}
当然不同的lcd对时序要求不一样。
看看读寄存器的某种写法
static void spi_write_byte(boolean dc, u8 data)
{
uint32 bit;
int bnum;
gpio_set_value(spi_sclk, 0);
gpio_set_value(spi_mosi, dc ? 1 : 0);
udelay(1); /* at least 20 ns */
gpio_set_value(spi_sclk, 1); /* clk high */
udelay(1); /* at least 20 ns */
bnum = 8; /* 8 data bits */
bit = 0x80;
while (bnum--) {
gpio_set_value(spi_sclk, 0); /* clk low */
gpio_set_value(spi_mosi, (data & bit) ? 1 : 0);
udelay(1);
gpio_set_value(spi_sclk, 1); /* clk high */
udelay(1);
bit >>= 1;
}
gpio_set_value(spi_mosi, 0);
}
static void samsung_spi_read_bytes(u8 cmd, u8 *data, int num)
{
int bnum;
/* Chip Select - low */
gpio_set_value(spi_cs, 0);
udelay(2);
/* command byte first */
samsung_spi_write_byte(0, cmd);
udelay(2);
gpio_direction_input(spi_mosi);
if (num > 1) {
/* extra dummy clock */
gpio_set_value(spi_sclk, 0);
udelay(1);
gpio_set_value(spi_sclk, 1);
udelay(1);
}
/* followed by data bytes */
bnum = num * 8; /* number of bits */
*data = 0;
while (bnum) {
gpio_set_value(spi_sclk, 0); /* clk low */
udelay(1);
*data <<= 1;
*data |= gpio_get_value(spi_mosi) ? 1 : 0;
gpio_set_value(spi_sclk, 1); /* clk high */
udelay(1);
--bnum;
if ((bnum % 8) == 0)
++data;
}
gpio_direction_output(spi_mosi, 0);
/* Chip Select - high */
udelay(2);
gpio_set_value(spi_cs, 1);
}
static const char *byte_to_binary(const u8 *buf, int len)
{
static char b[32*8+1];
char *p = b;
int i, z;
for (i = 0; i < len; ++i) {
u8 val = *buf++;
for (z = 1 << 7; z > 0; z >>= 1)
*p++ = (val & z) ? '1' : '0';
}
*p = 0;
return b;
}
msleep(120);
/* 0x0A: Read Display Power Mode */
samsung_spi_read_bytes(0x0A, &data, 1);
pr_info("%s: power=[%s]\n", __func__,
byte_to_binary(&data, 1));
msleep(120);