257 lines
6.8 KiB
C
257 lines
6.8 KiB
C
|
|
#include "sys_config.h"
|
|
#include "typesdef.h"
|
|
#include "dev.h"
|
|
#include "devid.h"
|
|
#include "osal/irq.h"
|
|
#include "osal/string.h"
|
|
#include "osal/work.h"
|
|
#include "dev/vpp/hgvpp.h"
|
|
#include "dev/scale/hgscale.h"
|
|
#include "osal/msgqueue.h"
|
|
#include "stream_frame.h"
|
|
#include "custom_mem.h"
|
|
#include "hal/dma.h"
|
|
|
|
//暂定这个scale3是在存在dvp的时候使用,所以用宏隔离
|
|
//实际scale3还有另一种模式不需要dvp那边启动的
|
|
#if DVP_EN == 1
|
|
|
|
|
|
//区分主要是为了类似结构体访问频繁,如果空间足够放在sram,减少访问psram导致cache切换频繁
|
|
//data因为一般是dma并且空间需要比较多,所以用psram
|
|
|
|
//data申请空间函数
|
|
#define SCALE3STREAM_MALLOC custom_malloc_psram
|
|
#define SCALE3STREAM_FREE custom_free_psram
|
|
#define SCALE3STREAM_ZALLOC custom_zalloc_psram
|
|
|
|
//结构体申请空间函数
|
|
#define SCALE3STREAM_LIBC_MALLOC custom_malloc
|
|
#define SCALE3STREAM_LIBC_FREE custom_free
|
|
#define SCALE3STREAM_LIBC_ZALLOC custom_zalloc
|
|
|
|
struct scale1_stream_arg_s
|
|
{
|
|
uint16_t iw;
|
|
uint16_t ih;
|
|
uint16_t ow;
|
|
uint16_t oh;
|
|
};
|
|
|
|
struct scale1Stream
|
|
{
|
|
struct os_work work;
|
|
stream *s;
|
|
uint8_t *scaler1buf; //scale的buf
|
|
struct scale_device *scale_dev;
|
|
struct dma_device *dma1;
|
|
uint16_t iw,ih,ow,oh;
|
|
uint8_t dma1_lock;
|
|
};
|
|
|
|
|
|
static int32_t scale_done(uint32 irq_flag,uint32 irq_data,uint32 param1)
|
|
{
|
|
_os_printf("=");
|
|
return 0;
|
|
}
|
|
|
|
static int32_t scale_ov_isr(uint32 irq_flag,uint32 irq_data,uint32 param1)
|
|
{
|
|
os_printf("sor");
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int32 scale1_stream_work(struct os_work *work)
|
|
{
|
|
struct scale1Stream *scale1_stream = (struct scale1Stream*)work;
|
|
if(scale1_stream->dma1_lock)
|
|
{
|
|
goto scale1_stream_work_lock;
|
|
}
|
|
//
|
|
dma_ioctl(scale1_stream->dma1, DMA_IOCTL_CMD_DMA1_LOCK, 0, 0);
|
|
scale1_stream->dma1_lock = dma_ioctl(scale1_stream->dma1, DMA_IOCTL_CMD_CHECK_DMA1_STATUS, 0, 0);
|
|
os_printf("scale1_stream->dma1:%X\n",scale1_stream->dma1);
|
|
os_printf("scale1_stream->dma1_lock:%d\n",scale1_stream->dma1_lock);
|
|
|
|
scale1_stream_work_lock:
|
|
if(scale1_stream->dma1_lock)
|
|
{
|
|
uint16_t s_w,s_h,d_w,d_h;
|
|
struct scale_device *scale_dev = scale1_stream->scale_dev;
|
|
uint8_t *yuvbuf_addr = scale1_stream->scaler1buf;
|
|
s_w = scale1_stream->iw;
|
|
s_h = scale1_stream->ih;
|
|
d_w = scale1_stream->ow;
|
|
d_h = scale1_stream->oh;
|
|
scale_close(scale_dev);
|
|
scale_set_in_out_size(scale_dev,s_w,s_h,d_w,d_h);
|
|
scale_set_step(scale_dev,s_w,s_h,d_w,d_h);
|
|
scale_set_line_buf_num(scale_dev,32);
|
|
scale_set_in_yaddr(scale_dev,(uint32_t)yuvbuf_addr);
|
|
scale_set_in_uaddr(scale_dev,(uint32_t)yuvbuf_addr+s_w*32);
|
|
scale_set_in_vaddr(scale_dev,(uint32_t)yuvbuf_addr+s_w*32+s_w*8);
|
|
scale_request_irq(scale_dev,FRAME_END,scale_done,(uint32)scale_dev);
|
|
scale_request_irq(scale_dev,INBUF_OV,scale_ov_isr,(uint32)scale_dev);
|
|
scale_set_data_from_vpp(scale_dev,1);
|
|
scale_open(scale_dev);
|
|
os_printf("%s lock success\n",__FUNCTION__,__LINE__);
|
|
}
|
|
//下一次重新获取
|
|
else
|
|
{
|
|
os_run_work_delay(work, 1000);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
static uint32_t stream_cmd_func(stream *s,int cmd,uint32_t arg)
|
|
{
|
|
uint32_t res = 0;
|
|
switch(cmd)
|
|
{
|
|
//支持配置输出,因为摄像头应该是固定的,除非多摄像头要切换,才需要对输入源也要修改
|
|
case SCALE1_RESET_DPI:
|
|
{
|
|
struct scale1Stream *scale1_stream = (struct scale1Stream*)s->priv;
|
|
uint32_t w_h = (uint32_t)arg;
|
|
scale1_stream->ow = w_h>>16;
|
|
scale1_stream->oh = w_h&0xffff;
|
|
//启动work,重新配置一下分辨率
|
|
OS_WORK_REINIT(&scale1_stream->work);
|
|
os_run_work_delay(&scale1_stream->work, 1);
|
|
}
|
|
break;
|
|
|
|
case STREAM_STOP_CMD:
|
|
{
|
|
struct scale1Stream *scale1_stream = (struct scale1Stream*)s->priv;
|
|
os_work_cancle2(&scale1_stream->work,1);
|
|
scale_close(scale1_stream->scale_dev);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
static int opcode_func(stream *s,void *priv,int opcode)
|
|
{
|
|
int res = 0;
|
|
switch(opcode)
|
|
{
|
|
case STREAM_OPEN_ENTER:
|
|
break;
|
|
case STREAM_OPEN_EXIT:
|
|
{
|
|
struct scale1_stream_arg_s *msg = (struct scale1_stream_arg_s*)priv;
|
|
struct scale1Stream *scale1_stream = (struct scale1Stream*)SCALE3STREAM_LIBC_ZALLOC(sizeof(struct scale1Stream));
|
|
scale1_stream->dma1 = (struct dma_device *)dev_get(HG_M2MDMA_DEVID);
|
|
s->priv = (void*)scale1_stream;
|
|
scale1_stream->iw = msg->iw;
|
|
scale1_stream->ih = msg->ih;
|
|
scale1_stream->ow = msg->ow;
|
|
scale1_stream->oh = msg->oh;
|
|
extern uint8 *yuvbuf;
|
|
scale1_stream->scaler1buf = yuvbuf;
|
|
scale1_stream->scale_dev = (struct scale_device *)dev_get(HG_SCALE1_DEVID);
|
|
register_stream_self_cmd_func(s,stream_cmd_func);
|
|
OS_WORK_INIT(&scale1_stream->work, scale1_stream_work, 0);
|
|
os_run_work_delay(&scale1_stream->work, 1);
|
|
|
|
}
|
|
break;
|
|
case STREAM_OPEN_FAIL:
|
|
break;
|
|
case STREAM_DATA_DIS:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case STREAM_DATA_FREE:
|
|
{
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case STREAM_FILTER_DATA:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case STREAM_DATA_FREE_END:
|
|
break;
|
|
|
|
|
|
//数据发送完成,可以选择唤醒对应的任务
|
|
case STREAM_SEND_DATA_FINISH:
|
|
break;
|
|
|
|
|
|
case STREAM_SEND_DATA_START:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case STREAM_DATA_DESTORY:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case STREAM_CLOSE_EXIT:
|
|
{
|
|
struct scale1Stream *scale1_stream = (struct scale1Stream *)s->priv;
|
|
os_work_cancle2(&scale1_stream->work,1);
|
|
|
|
//关闭scale1
|
|
scale_close(scale1_stream->scale_dev);
|
|
if(scale1_stream->dma1_lock)
|
|
{
|
|
dma_ioctl(scale1_stream->dma1, DMA_IOCTL_CMD_DMA1_UNLOCK, 0, 0);
|
|
}
|
|
|
|
SCALE3STREAM_LIBC_FREE(scale1_stream);
|
|
break;
|
|
}
|
|
|
|
case STREAM_MARK_GC_END:
|
|
{
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
//默认都返回成功
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
|
|
//不绑定流,需要由外部绑定然后使能,这样可以动态绑定,不需要创建后就绑定(如果运行过程绑定,可能会有异步问题,所以暂时没有使用动态绑定方式)
|
|
stream *scale1_stream_not_bind(const char *name,uint16_t iw,uint16_t ih,uint16_t ow,uint16_t oh)
|
|
{
|
|
struct scale1_stream_arg_s msg;
|
|
msg.iw = iw;
|
|
msg.ih = ih;
|
|
msg.ow = ow;
|
|
msg.oh = oh;
|
|
stream *s = open_stream_available(name,0,0,opcode_func,&msg);
|
|
return s;
|
|
}
|
|
#else
|
|
stream *scale1_stream_not_bind(const char *name,uint16_t iw,uint16_t ih,uint16_t ow,uint16_t oh)
|
|
{
|
|
os_printf("%s:%d err,dvp not open\n",__FUNCTION__,__LINE__);
|
|
return NULL;
|
|
}
|
|
#endif |