Chinaunix首页 | 论坛 | 博客
  • 博客访问: 192917
  • 博文数量: 60
  • 博客积分: 652
  • 博客等级: 上士
  • 技术积分: 460
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-15 14:26
文章分类
文章存档

2015年(4)

2014年(16)

2013年(16)

2011年(20)

2010年(4)

分类: 嵌入式

2010-05-29 17:57:30

 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;  
}
阅读(7245) | 评论(0) | 转发(0) |
0

上一篇:nand bad block check

下一篇:octeon twsi i2c

给主人留下些什么吧!~~