#include "media/includes.h" #include "system/includes.h" #include "app_config.h" #include "app_task.h" #include "app_action.h" #include "tone_player.h" #include "app_main.h" #include "ui_manage.h" #include "vm.h" #include "key_event_deal.h" #include "asm/pwm_led.h" #include "user_cfg.h" #include "ui/ui_api.h" #include "clock_cfg.h" #include "includes.h" #include "fm/fm_api.h" #include "fm/fm_manage.h" #include "fm/fm_rw.h" #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" /************************************************************* 此文件函数主要是fm模式按键处理和事件处理 void app_fm_task() fm模式主函数 static int fm_event_handler(struct sys_event *event) fm系统事件所有处理入口 static void fm_app_unint(void) fm模式退出 **************************************************************/ #if TCFG_APP_FM_EN static u8 fm_idle_flag = 1; static u8 *fm_code_run_addr = NULL; static u8 *vm_spi_code_run_addr = NULL; u8 *get_vm_spi_code_run_addr() { return vm_spi_code_run_addr; } //----------------------------------------------------------------------------- static u16 tm_led; static int t_cnt; static u8 led_flag; static void led_cb(void *priv) { if (fm_get_play_statue() == 0) { t_cnt++; if (t_cnt > 1) { t_cnt = 0; if (led_flag == 1) { led_flag = 0; gpio_set_output_value(IO_PORTB_05, led_flag); } else { led_flag = 1; gpio_set_output_value(IO_PORTB_05, led_flag); } } } else { led_flag = 1; gpio_set_output_value(IO_PORTB_05, led_flag); } } static void start_led(void) { if (tm_led) { sys_timer_del(tm_led); } t_cnt = 0; led_flag = 1; tm_led = sys_timer_add(NULL, led_cb, 250); } //-------------------------------------------------------------------------------- //*----------------------------------------------------------------------------*/ /**@brief fm按键消息入口 @param 无 @return 1、消息已经处理,不需要发送到common 0、消息发送到common处理 @note */ /*----------------------------------------------------------------------------*/ static int fm_key_event_opr(struct sys_event *event) { int ret = true; u16 fre; struct key_event *key = &event->u.key; int key_event = event->u.key.event; int key_value = event->u.key.value; // r_printf("key value:%d, event:%d \n", key->value, key->event); #if (TCFG_SPI_LCD_ENABLE) extern int key_is_ui_takeover(); if (key_is_ui_takeover()) { return false; } #endif switch (key_event) { case KEY_TEST_DEMO_0: log_info("KEY_TEST_DEMO_0 = %d \n", key_value); app_task_put_key_msg(KEY_TEST_DEMO_1, 5678); // test demo break; case KEY_TEST_DEMO_1: log_info("KEY_TEST_DEMO_1 = %d \n", key_value); // test demo break; case KEY_MUSIC_PP: // 暂停播放 /* app_task_put_key_msg(KEY_TEST_DEMO_0,1234); //test demo// */ fm_volume_pp(); break; case KEY_FM_SCAN_ALL: // 全自动搜台 case KEY_FM_SCAN_ALL_DOWN: // 全自动搜台 case KEY_FM_SCAN_ALL_UP: // 全自动搜台 fm_scan_all(); break; case KEY_FM_SCAN_DOWN: fm_scan_down(); // 半自动搜台 break; case KEY_FM_SCAN_UP: fm_scan_up(); // 半自动搜台 break; case KEY_FM_PREV_STATION: // 下一台 fm_prev_station(); break; case KEY_FM_NEXT_STATION: fm_next_station(); break; case KEY_FM_PREV_FREQ: // 下一个频率 fm_prev_freq(); break; case KEY_FM_NEXT_FREQ: fm_next_freq(); break; case KEY_VOL_UP: fm_volume_up(); break; case KEY_VOL_DOWN: fm_volume_down(); break; case KEY_FM_DEL_STATION: extern u16 fm_get_cur_fre(void); fre = fm_get_cur_fre(); delete_fm_point(VIRTUAL_FREQ(REAL_FREQ(fre))); UI_MSG_POST("fm_fre", NULL); break; default: ret = false; break; } #if (SMART_BOX_EN) extern void smartbot_fm_msg_deal(int msg); smartbot_fm_msg_deal(key_event); #endif return ret; } //*----------------------------------------------------------------------------*/ /**@brief fm 模式活跃状态 所有消息入口 @param 无 @return 1、当前消息已经处理,不需要发送comomon 0、当前消息不是fm处理的,发送到common统一处理 @note */ /*----------------------------------------------------------------------------*/ static int fm_event_handler(struct sys_event *event) { int err = 0; switch (event->type) { case SYS_KEY_EVENT: return fm_key_event_opr(event); break; case SYS_DEVICE_EVENT: if ((u32)event->arg == DEVICE_EVENT_FROM_FM) { if (event->u.dev.event == DEVICE_EVENT_IN) { log_info("fm online \n"); } else if (event->u.dev.event == DEVICE_EVENT_OUT) { log_info("fm offline \n"); app_task_switch_next(); } return true; } return false; default: return false; } } extern u32 __app_movable_slot_start[]; extern u32 __app_movable_slot2_start[]; extern u32 __app_movable_slot3_start[]; extern u32 __app_movable_slot4_start[]; extern u8 __movable_region_start[]; extern u8 __movable_region2_start[]; extern u8 __movable_region3_start[]; extern u8 __movable_region4_start[]; extern u8 __fm_overlay_movable_saddr[]; static u32 *start_of_region_fm = NULL; // 记录当前代码所在区域的起始地址 static u32 *start_of_region_spi = NULL; // 记录当前代码所在区域的起始地址 static void fm_app_init(void) { #if TCFG_CODE_RUN_RAM_FM_MODE int code_size = __movable_region2_start - __movable_region_start; printf("code_size:%d\n", code_size); mem_stats(); if (code_size && fm_code_run_addr == NULL) { #if TCFG_CODE_RUN_OVERLAY_FM_MODE fm_code_run_addr = __fm_overlay_movable_saddr; #else fm_code_run_addr = phy_malloc(code_size); #endif } if (fm_code_run_addr) { printf("fm_code_run_addr:0x%x", fm_code_run_addr); code_movable_load(__movable_region_start, code_size, fm_code_run_addr, __app_movable_slot_start, __app_movable_slot2_start, &start_of_region_fm); mem_stats(); } #endif #if TCFG_VM_SPI_CODE_AT_RAM_DYANMIC int code_size1 = __movable_region4_start - __movable_region3_start; printf("code_size1:%d\n", code_size1); if (code_size1 && vm_spi_code_run_addr == NULL) { vm_spi_code_run_addr = phy_malloc(code_size1); } if (vm_spi_code_run_addr) { printf("vm_spi_code_run_addr:0x%x", vm_spi_code_run_addr); code_movable_load(__movable_region3_start, code_size1, vm_spi_code_run_addr, __app_movable_slot3_start, __app_movable_slot4_start, &start_of_region_spi); } #endif fm_idle_flag = 0; sys_key_event_enable(); ui_update_status(STATUS_FM_MODE); clock_idle(FM_IDLE_CLOCK); fm_manage_init(); // fm_api_init(); // 设置频率信息 } static void fm_app_start(void) { fm_manage_start(); // 收音出声 } static void fm_app_uninit(void) { fm_api_release(); fm_manage_close(); /* tone_play_stop(); */ tone_play_stop_by_path(tone_table[IDEX_TONE_FM]); fm_idle_flag = 1; #if TCFG_CODE_RUN_RAM_FM_MODE if (fm_code_run_addr) { mem_stats(); code_movable_unload(__movable_region_start, __app_movable_slot_start, __app_movable_slot2_start, &start_of_region_fm); #if (!TCFG_CODE_RUN_OVERLAY_FM_MODE) phy_free(fm_code_run_addr); #endif fm_code_run_addr = NULL; mem_stats(); } #endif #if TCFG_VM_SPI_CODE_AT_RAM_DYANMIC if (vm_spi_code_run_addr) { code_movable_unload(__movable_region3_start, __app_movable_slot3_start, __app_movable_slot4_start, &start_of_region_spi); phy_free(vm_spi_code_run_addr); vm_spi_code_run_addr = NULL; } #endif } static void fm_tone_play_end_callback(void *priv, int flag) { u32 index = (u32)priv; if (APP_FM_TASK != app_get_curr_task()) { log_error("tone callback task out \n"); return; } switch (index) { case IDEX_TONE_FM: /// 提示音播放结束, 启动播放器播放 fm_app_start(); break; default: break; } } //*----------------------------------------------------------------------------*/ /**@brief fm主任务 @param 无 @return 无 @note */ /*----------------------------------------------------------------------------*/ extern int bt_background_close_bt_hardward(u8 wait_flag); int fm_close_bt() { int flag; int msg[32]; // fm和蓝牙共用模拟,后台时需要进入的时候关闭蓝牙 flag = bt_background_close_bt_hardward(1); if (flag != 0) { // 搞个消息获取驱动sys timer的执行 app_task_get_msg(msg, ARRAY_SIZE(msg), 1); } return flag; } void app_fm_task() { int msg[32]; /* //fm和蓝牙共用模拟的时候,蓝牙后台时需要进入FM的时候关闭蓝牙,谁需要自己打开用 if (fm_close_bt() != 0) { return; }*/ // PA mode set to class AB gpio_set_pull_down(IO_PORTA_02, 0); gpio_set_pull_up(IO_PORTA_02, 0); gpio_set_direction(IO_PORTA_02, 0); gpio_set_output_value(IO_PORTA_02, 1); fm_app_init(); #if TCFG_DEC2TWS_ENABLE extern void set_tws_background_connected_flag(u8 flag); extern u8 get_tws_background_connected_flag(); if (get_tws_background_connected_flag()) { // 不播放提示音 fm_app_start(); set_tws_background_connected_flag(0); } else #endif { tone_play_with_callback_by_name(tone_table[IDEX_TONE_FM], 1, fm_tone_play_end_callback, (void *)IDEX_TONE_FM); } // if (err) { // ///提示音播放失败,直接启动播放 // fm_app_start(); // } start_led(); while (1) { app_task_get_msg(msg, ARRAY_SIZE(msg), 1); switch (msg[0]) { case APP_MSG_SYS_EVENT: if (fm_event_handler((struct sys_event *)(&msg[1])) == false) { app_default_event_deal((struct sys_event *)(&msg[1])); // 由common统一处理 } break; default: break; } if (app_task_exitting()) { sys_timer_del(tm_led); gpio_set_output_value(IO_PORTB_05, 1); fm_app_uninit(); return; } } } static u8 fm_idle_query(void) { return fm_idle_flag; } REGISTER_LP_TARGET(fm_lp_target) = { .name = "fm", .is_idle = fm_idle_query, }; #else void app_fm_task() { } #endif