www.pudn.com > BK1080QB_101018_drv.zip > BK1080QB_101018_drv.c, change:2010-10-18,size:53154b
/***************************************************************************** * Copyright Statement: * -------------------- * This software is protected by Copyright and the information contained * herein is confidential. The software may not be copied and the information * contained herein may not be used or disclosed except with the written * permission of MediaTek Inc. (C) 2005 * * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. * * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. * * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC). * *****************************************************************************/ /******************************************************************************* * * Filename: * --------- * AR1000_drv.c * * Project: * -------- * MAUI * * Description: * ------------ * * FM Radio Driver (AR1000) * * Author: * ------- * ------- * *******************************************************************************/ #include "l1audio_def.h" #if (defined(AR1000)) //static int32 freq_rssi_array[2][3]={{0,0,0},{0,0,0}};//for auto search //static int8 index_count=0; ///#define force_mono #define USE_I2C #define AR1000_DEBUG #define ext_clk //#define AR1000_DEBUG_DUMP_LOG //Option log file //#define AR1000_timing_cal #define READ 1 #define WRITE 0 #if defined AR1000_DEBUG static uint8 dbg_cw_readbackM = 0; static uint8 dbg_cw_readbackL = 0; static uint16 dbg_cw_readdata; #endif #if (defined(MT6205B) || defined(MT6208)) && defined(AR1000_DEBUG_DUMP_LOG) #error "No file system on MT6205!" #endif #define UEBAND 0x0000 // US & Europe BAND 87.5MHz to 108MHz #define JBAND 0x1000 // Japen BAND 76MHz to 90MHz #define JWBAND 0x1800 // Japen BAND (wide) 76 MHz to 108MHz #define SPACE100K 1 #define SPACE200K 0 #define SEEKUP 1 #define SEEKDOWN 0 /* General propose constant */ #define AR1000_WRITE 32//192 #define AR1000_READ 33//193 #define ADDR_STATUS 0x13 // the address of status register #define MASK_STC 0x0020 // Seek/Tune/PowerOn complete D5 in adress 13H #define MASK_SF 0x0010 // Seek Fail D4 in address 13H #define MASK_READCHAN 0xFF80 // D7~D15 in address 13H #define SHIFT_READCHAN 7 #define ADDR_RSSI 0x12 #define MASK_RSSI 0xFE00 #define SHIFT_RSSI 9 /// Global variables for current FM status static int16 _current_frequency = -1; static bool _is_fm_on = false; //static bool _is_fm_mute = false; //static uint8 _rssi_threshold; static uint16 Chip_ID = 0; static uint16 Device_ID = 0; static uint8 HWSearch_flag = 0; static uint8 Valid_flag = 0; static uint16 FreqKHz = 0; static uint8 RSSI_value = 0; static uint16 FMChipid = 0; #ifdef AR1000_DEBUG_DUMP_LOG extern uint32 video_get_current_time(void); extern uint32 video_get_duration_ms(uint32 t1); static kal_uint8 _file_name[] = {"D\0:\0\\\0f\0m\0_\0l\0o\0g\0.\0t\0x\0t\0\0\0"}; static uint32 _data_written; static uint8 _dbg_str[128]; static FS_HANDLE _file_handle = 0; static kal_uint8 _channel_name[] = {"D\0:\0\\\0l\0i\0s\0_\0l\0o\0g\0.\0t\0x\0t\0\0\0"}; static uint32 _list_written; static uint8 _list_str[128]; static FS_HANDLE _file_list = 0; #endif bool BK1080_Intialization(void); void BK1080_SetVolumeLevel(uint8 level); uint16 BK1080_FreqToChan(uint16 frequency); uint8 BK1080_GetSigLvl( int16 curf ); bool BK1080_IsChipValid(void); void BK1080_Mute(uint8 mute); void BK1080_SetFreq(int16 curFreq); uint8 BK1080_ValidStop(int16 freq, int8 signalvl, bool is_step_up); uint8 BK1080_ValidStop_2(int16 freq); void BK1080_PowerOnReset(void); void BK1080_PowerOffProc(void); uint16 BK1080_GetChipID(void); uint16 BK1080_GetCurIF(void); unsigned char Operation_Beken_FM_2w(unsigned char operation, unsigned char *data,kal_uint8 start_reg, unsigned char numBytes); #ifdef BK1080_AUTO_SCAN_BY_CHIP uint8 BK1080_FmAutoScan (kal_uint16 *Freqs_buf,uint8 max_len,uint8 b_sort_by_RSSI); #endif #define FMCHANNELSMAX 30 /* Serial communication interfaces */ void SerialCommInit(void); void SerialCommRelease(void); void SerialCommCryClkOn(void); void SerialCommCryClkOff(void); void GPIO_WriteIO(char data,char port); #if defined USE_I2C void SerialCommStart(void); void SerialCommStop(void); uint8 SerialCommTxByte(uint8 data); void SerialCommRxByte(uint8 *data, uint8 ack); #elif defined USE_3_WIRE uint8 SerialCommTxByte(uint8 cw, uint8 data); void SerialCommRxByte(uint8 cw, uint8 *data); #endif void FMDrv_Mute(uint8 mute); void FMDrv_EvaluateRSSIThreshold(void); // enginner mode struct typedef enum group_idx { mono=0, stereo, RSSI_threshold, IF_count_delta, GROUP_TOTAL_NUMS } FACTORY_GROUP_ENUM; typedef enum item_idx { Sblend_OFF=0, Sblend_ON, ITEM_TOTAL_NUMS } FACTORY_ITEM_INDEX; // enginner mode struct #if 0 #if defined(ext_clk) /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ #else /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ /* under construction !*/ #endif #endif //- Modified code start #if defined(ext_clk) static uint16 AR1000reg[18]={ // the initial setting of AR1000 register ( base on ARF_V022_080118_MTK) 0xFF7B, // R0 -- the first writable register 0xFF7F 0x5915, // R1 0x5B15 0x10B9, // R2//F4B9 0xF0B9 0x8010, // R3//8012 0x0780, // R4 0x28AB, // R5//28AA 0x28AA 0x6400, // R6 0x4400 0x1EE7, // R7 0x7141, // R8 0x007D, // R9 0x81C6, // R10//82CE //disable wrap by purple 0x4F65, // R11//4F55 0x4F55 0x970C, // R12//970C 0xB845, // R13 0xFC2D, // R14//FC2D 0x8097, // R15//8097 0x04A1, // R16//04A1 0xE2A7 // R17//7F6A 0x7F6A }; #else static uint16 AR1000reg[18]={ // the initial setting of AR1000 register ( base on ARF_V022_080118_MTK) 0xFFFB, // R0 -- the first writable register . 0xFFFF 0x5915, // R1. 0x5B15 0x10B9, // R2. 0xF4B9 0x8010, // R3 0x0780, // R4 0x28AB, // R5 0x28AA 0x6400, // R6 0x4400 0x1EE7, // R7 0x7141, // R8 0x007D, // R9 0x81C6, // R10 //disable wrap by purple 0x4E65, // R11. <--- 0x4E55 0x970C, // R12. 0xB845, // R13 0xFC2D, // R14 0x8097, // R15 0x04A1, // R16 0xE2A7 // R17 0xDF6A }; #endif //- Modified code end static bool AR1000_ReadByte(uint8 CW, uint8 *dataM, uint8 *dataL) { // uint8 data1, data2; if (CW == 255) { *dataM = 0; *dataL = 0; return true; } #if defined USE_I2C SerialCommStart(); /// send the start sequence SerialCommTxByte(AR1000_WRITE); /// device ID and R/W bit SerialCommTxByte(CW); /// control word SerialCommStart(); /// resend the start sequence SerialCommTxByte(AR1000_READ); /// device ID and R/W bit SerialCommRxByte(dataM, 0); /// read data and send ACK SerialCommRxByte(dataL, 1); /// read data and send ACK SerialCommStop(); /// send the stop sequence #elif defined USE_3_WIRE SerialCommRxByte(CW, dataM); #else #error "Must define USE_I2C or USE_3_WIRE" #endif return true; } static bool AR1000_WriteByte(uint8 CW, uint16 data) { #if defined USE_I2C SerialCommStart(); /// send the start sequence SerialCommTxByte(AR1000_WRITE); /// device ID and R/W bit SerialCommTxByte(CW); /// control word SerialCommTxByte(data>>8); /// data to be written SerialCommTxByte(data&0xFF); /// data to be written SerialCommStop(); /// send the stop sequence #elif defined USE_3_WIRE SerialCommTxByte(CW, data); #else #error "Must define USE_I2C or USE_3_WIRE" #endif #if defined AR1000_DEBUG AR1000_ReadByte(CW, &dbg_cw_readbackM, &dbg_cw_readbackL); dbg_cw_readdata = (uint16)(dbg_cw_readbackM<<8|dbg_cw_readbackL); #endif return true; } /*********************************************************************** * Set radio frequency (internal) * * parameter-->CurFreq:set frequency * ***********************************************************************/ static bool AR1000_SetFreq(int32 CurFreq) { uint32 CHAN = 0x0000; uint8 dataM, dataL; uint16 dataRead, i=0; #ifdef AR1000_DEBUG_DUMP_LOG uint32 start_t, duration_t; kal_sprintf((void*)_dbg_str, "\nAR1000_SetFreq(%d);\n\0", CurFreq); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); start_t = video_get_current_time(); #endif //- Modified code start AR1000_WriteByte(17, AR1000reg[17]); //- Modified code end _current_frequency = CurFreq; CHAN = CurFreq - 690; CHAN = CHAN|0x200;//turn on TUNE AR1000_ReadByte(2, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(2, (dataRead&0xFC00)|CHAN); do { AR1000_ReadByte(ADDR_STATUS, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); // if (i++ >= 600) { // return false; // } } while ((dataRead & MASK_STC)==0); return true; }//AR1000_SetFreq /*********************************************************************** * Turn on/off tune (internal) * * parameter-->ON_OFF: 1:ON, 0:OFF * ***********************************************************************/ void AR1000_TUNE_ON_OFF(uint8 ON_OFF) { uint8 dataM, dataL; uint16 dataRead; AR1000_ReadByte(2, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); if (ON_OFF == 1) AR1000_WriteByte(2, (dataRead&0xFDFF)|0x200); else AR1000_WriteByte(2, (dataRead&0xFDFF)); } /*********************************************************************** * Seek on/off (internal) * * parameter-->ON_OFF: 1:ON, 0:OFF * ***********************************************************************/ void AR1000_SEEK_ON_OFF(uint8 ON_OFF) { uint8 dataM, dataL; uint16 dataRead; AR1000_ReadByte(3, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); if (ON_OFF == 1) AR1000_WriteByte(3, (dataRead&0xBFFF)|0x4000); else AR1000_WriteByte(3, (dataRead&0xBFFF)); } /*********************************************************************** * HiLo side Tune (internal) * * parameter-->Freq: curf:875~1080 * band:range87.5~108.0 * space:1:100k, 0:200k ***********************************************************************/ void AR1000_TUNE_HiLo(int32 Freq, int16 band, int8 space) { int8 rssi; uint8 dataM, dataL; uint16 dataRead; FMDrv_Mute(1); SerialCommInit(); AR1000_SEEK_ON_OFF(0); AR1000_ReadByte(3, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(3, ((dataRead&0xC7FF)|(space<<13))|band);//set space(100k/200k)and band(875~1080) //Read Low-Side LO Injection //R11 --> clear D15, clear D0/D2, D3 is the same as default AR1000_ReadByte(11, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(11, (dataRead&0x7FFA)); if (false == AR1000_SetFreq(Freq)) { ASSERT(0); } AR1000_ReadByte(ADDR_RSSI, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); rssi = (dataRead & MASK_RSSI); //Read Hi-Side LO Injection // R11-->set D15, set D0/D2, D3 is the same as default AR1000_ReadByte(11, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(11, (dataRead&0x8005)); if (false == AR1000_SetFreq(Freq)) { ASSERT(0); } AR1000_ReadByte(ADDR_RSSI, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); rssi = rssi- (dataRead & MASK_RSSI); if (rssi < 0) //errata in 0.82 { // LO // R11--> clear D15, set D0/D2, D3 is the same as default AR1000_ReadByte(11, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(11, (dataRead&0x7FFF)|0x0005); }else{ //HI //R11--> set D15, clear D0/D2, D3 is the same as default AR1000_ReadByte(11, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(11, (dataRead|0x8000)&0xFFFA); } //fine-tune !! //TUNE to FreqKHz with current setting if (false == AR1000_SetFreq(Freq)) { ASSERT(0); } } /*********************************************************************** * Get RSSI Value (internal) * * parameter--> ***********************************************************************/ uint16 AR1000_GetCurRSSI(void) { uint8 TmpRegM, TmpRegL; uint16 TmpReg; AR1000_ReadByte(ADDR_RSSI, &TmpRegM, &TmpRegL); TmpReg = (uint16)(TmpRegM<<8|TmpRegL); return ((TmpReg & MASK_RSSI)>>9); } /*********************************************************************** * Get IF_count Value (internal) * * parameter--> ***********************************************************************/ uint16 AR1000_GetCurIF(void) { uint8 TmpRegM, TmpRegL; uint16 TmpReg; AR1000_ReadByte(ADDR_RSSI, &TmpRegM, &TmpRegL); TmpReg = (uint16)(TmpRegM<<8|TmpRegL); return (TmpReg & 0x1FF); } /*********************************************************************** * Get Search freq (internal) * * parameter--> ***********************************************************************/ void AR1000_GetSearchFreq(uint16 *pfreq) { *pfreq = (uint16)FreqKHz; } void FMDrv_ChipInit(void) { // /// power down the chip // int32 i; // uint8 tmp_reg; SerialCommInit(); FMChipid = BK1080_GetChipID(); if (FMChipid == 0x1080) { BK1080_Intialization();//BK1080 chip BK1080_PowerOffProc(); } else { //- Modified code start AR1000_WriteByte(0, 0xFF7A); //0xFF7E //- Modified code end SerialCommCryClkOff(); } SerialCommRelease(); //#ifdef USE_AR1000_AMP // ExtSwitchInit(); //#endif } /*********************************************************************** * Engineer mode function (API) * * parameter-->group_idx: mono\stereo\RSSI_threshold\IF_count_delta * item_idx: sub select index * item_value: set parameter value ***********************************************************************/ void FMDrv_radio_item_info(kal_uint16 group_idx, kal_uint16 item_idx, kal_uint32 item_value) { uint8 dataM, dataL; uint16 dataRead; uint8 tmpdata[2]; SerialCommInit(); switch (group_idx) { case mono: if(item_value == 1) { if (0x1080==FMChipid) { Operation_Beken_FM_2w(READ, tmpdata, 2, 2); tmpdata[0] |=0x20; Operation_Beken_FM_2w(WRITE, tmpdata, 2, 2); } else { AR1000_ReadByte(1, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(1, (dataRead&0xFFF7)|0x08); } } else { if (0x1080==FMChipid) { Operation_Beken_FM_2w(READ, tmpdata, 2, 2); tmpdata[0] &=0xDF; Operation_Beken_FM_2w(WRITE, tmpdata, 2, 2); } else { AR1000_ReadByte(1, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(1, (dataRead&0xFFF7)); } } break; case stereo: if(item_value == 0) { if (0x1080==FMChipid) { Operation_Beken_FM_2w(READ, tmpdata, 2, 2); tmpdata[0] |=0x20; Operation_Beken_FM_2w(WRITE, tmpdata, 2, 2); } else { AR1000_ReadByte(1, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(1, (dataRead&0xFFF7)|0x08); } } else { switch (item_idx) { case Sblend_ON: // MT6188_ReadByte(CW(14, 0), &TmpReg1); // TmpReg1&=0x2F; // MT6188_WriteByte(CW(14, 0),TmpReg1|0xD0); // mono_flag = 3; break; case Sblend_OFF: // MT6188_ReadByte(CW(14, 0), &TmpReg1); // TmpReg1&=0x2F; // MT6188_WriteByte(CW(14, 0),TmpReg1|0x90); // mono_flag = 4; break; } } break; case RSSI_threshold: if (item_value == 1) RSSI_value = 12; else if (item_value == 2) RSSI_value = 14; else if (item_value == 3) RSSI_value = 16; else if (item_value == 4) RSSI_value = 18; else if (item_value == 5) RSSI_value = 20; else if (item_value == 6) RSSI_value = 22; else RSSI_value = 16;//FM_RADIO_INPUT_LEVEL_THRESHOLD; // AR1000_ReadByte(3, &dataM, &dataL); // dataRead = (uint16)(dataM<<8|dataL); // AR1000_WriteByte(3, (dataRead&0xFF80)|RSSI_value); break; case IF_count_delta: break; } SerialCommRelease(); } bool FMDrv_IsChipValid( void ) { /// anything to do? return true; } /// level ranges from 0 to 12 void FMDrv_SetVolumeLevel(uint8 level) { #ifdef AR1000_DEBUG_DUMP_LOG kal_sprintf((void*)_dbg_str, "\nFMDrv_SetVolumeLevel(%d);\n\0", level); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); #endif // AR1000_SetVolumeLevel(level); } void FMDrv_Mute(uint8 mute) { uint8 dataM, dataL; uint16 dataRead; #ifdef AR1000_DEBUG_DUMP_LOG kal_sprintf((void*)_dbg_str, "\nFMDrv_Mute(%d);\n\0", mute); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); #endif SerialCommInit(); if (0x1080==FMChipid) { BK1080_Mute(mute); } else { AR1000_ReadByte(1,&dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); if (mute == 1) AR1000_WriteByte(1, (dataRead&0xFFFD)|0x02); else AR1000_WriteByte(1, (dataRead&0xFFFD)); } SerialCommRelease(); } /************************************************************* * Radio power on Reset * *************************************************************/ void FMDrv_PowerOnReset(void) { uint8 fail_count=0; uint16 dataRead; int16 i; uint8 dataM, dataL; #ifdef AR1000_DEBUG_DUMP_LOG uint32 start_t, duration_t; _file_handle = FS_Open((const WCHAR *)_file_name, FS_CREATE); kal_sprintf((void*)_dbg_str, "\nFMDrv_PowerOnReset();\n\0"); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); start_t = video_get_current_time(); #endif #ifdef AR1000_DEBUG_DUMP_LOG _file_list = FS_Open((const WCHAR *)_channel_name, FS_CREATE); kal_sprintf((void*)_list_str, "\nchannel list;\n\0"); FS_Write(_file_list, _list_str, strlen((void*)_list_str), &_list_written); #endif SerialCommInit(); if (0x1080==FMChipid) { BK1080_PowerOnReset(); } else { SerialCommCryClkOn(); AR1000_ReadByte(0x1C, &dataM, &dataL); Chip_ID = (uint16)((dataM<<8)|dataL); AR1000_ReadByte(0x1B, &dataM, &dataL); Device_ID = (uint16)((dataM<<8)|dataL); /// Power On //- Modified code start AR1000_WriteByte(0, 0xFF7A); //0xFF7E //- Modified code end if (RSSI_value != 0) AR1000reg[3] = ((AR1000reg[3]&0xFF80)|RSSI_value); for (i=1; i<18; i++) { AR1000_WriteByte(i, AR1000reg[i]); } AR1000_WriteByte(0, AR1000reg[0]); do { AR1000_ReadByte(ADDR_STATUS, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); if (fail_count++ == 400) { ASSERT(0); } } while ((dataRead & MASK_STC)==0); SerialCommRelease(); _is_fm_on = true; _current_frequency = -1; // _rssi_threshold = FM_RADIO_INPUT_LEVEL_THRESHOLD; // if(RSSI_offset != 0) // _rssi_threshold = 6+RSSI_offset; // _rssi_threshold = 10+RSSI_offset; #ifdef AR1000_DEBUG_DUMP_LOG duration_t = video_get_duration_ms(start_t); kal_sprintf((void*)_dbg_str, " time cost: %d ms.\n Chip_ID = %d \n\0", duration_t, Chip_ID); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); #endif } } /***************************************************************** * Radio power off * *****************************************************************/ void FMDrv_PowerOffProc(void) { // int16 i; // uint8 tmp_reg; #ifdef AR1000_DEBUG_DUMP_LOG if (_file_handle == 0) ASSERT(0); kal_sprintf((void*)_dbg_str, "\nFMDrv_PowerOffProc();\n\0"); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); FS_Close(_file_handle); _file_handle = 0; #endif #ifdef AR1000_DEBUG_DUMP_LOG if (_file_list == 0) ASSERT(0); kal_sprintf((void*)_list_str, "\nFMDrv_PowerOffProc();\n\0"); FS_Write(_file_list, _list_str, strlen((void*)_list_str), &_list_written); FS_Close(_file_list); _file_list = 0; #endif #ifdef USE_AR1000_AMP SwitchExtFMPath(0); #endif SerialCommInit(); if (0x1080==FMChipid) { BK1080_PowerOffProc(); } else { //- Modified code start AR1000_WriteByte(0, 0xFF7A); //0xFF7E //- Modified code end SerialCommCryClkOff(); } SerialCommRelease(); _is_fm_on = false; _current_frequency = -1; } /********************************************************************* * Radio set frquency * * parameter-->curf:setting frequency value input value: 875 - 1080 ( 87.5 MHz - 108.0 MHz) *********************************************************************/ void FMDrv_SetFreq( int16 curf ) /* input value: 875 - 1080 ( 87.5 MHz - 108.0 MHz)*/ { uint8 dataM, dataL; uint16 dataRead; // if (_current_frequency != curf) { // int16 HiLo; // int32 curFreq = (int32)curf * FM_TUNER_GRID; #ifdef AR1000_DEBUG_DUMP_LOG uint32 start_t, duration_t; kal_sprintf((void*)_dbg_str, "\nFMDrv_SetFreq(%d);\n\0", curf); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); start_t = video_get_current_time(); #endif if (_is_fm_on != true) FMDrv_PowerOnReset(); FMDrv_Mute(1); SerialCommInit(); if (0x1080==FMChipid) { BK1080_SetFreq(curf); } else { AR1000_TUNE_ON_OFF(0); AR1000_SEEK_ON_OFF(0); AR1000_ReadByte(3, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(3, (dataRead&0xC7FF)|0x2000);//set space(100k/200k)and band(875~1080) if (false == AR1000_SetFreq(curf)) { ASSERT(0); } // AR1000_TUNE_HiLo(curf, 0, 1); } SerialCommRelease(); FMDrv_Mute(0); #ifdef USE_AR1000_AMP SwitchExtFMPath(1); #endif #ifdef AR1000_DEBUG_DUMP_LOG duration_t = video_get_duration_ms(start_t); kal_sprintf((void*)_dbg_str, " time cost: %d ms.\n\0", duration_t); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); #endif } /********************************************************************** * Get really signal level in current frequency * * parameter-->curf:frequency value of radio now **********************************************************************/ uint16 FMDrv_GetSigLvl( int16 curf ) { uint16 rssi; #ifdef AR1000_DEBUG_DUMP_LOG uint32 start_t, duration_t; kal_sprintf((void*)_dbg_str, "\nFMDrv_GetSigLvl(%d);\n\0", curf); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); start_t = video_get_current_time(); #endif if (curf != _current_frequency) FMDrv_SetFreq( curf ); SerialCommInit(); if (0x1080==FMChipid) { rssi=BK1080_GetSigLvl(curf); } else { rssi = AR1000_GetCurRSSI(); } SerialCommRelease(); #ifdef AR1000_DEBUG_DUMP_LOG duration_t = video_get_duration_ms(start_t); kal_sprintf((void*)_dbg_str, " time cost: %d ms.\n RSSI returned: %d.\n\0", duration_t, rssi); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); #endif return rssi; } /********************************************************************** * Get really IF count in current frequency * * parameter-->curf:frequency value of radio now **********************************************************************/ uint16 FMDrv_GetIF( int16 curf) { uint16 IF; #ifdef AR1000_DEBUG_DUMP_LOG uint32 start_t, duration_t; kal_sprintf((void*)_dbg_str, "\nFMDrv_GetIF(%d);\n\0", curf); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); start_t = video_get_current_time(); #endif if (curf != _current_frequency) FMDrv_SetFreq( curf ); SerialCommInit(); if (0x1080==FMChipid) { IF = BK1080_GetCurIF(); } else { IF = AR1000_GetCurIF(); } SerialCommRelease(); #ifdef AR1000_DEBUG_DUMP_LOG duration_t = video_get_duration_ms(start_t); kal_sprintf((void*)_dbg_str, " time cost: %d ms.\n IF returned: %d.\n\0", duration_t, IF ); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); #endif return IF; } /********************************************************************** * Radio valid station,used in HW auto search frequency to verify * valid positon * * parameter-->freq: start frequency is_step_up:1-->forward, 0-->backward space:search step,0:200KHz, 1:100KHz **********************************************************************/ void FMDrv_HWSearch(int16 freq, bool is_step_up, int16 space, bool is_preset) { int32 targetFreq; uint8 dataM, dataL, UpDown_flag=0; uint16 dataRead; uint8 _step; kal_uint8 TmpData8[8]; uint8 fm_count = 0; // int8 pt; //uint32 save_irq_mask; #ifdef AR1000_DEBUG_DUMP_LOG uint32 start_t, duration_t; kal_sprintf((void*)_dbg_str, "\nFMDrv_ValidStop(%d, %d, %d);\n\0", freq, signalvl, is_step_up); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); start_t = video_get_current_time(); #endif if (0x1080==FMChipid) { if (_is_fm_on == false) { HWSearch_flag = 1; Valid_flag = 1; return; } //uint32 save_irq_mask; //dump_printf("bk1080 hwsearch freq=%d,dir=%d,preset=%d\n",freq,is_step_up,is_preset); kal_prompt_trace(MOD_UEM,"bk1080 hwsearch freq=%d,dir=%d,preset=%d\n",freq,is_step_up,is_preset); if (is_step_up) UpDown_flag = 1; HWSearch_flag = 0; Valid_flag = 0; //calculate starting frequency if( space ) {// 100K _step = 1; }else { //200K _step = 2; } if (!is_preset) { if(is_step_up) {// up targetFreq = (int32)(freq+_step); } else { //down targetFreq = (int32)(freq-_step); } } else { if(is_step_up) {// up //targetFreq = (int32)(freq-_step); targetFreq = (int32)(freq); } else { //down //targetFreq = (int32)(freq+_step); targetFreq = (int32)(freq); if( targetFreq > 1080 ) targetFreq = 1080; } } FMDrv_Mute(1); SerialCommInit(); fm_count = 0; HWSearch_flag = 0; Valid_flag = 0; while(fm_count <206) { fm_count ++; if (BK1080_ValidStop_2(targetFreq) == 0) { HWSearch_flag = 0; Valid_flag = 1; if(is_step_up) { targetFreq += _step; if (targetFreq > 1080) { if(!is_preset) { targetFreq = 875; } else { FreqKHz = 1080; HWSearch_flag = 1; Valid_flag = 0; break; } } } else { targetFreq -= _step; if (targetFreq < 875) targetFreq = 1080; } } else { FreqKHz = targetFreq; HWSearch_flag = 1; Valid_flag = 0; break; } //HWSearch_flag = 1; //Valid_flag = 0; } if (fm_count > 205) { FreqKHz = targetFreq; HWSearch_flag = 1; Valid_flag = 1; } //dump_printf("bk1080 hwsearch search success freq=%d\n",FreqKHz); kal_prompt_trace(MOD_UEM,"bk1080 hwsearch search success freq=%d\n",FreqKHz); FMDrv_Mute(0); SerialCommRelease(); } else { if (is_step_up) UpDown_flag = 1; HWSearch_flag = 0; Valid_flag = 0; //calculate starting frequency if (!is_preset) { // this is not a auto_scan function ! targetFreq = (int32)(freq); }else{ if( space ) {// 100K _step = 1; }else{ //200K _step = 2; } if(is_step_up) {// up targetFreq = (int32)(freq-_step); }else{ //down targetFreq = (int32)(freq+_step); if( targetFreq > 1080 ) targetFreq = 1080; } } FMDrv_Mute(1); SerialCommInit(); //- Modified code start if (false == AR1000_SetFreq(targetFreq)) { ASSERT(0); } AR1000_TUNE_ON_OFF(0); AR1000_SEEK_ON_OFF(0); // AR1000_ReadByte(3, &dataM, &dataL); // dataRead = (uint16)(dataM<<8|dataL); // AR1000_WriteByte(3, (dataRead&0xC7FF)|0x2000);//set space(100k/200k)and band(875~1080) // if (false == AR1000_SetFreq(targetFreq)) // { // ASSERT(0); // } AR1000_ReadByte(3, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(3, (dataRead&0x47FF)|(UpDown_flag<<15)|(space<<13));//set space(100k/200k)and band(875~1080)and up/down // Setting before seek AR1000_ReadByte(17, &dataM, &dataL); dataM = (dataM & 0xC3) | 0x20; dataL =(dataL & 0xFF) | 0x00; dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(17, dataRead); if (!is_preset) { // this is not a auto_scan function ! AR1000_WriteByte(10, AR1000reg[10]|0x0008); //enable wrap , if it is not auto scan function }else{ AR1000_WriteByte(10, AR1000reg[10]&0xFFF7); //disable wrap , if it is auto scan function } AR1000_SEEK_ON_OFF(1); // AR1000_ReadByte(3, &dataM, &dataL); // dataRead = (uint16)(dataM<<8|dataL); // AR1000_WriteByte(3, (dataRead&0x47FF)|(UpDown_flag<<15)|(space<<13));//set space(100k/200k)and band(875~1080)and up/down //- Modified code end AR1000_ReadByte(ADDR_STATUS, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); HWSearch_flag = dataRead & MASK_STC; // check STC flag while( HWSearch_flag == 0) { // maybe you can delay for a while // delay ( 100 ms ) AR1000_ReadByte(ADDR_STATUS, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); HWSearch_flag = dataRead & MASK_STC; // check STC flag Valid_flag = 1; } FreqKHz = 690 + ((dataRead & MASK_READCHAN )>> SHIFT_READCHAN ); if (is_preset) { if (FreqKHz == 1080) { HWSearch_flag = 1; Valid_flag = 0; } } if((dataRead & MASK_SF)!=0) { HWSearch_flag = 1; Valid_flag = 0; } //- Modified code start // Restore setting after seek AR1000_WriteByte(17, AR1000reg[17]); //- Modified code end FMDrv_Mute(0); SerialCommRelease(); } // return 1; } uint8 FMDrv_HWSpolling(uint16 *curf, uint8 *is_valid) { if (HWSearch_flag != 0) { if (0x1080==FMChipid) { *curf = (uint16)FreqKHz; } else { AR1000_GetSearchFreq(curf); AR1000_SEEK_ON_OFF(0); } if (Valid_flag == 1) *is_valid = 1; else *is_valid = 0; return 1; } else return 0; } /********************************************************************** * Radio valid station,used in auto search frequency to verify * valid positon * * parameter-->freq: frequency signalv1:signal level range is 0 ~ 15 is_step_up:return value(Reserved) **********************************************************************/ uint8 FMDrv_ValidStop(int16 freq, int8 signalvl, bool is_step_up) { int32 targetFreq; uint8 dataM, dataL; uint16 dataRead, i=0; bool result; // int8 pt; //uint32 save_irq_mask; #ifdef AR1000_DEBUG_DUMP_LOG uint32 start_t, duration_t; kal_sprintf((void*)_dbg_str, "\nFMDrv_ValidStop(%d, %d, %d);\n\0", freq, signalvl, is_step_up); FS_Write(_file_handle, _dbg_str, strlen((void*)_dbg_str), &_data_written); start_t = video_get_current_time(); #endif targetFreq = (int32)freq; FMDrv_Mute(1); SerialCommInit(); if (0x1080==FMChipid) { result=BK1080_ValidStop(freq, signalvl, is_step_up); } else { AR1000_TUNE_ON_OFF(0); AR1000_SEEK_ON_OFF(0); AR1000_ReadByte(3, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(3, (dataRead&0xC7FF)|0x2000);//set space(100k/200k)and band(875~1080) if (false == AR1000_SetFreq(targetFreq)) { ASSERT(0); } AR1000_SEEK_ON_OFF(1); AR1000_ReadByte(3, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); AR1000_WriteByte(3, (dataRead&0x47FF)|(is_step_up<<15)|0x2000);//set space(100k/200k)and band(875~1080) do { AR1000_ReadByte(ADDR_STATUS, &dataM, &dataL); dataRead = (uint16)(dataM<<8|dataL); if (i++ >= 40) { return 0; } } while ((dataRead & MASK_STC)==0); if((dataRead & MASK_SF)!=0) return 0; } FMDrv_Mute(0); SerialCommRelease(); return 1; } kal_uint16 BK1080_Digital_Reg[]= { 0x0008, //REG0 0x1080, //REG1 0x8201, //REG2 //0x9201 For BK1080XB,0X8201 For BK1080QB 0x0000, //REG3 0x40C0, //REG4 0x0A1F, //REG5 0x002E, //REG6 0x02FF, //REG7 0x5B11, //REG8 0x0000, //REG9 0x411E, //REG10 0x0000, //REG11 0xCE00, //REG12 0x0000, //REG13 0x0000, //REG14 0x1000, //REG15 0x0010, //REG16 0x0000, //REG17 0x13FF, //REG18 0x9852, //REG19 0x0000, //REG20 0x0000, //REG21 0x0008, //REG22 0x0000, //REG23 0x51E0, //REG24 0x28BC, //REG25 // 28DC 0x2645, //REG26 0x00E4, //REG27 0x1CD8, //REG28 0x3A50, //REG29 0xEAF0, //REG30 0x3000, //REG31 0x0000, //REG32 0x0000, //REG33 }; #define BK1080_DEV_ADDRESS 0x80 //kal_uint16 bk1080_last_freq=875; unsigned char Operation_Beken_FM_2w(unsigned char operation, unsigned char *data,kal_uint8 start_reg, unsigned char numBytes) { unsigned char controlWord, j, error = 0; int i; int32 acknowledge=0; /*************************************************** START: make sure here SDIO_DIR =OUT, SCLK = 1, SDIO = 1 ****************************************************/ SerialCommStart(); /*************************************************** WRITE CONTROL DATA: make sure here: SLCK = 0; SDIO = 0 ****************************************************/ /*************************** CHECK ACK for control word ***************************/ acknowledge = SerialCommTxByte(BK1080_DEV_ADDRESS); if(operation == READ) acknowledge = SerialCommTxByte((start_reg<<1)|0x01); else acknowledge = SerialCommTxByte((start_reg<<1)); //kal_prompt_trace(MOD_MED_V,"OperationRda5800_2w lrjaaaaaa acknowledge =%d ",acknowledge); /*************************************** WRITE or READ data ****************************************/ /****************************** CHECK ACK or SEND ACK=0 *******************************/ for(j = 0; j < numBytes; j++, data++) { if(operation == READ) { if(j == (numBytes -1)) SerialCommRxByte(data,1); else SerialCommRxByte(data, 0); } else acknowledge = SerialCommTxByte(*data); //kal_prompt_trace(MOD_MED_V,"OperationBekenFM_2w numBytes =%d acknowledge=%d,data=%x",numBytes,acknowledge,*data); //lrj add for test 20060522 } /**************************** STOP: make sure here: SCLK = 0 *****************************/ SerialCommStop(); return acknowledge; } void BK1080_Mute(uint8 mute) { kal_uint8 TmpData8[2]; Operation_Beken_FM_2w(READ,TmpData8,2,2); if(mute) TmpData8[0]|=0x40; else TmpData8[0]&=0xbf; Operation_Beken_FM_2w(WRITE,&(TmpData8[0]),2,2);//write reg2 with 2 bytes } uint16 BK1080_FreqToChan(uint16 frequency) { return (frequency - 875); } void BK1080_SetFreq(int16 curFreq) { uint16 curChan; kal_uint8 TmpData8[2]; TmpData8[0] =0x0; TmpData8[1]= 0x0; kal_prompt_trace(MOD_UEM,"BK1080_SetFreq curFreq=%d",curFreq); curChan=BK1080_FreqToChan(curFreq); /*stop seek and tune*/ TmpData8[0]=(curChan>>8)&0xff; //TmpData8[0] |= 0x80;//start tune TmpData8[1]=curChan&0xff; Operation_Beken_FM_2w(WRITE,TmpData8,3,2); //write reg3,with 2 bytes // kal_sleep_task(6); TmpData8[0] |= 0x80;//start tune Operation_Beken_FM_2w(WRITE,TmpData8,3,2); //write reg3,with 2 bytes // kal_prompt_trace(MOD_MED_V,"TmpData8[%d] =0x%x;%x; ",2,TmpData8[0],TmpData8[1]); // kal_prompt_trace(MOD_MED_V,"TmpData8[%d] =0x%x;%x; ",3,TmpData8[2],TmpData8[3]); // kal_sleep_task(6); //TmpData8[0] =0x0;//reset tune //TmpData8[1]= 0x0; TmpData8[0] &= 0x7f;//start tune Operation_Beken_FM_2w(WRITE,TmpData8,3,2); //write reg3,with 2 bytes _current_frequency = curFreq; } uint16 g_freq_deviation_array[1081-875]; //max length=channel number uint8 BK1080_ValidStop_2(int16 freq) /* 自动搜索时,作为判定条件,再从中选择信号最强的9个台*/ { static int16 last_tuned_freq=0; uint16 cur_freq_deviation; kal_uint8 TmpData8[8]; kal_prompt_trace(MOD_UEM,"BK1080_ValidStop_2 freq=%d\n",freq); BK1080_SetFreq(freq); kal_sleep_task(15);//delay 10ms //////////////////////////////////// //new added 2009-05-30 Operation_Beken_FM_2w(READ,TmpData8,0x07,2);//start from reg 0x7,with 2bytes cur_freq_deviation=TmpData8[0]; cur_freq_deviation<<=8; cur_freq_deviation|=TmpData8[1]; cur_freq_deviation=cur_freq_deviation>>4; g_freq_deviation_array[freq-875]=cur_freq_deviation;//save deviation //////////////////////////////////// Operation_Beken_FM_2w(READ,TmpData8,7,8);//start from reg7,with 8bytes if(TmpData8[6]&0x10) //check AFCRL bit12 { last_tuned_freq=freq;//save last tuned freqency return 0;//false } #if defined(__M5070__) if(TmpData8[7]<10) //RSSI<10 #else if(TmpData8[7]<5) //RSSI<10 #endif { last_tuned_freq=freq;//save last tuned freqency return 0;//false } if( (TmpData8[1]&0xf) <2) //SNR<2 { last_tuned_freq=freq;//save last tuned freqency return 0;//false } #if defined(__M5070__) #if 0 //add frequency devation check if( (cur_freq_deviation>=0x100)&&(cur_freq_deviation<=(0xfff-0x100))) { last_tuned_freq=freq;//save last tuned freqency return 0; } #else //修改FM搜台有很多重复和空台,更改这个问题请走else. //add frequency devation check if( (cur_freq_deviation>=250)&&(cur_freq_deviation<=(0xfff-250))) //100~280间 搜台少可增大该值,假台多可减小该值。 { last_tuned_freq=freq;//save last tuned freqency return 0; } //new added 2009-05-30 if( (freq>=876)&&( (freq-last_tuned_freq)==1) ) { if(g_freq_deviation_array[freq-875-1]&0x800) { last_tuned_freq=freq;//save last tuned freqency return 0; } if(g_freq_deviation_array[freq-875-1]<150) //50~200 搜台较少可减小该值,假台较多可增大该值。 { last_tuned_freq=freq;//save last tuned freqency return 0; } } if( (freq>=875)&&( (last_tuned_freq-freq)==1) ) { if( (g_freq_deviation_array[freq-875+1]&0x800)==0) { last_tuned_freq=freq;//save last tuned freqency //g_last_freq_deviation_value=cur_freq_deviation; return 0; } if(g_freq_deviation_array[freq-875+1]>(0xfff-150) ) //50~200 搜台较少可减小该值,假台较多可增大该值。 { last_tuned_freq=freq;//save last tuned freqency //g_last_freq_deviation_value=cur_freq_deviation; return 0; } } #endif #else //__M5070__ #if 1 //add frequency devation check if( (cur_freq_deviation>=0x100)&&(cur_freq_deviation<=(0xfff-0x100))) { last_tuned_freq=freq;//save last tuned freqency return 0; } #else //修改FM搜台有很多重复和空台,更改这个问题请走else. //add frequency devation check if( (cur_freq_deviation>=0x200)&&(cur_freq_deviation<=(0xfff-0x200))) { last_tuned_freq=freq;//save last tuned freqency return 0; } //new added 2009-05-30 if( (freq>=876)&&( (freq-last_tuned_freq)==1) ) { if(g_freq_deviation_array[freq-875-1]&0x800) { last_tuned_freq=freq;//save last tuned freqency return 0; } if(g_freq_deviation_array[freq-875-1]<200) { last_tuned_freq=freq;//save last tuned freqency return 0; } } if( (freq>=875)&&( (last_tuned_freq-freq)==1) ) { if( (g_freq_deviation_array[freq-875+1]&0x800)==0) { last_tuned_freq=freq;//save last tuned freqency //g_last_freq_deviation_value=cur_freq_deviation; return 0; } if(g_freq_deviation_array[freq-875+1]>(0xfff-200) ) { last_tuned_freq=freq;//save last tuned freqency //g_last_freq_deviation_value=cur_freq_deviation; return 0; } } #endif #endif //__M5070__ last_tuned_freq=freq;//save last tuned freqency //g_last_freq_deviation_value=cur_freq_deviation; return 1; //OK } uint8 BK1080_ValidStop(int16 freq, int8 signalvl, bool is_step_up) /* 自动搜索时,作为判定条件,再从中选择信号最强的9个台*/ { int32 targetFreq; uint8 fm_count = 0; kal_uint8 TmpData8[8]; targetFreq = (int32)freq; FMDrv_Mute(0); SerialCommInit(); fm_count = 0; while(fm_count <206) { fm_count ++; if (BK1080_ValidStop_2(targetFreq) == 0) { if(is_step_up) { targetFreq += 1; if (targetFreq > 1080) { targetFreq = 875; } } else { targetFreq -= 1; if (targetFreq < 875) targetFreq = 1080; } } //HWSearch_flag = 1; //Valid_flag = 0; } if (fm_count > 205) { FreqKHz = targetFreq; return 0; } //dump_printf("BK1080_ValidStop success freq=%d\n",FreqKHz); FMDrv_Mute(1); SerialCommRelease(); return 1; } uint8 BK1080_GetSigLvl( int16 curf ) /*当满足rssi 的条件时,将信号记录,再选最强的9个频段*/ { kal_uint8 TmpData8[2]; if(875==curf) return(1); else { Operation_Beken_FM_2w(READ,TmpData8,0x0a,2);//start from reg 0xa,with 2bytes return (TmpData8[1]); /*返回rssi*/ } } uint16 BK1080_GetCurIF(void) { kal_uint8 readdata[2]; Operation_Beken_FM_2w(READ,readdata,10,2); return (uint16)(readdata[1]); } bool BK1080_IsChipValid(void) { // bool result; // SerialCommCryClkOn(); // kal_sleep_task(1); // SerialCommInit(); // result = BK1080_Intialization(); // SerialCommCryClkOff(); return 1; } void BK1080_SetVolumeLevel(uint8 level) /*一般不调用,即不用芯片来调节音量。*/ { // if(level) // { // bk1080_writeData8[7]&=0xf0; // bk1080_writeData8[7]|=level; // Operation_Beken_FM_2w(WRITE,bk1080_writeData8,8,0x0a); // } } bool BK1080_Intialization(void) { kal_uint8 index = 0; kal_uint8 ret = 0; kal_uint8 ReadData8[2]; kal_uint8 bk1080_writeData8[68]; //kal_uint8 i; for(index=0;index<(1081-875);index++) g_freq_deviation_array[index]=0; //max length=channel number //BK1080_EnableWire2(); //kal_sleep_task(50); Operation_Beken_FM_2w(READ,ReadData8,1,2);//check device ID kal_prompt_trace(MOD_UEM,"bk1080 init id= %x",ReadData8[1]); //Write Digital REG for(index = 0; index < 34; index++)//write reg2-reg31 ;reg0->device_id,reg1->chip_id only read ... { bk1080_writeData8[index*2] = (BK1080_Digital_Reg[index] >> 8)&0xff; bk1080_writeData8[index*2+1] = (BK1080_Digital_Reg[index])&0xff; } Operation_Beken_FM_2w(WRITE,&(bk1080_writeData8[0]),0,68);//start from reg2,total 60 byte #if 0 kal_sleep_task(20); bk1080_writeData8[16*2+1] = ((BK1080_Digital_Reg[16])&0xff)|1; Operation_Beken_FM_2w(WRITE,&(bk1080_writeData8[16*2]),16,2);//write from reg16,total 2 byte kal_sleep_task(20); bk1080_writeData8[16*2+1] = (BK1080_Digital_Reg[16])&0xff; Operation_Beken_FM_2w(WRITE,&(bk1080_writeData8[16*2]),16,2);//write from reg16.total 2 byte #endif // Operation_Beken_FM_2w(READ,ReadData8,1,2);//check device ID // for(i = 0;i < 64 ; i++) // kal_prompt_trace(MOD_MED_V,"OperationRda5800_2w ReadData8[%d] =%d ",i,ReadData8[i]); kal_sleep_task(100); //delay 250ms #if 1 bk1080_writeData8[25*2+1] = ((BK1080_Digital_Reg[25])&0x7f); Operation_Beken_FM_2w(WRITE,&(bk1080_writeData8[25*2]),25,2);//write from reg16,total 2 byte //kal_sleep_task(20); //delay 60ms bk1080_writeData8[25*2+1] = (BK1080_Digital_Reg[25])&0xff; Operation_Beken_FM_2w(WRITE,&(bk1080_writeData8[25*2]),25,2);//write from reg16.total 2 byte #endif if(ReadData8[1]!=0x80)//device is not BK1080 { // return 1;//error } #if 0 //start seek bk1080_writeData8[2*2]&=0xfe; Operation_Beken_FM_2w(WRITE,&(bk1080_writeData8[2*2]),2,2);//write from reg2,total 2 byte bk1080_writeData8[2*2]=(BK1080_Digital_Reg[2] >> 8)&0xff; bk1080_writeData8[2*2+1]=(BK1080_Digital_Reg[2])&0xff;//start seek Operation_Beken_FM_2w(WRITE,&(bk1080_writeData8[2*2]),2,2);//write #endif kal_sleep_task(50); //解决收音机power off 之后回到之前的同一个频点 BK1080_SetFreq(875); BK1080_Mute(1); //添加延时 return 0; } void BK1080_PowerOnReset(void) { kal_uint8 TmpData8[2]; kal_prompt_trace(MOD_UEM,"BK1080_PowerOnReset"); SerialCommCryClkOn(); kal_sleep_task(10); SerialCommInit(); //kal_sleep_task(10); BK1080_Intialization(); kal_sleep_task(50); _is_fm_on = true; //Operation_Beken_FM_2w(READ,TmpData8,2,2); //read reg2,with 2 bytes //TmpData8[1]=TmpData8[1]&0xbe; //Operation_Beken_FM_2w(WRITE,TmpData8,2,2); } void BK1080_PowerOffProc(void) { kal_uint8 TmpData8[2]; kal_prompt_trace(MOD_UEM,"BK1080_PowerOffProc"); Operation_Beken_FM_2w(READ,TmpData8,2,2); //read reg2,with 2 bytes TmpData8[1]=TmpData8[1]|0x41; Operation_Beken_FM_2w(WRITE, TmpData8, 2,2); kal_sleep_task(5); SerialCommCryClkOff(); _is_fm_on = false; } uint16 BK1080_GetChipID(void) { kal_uint8 ReadData8[2]; uint16 chipid; Operation_Beken_FM_2w(READ,ReadData8,1,2);//check device ID chipid = ((uint16)ReadData8[0] << 8) + (uint16)ReadData8[1]; kal_prompt_trace(MOD_UEM,"bk1080 chip id=%x, reg1=%x%x",chipid,ReadData8[0],ReadData8[1]); return chipid; } #elif defined(QN8035) #include "l1audio_def.h" #include "qndriver.h" #include "qnio.h" #define FM_32K 75// Base band 32k clock output #define FM_32K_MOD 2// 3 extern void SerialCommInit(void); extern void SerialCommRelease(void); extern void SerialCommCryClkOn(void); extern void SerialCommCryClkOff(void); /* void SerialCommInit(void) { GPIO_ModeSetup(SCL,0); GPIO_ModeSetup(SDA,0); GPIO_InitIO(1,SCL); GPIO_InitIO(1,SDA); GPIO_WriteIO(1,SCL); GPIO_WriteIO(1,SDA); } void SerialCommRelease(void) { GPIO_WriteIO(0,SCL); GPIO_WriteIO(0,SDA); } extern kal_uint8 FM_SetClk_32K(kal_uint8 numLpo,kal_bool enable); void SerialCommCryClkOn(void) { GPIO_ModeSetup(FM_32K, FM_32K_MOD); //GPIO_SetClkOut(FM_32K, FM_32K_MOD); //GPIO_SetClkOut(FM_32K_MOD, 4); FM_SetClk_32K(FM_32K,KAL_TRUE); Msdelay(10); } void SerialCommCryClkOff(void) { GPIO_ModeSetup(FM_32K,0); //GPIO_SetClkOut(FM_32K_MOD, 0); FM_SetClk_32K(FM_32K,KAL_FALSE); Msdelay(10); } */ void FMDrv_radio_item_info(kal_uint16 group_idx, kal_uint16 item_idx, kal_uint32 item_value) { } void FMDrv_SetVolumeLevel(UINT8 level) { QND_RXConfigAudio(QND_CONFIG_VOLUME,level); } void FMDrv_Mute(UINT8 mute) { SerialCommInit(); if (mute == 1) QND_RXConfigAudio(QND_CONFIG_MUTE, 1 ); else QND_RXConfigAudio(QND_CONFIG_MUTE, 0 ); SerialCommRelease(); } void FMDrv_PowerOnReset(void) { sys_print(0,"FMDrv_PowerOnReset start"); SerialCommCryClkOn(); SerialCommInit(); QND_Init(); QND_SetSysMode(QND_MODE_FM|QND_MODE_RX); //QND_RXConfigAudio(QND_CONFIG_MUTE, 1 ); //QND_RXConfigAudio(QND_CONFIG_VOLUME,40); //QND_RXConfigAudio(QND_CONFIG_MUTE, 0 ); //SerialCommRelease(); sys_print(0,"FMDrv_PowerOnReset end"); } void FMDrv_PowerOffProc(void) { //SerialCommInit(); QND_SetSysMode(QND_MODE_SLEEP); SerialCommCryClkOff(); //SerialCommRelease(); } void FMDrv_SetFreq( int16 curf ) { UINT16 ch; sys_print(0,"FMDrv_SetFreq"); SerialCommInit(); ch = (UINT16)(curf*10); QND_TuneToCH(ch); SerialCommRelease(); } uint16 FMDrv_GetSigLvl( int16 curf ) { UINT16 ch; UINT16 rssi; sys_print(0,"FMDrv_GetSigLvl"); SerialCommInit(); ch = (UINT16)(curf*10); rssi=QND_GetRSSI(ch); SerialCommRelease(); return rssi; } uint16 FMDrv_GetIF( int16 curf) { // return 120; } void FMDrv_EvaluateRSSIThreshold(void) { //kal_prompt_trace(MOD_MMI,"FMDrv_EvaluateRSSIThreshold"); } uint8 FMDrv_ValidStop(int16 freq, int8 signalvl, bool is_step_up) { UINT16 temp; sys_print(0,"FMDrv_ValidStop"); #if defined(__D252_INA__) QND_RXSetTH(2); //actually,for saving time of automatic scan channel,only need call once when enter to automatic seeking mode before. #else QND_RXSetTH(3); //actually,for saving time of automatic scan channel,only need call once when enter to automatic seeking mode before. #endif temp = QND_RXValidCH((UINT16)(freq * 10), QND_FSTEP_100KHZ); if(temp) return 1; else return 0; } void FMDrv_ChipInit(void) { /* uint16 reg; sys_print(0,"start to write"); QND_WriteReg(0x07,0xaa); reg = QND_ReadReg(0x07); sys_print(0,"reg = %x",reg); //kal_prompt_trace(MOD_MMI,"FMDrv_ChipInit"); */ uint16 FMChipid; FMChipid =QND_ReadReg(0x06); sys_print(0,"QN8035 chip id=%x",FMChipid); if(FMChipid == 0x84) { //SerialCommInit(); //QND_Init(); sys_print(0,"FMDrv_ChipInit"); //SerialCommCryClkOff(); } } bool FMDrv_IsChipValid( void ) { return true; } void FMDrv_HWSearch(int16 freq, bool is_step_up, int16 space, bool is_preset) { } uint8 FMDrv_HWSpolling(uint16 *curf, uint8 *is_valid) { } #endif // defined(AR1000A1)