#include "sys_config.h" #include "basic_include.h" #include "lib/common/atcmd.h" #include "lib/net/eloop/eloop.h" #include "lib/video/isp/isp_dev.h" #include "lib/video/dvp/jpeg/jpg.h" #include "lib/video/mipi_csi/mipi_csi.h" #include "lib/video/h264/h264_drv.h" #include "lib/video/vpp/vpp_dev.h" #include "lib/video/para_in/para_in_dev.h" #include "lib/multimedia/msi.h" #include "stream_define.h" #include "syscfg.h" #include "app_lcd/app_lcd.h" #include "lib/net/dhcpd/dhcpd.h" #include "audio_msi/audio_adc.h" #include "audio_msi/audio_dac.h" #include "intercom/intercom.h" #include "lib/audio/audio_code/audio_code.h" #include "lib/audio/audio_proc/audio_proc.h" #include "lib/audio/wsola/wsola_process.h" #if RTT_USB_EN #include "rtthread.h" #endif #include "lib/heap/av_psram_heap.h" #include "lib/heap/av_heap.h" #include "app/spook/spook.h" #include "app/recorder/recorder_viidure.h" #include "app/app_iic/app_iic.h" #include "ota.h" #include "cjson/cJSON.h" #include "scale_msi/scale_msi.h" #include "lib/touch/touch_pad.h" #include "gen420_hardware_msi.h" #include "lib/sdhost/sdhost.h" #include "hg_lv_mem.h" #include "keyWork.h" #include "video_app/video_msi.h" #include "lib/lvgl_rotate_rpc/lvgl_rotate_msi.h" #include "debug_log_msi.h" #include "log_save_msi.h" #include "fpv_mem.h" #include "babyprotocol_playback.h" #include "babyprotocol_record.h" int32 atcmd_recv(uint8 *data, int32 len); void user_workqueue_init(uint16 pri,void *stack,uint16 stack_size); extern uint32 psrampool_start; extern uint32 psrampool_end; extern uint32 srampool_start; extern uint32 srampool_end; struct fpv_status { uint32_t dbg_av_heap:1, dbg_av_psram_heap:1, dbg_sram_heap:1, dbg_psram_heap:1; }; static struct fpv_status g_fpv_status; //fpv工程增加AT命令 const static void *r_heap[] = { #if defined(MPOOL_ALLOC) && defined(AV_PSRAM_HEAP) && defined(PSRAM_HEAP) (void*)&av_psram_heap, #endif #if defined(MPOOL_ALLOC) && defined(AV_HEAP) && defined(PSRAM_HEAP) (void*)&av_heap, #endif (void*)&sram_heap, (void*)&psram_heap, NULL, }; static int32 fpv_atcmd_check_heap(const char *cmd, char *argv[], uint32 argc) { char *arg = argv[0]; int i = 0; uint8_t mode; if(argc == 1) { mode = 0; } else { mode = os_atoi(argv[1]); } struct sys_heap *heap = (struct sys_heap *)r_heap[i]; while(heap) { if (os_strcasecmp(arg, heap->name) == 0) { if(mode == 0) { os_printf(KERN_ALERT"%s heap free size:%d\n",heap->name, sysheap_freesize(heap)); } else { uint32_t s_buf[256]; sysheap_status(heap, s_buf, sizeof(s_buf)/sizeof(uint32_t), 0); } break; } i++; heap = (struct sys_heap *)r_heap[i]; } if(!heap) { os_printf(KERN_ALERT"no found heap %s\n",arg); } return 0; } static int32 fpv_atcmd_dbg(const char *cmd, char *argv[], uint32 argc) { char *arg = argv[0]; if (argc == 2) { if (os_strcasecmp(arg, "av_sram") == 0) { g_fpv_status.dbg_av_heap = (os_atoi(argv[1]) == 1); } if (os_strcasecmp(arg, "av_psram") == 0) { g_fpv_status.dbg_av_psram_heap = os_atoi(argv[1]); } if (os_strcasecmp(arg, "sram") == 0) { g_fpv_status.dbg_sram_heap = (os_atoi(argv[1]) == 1); } if (os_strcasecmp(arg, "psram") == 0) { g_fpv_status.dbg_psram_heap = (os_atoi(argv[1]) == 1); } return 0; } else { return -1; } return 0; } __weak void user_protocol() { spook_init(); config_Viidure(80); } // 应用程序初始化 __init static void fpv_app_init(void) { #if TAKEPHOTO_EN || JPG_EN int8_t takephoto_from = 0; int8_t takephoto1_from = -1; #endif #ifdef PSRAM_HEAP cJSON_Hooks hook; hook.malloc_fn = _os_malloc_psram; hook.free_fn = _os_free_psram; cJSON_InitHooks(&hook); #endif eloop_init(); os_task_create("eloop_run", user_eloop_run, NULL, OS_TASK_PRIORITY_NORMAL + 2, 0, NULL, 2048); os_sleep_ms(1); ota_Tcp_Server(); //独立的文件保存msi(独立线程,后续可以所有的fb需要保存都发到这个msi去执行) extern struct msi *file_msi_init(const char *msi_name); file_msi_init(R_FILE_MSI); #ifndef FORCE_SCALE_TO_H264 #if H264_EN == 1 extern struct msi *auto_h264_msi_init(const char *auto_h264_name, uint8_t src_from0, uint16_t w0, uint16_t h0, uint8_t src_from1, uint16_t w1, uint16_t h1); #if SUB_STREAM_EN == 1 auto_h264_msi_init(AUTO_H264,VPP_DATA0,0,0,GEN420_DATA,640,360); #else auto_h264_msi_init(AUTO_H264,VPP_DATA0,0,0,~0,0,0); #endif #endif #else uint8_t get_vpp_scale_w_h(uint16_t *w, uint16_t *h); uint16_t scale_w,scale_h; int scale_ret = get_vpp_scale_w_h(&scale_w,&scale_h); if(!scale_ret) { os_printf(KERN_INFO"scale_w:%d\tscale_h:%d\n",scale_w,scale_h); auto_h264_msi_init(AUTO_H264,SCALER_DATA,scale_w,scale_h,GEN420_DATA,640,360); } else { os_printf(KERN_ERR"scale cfg err,scale_ret:%d\n",scale_ret); } #endif // 支持拍照和缩略图,暂时默认启动,(紧紧支持录风者模式) #if TAKEPHOTO_EN // 正常拍照和缩略图 { extern uint8_t get_vpp_w_h(uint16_t *w, uint16_t *h); extern void takephoto_with_thumb_init(const char *thumb_msi_name); extern void takephoto_with_thumb_over_dpi_init(const char *thumb_msi_name, uint8_t jpg_num); extern void takephoto_720P_with_thumb_init(const char *thumb_msi_name); uint16_t camera_w, camera_h; get_vpp_w_h(&camera_w, &camera_h); // 没有识别到摄像头 if (!camera_w || !camera_h) { } // 如果是720P摄像头,支持原分辨率以及大分辨拍照 else if (camera_w == 1280 && camera_h == 720) { takephoto_with_thumb_init(R_THUMB); takephoto_with_thumb_over_dpi_init(SR_OVER_DPI_THUMB_JPG, JPGID0); takephoto_from = VPP_DATA0; } // 其他摄像头,主要是为了拍照720P的图片,1080P摄像头从VPP_DATA1,不支持大分辨率拍照 else { takephoto_with_thumb_init(R_THUMB); takephoto_with_thumb_over_dpi_init(SR_OVER_DPI_THUMB_JPG, JPGID1); takephoto_from = VPP_DATA1; takephoto1_from = VPP_DATA0; } } #endif #if JPG_EN == 1 if(takephoto_from >= 0) { auto_jpg_msi_init(AUTO_JPG, JPGID0, takephoto_from); } if(takephoto1_from >= 0) { auto_jpg_msi_init(AUTO_JPG, JPGID1, takephoto1_from); } #endif #if USB_JPG_ADD_WATERMARK usb_to_recode_init(JPGID1); #endif /* 添加其他应用代码初始化 ... */ #if ISP_TUNNING_EN void isp_tunning_init(uint32 img_w, uint32 img_h); isp_tunning_init(1920, 1080); #endif user_protocol(); } __weak void user_hardware_config() { } static uint8_t vcam_en(void) { uint8_t ret = TRUE; #if VCAM_EN pmu_vcam_dis(); os_sleep_ms(1); pmu_set_vcam_vol(VCAM_VOL_2V80); pmu_vcam_oc_set(VCAM_OC_200MA); pmu_vcam_lc_en(); pmu_vcam_oc_int_dis(); pmu_vcam_discharge_dis(); pmu_vcam_pg_dis(); #ifdef VCAM_33 pmu_set_vcam_vol(VCAM_VOL_3V25); pmu_vcam_en(); os_sleep_ms(1); pmu_vcam_pg_en(); #else pmu_vcam_en(); os_sleep_ms(1); #endif pmu_vcam_oc_pending_clr(); pmu_vcam_oc_int_dis(); pmu_lvd_oe_en(); #endif return ret; } extern void scale2_mutex_init(); static void hardware_init(uint8_t vcam) { void eff_stop(); eff_stop(); iic_thread_init(); sensor_info_init(); scale2_mutex_init(); #if KEY_MODULE_EN == 1 keyWork_init(10); #endif #if JPG_EN == 1 extern int32 jpg_mutex_init(); extern void jpg_mem_init(int num); jpg_mutex_init(); jpg_mem_init(32); #endif #if SDH_EN && FS_EN extern bool fatfs_register(); sd_open(); fatfs_register(); file_ota(); #endif #if DEBUG_LOG_FILE_SAVE_EN //默认写入到SD卡,不支持中断打印保存 //默认每10秒同步写卡,每60秒新建一个文件保存 creat_log_save_stream(R_DEBUG_STREAM, 1000, 60*1000); struct msi *dbg_msi = dbg_log_msi(S_DEBUG_STREAM); if(dbg_msi) { print_redirect((osprint_hook)hgprntf_debug_log_msi, dbg_msi->priv, 1); } #endif #if LCD_EN uint16_t osd_w, osd_h; uint16_t screen_w, screen_h; uint16_t video_w, video_h; uint8_t rotate, video_rotate; lcd_hardware_init(&osd_w, &osd_h, &rotate, &screen_w, &screen_h,&video_w, &video_h, &video_rotate); lcd_arg_setting(osd_w, osd_h, rotate, screen_w, screen_h,video_w,video_h, video_rotate); lcd_driver_init(R_OSD_ENCODE, R_LCD_OSD, R_VIDEO_P0, R_VIDEO_P1); #endif #if TOUCH_PAD_EN touch_pad_hareware_init(); #endif #if AUDIO_EN reg_auproc_alloc(av_malloc, av_zalloc, av_calloc, av_realloc, av_free); reg_wsola_alloc(av_malloc, av_zalloc, av_calloc, av_realloc, av_free); reg_aucoder_alloc(av_malloc, av_zalloc, av_calloc, av_realloc, av_free); aucode_mutex_init(); audio_adc_init(AUSYS_AUAD, 8000, 1, 4, 1); audio_dac_init(); #endif #if LCD_EN void lcd_demo_thread(int32_t d); void lvgl_init_msi(uint16_t w, uint16_t h, uint8_t rotate); #if LVGL_HW_ROTATE_RPC_EN struct hg_lv_mem_hooks hook = { .malloc = _os_malloc, .realloc = _os_realloc, .zalloc = _os_zalloc, .free = _os_free, }; #else struct hg_lv_mem_hooks hook = { .malloc = av_psram_malloc, .realloc = av_psram_realloc, .zalloc = av_psram_zalloc, .free = av_psram_free, }; #endif hg_lv_mem_register(&hook); lvgl_init_msi(osd_w, osd_h, rotate); lcd_demo_thread(2); #endif user_hardware_config(); } static struct os_work fpv_wk; extern void print_status(uint32_t *s_buf, uint32_t size); static int32 sys_fpv_loop(struct os_work *work) { uint32_t s_buf[256]; if(g_fpv_status.dbg_sram_heap) { sysheap_status(&sram_heap, s_buf, sizeof(s_buf) / 4, 0); } if(g_fpv_status.dbg_psram_heap) { sysheap_status(&psram_heap, s_buf, sizeof(s_buf) / 4, 0); } #if defined(MPOOL_ALLOC) && defined(AV_PSRAM_HEAP) && defined(PSRAM_HEAP) if(g_fpv_status.dbg_av_psram_heap) { sysheap_status(&av_psram_heap, s_buf, sizeof(s_buf) / 4, 0); } #endif #if defined(MPOOL_ALLOC) && defined(AV_HEAP) if(g_fpv_status.dbg_av_heap) { sysheap_status(&av_heap, s_buf, sizeof(s_buf) / 4, 0); } #endif os_run_work_delay(work, 1000); return 0; } //部分控制at命令 static void fpv_at_dbg() { //是否打开对应sdk的dbg atcmd_recv((uint8_t*)"at+print=1,7",0); atcmd_recv((uint8_t*)"AT+FPV_DBG=av_psram,0",0); atcmd_recv((uint8_t*)"AT+FPV_DBG=av_sram,0",0); atcmd_recv((uint8_t*)"AT+FPV_DBG=sram,0",0); atcmd_recv((uint8_t*)"AT+FPV_DBG=psram,0",0); atcmd_recv((uint8_t*)"AT+SYSDBG=top,0",0); #if 0 //一次性命令 atcmd_recv("AT+FPV_HEAP=av_psram,0",0); atcmd_recv("AT+FPV_HEAP=av_sram,0",0); atcmd_recv("AT+FPV_HEAP=sram,0",0); atcmd_recv("AT+FPV_HEAP=psram,0",0); #endif } /********************************************************************** * print_level设置打印的等级,7是将所有打印都打开(调试的时候可以打开) * 例子:对应不同等级参考string.h * os_printf(KERN_DEBUG"ABC"); //等级7 * os_printf(KERN_EMERG"ABC"); //等级1 * disable_print_color 是否关闭打印颜色(特定串口工具) *******************************************************************/ int sys_app_bbm_lcd_init(void) { print_level(7); disable_print_color(1); uint8_t vcam; user_heap_init(); vcam = vcam_en(); pmu_vcam2_ldo_en(1, VCC_LDO_VOL_1V80); msi_core_init(); //初始化fpv应用用的workqueue,注意这个workqueu是应用,尽量不要执行过长时间 user_workqueue_init(OS_TASK_PRIORITY_HIGH,NULL,2048); hardware_init(vcam); fpv_app_init(); intercom_init(); fpv_at_dbg(); OS_WORK_INIT(&fpv_wk, sys_fpv_loop, 0); os_run_work_delay(&fpv_wk, 1000); return 0; }