基于STM32F4和CPLD的高品質(zhì)立體聲USB數(shù)字音頻接口設(shè)計(jì)
引言
在高品質(zhì)音頻回放系統(tǒng)中,USB協(xié)議[1]被廣泛應(yīng)用于音頻數(shù)據(jù)的傳輸。目前高品質(zhì)音頻設(shè)備大多基于USB Audio Devices Class(以下簡(jiǎn)稱ADC)2.0規(guī)范[2]開發(fā)USB音頻接口。當(dāng)前較為常見的USB音頻接口方案的核心芯片有如下以下幾種選擇:1、專用USB音頻接口芯片;2、XMOS系列芯片;3、帶有USB2.0模塊的通用單片機(jī);4、FPGA芯片。從產(chǎn)品成本和生命周期考慮,產(chǎn)品方案中核心芯片應(yīng)該選擇市場(chǎng)上占有率大產(chǎn)品線成熟產(chǎn)品支持完善且價(jià)格相對(duì)低廉的型號(hào)。專用芯片底層不透明適用范圍窄難以根據(jù)需求進(jìn)行個(gè)性化開發(fā),XMOS芯片產(chǎn)品支持較少開發(fā)文檔不豐富,F(xiàn)PGA芯片開發(fā)難度和成本較高。通用單片機(jī)是一個(gè)較好的選擇,但通用單片機(jī)的數(shù)字音頻輸出功能通常較薄弱需要對(duì)其進(jìn)行一定的擴(kuò)充。本文基于市場(chǎng)上應(yīng)用廣泛的STM32F4芯片和CPLD芯片設(shè)計(jì)了一款高性能USB數(shù)字音頻接口。
本文所設(shè)計(jì)音頻接口指標(biāo)和特性如下:
1)支持的音頻數(shù)據(jù)流格式:16bit PCM、32bit PCM、DoP(DSD Audio over PCM Frames)、NativeDSD;
2)支持的最高數(shù)據(jù)規(guī)格:384kHz PCM、DSD256;
3)輸出接口規(guī)范:I2S、DSD;
4)異步反饋模式,主機(jī)時(shí)鐘與設(shè)備時(shí)鐘完全解耦,數(shù)字輸出信號(hào)質(zhì)量可控;
5)適配Windows、Linux系統(tǒng)原生ADC 2.0音頻驅(qū)動(dòng)。
1 基于ADC 2.0規(guī)范的立體聲音頻架構(gòu)設(shè)計(jì)
ADC 2.0規(guī)范相較于其1.0版本架構(gòu)更復(fù)雜包含的內(nèi)容更為豐富,也增加了開發(fā)的難度。ADC 2.0物理層面上基于USB 2.0協(xié)議,完全支持高速USB傳輸,帶寬不再受限。邏輯層面上,ADC 2.0規(guī)范為盡可能滿足不同的音頻數(shù)據(jù)傳輸需求,規(guī)定了一套較為復(fù)雜的抽象層邏輯。其中USB音頻功能通過定義完善的接口來實(shí)現(xiàn)與外部的連通。每個(gè)音頻功能都必須包含一個(gè)音頻控制接口和可選的音頻流接口。音頻控制接口用于訪問對(duì)應(yīng)的音頻功能,音頻流接口用于傳輸音頻數(shù)據(jù)。
為有效操地操作各種音頻功能,ADC規(guī)范將其分割為不同的實(shí)體,依據(jù)功能特征實(shí)體可分為三大類:?jiǎn)卧?、端口、時(shí)鐘。音頻設(shè)備通過設(shè)備描述符定義音頻控制接口、音頻流接口和功能實(shí)體并將其從邏輯上串接在一起向主機(jī)描述設(shè)備所能實(shí)現(xiàn)的邏輯行為。
基于ADC2.0規(guī)范設(shè)計(jì)功能架構(gòu)如圖1所示。
1)Audio Streaming Interface定義了主機(jī)到設(shè)備的數(shù)據(jù)傳輸接口。該接口有3個(gè)備選接口設(shè)置分別用于傳輸32bit PCM、16bit PCM和NativeDSD數(shù)據(jù)。
2)Audio Control Interface定義了主機(jī)到設(shè)備的控制接口,該接口下包含了用于傳輸音頻數(shù)據(jù)和實(shí)現(xiàn)部分功能的實(shí)體,主機(jī)通過設(shè)備請(qǐng)求來訪問不同實(shí)體的具體功能。ID1是input terminal用于接收USB數(shù)據(jù)流也定義了輸出聲道的數(shù)量;ID2是output terminal相當(dāng)于一個(gè)消耗USB數(shù)據(jù)的終端,主機(jī)一般需要結(jié)合audio streaming接口和端點(diǎn)描述符來確定此終端的具體特征行為;ID3是feature unit使能了音量控制和靜音控制;ID4、ID5是clock source,用于描述時(shí)鐘特征;ID6是clock selector,用于選擇時(shí)鐘信號(hào)的連接方式。
依據(jù)ADC規(guī)范編寫設(shè)備的配置描述符即可定義此架構(gòu)的邏輯結(jié)構(gòu),主機(jī)通過獲取配置描述符來知曉設(shè)備所具有的接口和功能。需要注意的是ADC僅僅提供了一個(gè)完整的協(xié)議框架,本身并不實(shí)現(xiàn)任何具體功能,開發(fā)者遵循ADC規(guī)范開發(fā)設(shè)備和驅(qū)動(dòng)可提高產(chǎn)品和驅(qū)動(dòng)的通用性。
圖1 基于ADC 2.0規(guī)范的音頻接口邏輯架構(gòu)
2 基于STM32F4 的USB Audio Class設(shè)備設(shè)計(jì)
由于ADC2.0規(guī)范是基于USB2.0協(xié)議的[2],需要設(shè)備具有高速傳輸能力。STM32F4的高速USB OTG模塊沒有片上高速PHY,只有UPLI接口,因此需要外接USB UPLI芯片來實(shí)現(xiàn)高速USB功能。本設(shè)計(jì)采用了較為常用的USB3300芯片與STM32F4連接,STM32F4提供完整的UPLI協(xié)議硬件支持[3],只需要操作對(duì)應(yīng)的寄存器即可實(shí)現(xiàn)相應(yīng)的通信功能,不需要過多關(guān)注USB控制器具體底層的操作,大大降低了程序設(shè)計(jì)難度。
2.1 音頻數(shù)據(jù)傳輸和頻率反饋控制
依據(jù)ADC規(guī)范,設(shè)備需要使用等時(shí)端點(diǎn)來傳輸音頻數(shù)據(jù)。由于主機(jī)和設(shè)備的時(shí)鐘存在頻率誤差、相位誤差和相位抖動(dòng),為保證音頻數(shù)據(jù)傳輸?shù)耐暾B貫性,必須在主機(jī)和設(shè)備間建立一種同步機(jī)制。USB協(xié)議針對(duì)等時(shí)傳輸提供了三種同步方案[1],以設(shè)備角度來分析如下
1)將設(shè)備時(shí)鐘同步到主機(jī)SOF(幀起始)信號(hào)上;
2)設(shè)備根據(jù)主機(jī)發(fā)送數(shù)據(jù)的速率調(diào)整數(shù)據(jù)消耗速率;
3)設(shè)備和主機(jī)獨(dú)立運(yùn)行在自己的時(shí)鐘上,設(shè)備提供時(shí)鐘速度的顯式反饋。
方案1)音頻回放質(zhì)量依賴于主機(jī)時(shí)鐘質(zhì)量和頻率跟蹤誤差,方案2)設(shè)備為保持同步必須在軟件里動(dòng)態(tài)調(diào)節(jié)回放頻率直接造成失真。只有方案3)才能完全消除主機(jī)和設(shè)備間的時(shí)鐘耦合,這是高品質(zhì)回放的必要條件。
在一般音頻驅(qū)動(dòng)程序中,主機(jī)使用EP1 OUT端點(diǎn)來傳輸音頻數(shù)據(jù),使用EP1 IN端點(diǎn)來進(jìn)行傳輸頻率的反饋。當(dāng)播放開始后,主機(jī)每個(gè)微幀都會(huì)向EP1發(fā)送音頻數(shù)據(jù),主機(jī)每4微幀向EP1請(qǐng)求一次4字節(jié)的IN傳輸。IN傳輸返回的數(shù)據(jù)是一個(gè)頻率參數(shù),主機(jī)根據(jù)此參數(shù)動(dòng)態(tài)地調(diào)整每個(gè)微幀發(fā)送的數(shù)據(jù)幀數(shù)量從而調(diào)節(jié)數(shù)據(jù)發(fā)送速率。
由于主機(jī)和設(shè)備獨(dú)立運(yùn)行在各自的時(shí)鐘源上,因此主機(jī)發(fā)送數(shù)據(jù)頻率和設(shè)備消耗數(shù)據(jù)頻率不可能完全一致,如果不進(jìn)行處理會(huì)出現(xiàn)數(shù)據(jù)溢出和丟失問題。解決方案是在設(shè)備程序中設(shè)計(jì)一個(gè)緩沖區(qū)暫存數(shù)據(jù),根據(jù)緩沖區(qū)長(zhǎng)度向主機(jī)發(fā)送需要的數(shù)據(jù)速率來進(jìn)行滯環(huán)控制,從而實(shí)現(xiàn)對(duì)緩沖區(qū)數(shù)據(jù)長(zhǎng)度的跟蹤。環(huán)寬和跟蹤目標(biāo)的選擇需結(jié)合主機(jī)和設(shè)備時(shí)鐘的最大可能誤差以及控制芯片允許的存儲(chǔ)空間來確定。依據(jù)USB 2.0協(xié)議,高速傳輸?shù)谋忍芈示葢?yīng)控制在500ppm(0.05%)以內(nèi),設(shè)環(huán)寬為,數(shù)據(jù)速率為則。
因主機(jī)傳輸數(shù)據(jù)以微幀為單位,設(shè)每個(gè)微幀內(nèi)可能傳輸?shù)淖畲髷?shù)據(jù)量為字節(jié),為防止數(shù)據(jù)上溢或下溢,追蹤數(shù)據(jù)長(zhǎng)度應(yīng)大于。
2.2 音頻輸出接口與STM32F4間的通信實(shí)現(xiàn)
由于STM32F4芯片自身音頻接口功能有限,且不能直接輸出DSD信號(hào),所以只能考慮駁接外部芯片來實(shí)現(xiàn)設(shè)計(jì)目標(biāo)。這部分功能主要是完成音頻信號(hào)時(shí)序輸出,因此選用CPLD芯片較為合理。
從主機(jī)接收的USB音頻數(shù)據(jù)在STM32F4芯片中處理后輸出到CPLD芯片,二者之間需要一個(gè)傳輸?shù)耐ǖ馈1驹O(shè)計(jì)最高數(shù)據(jù)規(guī)格是PCM 32bit/384kHz,計(jì)算可得數(shù)據(jù)帶寬為24.576Mbit/s,由參考手冊(cè)[3]可知SPI1通道與高速USB接口復(fù)用無法使用其SPI功能,而其它SPI通道最高速率為21Mbit/s無法滿足設(shè)計(jì)要求。因此需用并行傳輸來提高接口帶寬,由于音頻數(shù)據(jù)量大且對(duì)實(shí)時(shí)性要求很高,不宜直接通過操作IO口來輸出數(shù)據(jù),考慮使用STM32的DMA功能來實(shí)現(xiàn)并行傳輸。
得益于STM32F4的DMA IP核基于多層總線矩陣的設(shè)計(jì),可以利用DMA和GPIO端口進(jìn)行并行同步傳輸,其本質(zhì)原理是利用某種觸發(fā)機(jī)制實(shí)現(xiàn)數(shù)據(jù)從SRAM到GPIO的DMA傳輸[4]。
1)DMA控制器選擇
STM32F4片上集成2個(gè)DMA IP。每個(gè)DMA各有一個(gè)存儲(chǔ)器端口和一個(gè)外設(shè)端口。利用外部總線矩陣和專用DMA路徑,不僅在DMA級(jí)兩個(gè)端口可以同時(shí)工作,還可以實(shí)現(xiàn)DMA和系統(tǒng)其它主設(shè)備同時(shí)工作。GPIO位于AHB1總線上,由參考手冊(cè)[3]可知STM32F4的DMA1的AHB外設(shè)端口沒有連接到總線矩陣,因此只有DMA2可實(shí)現(xiàn)從SRAM到AHB1外設(shè)的訪問。
2)觸發(fā)機(jī)制選擇
同步傳輸根據(jù)同步信號(hào)的提供者可將設(shè)備分為主從兩方。本文以STM32F4作為從設(shè)備,CLPD作為主設(shè)備進(jìn)行設(shè)計(jì)。CLPD向STM32發(fā)出同步信號(hào)來請(qǐng)求數(shù)據(jù),當(dāng)STM32接收到一個(gè)合法的觸發(fā)信號(hào)應(yīng)觸發(fā)一次DMA傳輸,將存儲(chǔ)器(源地址)上的數(shù)據(jù)由DMA控制器傳輸?shù)紾PIO(目標(biāo)地址)上。這里就需要一個(gè)外設(shè)來接收并處理外部觸發(fā)信號(hào)并產(chǎn)生DMA請(qǐng)求,顯然定時(shí)器模塊很適合完成這項(xiàng)工作。
由參考手冊(cè)[3]可知只有兩個(gè)高級(jí)控制定時(shí)器TIM1和TIM8可以產(chǎn)生DMA2的請(qǐng)求,但可產(chǎn)生DMA請(qǐng)求的事件比較豐富,本設(shè)計(jì)選擇了TRIG事件來觸發(fā)DMA請(qǐng)求。具體實(shí)現(xiàn)方法是將定時(shí)器設(shè)置為外部時(shí)鐘觸發(fā)模式,選擇一個(gè)GPIO端口x的上升沿觸發(fā)TRIG事件,每當(dāng)CPLD在端口x處產(chǎn)生一個(gè)上升沿信號(hào)即觸發(fā)DMA傳輸請(qǐng)求,數(shù)據(jù)從預(yù)設(shè)的地址傳輸?shù)紾PIO端口上,CPLD即可從相應(yīng)端口并行地讀入取此數(shù)據(jù)。
3)最大傳輸帶寬計(jì)算
此設(shè)計(jì)中影響STM32F4到CPLD傳輸帶寬的因素主要有DMA傳輸時(shí)間、定時(shí)器收入捕獲數(shù)字濾波時(shí)間和CPLD端口建立時(shí)間。由于CPLD端口建立時(shí)間較短,此處不予考慮。
本設(shè)計(jì)DMA設(shè)置是從存儲(chǔ)器傳輸數(shù)據(jù)到AHB外設(shè),使用突發(fā)傳輸,不需要進(jìn)行總線仲裁,則DMA數(shù)據(jù)流的總傳輸時(shí)間為:
TS=TSP+TSM
其中是DMA外設(shè)端口訪問和傳輸?shù)目倳r(shí)間,TSM是DMA存儲(chǔ)器端口訪問和傳輸?shù)目倳r(shí)間。依據(jù)參考文獻(xiàn)[5]計(jì)算可得,最壞情況下DMA傳輸時(shí)間為8個(gè)AHB周期。
定時(shí)器輸入捕獲數(shù)字濾波器是為了消除干擾引起的誤觸發(fā),數(shù)字濾波器由事件計(jì)數(shù)器組成,每N個(gè)事件才視為一個(gè)有效邊沿,將其設(shè)置為連續(xù)4個(gè)AHB周期。則從CPLD給出上升沿觸發(fā)信號(hào)到CPLD讀取到數(shù)據(jù)的延時(shí)為12個(gè)AHB周期。將AHB頻率設(shè)置為84MHz,在用8位GPIO口并行輸出的情況下,接口帶寬為:
可見傳輸帶寬完全滿足設(shè)計(jì)需要。若使用整組16位GPIO做輸出可降低芯片主時(shí)鐘頻率且為帶寬留出較大裕度,為設(shè)備功能升級(jí)留有裕量。
2.3 音頻信號(hào)的輸出
本設(shè)計(jì)中,PCM音頻信號(hào)輸出采用I2S接口,DSD音頻信號(hào)輸出由DSD時(shí)鐘信號(hào)和DSD左右聲道數(shù)據(jù)信號(hào)構(gòu)成[6]。
對(duì)于PCM數(shù)據(jù),主機(jī)傳入設(shè)備的數(shù)據(jù)是低字節(jié)在前高字節(jié)在后,而I2S協(xié)議是從數(shù)據(jù)高字節(jié)開始串行輸出的;對(duì)于DSD數(shù)據(jù)而言主機(jī)整幀的傳入數(shù)據(jù)而在信號(hào)輸出端左右聲道卻是同時(shí)輸出的。因此設(shè)備需要對(duì)原始數(shù)據(jù)進(jìn)行重新組合處理。CPLD門資源較為有限,為降低片上資源的使用率和綜合布線難度,處理數(shù)據(jù)的工作全部由STM32芯片負(fù)責(zé)。CPLD依據(jù)前述設(shè)計(jì)方案從STM32緩沖區(qū)依次并行讀取數(shù)據(jù)再將數(shù)據(jù)按各播放模式的時(shí)序邏輯串行輸出即可。
2.4 硬件連接框圖
設(shè)備的主要硬件連接框圖如圖2所示。STM32通過ULPI PHY芯片與主機(jī)通信,與CPLD相連接的信號(hào)中CMD為控制信號(hào),本設(shè)計(jì)使用SPI總線向CPLD發(fā)送控制指令。RDY為程序通知CLPD可以進(jìn)行數(shù)據(jù)請(qǐng)求的信號(hào)。REQ為CPLD向STM32發(fā)送的數(shù)據(jù)請(qǐng)求信號(hào),此信號(hào)即用于觸發(fā)DMA請(qǐng)求。DATA為并行的數(shù)據(jù)信號(hào)。CPLD向外輸出I2S和DSD時(shí)序信號(hào),外部控制芯片可通過AUX接口來讀取設(shè)備的相關(guān)狀態(tài)。
主機(jī)時(shí)鐘源1和負(fù)責(zé)提供回放時(shí)鐘的時(shí)鐘源2相互獨(dú)立,因此時(shí)鐘源2可以選用低相位噪聲的時(shí)鐘來提升音頻回放質(zhì)量。
圖2 硬件連接框圖
3 應(yīng)用程序框架
由于基于上述設(shè)計(jì)方案的軟件實(shí)現(xiàn)方案非常靈活,部分技術(shù)雖為通用技術(shù)但細(xì)節(jié)又較為繁瑣,本節(jié)僅對(duì)一種可行性方案概括性說明。
此方案主要由三個(gè)模塊構(gòu)成:USB底層通信程序、Setup傳輸處理程序、播放處理程序。具體功能使用了三個(gè)狀態(tài)機(jī)實(shí)現(xiàn),由于USB通信程序中包含了硬件中斷,三個(gè)狀態(tài)機(jī)之間的通信由消息隊(duì)列來實(shí)現(xiàn)異步通信。此處不對(duì)USB底層通信和Setup傳輸處理程序進(jìn)行贅述,重點(diǎn)對(duì)播放處理的狀態(tài)機(jī)設(shè)計(jì)進(jìn)行說明。
基于上述原理設(shè)計(jì)的播放處理狀態(tài)機(jī)的UML狀態(tài)圖如圖3所示,整個(gè)播放過程在播放監(jiān)控狀態(tài)中運(yùn)行,在PlayGuard_IDLE狀態(tài)中程序接收相關(guān)的參數(shù)設(shè)置信號(hào)為播放做準(zhǔn)備。PlayGuard_PLAYING是一個(gè)組合狀態(tài),其自身負(fù)責(zé)與USB底層模塊通信進(jìn)行數(shù)據(jù)傳輸,其子狀態(tài)負(fù)責(zé)處理特定播放模式。
音頻數(shù)據(jù)的流轉(zhuǎn)是程序的核心算法。音頻數(shù)據(jù)通過OUT傳輸寫入程序緩沖區(qū),數(shù)據(jù)由播放子狀態(tài)處理并寫入FIFO中。程序?qū)MA傳輸設(shè)置為雙緩沖模式,在DMA完成事件中從FIFO讀出一組數(shù)據(jù)對(duì)雙緩沖區(qū)進(jìn)行交替填充。在IN傳輸完成事件中計(jì)算當(dāng)前FIFO區(qū)數(shù)據(jù)長(zhǎng)度據(jù)此反饋數(shù)據(jù)傳輸率給主機(jī)完成對(duì)數(shù)據(jù)長(zhǎng)度的追蹤控制。
圖3 播放處理狀態(tài)圖
4 結(jié)語(yǔ)
基于上述設(shè)計(jì)制作了硬件實(shí)物如圖4,分別在Windows 10系統(tǒng)和Linux發(fā)行版下進(jìn)行測(cè)試實(shí)驗(yàn),接口板在系統(tǒng)原生驅(qū)動(dòng)下工作正常,可播放所支持規(guī)格的PCM音頻文件。在三方驅(qū)動(dòng)下可正常通過DoP模式或NativeDSD模式播放DSD音頻文件。播放自定義音頻文件并用邏輯分析采集輸出接口的數(shù)據(jù)與源文件對(duì)比,接口板完整無失真的還原了源文件的數(shù)據(jù)。在軟件開發(fā)平臺(tái)上對(duì)緩沖隊(duì)列進(jìn)行監(jiān)控,程序能較好的跟蹤隊(duì)列長(zhǎng)度的穩(wěn)定,無數(shù)據(jù)溢出現(xiàn)象。最后將接口板連接至解碼器上進(jìn)行試聽,主觀聽感良好。以上試驗(yàn)證明設(shè)計(jì)達(dá)到了預(yù)期指標(biāo)。
圖4 硬件實(shí)物圖
設(shè)計(jì)在以下方面還有進(jìn)一步研究改進(jìn)的空間:1、優(yōu)化播放時(shí)鐘設(shè)計(jì),進(jìn)一步降低回放失真;2、增加對(duì)更多聲道音頻格式的支持;3、增加數(shù)字音效的功能;4、增加Bootloader程序,實(shí)現(xiàn)主機(jī)對(duì)設(shè)備功能和參數(shù)的在線升級(jí)與修改。
參考文獻(xiàn):
[1] Universal Serial Bus Specification[EB/OL]. Revision 2.0, USB-IF,(2000-4-27)[2020-4-25].https://www.usb.org.
[2] Universal Serial Bus Device Class Definition for Audio Devices[EB/OL]. Release 2.0,USB-IF, (2006-5-31)[2020-4-25].https://www.usb.org.
[3] STM32F405/415, STM32F407/417, STM32F427/437 and STM32F429/439 advanced Arm?-based 32-bit MCUs Reference manual (RM0090)[EB/OL]. Rev 18, STMicroelectronics, (2019)[2020-4-25].https://www.st.com.
[4] Parallel synchronous transmission using GPIO and DMA(AN4666)[EB/OL]. Rev 1, STMicroelectronics, (2016)[2020-4-25].https://www.st.com.
[5] Using the STM32F2, STM32F4 and STM32F7 Series DMA controller(AN4031)[EB/OL]. Rev 3, STMicroelectronics, (2016)[2020-4-25].https://www.st.com.
[6] J. ROBERT STUART. Coding for High-Resolution Audio Systems[J]. Audio Eng. Soc., 2004,Vol. 52, No. 3:117-144.
(本文來源于《電子產(chǎn)品世界》雜志2020年10月期)
評(píng)論