原文地址::http://www.analogcn.com/Article/wz3/200907/20090713000001.html
ADSPBF531 SPI Slave Boot 编程调试足足花了我两个星期的时间,想起编程调试那段日子,真的实在太累了,一天24小时总是想着问题,程序导到ADSP,ADSP没有一点反应,老外10月底11月初就要过来了,时间非常紧张,经过两个星期的辛苦努力,终于2008年10月09日下午4:30被我调通了,用ARM9导到ADSP后,看到LED闪烁,真的不容易,心里充满快乐和成就感!
作 者: JackChen(陈任)
2008年10月09日
第一章 准备所需要的硬件和工具
1.1、华恒科技ADSPBF531学习板一块(如下图)或者其它531开发板
注意: Silicon Revision版本一定要大于等于0.3,如下图所示Silicon Revision 0.4
1.2、AT91SAM9260开发板一板(要保留PB0,1,2,3和PB29及PC8)
1.3、Jlink(IAR)仿真器一个
1.4、ADSP仿真器一个
1.3、周立功逻辑分析仪(LA1016) 一个
第二章 准备所需要的源代码和软件工具
2.1、安装好VisualDSP 5.0++
2.2、安装好IAR FOR ARM 4.22
2.3、准备文档资料
A、ADSP-BF533 Blackfin Booting Process.pdf
B、VisualDSP++ 5.0 Loader and Utilities Manual (Revision 2.0, August 2007) .pdf
C、EE240v03.pdf
D、ADSP-BF533 Blackfin Processor Hardware Reference (Revision 3.3, September 2008).pdf
2.4、准备源程序
A、EE-240 Software Code EE240v03.zip (网上下载) (ADSP)
B、AT91SAM9260-SYSC-IAR4_41A.raràAT91SAM9260-SYSC-IAR4_41AàAT91SAM9260-RSTC
C、从http://www.dolomitics.com/downloads/ldrviewer.html下载ldrviewer_12.zip
第三章 硬件连接
3.1、ADSPBF531与AT91SAM9260硬件相连
AT91SAM9260 ADSPBF531 QFP封装
CLK(PB2)-------------------->SPICLK (53引脚)
NPCS0(PB3)-------------------->/SPISS(PF0) (51引脚)
MOSI(PB1)-------------------->MOSI (55引脚)
MISO(PB0)-------------------->MISO (54引脚)
PB29-------------------->PF15 (27引脚)
PC8-------------------->/RESET (13引脚)
在AT91SAM9260程序里定义
#define AT91_SPI1_MISO (1<<0) // PB0
#define AT91_SPI1_MOSI (1<<1) // PB1
#define AT91_SPI1_SPCK (1<<2) // PB2
#define AT91_SPI1_NPCS0 (1<<3) // PB3
#define AT91_HWAIT (1<<29) // PB29
#define AT91_ADSP_RST (1<<8) // PC8
3.2、Boot Mode方式硬件连接
ADSP-BF531/532/533支持如下几种Boot方式(Silicon Revision大于等于0.3)
引导方式 |
BMODE[1:0] |
说明 |
1 |
00 |
外部非同步存储器直接启动,启动地址0x20000000 |
2 |
01 |
外部非同步存储器启动,使用片上Loader,将外部非同步存储器中的程序加载到L1 Cache,启动地址 0xFFA08000(BF533为0xFFA00000) |
3 |
10 |
SPI Flash Slave模式启动,即可以使用别的CPU向ADSP-BF531/532/533输入程序,启动地址同2 |
4 |
11 |
SPI Flash Master模式启动,使用片上Loader,将SPI Flash中的程序加载到L1 Cache,启动地址同2 |
我们采用第三种引导方式
BMODE[0]---------------------à地
BMODE[1]---------------------àVCC
第四章 Init_Code_BF533引导初始代码移植到ADSPBF531
4.1、解压EE-240 Software Code EE240v03.zip,如下图所示
4.2、再解压其中的example.zip,得到example工程,如下图所示
4.2、把工程复制到根目录下,因为目录太长不好
4.3、进入init_codeInit_Code_BF533引导初始化程序
4.4、再用VisualDSP 5.0++打开D:BF533 ASM Blinkinit_codeInit_Code_BF533工程,打开时会提示如下对话框,点是(Y)
点是(Y)后,再弹出一个对话框架,点下图的红色圈,弹出LDF文件选择
4.5、选中ADSP-BF533.LDF后,点打开,再点OK,再点确定
4.6、编译工程后,提示编译成功,点Cancel
4.7、以上初始工程是基于ADSPBF533的CPU,现在把它移植成ADSPBF531的CPU
菜单->Project->Project options…. ALt+F7弹出Project Options选项,把Processor改成ADSP-BF531,弹出Change Processor对话框,点Yes,再点确定返回
4.8、再打开文件Init_code_BF533.asm,把#include 改成#include
4.9、再打开ADSP-BF533.ldf的源代码,把光标放到文件,右击选择Open with source windows
4.10、把文件ADSP-BF533.ldf开头的
ARCHITECTURE(ADSP-BF533)改成ARCHITECTURE(ADSP-BF531)
4.11、把文件ADSP-BF533.ldf里的
PROGRAM { TYPE(RAM) START(0xFFA00000) END(0xFFA0AFFF) WIDTH(8) } //L2
SDRAM { TYPE(RAM) START(0x00000000) END(0x07FFFFFF) WIDTH(8) } //SDRAM
改成
PROGRAM { TYPE(RAM) START(0xFFA08000) END(0xFFA0AFFF) WIDTH(8) } //L2
SDRAM { TYPE(RAM) START(0x00000000) END(0x07FFFFFF) WIDTH(8) } //SDRAM
如下图所示,因为533和531的存储器不一样,所示得改
4.12、改完后,编译成功,在DEBUG目录下生成Init_Code_BF533.dxe
第五章 ADSP-BF531 LED闪烁程序编写
5.1、在第四章中的有解压出来的example工程,如下图所示
5.2、用VisualDSP 5.0++打开D:BF533 ASM Blink ADSP-BF533_EZ-KIT_BlinkLeds.dpj工程
会有提示,点是(Y)
5.3、编译一下,成功编译
5.4、以上初始工程是基于ADSPBF533的CPU,现在把它移植成ADSPBF531的CPU
菜单->Project->Project options…. ALt+F7弹出Project Options选项,把Processor改成ADSP-BF531,弹出Change Processor对话框,点Yes,再点确定返回
5.5、把BF533_EZ-KIT_Flash_Setup.asm从工程中删去
5.6、把main.asm文件的所示内容删掉,换成以下内容
#include
#include "startup.h"
.section L1_code;
.global _main;
#define PF_DIR_LED 0x00FF // PF8-11 inputs
#define PF_DATA_LED 0x00FF // PF8-11 inputs
#define delay 0x3800000
_main:
p0.l = lo(FIO_DIR);
p0.h = hi(FIO_DIR);
r0.l = PF_DIR_LED;
w[p0] = r0;
ledloop:
p0.l = lo(FIO_FLAG_S);
p0.h = hi(FIO_FLAG_S);
r0.l = PF_DATA_LED;
w[p0] = r0;
call DELAY;
p0.l = lo(FIO_FLAG_C);
p0.h = hi(FIO_FLAG_C);
r0.l = PF_DATA_LED;
w[p0] = r0;
call DELAY;
jump ledloop ;
DELAY:
p2.l = lo(delay);
p2.h = hi(delay);
lsetup(delay_loop, delay_loop) lc0=p2;
delay_loop: nop;
rts;
_main.END:
5.7、把startup.asm中的#include 改成#include
5.8、把ADSP-BF533_ASM.ldf文件的所示内容删掉,换成以下内容
ARCHITECTURE(ADSP-BF531)
SEARCH_DIR( $ADI_DSPBlackfinlib )
$OBJECTS = $COMMAND_LINE_OBJECTS;
$LIBRARIES = $COMMAND_LINE_OBJECTS;
MEMORY
{ /* Instruction SRAM, 48K */
PROGRAM { TYPE(RAM) START(0xFFA08000) END(0xFFA0B000) WIDTH(8) }
/* Data Bank A, 16K */
DATA_A { TYPE(RAM) START(0xFF804000) END(0xFF807FFF) WIDTH(8) }
SCRATCH { TYPE(RAM) START(0xFFB00000) END(0xFFB00FFF) WIDTH(8) }
/* SDRAM memory, 4K */
SDRAM_MEM { TYPE(RAM) START(0x00000000) END(0x07FFFFFF) WIDTH(8) }
}
PROCESSOR p0
{
OUTPUT( $COMMAND_LINE_OUTPUT_FILE )
SECTIONS
{
program
{
INPUT_SECTION_ALIGN(4)
// INPUT_SECTIONS( $OBJECTS(L1_code1) $LIBRARIES(L1_code1))
INPUT_SECTIONS( $OBJECTS(L1_code) $LIBRARIES(L1_code))
} >PROGRAM
}
}
5.8、编译成功
5.9、挂上仿真器后,会发现PF0-PF3所在的LED同时在闪烁
第六章 如何由ADSP-BF531 LED闪烁程序生成SPI Slave Boot引导的Loader
(由点dxe生成SPI Slave Boot引导的点ldr)
6.1、打开第五章的LED闪烁工程
然后-》菜单->Project->Project options…. ALt+F7弹出Project Options选项
按下图设置
其中
A、Boot Mode 选中 SPI Slave
B、 Boot Format 选中 ASCII
C、Output Width
D、Initialization 打开由第四章生成的Init_Code_BF533.dxe
E、 Additional options输入-pFlag PF15 因为硬件连接时,由PF15作为HWAIT
6.2、编译成功,如下图所示,有一些警告,只是说明CPU的版本问题,没关系
6.3、在Debug目录下生成ADSP-BF533_EZ-KIT_BlinkLeds.ldr,共198行,共197字节
第七章 用查看引导点ldr文件
7.1解压ldrviewer_12.zip文件得到LdrViewer.exe,打开LdrViewer.exe软件,再打开第六章生成的ADSP-BF533_EZ-KIT_BlinkLeds.ldr,如下图所示
第八章 点ldr文件转换成数组
8.1、VDSP5.0++生成的点ldr文件的内容如下图,而数组要在每个字节后多加一个逗号
用UltraEDIT打开文件
8.2、在UltraEDIT中,转换到二进制方式,点击如下图的红圈,就会转换到二进制方式
8.3、^+F呼出查找,输入0d0a,表示是查找换行,如下图所示,找到了0d0a
8.4、^+R呼出替换,查找输入0d0a,替换为输入2C0D0A
点击全部替换后弹出以下对话框,点是(Y)
8.5、转换到ACILL方式
第九章 AT91SAM9260编程引导ADSP-BF531 SPI Slave Boot
9.1、首先了解一下ADSP-BF531 SPI Slave Boot引导时序
图 单字节发送时序
图 多个字节发送时序
图 整个引导时序
图 引导时,程序执行时序
9.2、底层驱动mosi(),spck(),npcs(),hwait(),adsp_rst()
#define AT91_SPI1_MISO (1<<0) // PB0
#define AT91_SPI1_MOSI (1<<1) // PB1
#define AT91_SPI1_SPCK (1<<2) // PB2
#define AT91_SPI1_NPCS0 (1<<3) // PB3
#define AT91_HWAIT (1<<29) // PB29
#define AT91_ADSP_RST (1<<8) // PC8
void mosi(unsigned char val)
{
if(val)
{
AT91F_PIO_SetOutput( AT91C_BASE_PIOB, AT91_SPI1_MOSI );
}
else
{
AT91F_PIO_ClearOutput( AT91C_BASE_PIOB, AT91_SPI1_MOSI );
}
}
void spck(unsigned char val)
{
if(val)
{
AT91F_PIO_SetOutput( AT91C_BASE_PIOB, AT91_SPI1_SPCK );
}
else
{
AT91F_PIO_ClearOutput( AT91C_BASE_PIOB, AT91_SPI1_SPCK );
}
}
void npcs(unsigned char val)
{
if(val)
{
AT91F_PIO_SetOutput( AT91C_BASE_PIOB, AT91_SPI1_NPCS0 );
}
else
{
AT91F_PIO_ClearOutput( AT91C_BASE_PIOB, AT91_SPI1_NPCS0 );
}
}
unsigned char hwait (void)
{
unsigned char f;
if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOB) & AT91_HWAIT ) == AT91_HWAIT )
{
f=1;
}
else
{
f=0;
}
return f;
}
void adsp_rst(unsigned char val)
{
if(val)
{
AT91F_PIO_SetOutput( AT91C_BASE_PIOC, AT91_ADSP_RST );
}
else
{
AT91F_PIO_ClearOutput( AT91C_BASE_PIOC, AT91_ADSP_RST );
}
}
9.3、delay函数
void delaya(void)
{
int i,i1;
for(i=0;i<5;i++)
for(i1=0;i1<10;i1++);
}
void delay2a(void)
{
int i,i1;
for(i=0;i<100;i++)
for(i1=0;i1<1000;i1++);
}
void delay1a(void)
{
int i,i1;
for(i=0;i<2;i++)
for(i1=0;i1<2;i1++);
}
void delay(void)
{
delaya();
delaya();
}
void delay1(void)
{
delay1a();
delay1a();
}
9.4、ADSP-BF531复位
void adsp532_rst(void)
{
int i;
adsp_rst(0);
for(i=0;i<50;i++)
{
delay2a();
delay2a();
delay2a();
delay2a();
delay2a();
}
adsp_rst(1);
}
9.4、发送字节函数
void spi_send_byte(unsigned char val)
{
unsigned char i,temp;
temp=val;
npcs(1);
spck(0);
mosi(1);
for(i=0;i<8;i++)
{
delay();
}
npcs(0);
delay();
for(i=0;i<8;i++)
{
if(temp&0x80)
{
mosi(1);
}
else
{
mosi(0);
}
temp=temp<<1;
delay1a();
spck(1);
delay();
spck(0);
delay();
}
spck(0);
npcs(0);
mosi(1);
for(i=0;i<8;i++)
{
delay();
}
spck(0);
mosi(1);
npcs(1);
}
9.5、ADSP程序代码数组
unsigned char adsp_code[]=
{
0x40,
0x00,
0x80,
0xFF,
0x04,
0x00,
0x00,
0x00,
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
0xE1,
0x00,
0x00,
0x4A,
0xE1,
0x80,
0x03,
0xA2,
0xE0,
0x02,
0x20,
0x00,
0x00,
0x10,
0x00,
};
9.6、ADSP引导
void boot_adsp532(void)
{
int len,i;
i=0;
len=sizeof(adsp_code);
spi_init();
delay();
adsp532_rst();
// boot_start();
while(i< P>
{
// while(hwait());
spi_send_byte(adsp_code[i++]);
}
boot_end();
}
9.7、主函数
int main(void)
{
AT91F_PIO_Init();
spi_init();
for (;;)
{
boot_adsp532();
delay();
delay();
delay();
}
}
9.8、用仿真器仿真AT91SAM9260后,运行到delay();时就可以看到ADSP531的LED闪烁,好爽,真的不容易
第十章 基于C工程SPI SLAVE BOO调试
1.第八章都是基于汇编程序的ADSP5.0++的工程,基于C工程SPI SLAVE BOO调试,作者花了一天的时间又搞定了!现整理如下:
说明:生成LDR时,在工程里不需要添加ldf配置文件,采用默认的
即可,如果添加了ldf文件,有可能spi slave boot加载不成功!
如工程 LED Blink(基于c)