您的位置: OpenADSP社区论坛 -> Blackfin专区 -> 新手上路 -> 21489 SPI Slave Boot
本帖共有1145个阅读者
发表帖子 发表投票 回复主题
21489 SPI Slave Boot
wityuan(论坛新手)
wityuan
头衔:社区公民
帮派:无帮无派
帖数:1
金钱:134
积分:5
注册时间:2015/12/8
楼主信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
精华主题 精华帖子
21489 SPI Slave Boot

SPI Slave Boot调试:



平台:BF548-master,21489做为从机



手册:ADSP-214xx_HRM_rev0.3





说明:



       Slave
boot程序是分为boot
image程序和应用程序两部分。Boot-image程序是由VisualDsp++默认生成的。在使用slave boot的时候,只需要做的是将boot type设置一下,设置为spi slave,这个最后生成的boot-image和parallel port(PROM)生成的boot-image是不同的。



上传的图片
  2015122414141494.png [ 29.64 KB 643×399 ] (缩略时请点击查看原图)

 




Boot-image:



       是程序开始执行的时候,最先开始的部分。用了256*48bit程序大小组成。这个也是中断向量表部分。对于两边沟通的处理器来说,可以用unsigned
char arr[]数组来发送和接收,就不存在8位,16位,32位组包问题了。

在将外部启动方式选择为slave
boot之后,spi dma会默认配置为:





上传的图片
  201512241434794.png [ 64.15 KB 921×472 ] (缩略时请点击查看原图)

 




有几个需要注意的点:



1、LSB first,也就是开始传输的是最小的位。



2、MISO是禁止的,也就是说传输数据过程中,读取数据是无效的结果。



3、spi模式设为3。





在BF548和12489启动之后,BF548会将程序(已经有了boot-image和应用程序,其实根本就不用管boot-image和应用程序)发给12489,12489会接收到256*48bit的程序,接收那么多的程序是通过dma的计数值来得到的,接收完成之后,自动从程序的开始地方运行,相当于boot-image启动起来了,这个boot-image是占用着中断向量表的位置,因此,中断是不允许的。Boot-image这个时候就会引导应用程序的装载,具体程序怎么装载,装载到哪里,就是通过boot-image里面的程序一段段分配的,在应用程序装载完毕之后,boot-image程序部分,会被中断向量表覆盖,至此整个程序发送完成。


注意点:



1、BF548上配置LSB,模式,时钟。



这个BF548和12489(这个是slave boot起来之后默认的配置)一定要匹配对,否则后续操作没法进行,而spi时钟是主机产生的,因此,时钟这个问题,只要没做的12489承受不住(可能性小),不会有什么问题的,模式选择为3。





2、VisualDsp++上的配置:



       这个是交叉在两个处理器芯片的熟悉程度和工具使用上的。按照上面给出的图的处理办法,12489部分就配置完成了,需要做的只是和BF548上如何测试,我做的方法是,在12489程序里面加上:BF548发数据,spi给返回,这样就能明确程序有没有起来了。





我在做的时候,出现了问题,验证的时候思考过查看汇编启动起来的情况,汇编文件可以在



F:\VisualDSP 5.1.2\214xx\ldr\489_spi里面找到。



汇编文件dxe可以自己生成,如下:




上传的图片
  201512241435194.png [ 29.81 KB 643×399 ] (缩略时请点击查看原图)

 



设置成executable
file就可以了。





参考部分测试代码:



BF548部分升级程序代码:



#include "stdio.h"



#include <sys/types.h>



#include <sys/stat.h>



#include <fcntl.h>



#include <unistd.h>



#include <stdlib.h>



#include <linux/types.h>



#include <fcntl.h>



#include <sys/ioctl.h>



#include <linux/spi/spidev.h>



int main(int argc,char *argv[])



{



       int
spi_fd;



       int
i = 0;



       int
iRet;



       unsigned
char spiData[4];



       int
mode;



       unsigned
int fileFd;



       struct  stat fileStat;



       int
filep;



       spi_fd
= open("/dev/spidev2.33",O_RDWR);



       if(spi_fd
< 0){



              printf("can't
open spi_device\r\n");



              return
-1;



       }



       mode
= 1;



       iRet
= ioctl(spi_fd,SPI_IOC_WR_LSB_FIRST,&mode);



           if (iRet == -1)



      
       printf("can't set bits
lsb_first\n");  



       printf("read
spi device ok\n");



       printf("raw
data is : 0x%08x\r\n",spiData);



       filep
= 0;



       fileFd
= open ( "/app/dsp12489.ldr", O_RDONLY);



       if(fileFd
< 0){



              printf("can't
open fileFd\r\n");



              return
-1;



       }



       printf("read
fileFd ok\n");



       fstat
(fileFd, &fileStat);



       printf("/app/dsp12489.ldr
file size = %d\n",(int)(fileStat.st_size));



       filep
= 0;        



       while(filep<fileStat.st_size)



       {



              //
boot kernel code



              //app
code



              read(fileFd,spiData,4);



              write(spi_fd,spiData,4);



              filep
+= 4;      



       }



       printf("write
end\n");



       return
0;



}







BF548测试程序代码:



#include "stdio.h"



#include <sys/types.h>



#include <sys/stat.h>



#include <fcntl.h>



#include <unistd.h>



#include <stdlib.h>



#include <linux/types.h>



#include <fcntl.h>



#include <sys/ioctl.h>



#include <linux/spi/spidev.h>



#if 1



int main(int argc,char *argv[])



{



       int
spi_fd;



       int
iRet;



       int
mode;



       unsigned
char spiData[4] = {0x12,0x34,0x56,0x78};



       unsigned
char buf[5]={0};



      



       spi_fd
= open("/dev/spidev2.33",O_RDWR);



       if(spi_fd
< 0){



              printf("can't
open spi_device\r\n");



              return
-1;



       }



       printf("read
spi device ok\n");



       mode
= 0;



       iRet
= ioctl(spi_fd,SPI_IOC_WR_LSB_FIRST,&mode);



           if (iRet == -1)



      
       printf("can't set bits
msb_first per word");



       while(1)



       {



              #if
1



              if
(write(spi_fd,spiData,4) < 0) {



                     perror("write
Error");





                     return
-1;



              }



              #endif



              if (read(spi_fd,buf,4) < 0) {



                     perror("read
Error");





                     return
-1;



              }



              printf("buf[0]=0x%02x,buf[1]=0x%02x,buf[2]=0x%02x,buf[3]=0x%02x\r\n",



                     buf[0],buf[1],buf[2],buf[3]);



              sleep(1);



       }



       return
0;



}



#endif





注:测试代码速度会比较慢,40K的程序大概4s,修改程序即可。











3个spi升级程序代码示例,速度能达到秒速,45.2KB的程序。



升级程序:



#include "stdio.h"



#include <sys/types.h>



#include <sys/stat.h>



#include <fcntl.h>



#include <unistd.h>



#include <stdlib.h>



#include <linux/types.h>



#include <fcntl.h>



#include <sys/ioctl.h>



#include <linux/spi/spidev.h>



#include <sys/mman.h>



#include <string.h>





unsigned char *p[]={



       "/dev/spidev2.33","/dev/spidev2.34","/dev/spidev2.35"



};





#if 1



int main(int argc,char *argv[])



{



       int
spi_fd;



       int
i = 0;



       int
iRet;



       unsigned
char spiData[256];



       int
mode;



       unsigned
int fileFd;



       struct  stat fileStat;



       int
filep;



       unsigned
char *mmapMem;



       for(i
= 0 ;i < 3 ; i ++)



       {



              //spi_fd
= open("/dev/spidev2.33",O_RDWR);



              spi_fd
= open(p[i],O_RDWR);



              if(spi_fd
< 0){



                     printf("can't
open spi_device\r\n");



                     return
-1;



              }



              mode
= 1;



              iRet
= ioctl(spi_fd,SPI_IOC_WR_LSB_FIRST,&mode);



                  if
(iRet == -1)



                      printf("can't
set bits lsb_first\n");  



              printf("read
spi device ok\n");



              printf("raw
data is : 0x%08x\r\n",spiData);



              filep
= 0;



              fileFd
= open ( "/app/dsp12489.ldr", O_RDONLY);



              if(fileFd
< 0){



                     printf("can't
open fileFd\r\n");



                     return
-1;



              }



              printf("read
fileFd ok\n");



              fstat
(fileFd, &fileStat);



              



              printf("/app/dsp12489.ldr
file size = %d\n",(int)(fileStat.st_size));



              mmapMem
= mmap(NULL, fileStat.st_size, PROT_READ, MAP_PRIVATE, fileFd, 0);



              



              filep
= 0;





              while(filep<(fileStat.st_size
/ 256 * 256))



              {



                     //
boot kernel code



                     //app
code



                     #if
0



                     //loop
again and again too slow,just read a big block to be fast.



                     read(fileFd,spiData,4);



                     write(spi_fd,spiData,4);



                     filep
+= 4;      



                     #endif



                     memcpy(spiData,&mmapMem[filep],256);



                     write(spi_fd,spiData,256);



                     filep
+= 256;



              }





              if(filep
!= fileStat.st_size)



              {



                     memcpy(spiData,&mmapMem[filep],fileStat.st_size
- filep);



                     write(spi_fd,spiData,fileStat.st_size
- filep);



              }



              printf("write
end\n");



              close(fileFd);



              munmap(mmapMem,
fileStat.st_size);



       }



       return
0;



}



#endif









spi的测试程序:



#include "stdio.h"



#include <sys/types.h>



#include <sys/stat.h>



#include <fcntl.h>



#include <unistd.h>



#include <stdlib.h>



#include <linux/types.h>



#include <fcntl.h>



#include <sys/ioctl.h>



#include <linux/spi/spidev.h>



#include <sys/mman.h>



#include <string.h>



unsigned char *p[]={



       "/dev/spidev2.33","/dev/spidev2.34","/dev/spidev2.35"



};





int main(int argc,char *argv[])



{



       int
spi_fd;



       int
iRet;



       int
mode;



       int
i = 0;



       unsigned
char spiData[4] = {0x12,0x34,0x56,0x78};



       unsigned
char buf[5]={0};







       for(i
= 0 ; i < 3 ;i ++)



       {



              spi_fd
= open(p[i],O_RDWR);



              if(spi_fd
< 0){



                     printf("can't
open spi_device\r\n");



                     return
-1;



              }



              printf("read
spi device ok\n");



              mode
= 0;



              iRet
= ioctl(spi_fd,SPI_IOC_WR_LSB_FIRST,&mode);



                  if
(iRet == -1)



                      printf("can't
set bits msb_first per word");



                    



              if
(write(spi_fd,spiData,4) < 0) {



                     perror("write
Error");





                     return
-1;



              }



              if
(read(spi_fd,buf,4) < 0) {



                     perror("read
Error");





                     return
-1;



              }



              printf("%s
",p[i]);



              printf("buf[0]=0x%02x,buf[1]=0x%02x,buf[2]=0x%02x,buf[3]=0x%02x\r\n",



                     buf[0],buf[1],buf[2],buf[3]);



              memset(buf,0,sizeof(buf));



              sleep(1);



       }



       return
0;



}


这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2015/12/24 14:35:20
尊贵身份标志
OpenADSP(管理员)
OpenADSP
头衔:社区公民
帮派:无帮无派
帖数:5187
金钱:34761
积分:6369
注册时间:2011/6/7
1信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线

感谢分享!


我是OP...
等级:管理员 参考IP地址:*.*.*.*
2015/12/24 16:26:51
daviscai(论坛新手)
daviscai
头衔:社区公民
帮派:无帮无派
帖数:3
金钱:105
积分:1
注册时间:2013/5/1
2信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
这帖子要顶顶

这家伙很懒,什么也没有留下!
等级:论坛新手 参考IP地址:*.*.*.*
2015/12/24 21:51:12
Powered by OpenADSP Copyright © 2010 www.Openadsp.com. All rights reserved.154628 Call, 1 Queries, Processed in 0.031250 second(s),