S3C2410 SPI在win ce下的编程(2)

S3C2410 SPI的使用(1)  中不知道怎么回事儿,POWERPOINT的东西发上来就变了形了,搞不懂,不过还是得发啊,不能半途而废啊。

 

2 SPI 状态寄存器( SPSTA
 
Register
Address
R/W
Description
Reset Value
SPSTA0
0x59000004
R
SPI0 状态寄存器
0x01
SPSTA1
0x59000024
R
SPI1 状态寄存器
0x01
 
字段名
   
初值
reserved
7:3
     

 

Data Collision Error Flag (DCOL)
2
  数据写碰撞 ( 正在发送时写 SPTDAT)
  错误标志。 0 :无错; 1 :碰撞错误
0
Multi Master Error Flag (MULF)
1
  多主 SPI 错误标志。
 0 :无错; 1 :多主 SPI 错误。
0
Transfer Ready
Flag (REDY)
0
  收发就绪 标志
 0 :未就绪; 1 :收或发就绪。
  SPTDAT 后该位自动清 0
1

 

 

3 SPI 引脚控制寄存器( SPPIN
 
Register
Address
R/W
Description
Reset Value
SPPIN0
0x59000008
R/W
SPI0 引脚控制寄存器
0x02
SPPIN1
0x59000028
R/W
SPI1 引脚控制寄存器
0x02
 
字段名
   
初值
reserved
7:3
     

 

Multi Master error detect Enable (ENMUL)
2
  引脚多主 SPI 错误测试设置。
 0 :禁测; 1 :允许多主错误测试。
  测试结果在 SPSTAn 中的 MULF
0
reserved
1
  该位应该为 1
1
Master Out Keep
(KEEP)
0
  1 字节发完后 MOSI 的控制与释放
 0 :释放; 1 :保持 MOSI 原电平
0

剩下的寄存器也就没有什么了,大家自己看看吧

接着来点文字:

应用方法

一般操作步骤
  如果SPI控制寄存器SPCON已经设置过,则写数据发送寄存器SPTDAT启动发送。对SPI卡操作步骤如下:
  (1)设置预分频寄存器SPPRE;
  (2)设置控制寄存器SPCON;
  (3)设置一个GPIO引脚,使选中的MMC或SD卡的片选信号nSS有效;
  (4)向数据发送寄存器SPTDAT写10次0xFF,对MMC或SD卡初始化;
  (5)发送数据:先要查询Tx/Rx REDY是否为1,然后向数据发送寄存器SPTDAT写数据;
   (6)接收数据:
  一般方式(同时收发,TAGD=0):向数据发送寄存器SPTDAT写0xFF,查询并确认Rx REDY为1,然后从数据接收寄存器中读取数据。
  仅接收方式(TAGD=1):并确认Rx REDY为1,然后从数据接收寄存器中读取数据。读取数据的同时启动一次发送。
  (7)设置GPIO引脚,使选中的MMC或SD卡的片选信号nSS无效,结束传输。

 

基本上看了这些,再看一下E文,对于2410的SPI就应该没问题了

下面是我的代码,是在WIN CE5。0下用的

2410 SPI初使化代码(WIN CE驱动下)



// ======================================================================
//  Name      : InitSPI
// ======================================================================
void  InitSPI( void )              // 初使化SPI
{
        unsigned 
int  pclk  =  S2410PCLK;   //  s2410.h define
                                                    
//  #define S2410FCLK           (203 * 1000 * 1000)         //  203MHz (FCLK).
                                                   
//  #define PCLKDIV             4                         //  P-clock (PCLK) divisor.
                                                      
//  #define S2410PCLK           (S2410FCLK / PCLKDIV)     //  PCLK.

         RETAILMSG (
0 , (TEXT( " ::: InitSPI " ) ));
/*
    //Set GPH10(CLKOUT1) as TXEN,GPH9(CLKOUT0) as RXEN ,both is GPIO
    v_pIOPregs->rGPHCON &= ~(0xf << 18); 
       v_pIOPregs->rGPHCON |=(0x5 << 18);
    //init is low
    v_pIOPregs->rGPGDAT &=~ (0x3<< 9);
    
*/             

    v_pIOPregs
-> rGPGCON    &=   ~ ( 0x3   <<   14 );             // Set GPF7(EINT15) as EINT
    v_pIOPregs -> rGPGCON   |=   ( 0x2   <<   14 );
    v_pIOPregs
-> rGPGUP  = ( 0x1 << 7 );                     // disable up

    
// EINT15==GPG7==GDO2 and Init as in
//     v_pIOPregs->rGPGCON &= ~(0x3<<14); 
//        v_pIOPregs->rGPGCON |=(0x0<<14);
//     v_pIOPregs->rGPGUP &=~(0x1<<7);             // enable up
       
    v_pIOPregs
-> rGPBCON  &=   ~ (( 0x3   <<   10 ) | ( 0x3 << 20 )); 
       v_pIOPregs
-> rGPBCON  |= (( 0x1   <<   10 ) | ( 0x1 << 20 ));
    
// init is low
    v_pIOPregs -> rGPBDAT  &=~ (( 0x1 <<   5 ) | ( 0x1 << 10 ));
    
      
//  Set I/O is SPI interface
      
//  Config GPE11,12,13 is SPIMIO0,SPIMOSI0,SPICLK0,and disable pullup
      v_pIOPregs -> rGPECON  &=   ~ ( 0x3F   <<   22 ); 
      v_pIOPregs
-> rGPECON  |=  ( 0x2A   <<   22 );
      v_pIOPregs
-> rGPEUP |= ( 0x7 << 11 );
      
      
//  Config GPB7(also KEY_ROW1 SPICLK1) is Master SPI CS                                     
      v_pIOPregs -> rGPBCON  &=   ~ ( 0x3   <<   14 );                          
      v_pIOPregs
-> rGPBCON  |=  ( 0x1   <<   14 );         // as out
      v_pIOPregs -> rGPBUP  &=   ~ ( 0x1   <<   7 );         // enable pullup for GPB7    
      
//  Initialize CS is high      
      v_pIOPregs -> rGPBDAT  |=  ( 0x1   <<   7 );

      v_pCLKPWRregs
-> rCLKCON  |= ( 1 << 18 );
    
    
//  Baudrate = PCLK/2/(Prescaler value + 1)
    
//  PCLK = 203000000/4 = 50750000 Hz
    
//  Prescaler value = 0x18 = 24
    
//  Baudrate = 50750000/2/(24 + 1) = 1015000 = 1.015MHz
    
//  MCP41010 max clock frequency is 10MHz
    v_pSSPregs -> rSPPRE0  =   0x18 ; // 0x18;    
    
    
//  Set SPCON0 to configure properly the SPI module.    
    
//  Master  
    
//  SCK enable
    
//  polling mode
    
// v_pSSPregs->rSPCON0 =0x18; //  0x18;     // 001 1000
    
    v_pSSPregs
-> rSPPIN0 = 0x02 ;
    v_pSSPregs
-> rSPCON0  |= ( 1 << 4 ) | ( 1 << 3 ) | ( 0 << 2 ) | ( 0 << 1 );
//     v_pSSPregs->rSPCON0 =0;
    
//  0 Tx Auto Garbage Data mode enable (TAGD):Decide whether the receiving data only needs or not.
    
//                                            0 = normal mode, 1 = Tx auto garbage data mode
    
//                                            NOTE: In normal mode, if you only want to receive data,
    
//                                            you should transmit dummy 0xFF data.
    
//  1,2 It is possible to operate the devices in SPI modes 0,0and 1,1. (MCP41010 datasheet)
    
//      Set SPI mode is 0,0.
    
//  3 Set S3C2410 is Master.
    
//  4 SCK Enable (ENSCK)
    
//  5,6 Determine how and by what SPTDAT is read/written.
    
//      00 = polling mode, 01 = interrupt mode
    
//      10 = DMA mode, 11 = reserved
    
//      Set polling mode
    
    
    RETAILMSG (
0 , (TEXT( " ::: InitSPI over " ) ));
}

WIN CE 下的SPI口地址映射

 



// ======================================================================
//  Name      : InitSPI addr
//
// ======================================================================
BOOL
SPI_InitAddrIO(VOID)        
// IO口地址映射
{
        BOOL    RetValue 
=  TRUE;
        
        v_pIOPregs 
=  ( volatile  IOPreg  * )VirtualAlloc( 0 sizeof (IOPreg), MEM_RESERVE, PAGE_NOACCESS);
        
        v_pCLKPWRregs 
=  ( volatile  CLKPWRreg  * )VirtualAlloc( 0 sizeof (CLKPWRreg), MEM_RESERVE, PAGE_NOACCESS);
        VirtualCopy((PVOID)v_pCLKPWRregs, (PVOID)(CLKPWR_BASE), 
sizeof (CLKPWRreg), PAGE_READWRITE  |  PAGE_NOCACHE);
        
        
if  (v_pIOPregs  ==  NULL) 
        {
                
            RETAILMSG(
1 ,(TEXT( " For SPI_IOPregs : VirtualAlloc failed! " )));
            RetValue 
=  FALSE;
        }
        
else  
        {
            
if  ( ! VirtualCopy((PVOID)v_pIOPregs, (PVOID)(IOP_BASE),  sizeof (IOPreg), PAGE_READWRITE  |  PAGE_NOCACHE)) 
            {
                RETAILMSG(
1 ,(TEXT( " For SPI_IOPregs: VirtualCopy failed! " )));
                RetValue 
=  FALSE;
            }
        }
    
        
if  ( ! RetValue) 
        {
            RETAILMSG (
1 , (TEXT( " ::: SPI_InitializeAddresses - Fail!! " ) ));
            
if  (v_pIOPregs) 
            {
                VirtualFree((PVOID) v_pIOPregs, 
0 , MEM_RELEASE);
            }
            v_pIOPregs 
=  NULL;
        }
        
else  
        {
        
            RETAILMSG (
0 , (TEXT( " ::: SPI_InitializeAddresses - Success " ) ));
        }

        
return (RetValue);
}

 

看程序不能断章取义,这个是我的一部分代码,只是给大家参考一下,要是自己写的话还是得看明白文档,不过这个初使化还是可以拿来主义的。哈哈

最后说的:

一般到用SPI全是针对一个外器的初使化或者是数据读取和写入,SPI的协议只规定了他的基本时序,但是一个器件如果能正常的使用SPI还必需符合他自己的协议,比如CC1100的SPI数据操作时序就是先送地址,再送数据,其实一般的器件也都是这样的,1100是8位操作的,而用ILI9320IC的TFT液晶屏却是十六位的,而且还有一些其它的比如晶振的起振等,这样就要先看明白器件的手册再根据2410的SPI发送接收程序来写符合相当器件时序的SPI程序,ILI9320的介绍我将在其它的文章中介绍。

最最重要的,也是我遇到的弄了N天的点儿就是SPI各个时序信号的极性问题,这个可以从器件的手册上看到,在S3C2410 SPI的使用(1)中的那个表中有详细的介绍, 主要是CLK的时序和数据传输时序和匹配,一共四种,读者自己区别,2410的时序图和器件的时序图比较就可得到。

今天先写到这里,晚了,饿了,回家了。哦了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值