2015年3月搬家感言

乙未羊年,网站搬家完成,由美帝服务器成功迁移到HK,貌似访问速度大有提升,也算是喜事一桩吧.

上次网站大变样,应该是五年前吧,当时刚毕业一年,也不知道是哪根筋搭牢,放弃了家乡的工作,独自来到大城市做一个屌丝(虽然在家乡也是屌丝,但大城市应该算超级屌丝),难道是因为年轻不懂事?估计是!大凡很多年轻人,都会犯此类错误吧.但生活没有后悔药,最重要的还是当下!这次搬家,想着网站是否应该改一改,也确实应该改一下了,但没有想好怎么改,就先这样吧,大凡也是内容上改,程序感觉挺好用,就先用着吧.也许会加一下电子以外的东西,突然感觉没那么喜欢电子了.可能是因现实太骨感了吧–同样是屌丝,待遇没有写软件(APP,游戏开发等)的高,工作岗位,也只有少数城市有.其实,电子最多也只能算本人的第二爱好,大概傻傻的执着下去,也只能一辈子是傻傻的屌丝吧,别人眼中的高科技,其实只是冷暖自知!

每一个孩子,都曾有梦想,只是曾经孩子们不知道现实的残酷而已,也不知道是哪一天,残酷的社会让我们淡淡的忘却了曾经的爱好,现实也许也只是出于好心,任由每一个孩子的梦想持续发芽,生根,落叶,那谁来做科学家,文学家,艺术家…以外的职业?故,社会会给每一个人安排职位,可能是喜欢的,但大多数都不是自己当初的爱好,这也是顾全大局.任何没有自己理想职业的孩子,也不必要郁闷,毕竟现在社会发展了,我们多多少少会有一点空闲,就把第一爱好纯粹当一个爱好吧,尽力而为之.

扯远了,总结一下,网站搬家,整理文章,想着改变,赞未想好如何改.

USB 键盘键值前两Byte说明(备忘)

使用USB键盘利用小键盘绕过输入法进行报键值时,如下数据:

08 00 15 00 00 00 00 00
与具体的键值相对应第一个字节是用来发送 左右的ctrl,shift,alt,win,8个按键01 L ctrl 10 R ctrl 
02 L shift 20 R shift
04 L alt 40 R alt 
08 L win 80 R win第二个byte是常量,写00就好普通键都是在后面6个byte填当HID report为keyboard时,在set report(wValue=02h)请求之后,OUT输出的一字节数据为键盘
上numlock、capslock、scrolllock三个灯的状态。当灯亮时,对应位为1。对应关系为:
numlock bit0
capslock bit1
scrolllock bit2 此文转自:http://www.xuebuyuan.com/218870.html

【转】strtol()详解

long int strtol(const char *nptr, char **endptr, int base)
strtol()会将nptr指向的字符串,根据参数base,按权转化为long int, 然后返回这个值。
参数base的范围为2~36,和0;它决定了字符串以被转换为整数的权值。
可以被转换的合法字符依据base而定,举例来说,当base为2时,合法字符为‘0’,‘1’;base为8时,合法字符为‘0’,‘1’,……‘7’;base为10时,合法字符为‘0’,‘1’,……‘9’;base 为16时,合法字符为‘0’,‘1’,……‘9’,‘a’,……‘f’;base为24时,合法字符为‘0’,……‘9’,‘a’,……‘n’,base为36时,合法字符为‘0’,……‘9’,‘a’,……‘z’;等等。其中,不区分大小写,比如,‘A’和‘a’会都会被转化为10。
当字符合法时,‘0’,……‘9’依次被转换为十进制的0~9,‘a’,……‘z’一次北转换为十进制的10~35。
strtol()函数检测到第一个非法字符时,立即停止检测,其后的所有字符都会被当作非法字符处理。合法字符串会被转换为long int, 作为函数的返回值。非法字符串,即从第一个非法字符的地址,被赋给*endptr。**endptr是个双重指针,即指针的指针。strtol()函数就是通过它改变*endptr的值,即把第一个非法字符的地址传给endptr。

多数情况下,endptr设置为NULL, 即不返回非法字符串。
下面看几个例子:
——————————————————
char buffer[20]=”10379cend$3″;
char *stop;
printf(“%d\n”,strtol(buffer, &stop, 2));
printf(“%s\n”, stop);
输出结果:
2
379cend$3
——————————————————-
char buffer[20]=”10379cend$3″;
char *stop;
printf(“%d\n”,strtol(buffer, &stop, 8));
printf(“%s\n”, stop);
输出结果:
543
9cend$3
——————————————————–
char buffer[20]=”10379cend$3″;
char *stop;
printf(“%d\n”,strtol(buffer, &stop, 10));
printf(“%s\n”, stop);
输出结果:
10379
cend$3
——————————————————-
char buffer[20]=”10379cend$3″;
char *stop;
printf(“%d\n”,strtol(buffer, &stop, 16));
printf(“%s\n”, stop);
输出结果:
17005006
nd$3

另外,如果base为0,且字符串不是以0x(或者0X)开头,则按十进制进行转化。如果base为0或者16,并且字符串以0x(或者0X)开头,那么,x(或者X)被忽略,字符串按16进制转化。如果base不等于0和16,并且字符串以0x(或者0X)开头,那么x被视为非法字符。 例如:
——————————————————-
char buffer[20]=”0x31da6c”;
char *stop;
printf(“%d\n”,strtol(buffer, &stop, 0));
printf(“%s\n”, stop);
输出结果(stop为空):
3267180

——————————————————-
char buffer[20]=”0x31da6c”;
char *stop;
printf(“%d\n”,strtol(buffer, &stop, 13));
printf(“%s\n”, stop);
输出结果:
0
0x31da6c
——————————————————-

最后,需要说明的是,对于nptr指向的字符串,其开头和结尾处的空格被忽视,字符串中间的空格被视为非法字符。
例如:
——————————————————-
char buffer_1[20]=”10379c”;
char buffer_2[20]=” 10379c “;
char buffer_3[20]=” 10 379c “;
printf(“%d\n”,strtol(buffer_1,NULL,0));
printf(“%d\n”,strtol(buffer_2,NULL,0));
printf(“%d\n”,strtol(buffer_3,NULL,0));
输出结果为:
10379
10379

10

转自:http://blog.sina.com.cn/s/blog_6c26d57b01012l0x.html

单端信号与差分信号(转)

早期的数字总线大部分使用单端信号做信号传输,如TTL/CMOS信号都是单端信号。所谓单端信号,是指用一根信号线的高低电平的变化来进行0、1信息的传输,这个电平的高低变化是相对于其公共的参考地平面的。单端信号由于结构简单,可以用简单的晶体管电路实现,而且集成度高、功耗低,因此在数字电路中得到最广泛的应用。下图是个单端信号的传输模型。

当信号传输速率更高时,为了减小信号的跳变时间和功耗,信号的幅度一般都会相应减小。比如以前大量使用的5V的TTL信号现在使用越来越少,更多使用的是3.3V/2.5V/1.8V/1.5V/1.2V的LVTTL电平,但是信号幅度减小带来的问题是对噪声的容忍能力会变差一些。进一步的,很多数字总线现在需要传输更长的距离,从原来芯片间的互连变成板卡间的互连甚至设备间的互连,信号穿过不同的设备时会受到更多噪声的干扰。更极端的情况是收发端的参考地平面可能也不是等电位的。因此,当信号速率变高、传输距离变长后仍然使用单端的方式进行信号传输会带来很大的问题。下图是个受到严重共模噪声干扰的单端信号,对于这种信号,无论接收端的电平判决阈值设置在哪里都有可能造成信号的误判。

差分信号
为了提高信号在高速率、长距离情况下传输的可靠性,大部分高速的数字串行总线都会采用差分信号进行信号传输。差分信号是用一对反相的差分线进行信号传输,发送端采用差分的发送器,接收端相应采用差分的接收器。下图是个差分线的传输模型及真实的差分PCB走线。

采用差分传输方式后,由于差分线对里正负信号的走线是紧密耦合在一起的,所以外界噪声对于两根信号线的影响是一样的。而在接收端,由于其接收器是把正负信号相减的结果做为逻辑判决的依据,因此即使信号线上有严重的共模噪声或者地电平的波动,对于最后的逻辑电平判决影响很小。相对于单端传输方式,差分传输方式的抗干扰、抗共模噪声能力大大提高。下图是一个差分传输对共模噪声抑制的一个例子。

采用差分方式进行信号传输会使得收发端的电路变得复杂,系统的功耗也随之上升,但是由于其优异的抗干扰能力以及可靠的传输特性,使得差分传输方式在需要进行高速数字信号的传输或者恶劣工作环境的领域得到了广泛的应用,如LVDS、PCI-E、SATA、USB、1394、CAN、Flexray等总线都是采用差分的信号传输方式。转自:http://www.cnblogs.com/AijunHe/p/6947620.html

[转]csr 蓝牙

sink与source的断开和连接  

sink与source的断开可以选择如下两种方式:


法1:
 StreamDisconnect(mic_source_a, spkr_sink_a);


法2:
 StreamDisconnect(0, spkr_sink_a);
 StreamDisconnect(mic_source_a, 0);


在test mode时,连接mic的source与音频输出的sink时,要先断开两者的连接,再重生连接。
如果没有先断开,则连续按两次进入mic的source与音频输出的sink,即线路的重复执行,会painc。

如果运行蓝牙的开发环境时发现panic,自动弹出运行到的汇编文件headset.xap,要判断出现panic的地方可以有以下两种方法:

判断出现panic位置的方法 
法1:可以根据汇编的大概标号判断。

如果是刚更改的地方造成的,涉及的标号不多,应该很容易判断出具体的位置。


法2:view\debug windows\call stack(vm-‘headset’),弹出的窗口有指示哪个函数出现panic。

Product ID & VendorID 

在usb的产品中,会遇到Product ID和VendorID,它们有些什么意义呢?笔者转载如下:

        根据USB 规范的规定,所有的USB设备都有供应商ID(VID )和产品识别码(PID ),主机通过不同的VID和PID来区别不同的设备,VID和PID都是两个字节长,其中,供应商ID(VID)由供应商向USB执行论坛申请,每个供应商的VID是唯一的,PID由供应商自行决定。

 VID和PID通常情况下有两种存储方式,第一种是主控生产商的VID和PID,存储在主控的bootcode中;第二种是设备生产商的VID和PID,该VID和PID存储在主控外部的非易失性存储设备中(EEPROM 或Flash )的设备固件中,当USB设备连接主机时,如果固件中有设备生产商的VID和PID,会将该VID和PID报告给主机,而忽略主控生产商的VID和PID。所以理论上一个USB存储设备的VID应该是设备生产商的VID,而不是主控生产商的VID,这两个VID应该是不同的(主控生产商自己生产的设备除外)。

 由于VID和PID重复并不会对产品的使用带来严重影响,很多USB设备生产商(山寨厂居多)为了方便,并不会向USB执行论坛申请自己的VID,而是依然沿用主控生产商的VID或随便向产品写入VID和PID;同时,正规厂家只需要申请VID ,PID由厂家自行确定 ,所以存在相同型号的产品,可能采用了不同的主控(商业需要,很正常),而他们的PID是一样的,基于上述原因通过VID和PID就不能准确识别USB设备的主控型号,这个问题大家在使用USB设备的过程中需要注意。

BC7充电设置  

BC7充电配置及注意事项:

一、使用configuration配置充电。

选择第一项charge的boost为Int Enable或Ext Enable。这两种充电方式的区别,在硬件上也有不同,后者会在CHG_EXT引脚外加三极管作充电电路,也为限制充电电流之用。VSL选项选择CHG。CURRENT选择适当的充电电流,最大为200(单位为MA)。TYPE可以选择为DEFAULT。

在默认的方式下,充电只需做这一步处理即可。

二、插入USB要不要重启。

当监测到USB插入时,要不要重启蓝牙,是可以通过PS KEY设置的。选择(0x25af)PSKEY_RESET_ON_CHARGER_ATTACH为FALSE时,监测到USB的上升沿,不会重启蓝牙。

三、PS KEY 的各个充电选择设置。

基本上PS KEY 的各个充电选项都可以通过PS TOOL以“CHARGE”来搜索到,选项也不多。在默认的方式下,这些设置并不起作用,仅用步骤一即可设置简单的充电参数。这些PS KEY的意义有,如充电电流、充电电压阀值、每步充电进步值……具体说明可参考充电文档。

蓝牙的codec输出有几种格式,视不同的蓝牙版本,支持的codec不同,codec有:SBC、MP3、AAC、APTX。其中,APTX是最为高级的一种格式,那么,如何设置呢?

 APTX设置  

1、与licence key对应的蓝牙地址;

2、写入licence key;

     这个ps key的地址会根据蓝牙开发版本的不同有所不同,如ADK1.1的在DSP20、SDK2010的在DSP28。

3、使用configuration开户APTX选项;

4、在project下打开a2dp_extra_codecs宏定义;

5、加入APTX插件(以属于project);

 函数体内表格容易panic  

特别要注意的是:

在ADK版本下,APTX的默认输出方式是analogue,所以,当采用I2S输出音频时,必须要修改库文件才有信号从I2S输出,否则没有声音。

对于蓝牙的编译环境,对于表格的处理是比较讲究的。之前提及过定义表格时,要使用const声明,把其存放在FLASH中,而不应存在RAM中,毕竟对于一个大型的project来讲,RAM的资源是有限的。经笔者验证,除了这一点之外,定义表格时,还有以下一个重要的特点:

如果过多的把表格定义在函数体内,很容易出现运行后panic的情况,如表格数据达到20bytes以上。解决的方法是,把其定义在函数体之外,以const的方式作为公共表格。

蓝牙BC7的音频输出可以选择analog或I2S输出。analog是输出最多的方式,因为其需要的外围电路比较简单,声音直接从蓝牙芯片出来即可以驱动耳塞,或经过耳塞类功放驱动电路,所以,音质不错的同时,成本最低。

 analog输出特性  

analog有哪些特性呢?多一点熟悉它,有助于调试蓝牙。

一、N、P的输出均压都在0.8V左右,音频波动范围约在200mv左右。

二、可以直接驱动耳塞。

        因为音量不会太大,所以,最好把手机音量调至最大。

三、当处接功放时,为了确定功放是否处于正常工作状态,可以先使用步骤二确定蓝牙一定有声音出来。一个简单检查功放是否

       正常的方法是:用手触摸功放的音频输入部分电路,如果有噪音输出到耳塞,一般可证明功放正常。

在调试更新蓝牙程式的时候,笔者以为有几点要注意的:

 使用USB-SPI烧录器更新程式不能开HOLD档  

一:使用USB-SPI烧录下载程式时,不能把拔动开关打到HOLD档。在HOLD档的情况下,从下载的状态及更新进度上看,不会发觉有任何的异常情况,但运行起来却发现没有更新程式。这种情况,很可能会误导USER花费大量时间去查找程式或PS KEY的原因,这是不必要的。

二:如果项目下有HEADSET.PSR,要注意每次改动PS KEY 后同步更新该文件。因为下载更新程式时,如果发现目录下有该文件,则会再次更新PS KEY。

三:更新程式前,要使蓝牙内部reguration开启。如果没有,手动按一下vreg即可。

三色灯中LED2的配置  

在前两编博文中,提到的关于HIGH 16 BIT KEY配置及引线干扰的问题中,在笔者的PCB板上再次印证,引线干扰的论点。所以,按键的时候,一定不能用手去捏着引线,当然相信产品是不会有这样的长引线让USER触摸到的。

有一些蓝牙IC只有两个LED灯显示,也有三个的或更多。在ADK版本中,有绿、蓝、红三种颜色的LED。利用CONFIGURATION配置三个LED的时候,可以很直观地看到选择LED0及LED1,但找不到LED2的配置,那么如何配置LED2呢?

在默认的方式下,选择了PIO10即为配置了LED2。透过程序上的SET LED程序,可以看到,控制这三个LED的部分有四个状态分支,分别是索引为15、14、10、ELSE。很明显,15与14就是对应的LED0和LED1,而中间相隔的三个NOUSED索引,自然,10就成了LED2的控制,ELSE则为其它IO的控制。

笔者以为,可以透过改动SET LED的程序(增加分支),同样把其它更多的LED得到有效的控制。而CONFIGURATION的选项,可以这样理解:在程式没有特别做分支处理的情况下,它代表的是实际IO的控制,也就是进入到ELSE的分支,否则它仅代表一个索引。

IPHONE上显示蓝牙产品电量  

如何在IPHONE上显示蓝牙产品电量?做法也很简单,只需要通过蓝牙向IPHONE发送AT命令,IPHONE就会在显示本身电量旁边多出一条BAR,用来显示蓝牙产品的电量。但这种命令要符合IPHONE的固有格式,把它做成数组字符串的形式即可,由于比较多,这里不作一一列出。

一:使用的是ADK版本时,发送函数为:
HfpAtCmdRequest(hfp_primary_link,battaryLevel);

二:使用的是SDK版本时,发送函数为:

hfp_link_data* link = hfpGetLinkFromPriority(priority);
hfpSendAtCmd1(link, strlen(battaryLevel1), battaryLevel);

high 16 bit key配置&引线干扰  

在前面讲述过的多个congiguration配置方法,如:key、led、usb、wired、speech、input/output。在key的配置这一块,笔者以为还应注意以下几点:

第一:high 16 bit IO。

如果线路设计上,如按键使用的是low16 bit,可以完全按之前提及的方法来实现,触摸也是一样,但当按键分配在high 16 bit时,还必须增加对应的mapping才可以。即:在input/output的页面下,PIO Mapping assigments hardware dependant对应的IO一定要打勾。当高电平触发按键时,pio invert mask bits不用勾任何IO。

第二点:注意开发板的引线测试。

如果开发板上,使用的是自行从IO接线出来,要特别注意干扰问题,如:按键时不要用手去触摸引线。因为,如果利用固有的按键检测方式加上2.4gRF影响,难免小量的干扰信号造成检测的不稳定。

Headset自动关机条件  

蓝牙headset自动关机的条件:
headset只有在LIMBO、CONNECTABLE、CONNDISCOVERABLE三种状态下,且在theHeadset.conf1-<timeouts.AutoSwitchOffTime_s时间还没有为0的时候,才自动关机power off。具体的时间由以上提到的register决定,它可通过configuration tool的times页面设置。

在handleUEMessage的开头部分,可以看到除了列出的事件外,只要有其它事件发出都会重新更新
theHeadset.conf1-<timeouts.AutoSwitchOffTime_s的自动关机时间。所以,自动关机的条件还应加上,没有任何触发更新自动关机时间的event发生

DFU模式  

蓝牙上的DFU模式是用来更新软件程式的,那么,如何进入DFU模式呢?主要有以下几个步骤:

第一步:用configuration tool配置相关的enter DFU event。

选择该event时,要注意的是其进入的状态,一般会在关机的状态下按多键组合。因为关机后,基本功能已失效,不影响操作;多键操作是为了防止过于简单进入DFU模式,而难以回到正常状态。

第二步:ps key文档的设置。

除了上面的配置外,有部分PS KEY是没可以通过configuration来完成的,可以通过手动把相关的设置放到文档的最后,另外还得把其中一值设置成0XFFFF。这里说得是大概,至于具体要设置的内容,由于参数较多,笔者认为也没必要完全把其记住。记录相关的步骤,即可方便以后的操作。

第三步:生成.DFU文件。

建立一个.bat文件,利用image.fs生成.dfu,具体方法已在前面的usb upgrade有详细说明。

第四步:更新程式。

通过DFUWizer工具一步步来更新软件,完成后自动退出DFU模式。

要注意的说明是:

1、退出DFU的方法:重新上电或更新完软件。

2、成功过入DFU模式后,能在电脑硬件处,看到多出一个列表csr dfu。

3、在没有屏蔽DFU函数的打印信息中,即使进入了DFU模式,也看不到打印的内容。在DEBUG模式下,要确定真的进入了DFU模 式,可以把DFU函数先屏蔽。

转自:http://blog.csdn.net/ge23456789/article/details/8089021