4703|9

81

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

【求助】SPI(DMA方式),代码分析! [复制链接]



  1. void SPI_Init()
  2. {

  3.         //----------- IMPORTANT: By default, the internal clock is disabled.  To configure the controller ------
  4.         //                                                  we must first enable it.
  5.        
  6.                  StartSPIClock();

  7.          
  8.                  // ----------------------Configure the GPIO pins for SPI mode -------------------------------
  9.         //
  10.         //                   nSPICS0  (chip select)                = GPG2
  11.         //                   SPICLK0  (SPI clock)                        = GPE13
  12.         //                   SPIMOSI0 (SPI output data)        = GPE12
  13.         //                   SPIMISO0 (SPI input data)                = GPE11
  14.          
  15.          s2440IOP->rGPGCON &=~(0x3<<4);
  16.          s2440IOP->rGPGCON |=(0x1<<4);  //GPG2 [OUTPUT]
  17.          s2440IOP->rGPGUP &=~(0x1<<2);  //enable pullup
  18.          
  19.            s2440IOP->rGPECON &= ~((3<<26) | (3<<24)|(3<<22));
  20.    s2440IOP->rGPECON |= ((0x2<<26)|(0x2<<24)|(0x2<<22));
  21.    s2440IOP->rGPEUP |= (0x7<<11);


  22. //SPI register init
  23.    s2440SPIreg->rSPCON0=(0<<5)| //(SMOD) ; 10 = DMA mode ;  01 = interrupt mode               
  24.                                                                                                 (1<<4)|   //clock enable
  25.                                                                                                 (1<<3)|   //(MSTR) :1 = master mode
  26.                                                                                                 (SPI_CLOCK_POLARITY<<2)|    //(CPOL) Determine an active high or active low clock;
  27.                                                                                                 (1<<1)|     //(CPHA)   format B
  28.                                                                                                 (0);        //TAGD   
  29.    
  30.     s2440SPIreg->rSPPIN0=(0<<2)|(1<<1)|(0);  
  31.   
  32.                        
  33.          // RETAILMSG(DEBUG_ZONE,(TEXT("SPI_Init__rSPSTA0={0x%x}\r\n"),s2440SPIreg->rSPSTA0));       
  34.     SetSPIClockRate(CLK_RATE_SIXTY4);  

  35.    
  36.    
  37. }
复制代码


  1. void DmaWriteData(/*const unsigned char *buffer,*/DWORD dwNumBytes)
  2. {
  3.    RETAILMSG(1,(TEXT(">>>>DmaWriteData \r\n")));
  4.    
  5.    RETAILMSG(DEBUG_ZONE,(TEXT("dwNumBytes=%d\r\n"),dwNumBytes));       
  6.    unsigned int ct=0;
  7.    int delay_count=0,i=0,waitCount=0;       
  8.     for(ct=0;ct<(dwNumBytes);ct+=2)
  9.    RETAILMSG(DEBUG_ZONE,(TEXT("%dth:{0x%x,0x%x}\r\n"),ct/2 ,*(pDmaBuffer+ct),*(pDmaBuffer+ct+1)));       


  10.    RETAILMSG(DEBUG_ZONE,(TEXT("DMA__Current source address before tx ={0x%x}\r\n"),s2440DMA->rDCSRC1));
  11.    
  12.         //------------------------------ wait for DMA to complete.-------------------------------
  13.         while((s2440DMA->rDSTAT1 & 0xfffff)!=0)
  14.         {
  15.             RETAILMSG(1,(TEXT("DMA is busy now! 1th\r\n")));
  16.         };
  17.        
  18.         if((s2440DMA->rDSTAT1 & 0x300000)==0)
  19.         {
  20.                  RETAILMSG(1,(TEXT("DMA is ready now! 1th\r\n")));
  21.         }

  22. //-------------------------------- Configure the DMA SPI mode -------------------------
  23.         SpiInitDma();       
  24.        
  25.        
  26.           //nss0    low        
  27.    s2440IOP->rGPGCON &=~(0x3<<4);
  28.          s2440IOP->rGPGCON |=(0x3<<4);  
  29.          //s2440IOP->rGPGUP &=~(0x1<<2);  //enable pullup          
  30.    s2440IOP->rGPGDAT &=~(1<<2);  
  31.        
  32.         SPI_CS_High();
  33.         SPI_CS_Low();       
  34.        
  35.    s2440DMA->rDISRC1 =(int)(SPI_BUF_PHYS_BASE);   //源地址 :DMA对应物理地址
  36.    s2440DMA->rDISRCC1 &= ~(0x3);
  37.    // Source is system bus(内存块中), increment addr(每次数据传送之后地址递增)

  38.         //---------------- Initialize the DMA channel to send data over the SPI bus --------------------
  39.     s2440DMA->rDIDST1        = (int)D_ADDR;      // 要传送的目的地址,这里应该是SPI的数据数据地址(SPTDAT0)   
  40.     s2440DMA->rDIDSTC1 = //(CHK_INT<<2)|    //中断触发模式
  41.                                                                                                          (1<<1)|   //                                                                                                         (1);        // fixed addr ,
  42.                                                                                                          
  43.   
  44. //-------- Configure the DMA channel's transfer characteristics: handshake, sync PCLK,  ----------
  45.         //                   single tx, single service,  no auto-reload, byte, tx count
  46.                 s2440DMA->rDCON1        = (1<<31)|  //Handshake mode   ,
  47.                                                                                                 (0<<30) |  //while for those attached to APB system, it should be set to 0
  48.                                                                                                 //(1<<30) |  //while for those attached to APB system, it should be set to 0
  49.                                                                                                 (0<<29) |  // 决定DMA中断何时产生(i.e.CURR_TC becomes 0).
  50.                                                                                                 (0<<28) |  // a unit transfer is performed. 数据一直传送直到TC为0
  51.                                                                                                 (1<<27) |  //Whole service mode
  52. #if HARD_TRIGGER
  53.                                                                                                 (0x3<<24) |   //DMA request source is  SPI
  54.                                                                                                 (1<<23) |     //H/W request mode
  55. #else       
  56.                                                                                                 (0<<23) |  //S/W request mode ,triggered by setting SW_TRIG
  57. #endif
  58.                                                                                                 (1<<22) |   //NO_DMA_AUTO_RELOAD
  59.                                                                                                 (0<<20) |  //Data size to be transferred.   ;BYTE
  60.                                                                                                 (dwNumBytes)  ;  //       
  61.        
  62.        

  63.          RETAILMSG(1, (TEXT(" 1TH CURR_TC =%x.\r\n"),s2440DMA->rDSTAT1));
  64.   
  65.                                                                
  66.             //------------------------------ wait for DMA to complete.-------------------------------
  67.         while((s2440DMA->rDSTAT1 & 0xfffff)!=0)
  68.         {
  69.                  RETAILMSG(1, (TEXT(" ... CURR_TC =%x.\r\n"),s2440DMA->rDSTAT1));
  70.            RETAILMSG(1,(TEXT("DMA is busy now! 2th\r\n")));
  71.         };
  72.        
  73.         //RETAILMSG(1, (TEXT("  CURR_TC =%d.\r\n"),s2440DMA->rDSTAT1));
  74.   
  75.   //---------------------------------Trigger DMA---------------------------------------
  76.   //Note. This bit should not be changed manually during DMA operations
  77.         s2440DMA->rDMASKTRIG1 &= ~(1<<2);
  78. //        s2440DMA->rDMASKTRIG1 |= (1<<1);  //0110
  79.         s2440DMA->rDMASKTRIG1 = 0x006;  //0110
  80.        
  81.                 while((s2440DMA->rDSTAT1 & 0xfffff)!=0)
  82.         {
  83.                  RETAILMSG(1, (TEXT(" DMA_CURR_TC =%x.\r\n"),s2440DMA->rDSTAT1));
  84.          };
  85. #if 1
  86.         RETAILMSG(DEBUG_ZONE,(TEXT("DMA__rDSTAT1.={0x%x}\r\n"),s2440DMA->rDSTAT1));
  87. //[21:20] 0:ready,1:busy   [19:0] Current value of transfer count

  88.         RETAILMSG(DEBUG_ZONE,(TEXT("SPI__rSPTDAT0={0x%x}\r\n"),s2440SPIreg->rSPTDAT0));//输出为0x8,说明数据是传递到SPTDAT端了       
  89.        
  90.         RETAILMSG(DEBUG_ZONE,(TEXT("SPI__rSPSTA0={0x%x}\r\n"),s2440SPIreg->rSPSTA0));       
  91. //[0] 0 = not ready ;1 = data Tx/Rx ready;
  92. //[1] 0 = not detect 1 = multi master error detect
  93. //[2] This flag is set if the SPTDATn is written or SPRDATn is read whilea transfer is in progress and cleared by reading the SPSTAn.   0 = not detect 1 = collision error detect

  94.         RETAILMSG(DEBUG_ZONE,(TEXT("DMA__Current source address ={0x%x}\r\n"),s2440DMA->rDCSRC1));
  95.         RETAILMSG(DEBUG_ZONE,(TEXT("DMA__Current destination address={0x%x}\r\n"),s2440DMA->rDCDST1));
  96. #endif

  97.    
  98.         delay_count = 0;
  99.         while((s2440DMA->rDSTAT1 & 0xfffff)==0)
  100.         {
  101.                 if( delay_count++ > DELAY_COUNT )
  102.                 {               
  103.                         RETAILMSG(1, (TEXT("  timeout occurred while waiting to start DMA.\r\n")));
  104.                         break;
  105.                 }
  106.         }  



  107.         SPI_CS_High();
  108.        
  109.    RETAILMSG(1,(TEXT("<<<<<
  110. }

复制代码

帮我分析下!  
情况是:我用SPI(dma mode)来将数据传递到外设,
但现在我抓 SPIMISO 、SPIMOSI 、SPICLK的波形抓不到!
SPLCLK有时候会出来

不知道是什么没有配置好;

源地址:SPI_BUF_PHYS_BASE 是我在对应的是我在config.bib中的地址
目的地址:D_ADDR 是SPTDAT0 0x59000010  
[code]


我打打印信息:
DMA__rDSTAT1.={0x0}
SPI__rSPTDAT0={0x8}
SPI__rSPSTA0={0x1}
DMA__Current source address ={0x3005004c}
DMA__Current destination address={0x59000010}
  timeout occurred while waiting to start DMA.

我通过for循环,连续写5组数据进去,进行测试的

最新回复

看下,mark   详情 回复 发表于 2010-4-29 00:36
点赞 关注

回复
举报

69

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
Up
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
如果我改变数据的末尾的值,那么SPI的数据输出端SPI__rSPTDAT0={0x8} 得值也会变,
而且输出TC的值,也是预定值,
            -------说明DMA收到了SPI的请求,并已经装载TC值,而且,所有的数据都已传到SPI的输出端

但现在用示波器却抓不到波形?
 
 
 

回复

54

帖子

0

TA的资源

一粒金砂(初级)

4
 
量过电路是通的吗?通常这种错误是由最简单的问题引起的,先确认电路没问题再说
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

5
 
同意楼上的,如果电路通,看看波形是否正确等
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

6
 
电路通?  这个不存在问题!
我直接测试的是GPIO口,  所以只要IO复用配置好,就OK了!
 
 
 

回复

98

帖子

0

TA的资源

一粒金砂(初级)

7
 
wait ....
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

8
 
SPI
一、如果采用中断方式,那么中断时在什么情况下被触发的?
二、如果采用查询方式,应该怎么实现,

    1、配置SPI为查询方式
    2、检测什么信号?
    3、写数据?
   
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

9
 
一、如果采用中断方式,那么中断时在什么情况下被触发的?SPI接收或发送都可以产生中断的

二、如果采用查询方式,应该怎么实现,
? ? 1、配置SPI为查询方式
? ? 2、检测什么信号?读相应的寄存器
? ? 3、写数据?就直接写,然后确定发送完毕
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

10
 
看下,mark

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表