切换到宽版
  • 6311阅读
  • 49回复

[C51]使用TAS1020制作的USB异步声卡(开源) [复制链接]

上一主题 下一主题
离线rush
 

发帖
3953
M币
8583
专家
65
粉丝
260
— 本帖被 青柠 设置为精华,作者+3000M币+5专家(2018-11-22) —
很久以前尝试使用STM32实现USB异步设计,最后搞不清反馈量计算,烂尾了。。。时隔多年RUSH并没有放弃这个项目!最近,经过苦苦尝试终于猜出该如何计算异步反馈。RUSH可以大言不惭地说这是网上第一份写的最清楚的异步程序,就是希望大家知道原理,不要让JS仗着异步就把声卡卖的多贵,同时,会来单片机论坛的小伙伴都是理性的,让我们告别钱多人傻,认清音响玄学及非玄学问题。

敬告:阅读本文前确保你能看懂stm32官方那个最简单的USB声卡程序,否则以下内容都是外星文字。。。但我果然还是放心不下小白们,在文章开始之前,先简单的介绍下USB的些小常识。纯手打,就不要抄袭了好么

描述符:描述符就是USB设备向电脑的自我介绍,实质就像一段文本或者一个ini文件,例如一个串口自我介绍是(9600,N,1)这样的;但是介绍总归是“文本”不是程序,硬件怎么做完全又是另外代码负责了,介绍对不上硬件,那就别指望工作。。
端点:端点就可以理解成TCP那个端口,几乎就是同样概念,只不过USB端点都是单方向的,例如IN1和OUT1是完全独立的两个东西,IN端点指单片机IN到电脑,OUT端点是电脑OUT到单片机,都是以电脑的眼光去看来起名。上面说的描述符里面当然有指定各端点的用途,如果描述符里的端点号和单片机实际初始化端点号错误了,当然就不能正常工作。
SOF:帧开始start of frame,在usb1.1上,每1毫秒是一个传输周期,按照高低优先级传输数据。简单粗暴也可理解成总线上带有1ms时钟。
USB的四种传输方式:网上很多介绍,我这里吐槽一下,作为一个屌丝接口,USB传输方式要么是小带宽,高优先,带出错重发;要么是大带宽,高优先,不补发;总之没有一种适合实时承载音频带宽,又能出错重发的方式。所以,玄学线材在一定程度上确实能保护你那只有一次的音频数据报。
连续传输:USB连续传输(同步传输)是一种设计给固定大带宽的传输,数据包会在每个SOF开始时固定发走,这样音频就不要和你的U盘抢带宽,但是出错就不再补发了,屌丝接口不会考虑HIFI应用的,这也就给了线材供应商很大的商机。
USB异步音频:原创一张图解释异步音频,为什么异步=音质好


正文开始TAS1020是Ti公司的一款古老51单片机,2000年的东西,出生已经有18年了。内部其实就是两部分拼接的,有一个8052单片机内核,配置不高,比我们常用STC是差多了,在他片外XRAM空间挂了一些USB音频相关外设,这两部分装到同一个硅片里面构成一个新玩意,51基本是大家必学的,开发简单了,想想也是很有意思的一件事。因为总线已经被占用所以这个单片机的P0,P2口就没有了,暴露在外的有P1P3口还有USB及I2S接口。


为啥选择TAS这个玩意呢,除了以前抄音响板研究时候经常遇到它耳濡目染之外,还有很多优势,他有一份大家最喜欢的“拿来就响”的SDK,“改改就能用啊”(自适应模式,AC97,实践证明拿来才不会响)。其内部的DMA可以完全自主控制音频流,将内存作为FIFO管理,毕竟本来就是做这个用的,毛病少,不像stm32很喜欢立ERROR FLAG,大事小事都给你原地停机。支持USB的51单片机也是51单片机,51单片机该怎么写他也怎么写,没什么难度。这种大程序不可能从0起步,以下程序均由ti的SDK改造而成,开发环境需要严格用KEIL uv2,不要用新版本,避免对中断程序添油加醋,导致异常。USB异步音频传输,主要需要2个同步端点:   1.同步IN端点,该端点负责实时反馈设备的速度(可以理解为传快传慢)。这个反馈值以USB上的SOF为参考,代表每一帧需要消耗的数据量,在USB全速设备中(full speed),该值以10.10的格式放在3byte中(对齐MSB),这前后各10位分别代表实际消耗速度的整数和小数部分。   2.同步OUT端点,音频数据流就在这个端点上传输,每一帧(Frame)都会有数据传过来。以上是USB规范对异步的规定,按照上面的说明,我们目前那个自适应方式的SDK有几个地方需要改的1是让他响起来。这不是废话,因为这个SDK拿来不响;2是要修改声卡的描述符,初步告诉电脑我是一个异步声卡;3是建立反馈端点,算出10.10格式的数值,怎么发到电脑;4是控制反馈算法,USB手册上面的反馈框架坑死人了;1是让他响起来由于原来的SDK是AC97的,AC97是双向通信,没有真实芯片的话某些while(1)会锁死。我们要删掉这些东西改为I2S。然后需要精简垃圾代码,满足我们的洁癖和强迫症,具体需要修改的部分全部都在codec.c里面,大家可以看下面的文件对比,想自己动手的朋友可以参考,伸手党直接拿开源代码。


那些带着While的内容都必须删掉,删掉这些内容后SDK可以在外面啥都没有的情况跑起来,不会初始化失败了2是要修改声卡的描述符,告诉电脑我是一个异步声卡改描述符在以前鸽子掉的帖子里面也有,描述符这个东西。。改多了就会,需要注意的是描述符里有个参数就是“自己的长度”(字节数),这个要记得一起改


USB开发调试,有个软件非常重要:USBlyzer堪称抓包神器,完美PJ,完全支持x64,值得你拥有。


首先我们就要用到描述符查看功能很多同学会说“usbTreeViewer”也行,其实不然,“USBTreeView”在描述符错误的情况下根本看不到描述符,这个软件则因为带有底层驱动,可以从底层直接看到错误的描述符,还能给你红色提示,方便不止一点点啊比如:


多一个反馈端点,我忘记改成2了 像这样的描述符问题,往往导致windows“启动该设备失败”,按Windows的尿性就没有靠谱的错误代码,其实硬件没有问题。就是描述符有问题而已。如果使用USBlyzer就可以明确提示问题。3是建立反馈端点,那个10.10格式的数值怎么算出来,怎么发到电脑google出来大部分文章都会跟你讲反馈值fbvalue=(nInt<<14) + (nFrac<<4);实际上,现实是这样的//例如采样率44100HZ,USB传输间隙是1mS,每间隙数据包就是44.100个// 44.100数据包每秒 分成整数部分44 小数部分100// 反馈量10.10格式= 44 << 14 + 100 << 4      nInt=MclkPerMs/256;//整数部分   nFrac=(MclkPerMs- nInt*256)*1000/256;//小数部分      fbvalue= nInt;   fbvalue= fbvalue<< 14;   nFrac=nFrac<< 4;   fbvalue= nFrac |fbvalue;别忘了51单片机是8位的     INEP2_X[0]=fbvalue& 0xff;   INEP2_X[1]=(fbvalue>>8)& 0xff;   INEP2_X[2]=(fbvalue>>16)& 0xff;4是控制反馈算法,手册上面的反馈框架坑死人了

下图是对USB异步音频反馈机制的简单理解(错误的)


我们可以写出以下程序,测量这个“帧每秒”的参数发回PC


但是这样出来的是断断续续的声音,这时候就需要抓包神器出场啦
这是上面那一份程序算出来的值,什么都有:





这里对比了某个异步声卡:





看过对比我就怀疑手册的描述我理解有误,这个反馈不能做实时反馈,而是针对缓冲容量做判断,结合网上一段话:实现异步传输,需要通过固件实时控制USB口传输速率来完成,保证缓存不会溢出或断流。说明我本身理解存在偏差。总体上研究别人的反馈,大概就是快/中/慢3档,控制电脑过来的数据流,当然了这样也不容易做到异步变速播放(其实毫无意义。。。)实际使用的反馈程序如下,是不是感觉智商受到了打击。。。



强迫症楼主后来对这个问题进行了深究,原因见下图,具体有两个原因1是USB并不能每个周期精确控制数据量,传输每1ms进行一次,反馈调节则是至少每16ms进行一次2是windows就像你那贪心的父母,总想多喂你几口饭(并不是严格按照你提供的数据量给你包数,总会多给一两个的),直到你呛到了都不知道这些理由使得你无法精确要求下一个周期要拿到多少多少个具体数量的数据包,但是如果是使用前面那种快/中/慢3档的逻辑,还真就能简单粗暴控制住缓存在一个合理的范围内。



折腾完这个程序楼主感觉身体被掏空,赶紧让我听一会儿音乐压压惊最后是硬件


原理图


最后。。。
大家可以先评个分,再伸手拿程序吗?


使用源码请做好继续开源,谢谢
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共51条打赏M币+694专家+7
wjhwpp M币 +9 歡迎探討 12-03
llcc M币 +20 - 12-01
eros8269 M币 +13 謝謝分享 11-29
hongo 专家 +1 優秀文章,加砖家!STM32弄成了吗? 11-29
hongo M币 +20 優秀文章,加砖家!STM32弄成了吗? 11-29
hbozyq M币 +20 優秀文章 11-29
bhpnb002 M币 +15 優秀文章 11-28
zhujinliang M币 +15 優秀文章 11-28
nnbuchicao M币 +15 没看懂,凑热闹 11-28
李志路 M币 +8 看不懂,但是佩服楼主的精神 11-28

发帖
4667
M币
1144
专家
15
粉丝
96
只看该作者 1楼 发表于: 11-21
搞得太复杂了
离线ahyu99

发帖
2546
M币
5855
专家
5
粉丝
40
只看该作者 2楼 发表于: 11-21
这个写的相当不错,虽然我看的一脸蒙蔽。
离线金向维

发帖
5265
M币
1412
专家
111
粉丝
577
只看该作者 3楼 发表于: 11-21
虽然看不懂 觉得很厉害
离线renpeng009

发帖
300
M币
3238
专家
9
粉丝
39
只看该作者 4楼 发表于: 11-21
图文并茂,牛逼了
离线张大为

发帖
168
M币
-290
专家
1
粉丝
6
只看该作者 5楼 发表于: 11-21
楼主这板子在哪里买的?

楼主留言:

自己打样的

离线jsycwnw

发帖
10216
M币
26647
专家
387
粉丝
284
只看该作者 6楼 发表于: 11-21
認真發帖!高深的学问,看不懂也支持
离线2545889167

发帖
13044
M币
20330
专家
301
粉丝
4701
只看该作者 7楼 发表于: 11-22
好东西 这个必须支持你
离线2545889167

发帖
13044
M币
20330
专家
301
粉丝
4701
只看该作者 8楼 发表于: 11-22
这教程写的真的相当详细了 有点usb基础的 应该是包教会的了
p
离线widjrerpfnvd

发帖
1108
M币
2122
专家
9
粉丝
31
只看该作者 9楼 发表于: 11-22
不会精吗?楼主辛苦了

内容来自Android手机客户端