GPIO模拟SPI驱动的关键点:每次传送8bit的时候都要先拉低时钟,本次传送结束后拉高时钟
下面是source code分析:
#define APB_BASEADDR 0x10000000
#define GPIO_BASEADDR APB_BASEADDR + 0x070000
#define ROBO_SPI_BASEADDR(id) (GPIO_BASEADDR + (id)*0x2000)
#define ROBO_GPIO_0 0 //SDO
#define ROBO_GPIO_1 1 //SDI
#define ROBO_GPIO_2 2 //SCK
#define ROBO_GPIO_3 3 //CS
#define ROBO_SPI_SDO ROBO_SPI_BASEADDR(id) + 0X00 //输出
#define ROBO_SPI_SDO_CTRL ROBO_SPI_BASEADDR(id) + 0X04
#define ROBO_SPI_SDI ROBO_SPI_BASEADDR(id) + 0X10 //输入
#define ROBO_SPI_CS ROBO_SPI_BASEADDR(id) + 0X00
void robo_spi_write(u8 out_data)
{
int i, rd_val, wr_val;
//*(volatile u32 *)ROBO_SPI_CS &= ~(1<
for (i = 7; i >= 0; i--) {
rd_val = *(volatile u32 *)ROBO_SPI_SDO;
rd_val &= ~(1 << ROBO_GPIO_2); /* lower clock */
wr_val = (((out_data >> i) & 1) << ROBO_GPIO_0);
wr_val |= (rd_val & ~(1 << ROBO_GPIO_0));
*(volatile u32 *)ROBO_SPI_SDO = wr_val;
udelay (1000);
wr_val |= (1 << ROBO_GPIO_2); /* high clock */
*(volatile u32 *)ROBO_SPI_SDO = wr_val;
udelay (1000);
}
//*(volatile u32 *)ROBO_SPI_CS |= 1<
}
u8 robo_spi_read()
{
int i, rd_val;
u8 ret_val = 0;
//*(volatile u32 *)ROBO_SPI_CS &= ~(1<
/* Configure GPIO as input for data */
rd_val = ((*(volatile u32 *)ROBO_SPI_SDI) & ~(1 << ROBO_GPIO_1));
*(volatile u32 *)ROBO_SPI_SDI = rd_val;
/* Configure GPIO as output for clock */
rd_val = ((*(volatile u32 *)ROBO_SPI_SDO) | (1 << ROBO_GPIO_2));
*(volatile u32 *)ROBO_SPI_SDI = rd_val;
for (i = 7; i >= 0; i--) {
rd_val = *(volatile u32 *)ROBO_SPI_SDO;
rd_val &= ~(1 << ROBO_GPIO_2); /* lower clock */
*(volatile u32 *)ROBO_SPI_SDO = rd_val;
udelay (1000);
rd_val = *(volatile u32 *)ROBO_SPI_SDO;
rd_val |= (1 << ROBO_GPIO_2); /* high clock */
*(volatile u32 *)ROBO_SPI_SDO = rd_val;
udelay (1000);
rd_val = *(volatile u32 *)ROBO_SPI_SDI;
ret_val |= ((rd_val & (1 << ROBO_GPIO_1)) >> ROBO_GPIO_1) << i;
}
rd_val = *(volatile u32 *)ROBO_SPI_SDO;
rd_val &= ~(1 << ROBO_GPIO_2); /* lower clock */
*(volatile u32 *)ROBO_SPI_SDO = rd_val;
//*(volatile u32 *)ROBO_SPI_CS |= 1<
return ret_val;
}
u8 robo_spi_read_write(u8 out_data)
{
int i, rd_val,wr_val;
u8 ret_val = 0;
//*(volatile u32 *)ROBO_SPI_CS &= ~(1<
/* Configure GPIO as input for data */
rd_val = ((*(volatile u32 *)ROBO_SPI_SDI) & ~(1 << ROBO_GPIO_1));
*(volatile u32 *)ROBO_SPI_SDI = rd_val;
/* Configure GPIO as output for clock */
rd_val = ((*(volatile u32 *)ROBO_SPI_SDI) | (1 << ROBO_GPIO_2));
*(volatile u32 *)ROBO_SPI_SDI = rd_val;
for (i = 7; i >= 0; i--) {
rd_val = *(volatile u32 *)ROBO_SPI_SDO;
rd_val &= ~(1 << ROBO_GPIO_2); /* lower clock */
wr_val = (((out_data >> i) & 1) << ROBO_GPIO_0);
wr_val |= (rd_val & ~(1 << ROBO_GPIO_0));
*(volatile u32 *)ROBO_SPI_SDO = wr_val;
udelay (1000);
rd_val = *(volatile u32 *)ROBO_SPI_SDO;
rd_val |= (1 << ROBO_GPIO_2); /* high clock */
*(volatile u32 *)ROBO_SPI_SDO = rd_val;
udelay (1000);
rd_val = *(volatile u32 *)ROBO_SPI_SDI;
ret_val |= ((rd_val & (1 << ROBO_GPIO_1)) >> ROBO_GPIO_1) << i;
}
rd_val = *(volatile u32 *)ROBO_SPI_SDO;
rd_val &= ~(1 << ROBO_GPIO_2); /* lower clock */
*(volatile u32 *)ROBO_SPI_SDO = rd_val;
//*(volatile u32 *)ROBO_SPI_CS |= 1<
return ret_val;
}
阅读(7235) | 评论(0) | 转发(0) |