ULM300BOX項(xiàng)目

導(dǎo)語(yǔ):此主題為ULM300系列項(xiàng)目開(kāi)發(fā)中遇到的一些問(wèn)題以及它們的解決方式。

一,IA2E芯片無(wú)法直接輸出RSSI信號(hào)強(qiáng)度信息

  • IA2E芯片是一款2.4G頻段的無(wú)線音頻芯片,屬于10年前的產(chǎn)品,芯片原廠的技術(shù)支持較弱,芯片文檔簡(jiǎn)單;
  • 該芯片推薦電路方案中,開(kāi)發(fā)的源代碼是匯編由供應(yīng)商提供,外圍電路指示信號(hào)強(qiáng)度的4個(gè)燈,若要用該芯片直接接燈并修改底層程序來(lái)實(shí)現(xiàn)指示信號(hào)強(qiáng)度的功能則困難較大;
  • 公司前期產(chǎn)品USB300里通過(guò)加第三方MCU接收IA2E的音頻數(shù)據(jù)流實(shí)現(xiàn)了USB可插拔播放音樂(lè)的功能和一些其它的IA2E無(wú)法實(shí)現(xiàn)的功能,由此若IA2E芯片能夠在工作時(shí)把其RSSI數(shù)據(jù)傳輸給第三方MCU、由MCU控制指示燈來(lái)顯示產(chǎn)品工作時(shí)的信號(hào)強(qiáng)度則可達(dá)到所開(kāi)發(fā)產(chǎn)品的功能設(shè)計(jì)目的。

解決思路

在上一代產(chǎn)品USB300中發(fā)現(xiàn),若發(fā)送端(TX)改變了音量大小,則TX會(huì)發(fā)送一個(gè)代表音量大小的值(比如0xd7)到接收端(RX),這個(gè)值只會(huì)在音量大小有改變的時(shí)候發(fā)送一次。

  • 人為模擬RSSI信號(hào)發(fā)送過(guò)程
    人為假定一個(gè)信號(hào)發(fā)送周期T(實(shí)際測(cè)試周期T=1080ms)、TX端在這個(gè)周期T內(nèi)重復(fù)發(fā)送音量大小值(比如0xd7)、據(jù)統(tǒng)計(jì)大概發(fā)送了Ntx=168個(gè)、每個(gè)間隔6.4ms左右,然后在RX端統(tǒng)計(jì)接收到的該音量值的個(gè)數(shù)(比如Nrx=80個(gè)),那么誤碼率BER=Ntx/Nrx=50%,根據(jù)不同的BER值來(lái)顯示滿格、兩格或者一格信號(hào)強(qiáng)度,具體代碼如下。
#define BER_FULL_VALUE      168//在一個(gè)周期里總共可以接收168個(gè)數(shù)據(jù)
#define BER_COUNT_CYCLE     108     /*set  the PER count cycle 1080ms*/
void RSSI_Process(uint8_t PER_CODE){
    if((PER_CODE==0xee)||(PER_CODE==0xf1)||(PER_CODE==0xf4)||(PER_CODE==0x0f7)\
        ||(PER_CODE==0xfa)||(PER_CODE==0xfd)||(PER_CODE==0x00)){
        ANT_RSSI.ber_count++;
        if(ANT_RSSI.ber_count_time>=BER_COUNT_CYCLE){/*set  the BER count cycle 1080ms*/
            ANT_RSSI.ber_count_time=0;
            ANT_RSSI.BER=((ANT_RSSI.ber_count*100)/BER_FULL_VALUE);
            if(ANT_RSSI.BER>=80){
                Led.RSSI=RSSI_Good;
            }
            if((ANT_RSSI.BER>=70)&&(ANT_RSSI.BER<80)){
                Led.RSSI=RSSI_soso;
            }
            if((ANT_RSSI.BER>=60)&&(ANT_RSSI.BER<70)){
                Led.RSSI=RSSI_low;
            }
            if(ANT_RSSI.BER<60){
                Led.RSSI=RSSI_bad;
                ANT_RSSI.count++;
                if(ANT_RSSI.count==4){//連續(xù)5S信號(hào)差就切換天線
                    ANT_RSSI.count=0;
                    ANT_Switch();           /*switch the ant*/
                }
            }
            ANT_RSSI.ber_count=0;
        }
    }
}
  • 數(shù)據(jù)包傳輸給MCU
    IA2E接收到音量值數(shù)據(jù)包package后通過(guò)I2C傳輸給MCU,MCU獲得package后處理數(shù)據(jù)來(lái)控制四個(gè)LED燈指示信號(hào)強(qiáng)度。共5種信號(hào)強(qiáng)度等級(jí):good(亮4個(gè)綠燈)、soso(亮3個(gè)綠燈)、low(亮2個(gè)綠燈)、bad(亮1個(gè)綠燈)、none(亮1個(gè)紅燈)相關(guān)效果如下圖。
信號(hào)good

信號(hào)soso

無(wú)信號(hào)

二、更改后的軟件無(wú)MUTE功能

發(fā)送端TX長(zhǎng)按Down鍵達(dá)3秒以上,接收端RX(只有RX端有第三方MCU)收到后不播放聲音來(lái)實(shí)現(xiàn)MUTE功能。

解決過(guò)程

此為純軟件BUG,經(jīng)過(guò)調(diào)試軟件發(fā)現(xiàn)產(chǎn)生此問(wèn)題的兩個(gè)原因。

1、IA2E芯片的運(yùn)行程序存儲(chǔ)背景

  • IA2E芯片的代碼是BIN文件(BACHRX_inno_per_vol.bin),由供應(yīng)商提供;此BIN文件數(shù)據(jù)作為一個(gè)數(shù)組const uint8_t IA2E_ROM[/*6144*/]合成在MCU程序中。

  • 編譯MCU軟件后,數(shù)組const uint8_t IA2E_ROM[/*6144*/]成為MCU軟件的一部分放置于FLASH中,具體在哪個(gè)位置由編譯器決定,但可以肯定的是數(shù)組const uint8_t IA2E_ROM[/*6144*/]名代表IA2E軟件存儲(chǔ)的首地址。

  • RX端MCU發(fā)送bin文件給IA2E具體代碼如下。

uint8_t EEPROM_TxByte() {
    
    uint8_t tx;
    
    if( byte_addr >= sizeof( IA2E_ROM ) ) {
        IA2E_Boot_Complete = SET;
    }
    
    if( byte_addr == IA2E_LATENCY_ADDR ) {
        byte_addr++;
        tx = IA2E_LATENCY_VAL;
    } else if( ( byte_addr >= IA2E_ID_ADDR ) &&
        ( byte_addr < ( IA2E_ID_ADDR + IA2E_ID_SIZE ) ) ) {//三個(gè)字節(jié)存放MCU的ID號(hào)
        tx = UID >> ( ( byte_addr++ - IA2E_ID_ADDR ) << 3 );//寫固定的MCU的ID號(hào),只寫6位
    } else {
        tx = *( IA2E_ROM + byte_addr++ );
    }
    return tx;
    
}

2、無(wú)MUTE功能產(chǎn)生的原因

  • 修改后的代碼如下
void EEPROM_RxByte( uint8_t rx ) {
    
    switch( byte_cnt++ ) {
        case 0:
            ( ( uint8_t *)&byte_addr )[1] = rx;     // store MSB
            break;
        case 1:
            ( ( uint8_t *)&byte_addr )[0] = rx;     // store LSB
            break;
        default:
//          IA2E_ROM[ ( byte_addr++ - 2 ) & 0x1FFF ] = rx;
            switch( byte_addr++ ) {
//              case SYNIC_EEPROM_PER_ADDR:
//                  RSSI_Process( rx );
//                  break;
                case SYNIC_EEPROM_STATUS_ADDR:
//                  SYNIC_STATUS=rx;
                    SYNIC_SetStatus( rx );
                    break;
                case SYNIC_EEPROM_VOLUME_ADDR:
                    if(rx==0x06)//衣領(lǐng)夾麥克峰固定發(fā)射06值過(guò)來(lái)表示最大值
                        rx=0x00;//00表示音量最大值
                    if(SYNIC_Volume_Mute==0)
                    {
                        SYNIC_SetVolume( rx );
                    }
                    RSSI_Process( rx );
                    break;
            }
            break;
    }
    
}
  • 函數(shù)Stream_SetLevel( volume )實(shí)現(xiàn)音量大小的改變,程序case SYNIC_EEPROM_STATUS_ADDR:和程序case SYNIC_EEPROM_VOLUME_ADDR:都會(huì)調(diào)用Stream_SetLevel( volume )函數(shù);
  • RX端中IA2E芯片音量狀態(tài)值放置在地址#define SYNIC_EEPROM_STATUS_ADDR 0x17DD上,音量值放置在地址#define SYNIC_EEPROM_VOLUME_ADDR 0x17F0上,MUTE屬于音量狀態(tài)數(shù)據(jù);
  • 無(wú)論status值還是volume值,只有有按鍵變化TX端才會(huì)發(fā)送值到RX端且一次只可能發(fā)送其中的一種,如此在按了MUTE鍵后,RX端只會(huì)執(zhí)行case SYNIC_EEPROM_STATUS_ADDR:中的程序?qū)崿F(xiàn)MUTE功能;
  • 若后續(xù)TX端無(wú)按鍵變化,則RX端的IA2E芯片不會(huì)通過(guò)I2C發(fā)送音量值到RX中的MCU中,這樣MCU也就不會(huì)執(zhí)行switch( byte_addr++ )里面的程序,如此RX端音量狀態(tài)和音量大小將保持前一狀態(tài);
  • 由于要模擬RSSI功能,產(chǎn)生了以下現(xiàn)象:
  • TX端會(huì)不斷的發(fā)送volume值(假設(shè)volume=0xD7)到RX,意味著無(wú)論TX端有無(wú)按鍵變化都會(huì)隔一小段時(shí)間(6.4ms)發(fā)送volume值給RX,RX端會(huì)周期性的執(zhí)行case SYNIC_EEPROM_VOLUME_ADDR:程序?qū)崿F(xiàn)聲音;
  • 假設(shè)某一時(shí)刻t=6.4ms內(nèi),有一個(gè)MUTE值過(guò)來(lái)(假設(shè)此時(shí)volume=0xD7,聲音正常大?。@時(shí)RX端執(zhí)行case SYNIC_EEPROM_STATUS_ADDR:程序?qū)崿F(xiàn)了MUTE功能,在過(guò)t=6.4ms后,TX又發(fā)送volume=0xD7數(shù)據(jù)到RX,之后RX端執(zhí)行程序case SYNIC_EEPROM_VOLUME_ADDR:實(shí)現(xiàn)聲音正常大小,這樣MUTE的效果就聽(tīng)不出來(lái)了。

3、解決的方法

case SYNIC_EEPROM_VOLUME_ADDR:程序內(nèi)執(zhí)行函數(shù)SYNIC_SetVolume( rx )前添加條件if(SYNIC_Volume_Mute==0),表示只有在無(wú)MUTE情況下,才會(huì)執(zhí)行SYNIC_SetVolume( rx )函數(shù),這樣在MUTE狀態(tài)不解除的情況下即使有volume值發(fā)送到RX端也不會(huì)影響MUTE功能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容