S3C6410 SPI全双工读写流程分析(原创)

发布者:RadiantDusk最新更新时间:2024-11-08 来源: cnblogs关键字:S3C6410  SPI 手机看文章 扫描二维码
随时随地手机看文章

一、SPI控制器datasheet


1详细请参考:http://blog.csdn.net/hustyangju/article/details/20474659


2 SPI的所有寄存器都是映射到内核空间的,采用基地址+偏移地址的方式访问


static volatile void  __iomem *spiregs;                            //global variable for mapping spiregister


spiregs = (volatile)ioremap(0x7F00B000,0x30);  //just request for the spi0


3 下文可能用到的偏移地址


#define S3C_CH_CFG                (0x00)     //SPI configuration  

#define S3C_CLK_CFG               (0x04)      //Clock configuration  

#define S3C_MODE_CFG                   (0x08)     //SPI FIFO control  

#define S3C_SLAVE_SEL            (0x0C)      //Slave selection  

#define S3C_SPI_INT_EN                   (0x10)      //SPI interrupt enable  

#define S3C_SPI_STATUS          (0x14)      //SPI status  

#define S3C_SPI_TX_DATA                (0x18)      //SPI TX data  

#define S3C_SPI_RX_DATA                (0x1C)      //SPI RX data  

#define S3C_PACKET_CNT                (0x20)      //count how many data master gets  

#define S3C_PENDING_CLR             (0x24)      //Pending clear  

#define S3C_SWAP_CFG           (0x28)      //SWAPconfig register  

#define S3C_FB_CLK                  (0x28)     //SWAP FB config register  

   

   

#define SPI_CH_SW_RST                   (1<<5)  

#define SPI_CH_MASTER                  (0<<4)  

#define SPI_CH_SLAVE              (1<<4)  

#define SPI_CH_RISING            (0<<3)  

#define SPI_CH_FALLING                   (1<<3)  

#define SPI_CH_FORMAT_A             (0<<2)  

#define SPI_CH_FORMAT_B             (1<<2)  

#define SPI_CH_RXCH_OFF              (0<<1)  

#define SPI_CH_RXCH_ON               (1<<1)  

#define SPI_CH_TXCH_OFF               (0<<0)  

#define SPI_CH_TXCH_ON                (1<<0)  

   

#define SPI_CLKSEL_PCLK                 (0<<9)  

#define SPI_CLKSEL_USBCLK   (1<<9)  

#define SPI_CLKSEL_ECLK                 (2<<9)  

#define SPI_ENCLK_DISABLE  (0<<8)  

#define SPI_ENCLK_ENABLE   (1<<8)  

   

#define SPI_MODE_CH_TSZ_BYTE (0<<29)  

#define SPI_MODE_CH_TSZ_HALFWORD       (1<<29)  

#define SPI_MODE_CH_TSZ_WORD       (2<<29)  

#define SPI_MODE_BUS_TSZ_BYTE        (0<<17)  

#define SPI_MODE_BUS_TSZ_HALFWORD     (1<<17)  

#define SPI_MODE_BUS_TSZ_WORD     (2<<17)  

#define SPI_MODE_RXDMA_OFF    (0<<2)  

#define SPI_MODE_RXDMA_ON     (1<<2)  

#define SPI_MODE_TXDMA_OFF    (0<<1)  

#define SPI_MODE_TXDMA_ON     (1<<1)  

#define SPI_MODE_SINGLE              (0<<0)  

#define SPI_MODE_4BURST             (1<<0)  

   

#define SPI_SLAVE_MAN                   (0<<1)  

#define SPI_SLAVE_AUTO                  (1<<1)  

#define SPI_SLAVE_SIG_ACT   (0<<0)  

#define SPI_SLAVE_SIG_INACT        (1<<0)  

   

#define SPI_INT_TRAILING_DIS      (0<<6)  

#define SPI_INT_TRAILING_EN       (1<<6)  

#define SPI_INT_RX_OVERRUN_DIS       (0<<5)  

#define SPI_INT_RX_OVERRUN_EN        (1<<5)  

#define SPI_INT_RX_UNDERRUN_DIS    (0<<4)  

#define SPI_INT_RX_UNDERRUN_EN     (1<<4)  

#define SPI_INT_TX_OVERRUN_DIS        (0<<3)  

#define SPI_INT_TX_OVERRUN_EN         (1<<3)  

#define SPI_INT_TX_UNDERRUN_DIS    (0<<2)  

#define SPI_INT_TX_UNDERRUN_EN     (1<<2)  

#define SPI_INT_RX_FIFORDY_DIS (0<<1)  

#define SPI_INT_RX_FIFORDY_EN  (1<<1)  

#define SPI_INT_TX_FIFORDY_DIS (0<<0)  

#define SPI_INT_TX_FIFORDY_EN  (1<<0)  

   

#define SPI_STUS_TX_DONE   (1<<21)  

#define SPI_STUS_TRAILCNT_ZERO        (1<<20)  

#define SPI_STUS_RX_OVERRUN_ERR   (1<<5)  

#define SPI_STUS_RX_UNDERRUN_ERR         (1<<4)  

#define SPI_STUS_TX_OVERRUN_ERR    (1<<3)  

#define SPI_STUS_TX_UNDERRUN_ERR          (1<<2)  

#define SPI_STUS_RX_FIFORDY       (1<<1)  

#define SPI_STUS_TX_FIFORDY       (1<<0)  

   

#define SPI_PACKET_CNT_DIS         (0<<16)  

#define SPI_PACKET_CNT_EN (1<<16)  


二、重点参数及初始化步骤



1 双通道SPI管脚配置




2 传输模型配置


/*     Set transfer type (CPOL & CPHA set)    */


         spi_chcfg= SPI_CH_RISING | SPI_CH_FORMAT_A;


         spi_chcfg|= SPI_CH_MASTER;


         writel(spi_chcfg , spiregs + S3C_CH_CFG);


详细请参考:http://blog.csdn.net/hustyangju/article/details/20474659


3 时钟配置



使用PCLK,外部时钟66M,100分屏:


 


/*     Set clock configuration register    


        *       SPIclockout = clock source / (2 * (prescaler +1))    


         *       PCLK=66Mhz, SPI clockout = clock source /(2 * (prescaler +1))      */


         spi_clkcfg= SPI_ENCLK_ENABLE;


         spi_clkcfg|= SPI_CLKSEL_PCLK;


         writel(spi_clkcfg , spiregs + S3C_CLK_CFG);


         spi_clkcfg= readl( spiregs + S3C_CLK_CFG);


 


         spi_clkcfg|= 49;       // the least spi speed =660Khz


         writel(spi_clkcfg , spiregs + S3C_CLK_CFG);


4 SPI 模块设置



/*     Set SPI MODE configuration register    */


         spi_modecfg= SPI_MODE_CH_TSZ_BYTE| SPI_MODE_BUS_TSZ_BYTE;


         spi_modecfg|= SPI_MODE_TXDMA_OFF| SPI_MODE_SINGLE| SPI_MODE_RXDMA_OFF;


         spi_modecfg&= ~( 0x3f << 5);


         spi_modecfg|= ( 0x1 << 5);    // Tx FIFOtrigger level in INT mode


         spi_modecfg&= ~( 0x3f << 11);


         spi_modecfg|= ( 0x1 << 11);           // Rx FIFOtrigger level in INT mode


         spi_modecfg&= ~( 0x3ff << 19);     


         spi_modecfg|= ( 0x1 << 19);   // Counting ofTailing Bytes


 


         writel(spi_modecfg,spiregs + S3C_MODE_CFG);


 


设置在fifo和bus中的数据宽度为byte,关闭DMA访问fifo,并设置fifo中保存最大字节数为1,设置接收和发送fifo的触发值为1byte。


5 中断配置



/*     SetSPI INT_EN register   */


         writel(spi_inten,spiregs + S3C_SPI_INT_EN); //u32 spi_inten =0x00


         writel(0x1f,spiregs + S3C_PENDING_CLR);


6 设置最大接收数据包数量


SPI can control the number of packets to bereceived in master mode. If there is any number of packets to bereceived, justset the SFR (Packet_Count_reg). SPI stops generating SPICLK when the number ofpackets is thesame as what you set. It is mandatory to follow software orhardware reset before this function is reloaded.(Software reset can clear allregisters except special function registers, but hardware reset clears allregisters.)


这里使能并设置为最大值。


/*     Set Packet Count configuration register        */


         spi_packet= SPI_PACKET_CNT_EN;


         spi_packet|= 0xffff;


writel(spi_packet,spiregs + S3C_PACKET_CNT);



7 打开spi接收和发送通道


/*     SetTx or Rx Channel on   */


         spi_chcfg= readl(spiregs + S3C_CH_CFG);


         spi_chcfg|= SPI_CH_TXCH_OFF | SPI_CH_RXCH_OFF;

[1] [2]
关键字:S3C6410  SPI 引用地址:S3C6410 SPI全双工读写流程分析(原创)

上一篇:makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解
下一篇:手把手教你写Linux设备驱动---中断(三)--workqueue实现(基于友善之臂4412开发板)

小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved