GR-SAKURA板的配置参数:
樱花板的外观及器件配置如下图所示:
(1)SAKURA板的硬件系统配置:
1) 支持流行开源的Arduino硬件相容的排针,即表示你可以使用种类繁多的现有外围转接板、电路板及开发应用程式。
2) 支持RX63N芯片的所有功能I/O,方便用户扩展。
3) 开发软件采用Renesas网站提供的Web编译器。
4) 外设支持局域网(LAN)、microSD及Xbee排针引脚。
5) 支持USB主机功能(Andriod-ADB/ADK),其是开发Android智能手机应用的软件。
6) 通过局域网(LAN)可以支持远程下载和升级。
其硬件配置如下表:
(2)SAKURA板的引脚分布及宏定义(Value与other name的对应关系)
(3)SAKURA开发板上4个LED和一个User开关的引脚对应表:
GR-SAKURA开发板程序局域网远程下载设想
Gadget Renesas SAKURA板(兼容Arduino) 以瑞萨RX63N系列32位单片机为基础。它有芯片上快闪记忆体和增强通信功能,包括以太网控制器和USB2.0主机/功能。说到快闪记忆体大家或许认为这是一个很新鲜的事物(当我第一次看到这个词时,我也感觉是不是又有一个新的存储器诞生了?答案是否定的),不过随后我就对其进行了搜索发现在维基百科里是这么解释的:
快閃記憶體(英語:Flash Memory),中國大陸簡稱為閃存,是一種電子清除式可程式唯讀記憶體的形式,允許在操作中被多次擦或寫的記憶體。
这里之所以采用繁体形式,是因为只有在台湾那边才这么称呼,在大陆大家一般称之为:快闪存储器(英语:Flash Memory),简称闪存。
说到这里大家或许都已明白,RX63N芯片里集成的存储程序的存储器的类型了,大家还记得RX63N芯片上提供增强型的通信功能,其中就有以太网控制器和USB2.0控制器,同时Rx63N又支持JTAG调试和编程。平时大家所见的U盘其内部也是Flash Memory结构的,说到这里大家也许会有所明白,是的,本次开发板上的RX63N芯片上的Flash存储器是支持USB大容量存储模式进行编程的,换句话说,RX63N的片上存储器通过USB连接到PC机上后,其Flash在PC机上是可见的驱动器,编程就如同向优盘里拖放文件一样方便。
既然,RX63N能通过增强通信功能之一:USB2.0控制器进行编程,那么显然,RX63N也能支持通过增强通信功能之二:以太网控制器来对其内部的Flash进行编程,这也许就是传说中的“通过局域网 (LAN)(有线及无线)远程下载软件及进行覆写”功能。看到论坛里有许多大虾们都成功实现了局域网通信,我猜想能否在此基础上做一些稍稍的扩展,从而实现通过LAN来传输程序文件(.bin)至RX63N的片上Flash里,实现通过局域网 (LAN)(有线及无线)远程下载软件及进行覆写的功能。
期待中。。。
TEthernet库的库函数:
函数1:static unsigned long getVersion(version_info *vi);
功能概要:依据vi指针返回TEthernet库的版本信息,
例如:1.00版本就返回:0x01000000
1.23版本就返回:0x010203
也即将版本号去掉点后,以16进制的形式返回。
函数2:static void processPackets();
功能概要:该函数要放在主函数中不断地循环执行,以确定是否有需要接收的数据包,同时也能够接收是否有错误发生,该函数依据接收到的数据内容而不断被执行(这句话的意思是说:当有错误发生时,通过该函数的执行,系统会给出报错警告。
函数3:void setHostname (const char * myhostname);
功能概要:该函数设置当SAKURA开发板作为主机时的主机名,例如,默认设置为“GR-SAKURA”。
函数4:int begin (byte mac [6]);
功能概要:仅依据MAC地址来启动Ethernet库的使用,成功返回1,失败返回0。
函数5: void begin (byte mac [6], byte ip [4]);
函数6:void begin (byte mac [6], byte ip [4], byte dns [4]);
函数7: void begin (byte mac [6], byte ip [4], byte dns [4], byte gateway [4]);
函数8: void begin (byte mac [6], byte ip [4], byte dns [4], byte gateway [4], byte subnet [4]);
功能概要:其它都类似,这里只对函数8作简要说明,依据MAC地址、IP地址、DNS域名解析、网关、子网掩码来启动Ethernet库的使用,成功返回1,失败返回0。
函数9:char * localIP ();
功能概要:返回本地IP地址。
函数10:bool isLinkup ();
功能概要:Ethernet是否已经连接上,成功返回true,失败返回false。
函数11:bool Ping (const char * hostname);
功能概要:尝试连接某一网址,成功返回true,失败返回false。
函数12:bool Ping (byte ip [4]);
功能概要:尝试连接某一主机名,成功返回true,失败返回false。
函数13:byte * gethostbyname (const char * hostname);
功能概要:进入DNS域名解析器,依据用户名返回Host的IP地址,成功返回一组IP地址,失败返回0.0.0.0,返回IP地址的格式是4字节的序列。
函数14:bool dhcp (void);
功能概要:通过获得的IP地址、DNS、Gateway网关来运行动态主机配置协议,成功返回true,失败返回false。该命令旨在检测Host端的网络参数是否正确获取和配置。
函数15:bool sendUDP (byte ipaddr [4], unsigned short dest_port, byte * buf, int len);
功能概要:向目标进程发送一个UDP包,成功返回true,失败返回false。
函数16: void registUdpHandler (UDP_HANDLE_FUNC func);
功能概要:当接收到一个UDP包后,准备调用某一函数func,该函数旨在获取当前接收到的UDP包的句柄,并对该包执行某一操作。
至此,TEthernet中的库函数罗列完毕。。。
SPI通信测试成功
今天晚上对我来说注定又是一个不眠的夜晚,这种感觉曾在上次的RL78/G13单片机中LCD液晶屏显示的实验中体会到----经过许多天的纠结和失望之后成功的喜悦,这种喜悦难于表达而又发自内心。
俗话说:人逢喜事精神爽,精神爽思路就清晰(后半句是我杜撰的,嘿嘿!),为什么这么说呢?是这样的,今天中午接到韵达快递的电话说是有我的快递在学苑门口,可我当时正在公司实现,不在学校,就让我同学给我代领了快递。直到晚上回宿舍才拿到快递,在这之前一直猜测是不是我的证书到了,不过也纳闷,老王一贯习惯用优速啊,怎么这次变了呢,所以我一直还不太确定,这时,可怜的我还在拼命地调试我的SPI程序,我也曾怀疑过是不是我板子的毛病,但是我还是不停地调试着,当同学把快递送来时(晚上他才从实验室回来的),我拿到后打开一看竞然真的是我的荣誉证书,当时心里别提有多高兴了,室友也挺羡慕我的,证书我还拍了照,在这里秀一下:
就在这高兴之际我还没有忘记调试我的程序,忽然脑子一亮有一个想法浮现在我的脑海:
曾经在书上看到过,对于SPI通信的SS引脚使用时一定要特别注意,记得做Master时一定要先将SS引脚对应的I/O口设置为输出模式,否则SPI会认为其是工作在slave模式下的,带着这个想法我就将pinMode(10,OUTPUT);(板子上的10引脚对应的就是SS引脚)指令放在了SPI.begin();函数的前面,这个顺序至关重要假如顺序放翻的话是无效的,同时也要注意这个顺序:就是SPI.begin();函数一定要放在所有SPI配置函数的前面,如:
SPI.port=SPI_PORT_CS0_DUINO;
SPI.setBitOrder(MSBFIRST);
SPI.setBitLength(32);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.setDataMode(SPI_MODE0);
否则配置函数的功能同样是无效的,到这里经过无数次的调试我才算明白,对于开源的Arduino编程而言,难的不在于对各个函数功能的理解,而在于通过调试来理解各个函数工作的相互关系(因为,USER在这里是看不到函数的底层驱动的,所以只有采用黑盒测试法喽,嘿嘿!),只有这样才能使程序正常的工作。
这里总结一下,对于SPI通信程序,SPI类各函数的顺序应该是这样的:
SS的I/O口类型设置函数,设置为:OUTPUT类型,具体函数如下:
pinMode(10,OUTPUT);
紧接着是启动SPI类库,这点是很值得注意的,因为它和我们平时的思维是相反的,具体的函数如下:
SPI.begin();
接下来当然是对SPI的配置函数了,由于这些配置在函数的功能中都有详细的介绍,再说针对SPI控制对象的不同,SPI的配置参数也是不一样的,所以,这里就不过多解释了,具体的函数如下:
SPI.port=SPI_PORT_CS0_DUINO;
SPI.setBitOrder(MSBFIRST);
SPI.setBitLength(32);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.setDataMode(SPI_MODE0);
为了给大家一个系统的概念,这里给出本次测试的整个主程序,如下所示:
#include <rxduino.h>
#include <spi.h>
unsigned long res;
void setup(){
pinMode(PIN_LED0,OUTPUT);
pinMode(10,OUTPUT);
SPI.begin();
Serial.begin(9600); //set baudrate 9600bps
SPI.port=SPI_PORT_CS0_DUINO;
SPI.setBitOrder(MSBFIRST);
SPI.setBitLength(32);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.setDataMode(SPI_MODE0);
Serial.println("Please send SPI command!");
}
void loop()
{
digitalWrite(PIN_LED0,1); //set led0 on
while(!Serial.available()); //wait command from upper computer
char c=Serial.read();
if(c=='r') //if receive command 'r'
{
res = SPI.transfer(50331648); //0000 0011 0000 0000 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(50397184); //0000 0011 0000 0001 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(50462720); //0000 0011 0000 0010 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(50528256); //0000 0011 0000 0011 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(50593792); //0000 0011 0000 0100 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(50659328); //0000 0011 0000 0101 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(50724864); //0000 0011 0000 0110 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(50790400); //0000 0011 0000 0111 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(50855936); //0000 0011 0000 1000 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(50921472); //0000 0011 0000 1001 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(50987008); //0000 0011 0000 1010 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(51052544); //0000 0011 0000 1011 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(51118080); //0000 0011 0000 1100 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(51183616); //0000 0011 0000 1101 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(51249152); //0000 0011 0000 1110 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
res = SPI.transfer(51314688); //0000 0011 0000 1111 0000 0000 0000 0000
Serial.println(res, BIN); //output the result in BIN
delay(500);
}
else
{
Serial.println("Please send the right SPI command!");
}
digitalWrite(PIN_LED0,0); //turn off the led0
}
对了,在编译前别忘了把SPI类库加上喽(这个不用我说大家也都明白,嘿嘿!)。
好了,下面就开始上图吧:
先来张系统搭载图(杜邦线貌似有点乱喽!):
通过串口将GR-SAKURA开发板通过SPI总线从VS1053B内部寄存器中读取的数据传到串口调试助手上来,来验证试验结果,得到的返回的数据如下图所示:
未完待续。。。
下面发上来一份VS1053B的内部寄存器初始化值表,如下表所示:
显然,经过对比可以发现,寄存器0的值是很好的吻合的,接着看寄存器1和寄存器5是不是发现这些数据有些不符合初试化后的值,现在首先来看寄存器1:SCI_STATUS引脚,其各位的功能如下表所示:
可以看到第7位是版本号,这正是在新版改版后而datasheet没有作相应改变的结果,至于2、3位为何测试均为0,而datasheet中确为1,这也完全是复位模式下电源配置的问题,完全不影响VS1053B的使用,所以,寄存器1测试结果没问题。
接着看寄存器5,大家还记得我前几天的SOS SPI问题求救吗,对了,就是在那次作调试时误写进去的,1111101000000看上去是不是可像读写代码的形式,这就对了,有可能这些寄存器是有记忆性质的,因为我在调试过程中就用到了这两个寄存器,结果就两个寄存器的变量值出现了不同,好了,经过以上的分析SPI驱动宣布测试成功,工程未完待续。。。
最后,来个动态的视频看看:
在这里还要对瑞萨小鱼等热心EEPW友以及我的“天籁齐舞”的“战友”们(一场无硝烟的战斗,嘿嘿!)表示衷心的感谢!
好了,夜已深了,不过还是希望大家能先休息好,才能工作和学习好,不要想我一样熬夜(嘿嘿,我也不是经常熬夜的哦!)。
【语音平台开发进程】:VS1053B内部寄存器的功能和配置
在天籁齐舞的团队合作和EEPW的大虾们的帮助下,语音平台开发进展顺利,在实现SAKURA开发板对VS1053B内部寄存器SPI读写之后,需要了解这些寄存器的功能以及如何在程序中去实现这些功能和这些寄存器都是如何配置的等等,为此我和我的天籁齐舞团队整理出《关于对VS1053B内部寄存器的设置》一帖,发在SAKURA论坛里,链接地址如下:
http://forum.eepw.com.cn/thread/223166/1
希望大家一起,共同学习,共同进步,欢迎提出宝贵意见和建议哦
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |