KT24-1110_65E-HA-651B/apps/soundbox/task_manager/fm/fm.c
2024-11-10 21:14:01 +08:00

437 lines
11 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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