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

来源:互联网 发布:网络投融资平台 编辑:程序博客网 时间:2024/06/05 16:43

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

 

2SPI状态寄存器(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

 

 

3SPI引脚控制寄存器(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(0sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
        
        v_pCLKPWRregs 
= (volatile CLKPWRreg *)VirtualAlloc(0sizeof(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的时序图和器件的时序图比较就可得到。

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

原创粉丝点击