#include "app_config.h" #include "system/includes.h" #include "fm/fm_manage.h" #include "rda5807/RDA5807.h" #include "bk1080/BK1080.h" #include "qn8035/QN8035.h" #include "fm_inside/fm_inside.h" #include "asm/audio_linein.h" #include "audio_config.h" #include "audio_dec/audio_dec_fm.h" #if TCFG_APP_FM_EN #define LOG_TAG_CONST APP_FM #define LOG_TAG "[APP_FM]" #define LOG_ERROR_ENABLE #define LOG_DEBUG_ENABLE #define LOG_INFO_ENABLE /* #define LOG_DUMP_ENABLE */ #define LOG_CLI_ENABLE #include "debug.h" static FM_INTERFACE *t_fm_hdl = NULL; static FM_INTERFACE *fm_hdl = NULL; static struct _fm_dev_info *fm_dev_info; static struct _fm_dev_platform_data *fm_dev_platform_data; int linein_dec_open(u8 source, u32 sample_rate); void linein_dec_close(void); int fm_dev_init(void *_data) { fm_dev_platform_data = (struct _fm_dev_platform_data *)_data; return 0; fm_dev_info = (struct _fm_dev_info *)malloc(sizeof(struct _fm_dev_info)); if (fm_dev_info == NULL) { printf("fm_dev_init info malloc err!"); return -1; } fm_dev_platform_data = (struct _fm_dev_platform_data *)_data; memset(fm_dev_info, 0x00, sizeof(struct _fm_dev_info)); fm_dev_info->iic_hdl = fm_dev_platform_data->iic_hdl; fm_dev_info->iic_delay = fm_dev_platform_data->iic_delay; /* iic_init(fm_dev_info->iic_hdl); extern void bk1080_test(void); bk1080_test(); */ fm_manage_check_online(); if (!fm_hdl) { /* printf("fm_manage could not find dev\n"); */ return -1; } else { extern void wdt_clear(); wdt_clear(); memcpy(fm_dev_info->logo, fm_hdl->logo, strlen(fm_hdl->logo)); /* printf("fm_manage found dev %s\n", fm_dev_info->logo); */ /* fm_manage_init(); */ /* fm_manage_set_fre(875); */ /* fm_manage_mute(0); */ /* u16 iii = 875; */ /* while(!fm_manage_set_fre(iii) && (iii < 1080)) { */ /* printf("fm fre no %d\n", iii); */ /* iii++; */ /* os_time_dly(1); */ /* } */ /* printf("fm fre %d\n", iii); */ /* while(1) { */ /* os_time_dly(1); */ /* } */ } return 0; } u8 fm_dev_iic_write(u8 w_chip_id, u8 register_address, u8 *buf, u32 data_len) { u8 ret = 1; iic_start(fm_dev_info->iic_hdl); if (0 == iic_tx_byte(fm_dev_info->iic_hdl, w_chip_id)) { ret = 0; log_e("\n fm iic wr err 0\n"); goto __gcend; } delay(fm_dev_info->iic_delay); if (0 == iic_tx_byte(fm_dev_info->iic_hdl, register_address)) { ret = 0; log_e("\n fm iic wr err 1\n"); goto __gcend; } u8 *pbuf = buf; while (data_len--) { delay(fm_dev_info->iic_delay); if (0 == iic_tx_byte(fm_dev_info->iic_hdl, *pbuf++)) { ret = 0; log_e("\n fm iic wr err 2\n"); goto __gcend; } } __gcend: iic_stop(fm_dev_info->iic_hdl); return ret; } u8 fm_dev_iic_readn(u8 r_chip_id, u8 register_address, u8 *buf, u8 data_len) { u8 read_len = 0; iic_start(fm_dev_info->iic_hdl); if (0 == iic_tx_byte(fm_dev_info->iic_hdl, (r_chip_id & 0x01) ? (r_chip_id - 1) : (r_chip_id))) { log_e("\n fm iic rd err 0\n"); read_len = 0; goto __gdend; } delay(fm_dev_info->iic_delay); if (0 == iic_tx_byte(fm_dev_info->iic_hdl, register_address)) { log_e("\n fm iic rd err 1\n"); read_len = 0; goto __gdend; } delay(fm_dev_info->iic_delay); iic_start(fm_dev_info->iic_hdl); if (0 == iic_tx_byte(fm_dev_info->iic_hdl, r_chip_id)) { log_e("\n fm iic rd err 2\n"); read_len = 0; goto __gdend; } delay(fm_dev_info->iic_delay); for (; data_len > 1; data_len--) { *buf++ = iic_rx_byte(fm_dev_info->iic_hdl, 1); read_len ++; } *buf = iic_rx_byte(fm_dev_info->iic_hdl, 0); __gdend: iic_stop(fm_dev_info->iic_hdl); delay(fm_dev_info->iic_delay); return read_len; } void fm_manage_check_online(void) { /* printf("fm check online dev \n"); */ /* printf("addr %x %x\n", fm_dev_begin, fm_dev_end); */ ////先找外挂fm list_for_each_fm(t_fm_hdl) { /* printf("find %x %x %s\n", t_fm_hdl, t_fm_hdl->read_id((void *)fm_dev_info), t_fm_hdl->logo); */ if (t_fm_hdl->read_id((void *)fm_dev_info) && (memcmp(t_fm_hdl->logo, "fm_inside", strlen(t_fm_hdl->logo)))) { fm_hdl = t_fm_hdl; printf("fm find dev %s \n", t_fm_hdl->logo); return; } } /* printf("no ex fm dev !!!\n"); */ list_for_each_fm(t_fm_hdl) { /* printf("# find %x %x %s\n", t_fm_hdl, t_fm_hdl->read_id((void *)fm_dev_info), t_fm_hdl->logo); */ if (t_fm_hdl->read_id((void *)fm_dev_info) && (!memcmp(t_fm_hdl->logo, "fm_inside", strlen(t_fm_hdl->logo)))) { fm_hdl = t_fm_hdl; printf("fm find dev %s \n", t_fm_hdl->logo); return; } } } /* early_initcall(fm_manage_check_online); */ int fm_manage_init() { fm_dev_info = (struct _fm_dev_info *)malloc(sizeof(struct _fm_dev_info)); if (fm_dev_info == NULL) { printf("fm_dev_init info malloc err!"); return -1; } memset(fm_dev_info, 0x00, sizeof(struct _fm_dev_info)); #if TCHFG_SOFT_I2C_ENABLE fm_dev_info->iic_hdl = fm_dev_platform_data->iic_hdl; fm_dev_info->iic_delay = fm_dev_platform_data->iic_delay; iic_init(fm_dev_info->iic_hdl); #endif fm_manage_check_online(); if (!fm_hdl) { printf("fm_manage could not find dev\n"); return -1; } else { memcpy(fm_dev_info->logo, fm_hdl->logo, strlen(fm_hdl->logo)); printf("fm_manage found dev %s\n", fm_dev_info->logo); } if (fm_hdl) { fm_hdl->init((void *)fm_dev_info); } return 0; } int fm_manage_start() { if (!fm_hdl || !fm_dev_info) { printf("fm_manage could not find dev\n"); return -1; } if (memcmp(fm_dev_info->logo, "fm_inside", strlen(fm_dev_info->logo))) {//不开启内部收音开启linein #if (TCFG_FM_INPUT_WAY != LINEIN_INPUT_WAY_ADC) if (!app_audio_get_volume(APP_AUDIO_STATE_MUSIC)) { audio_linein_mute(1); //模拟输出时候,dac为0也有数据 } #endif #if (TCFG_FM_INPUT_WAY == LINEIN_INPUT_WAY_ADC) linein_dec_open(TCFG_FMIN_LR_CH, 44100); #else if (TCFG_FMIN_LR_CH & (BIT(0) | BIT(1))) { audio_linein0_open(TCFG_FMIN_LR_CH, 1); } else if (TCFG_FMIN_LR_CH & (BIT(2) | BIT(3))) { audio_linein1_open(TCFG_FMIN_LR_CH, 1); } else if (TCFG_FMIN_LR_CH & (BIT(4) | BIT(5))) { audio_linein2_open(TCFG_FMIN_LR_CH, 1); } audio_linein_gain(1); // high gain #endif #if (TCFG_FM_INPUT_WAY != LINEIN_INPUT_WAY_ADC) if (app_audio_get_volume(APP_AUDIO_STATE_MUSIC)) { audio_linein_mute(0); app_audio_set_volume(APP_AUDIO_STATE_MUSIC, app_audio_get_volume(APP_AUDIO_STATE_MUSIC), 1);//防止无法调整 } //模拟输出时候,dac为0也有数据 #endif } else { fm_dec_open(0xff, 37500);//打开内置收音解码通道 } return 0; } static u16 cur_fmrx_freq = 0; bool fm_manage_set_fre(u16 fre) { if (fm_hdl) { cur_fmrx_freq = fre; return fm_hdl->set_fre((void *)fm_dev_info, fre); } return 0; } u16 fm_manage_get_fre() { if (fm_hdl) { return cur_fmrx_freq; } return 0; } void fm_manage_close(void) { if (fm_hdl) { fm_hdl->close((void *)fm_dev_info); fm_hdl = NULL; } if (fm_dev_info != NULL) { free(fm_dev_info); fm_dev_info = NULL; } if (t_fm_hdl && memcmp(t_fm_hdl->logo, "fm_inside", strlen(t_fm_hdl->logo))) { //不使用内部收音开启linein #if (TCFG_FM_INPUT_WAY == LINEIN_INPUT_WAY_ADC) linein_dec_close(); #else if (TCFG_FMIN_LR_CH & (BIT(0) | BIT(1))) { audio_linein0_close(TCFG_FMIN_LR_CH, 0); } else if (TCFG_FMIN_LR_CH & (BIT(2) | BIT(3))) { audio_linein1_close(TCFG_FMIN_LR_CH, 0); } else if (TCFG_FMIN_LR_CH & (BIT(4) | BIT(5))) { audio_linein2_close(TCFG_FMIN_LR_CH, 0); } #endif } } void fm_manage_mute(u8 mute) { if (fm_hdl) { fm_hdl->mute((void *)fm_dev_info, mute); } } #endif