GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
Symlink
+1
@@ -0,0 +1 @@
|
||||
../build/mcu.mk
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
|
||||
SRCS-y += drivers/
|
||||
SRCS-y += devices/
|
||||
SRCS-y += sensors/
|
||||
SRCS-y += sample/
|
||||
|
||||
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../source/gmp/usr/isp/libs/riscv
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
|
||||
SRCS-y += i2c_dev.c
|
||||
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#include"xmedia_type.h"
|
||||
#include"xmedia_errcode.h"
|
||||
#include"i2c.h"
|
||||
#include "compile.h"
|
||||
|
||||
#define REG_ADDR_MAX_WIDTH 2//16BIT
|
||||
|
||||
STAGE1_FUNC xmedia_s32 i2c_read(xmedia_s32 fd, xmedia_u16 slave_addr, xmedia_u32 read_addr,
|
||||
xmedia_u8 addr_width, xmedia_u8 *buff, xmedia_u32 length)
|
||||
{
|
||||
struct i2c_client client;
|
||||
|
||||
if(addr_width > REG_ADDR_MAX_WIDTH){
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
client.i2c_num = fd;
|
||||
client.dev_addr = slave_addr >> 1;
|
||||
client.reg_addr = read_addr;
|
||||
client.reg_width = addr_width;
|
||||
|
||||
return i2c_recv(&client, buff, length);
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_s32 i2c_write(xmedia_s32 fd, xmedia_u16 slave_addr, xmedia_u8 *buff, xmedia_u32 length)
|
||||
{
|
||||
return i2c_send(fd, slave_addr >> 1, (xmedia_void *)buff, length);
|
||||
}
|
||||
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
|
||||
SRCS-y += hal_isp.c
|
||||
SRCS-y += drv_isp.c
|
||||
SRCS-y += hal_vi.c
|
||||
SRCS-y += drv_vi.c
|
||||
|
||||
|
||||
Executable
+826
@@ -0,0 +1,826 @@
|
||||
#include "config.h"
|
||||
#include "string.h"
|
||||
#include "stdlib.h"
|
||||
#include "stdio.h"
|
||||
#include "xmedia_type.h"
|
||||
#include "xmedia_isp.h"
|
||||
#include "xmedia_errcode.h"
|
||||
#include "isp_def.h"
|
||||
#include "hal_isp.h"
|
||||
#include "drv_isp.h"
|
||||
#include "platform.h"
|
||||
#include "timer.h"
|
||||
|
||||
#define CCM_MINUS_PARAM_TH 32768
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool ae_lib;
|
||||
xmedia_bool awb_lib;
|
||||
xmedia_bool sensor_lib;
|
||||
xmedia_isp_ae_register_info ae_info;
|
||||
xmedia_isp_awb_register_info awb_info;
|
||||
xmedia_sensor_register_info sensor_info;
|
||||
} isp_lib_info;
|
||||
|
||||
typedef struct {
|
||||
xmedia_isp_config isp_config;
|
||||
xmedia_u32 isp_frame_cnt;
|
||||
xmedia_void *firmware_info;
|
||||
isp_lib_info *lib_info;
|
||||
|
||||
xmedia_sensor_init_param *result;
|
||||
} isp_context;
|
||||
|
||||
STAGE1_GLOBAL static isp_context *g_isp_ctx[ISP_PIPE_MAX_NUM] = { 0 };
|
||||
STAGE1_GLOBAL static isp_lib_info g_isp_lib[ISP_PIPE_MAX_NUM] = { 0 };
|
||||
STAGE1_GLOBAL static xmedia_u8 g_sensor_clk_ch[ISP_PIPE_MAX_NUM] = { 0 };
|
||||
STAGE1_GLOBAL static xmedia_u8 g_sensor_rst_ch[ISP_PIPE_MAX_NUM] = { 0 };
|
||||
|
||||
#define ISP_GET_CTX(pipe, ctx) ctx = g_isp_ctx[pipe]
|
||||
#define ISP_GET_LIB(pipe, ptr) ptr = &g_isp_lib[pipe]
|
||||
|
||||
#define TIMER_CLOCK_FRQ 24000000
|
||||
|
||||
xmedia_u32 isp_get_time_stamp(xmedia_void)
|
||||
{
|
||||
return (xmedia_u32)timer_get_val() / 24; // = timer_value * 10000000 / 24000000
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_s32 xmedia_isp_register_sensor(xmedia_u32 pipe, const xmedia_sensor_register_info *info)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM || info == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
|
||||
if (lib->sensor_lib == XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_EXIST;
|
||||
}
|
||||
|
||||
// sensor需要在ISP初始化之前注册,ISP初始化时才会为ctx分配内存,所以用ctx来作为判断条件
|
||||
if (ctx != XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
memcpy(&lib->sensor_info, info, sizeof(xmedia_sensor_register_info));
|
||||
lib->sensor_lib = XMEDIA_TRUE;
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_isp_unregister_sensor(xmedia_u32 pipe, xmedia_u32 dev_id)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
|
||||
if (lib->sensor_lib == XMEDIA_FALSE) {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
// sensor需要在ISP退出之后反注册,ISP退出时才会释放ctx内存,所以用ctx来作为判断条件
|
||||
if (ctx != XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
if (lib->sensor_info.dev_id != dev_id) {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
lib->sensor_lib = XMEDIA_FALSE;
|
||||
memset(&lib->sensor_info, 0, sizeof(xmedia_sensor_register_info));
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_isp_register_ae_lib(xmedia_u32 pipe, const xmedia_isp_ae_register_info *ae_info,
|
||||
xmedia_sensor_register_ae_info *sensor_func)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM || ae_info == XMEDIA_NULL || sensor_func == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
|
||||
if (lib->ae_lib == XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_EXIST;
|
||||
}
|
||||
|
||||
// 3a需要在ISP初始化之前注册,ISP初始化时才会为ctx分配内存,所以用ctx来作为判断条件
|
||||
if (ctx != XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
if (lib->sensor_lib != XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
memcpy(&sensor_func->func, &lib->sensor_info.ae_func, sizeof(xmedia_sensor_register_ae_func));
|
||||
sensor_func->dev_id = lib->sensor_info.dev_id;
|
||||
|
||||
memcpy(&lib->ae_info, ae_info, sizeof(xmedia_isp_ae_register_info));
|
||||
lib->ae_lib = XMEDIA_TRUE;
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_isp_unregister_ae_lib(xmedia_u32 pipe, xmedia_char name[XMEDIA_ISP_ALG_NAME_MAX_SIZE], xmedia_s32 id)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM || name == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
|
||||
if (lib->ae_lib == XMEDIA_FALSE) {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
// 3a需要在ISP退出之后反注册,ISP退出时才会释放ctx内存,所以用ctx来作为判断条件
|
||||
if (ctx != XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
if (lib->ae_info.alg_id == id && strncmp(lib->ae_info.alg_name, name, XMEDIA_ISP_ALG_NAME_MAX_SIZE) == 0) {
|
||||
memset(&lib->ae_info, 0, sizeof(xmedia_isp_ae_register_info));
|
||||
lib->ae_lib = XMEDIA_FALSE;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_isp_register_awb_lib(xmedia_u32 pipe, const xmedia_isp_awb_register_info *awb_info,
|
||||
xmedia_sensor_register_awb_info *sensor_func)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM || awb_info == XMEDIA_NULL || sensor_func == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
|
||||
if (lib->awb_lib == XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_EXIST;
|
||||
}
|
||||
|
||||
// 3a需要在ISP初始化之前注册,ISP初始化时才会为ctx分配内存,所以用ctx来作为判断条件
|
||||
if (ctx != XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
if (lib->sensor_lib != XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
memcpy(&sensor_func->func, &lib->sensor_info.awb_func, sizeof(xmedia_sensor_register_awb_func));
|
||||
sensor_func->dev_id = lib->sensor_info.dev_id;
|
||||
|
||||
memcpy(&lib->awb_info, awb_info, sizeof(xmedia_isp_awb_register_info));
|
||||
lib->awb_lib = XMEDIA_TRUE;
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 xmedia_isp_unregister_awb_lib(xmedia_u32 pipe, xmedia_char name[XMEDIA_ISP_ALG_NAME_MAX_SIZE], xmedia_s32 id)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM || name == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
|
||||
if (lib->awb_lib == XMEDIA_FALSE) {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
// 3a需要在ISP退出之后反注册,ISP退出时才会释放ctx内存,所以用ctx来作为判断条件
|
||||
if (ctx != XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
if (lib->awb_info.alg_id == id && strncmp(lib->awb_info.alg_name, name, XMEDIA_ISP_ALG_NAME_MAX_SIZE) == 0) {
|
||||
memset(&lib->awb_info, 0, sizeof(xmedia_isp_awb_register_info));
|
||||
lib->awb_lib = XMEDIA_FALSE;
|
||||
} else {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_s32 drv_sensor_init(xmedia_u32 pipe, xmedia_sensor_config *cfg)
|
||||
{
|
||||
xmedia_s32 ret = 0;
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
xmedia_sensor_capability capability;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM || cfg == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
if (lib->sensor_lib != XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (lib->sensor_info.isp_func.pfn_sensor_init == XMEDIA_NULL ||
|
||||
lib->sensor_info.isp_func.pfn_sensor_set_bus_info == XMEDIA_NULL ||
|
||||
lib->sensor_info.isp_func.pfn_sensor_get_capability == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
g_sensor_clk_ch[pipe] = cfg->ctrl_sig.clk_ch;
|
||||
g_sensor_rst_ch[pipe] = cfg->ctrl_sig.rst_ch;
|
||||
|
||||
ret = lib->sensor_info.isp_func.pfn_sensor_set_bus_info(lib->sensor_info.dev_id, &cfg->comm_bus);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = lib->sensor_info.isp_func.pfn_sensor_get_capability(&capability);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (capability.reset_time <= 0) {
|
||||
capability.reset_time = 100;
|
||||
}
|
||||
|
||||
hal_sensor_set_mclk(g_sensor_clk_ch[pipe], capability.init_mclk);
|
||||
|
||||
//sensor cold start use normal, hot start use skip
|
||||
if (cfg->init_mode != XMEDIA_SENSOR_INIT_MODE_SKIP) {
|
||||
hal_sensor_reset(g_sensor_rst_ch[pipe], XMEDIA_TRUE);
|
||||
udelay(capability.reset_time);
|
||||
hal_sensor_reset(g_sensor_rst_ch[pipe], XMEDIA_FALSE);
|
||||
}
|
||||
|
||||
udelay(1000*4);
|
||||
|
||||
return lib->sensor_info.isp_func.pfn_sensor_init(lib->sensor_info.dev_id, cfg->init_mode);
|
||||
}
|
||||
|
||||
xmedia_s32 drv_sensor_exit(xmedia_u32 pipe)
|
||||
{
|
||||
xmedia_s32 ret = 0;
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
if (lib->sensor_lib != XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (lib->sensor_info.isp_func.pfn_sensor_exit == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
ret = lib->sensor_info.isp_func.pfn_sensor_exit(lib->sensor_info.dev_id);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_s32 drv_sensor_resume(xmedia_u32 pipe)
|
||||
{
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
puts("pipe error \n");
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
if (lib->sensor_lib != XMEDIA_TRUE) {
|
||||
puts("sensor lib error\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (lib->sensor_info.isp_func.pfn_sensor_resume == XMEDIA_NULL) {
|
||||
puts("sensor resume none\n");
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return lib->sensor_info.isp_func.pfn_sensor_resume(lib->sensor_info.dev_id);
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_s32 drv_sensor_start(xmedia_u32 pipe)
|
||||
{
|
||||
xmedia_s32 ret = 0;
|
||||
xmedia_u32 mclk = 0;
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
xmedia_sensor_property property;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
if (lib->sensor_lib != XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (lib->sensor_info.isp_func.pfn_sensor_start == XMEDIA_NULL ||
|
||||
lib->sensor_info.isp_func.pfn_sensor_get_property == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
ret = lib->sensor_info.isp_func.pfn_sensor_get_property(lib->sensor_info.dev_id, &property);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
hal_sensor_read_mclk(g_sensor_clk_ch[pipe], &mclk);
|
||||
if (property.input_clock != mclk) {
|
||||
hal_sensor_set_mclk(g_sensor_clk_ch[pipe], property.input_clock);
|
||||
}
|
||||
|
||||
return lib->sensor_info.isp_func.pfn_sensor_start(lib->sensor_info.dev_id);
|
||||
}
|
||||
|
||||
xmedia_s32 drv_sensor_stop(xmedia_u32 pipe)
|
||||
{
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
if (lib->sensor_lib != XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (lib->sensor_info.isp_func.pfn_sensor_stop == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return lib->sensor_info.isp_func.pfn_sensor_stop(lib->sensor_info.dev_id);
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_s32 drv_sensor_set_mipi_lanes(xmedia_u32 pipe, const xmedia_sensor_mipi_lanes mipi_lanes)
|
||||
{
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
if (lib->sensor_lib != XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (lib->sensor_info.isp_func.pfn_sensor_set_mipi_lanes == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return lib->sensor_info.isp_func.pfn_sensor_set_mipi_lanes(lib->sensor_info.dev_id, mipi_lanes);
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_s32 drv_sensor_set_attr(xmedia_u32 pipe, const xmedia_sensor_attr *sns_attr)
|
||||
{
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
if (lib->sensor_lib != XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (lib->sensor_info.isp_func.pfn_sensor_set_attr == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return lib->sensor_info.isp_func.pfn_sensor_set_attr(lib->sensor_info.dev_id, sns_attr);
|
||||
}
|
||||
|
||||
xmedia_s32 drv_sensor_set_init_param(xmedia_u32 pipe, const xmedia_sensor_init_param *init_param)
|
||||
{
|
||||
isp_lib_info *lib = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM || init_param == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_LIB(pipe, lib);
|
||||
if (lib->sensor_lib != XMEDIA_TRUE) {
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (lib->sensor_info.isp_func.pfn_sensor_set_init_param == XMEDIA_NULL) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
return lib->sensor_info.isp_func.pfn_sensor_set_init_param(lib->sensor_info.dev_id, init_param);
|
||||
}
|
||||
|
||||
xmedia_s32 drv_isp_init(xmedia_u32 pipe, xmedia_isp_config *cfg)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
xmedia_sensor_black_level blc;
|
||||
xmedia_s32 ret;
|
||||
xmedia_isp_ae_param ae_param;
|
||||
xmedia_isp_awb_param awb_param;
|
||||
xmedia_sensor_isp_default isp_default;
|
||||
|
||||
#if ISP_COST_TIME_DEBUG
|
||||
xmedia_u32 start, end;
|
||||
|
||||
start = isp_get_time_stamp();
|
||||
#endif
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM || cfg == XMEDIA_NULL) {
|
||||
puts("isp invalid param!\n");
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
if (ctx != XMEDIA_NULL) {
|
||||
puts("isp ctx already exist!\n");
|
||||
return XMEDIA_ERRCODE_EXIST;
|
||||
}
|
||||
|
||||
if (g_isp_lib[pipe].ae_lib == XMEDIA_FALSE) {
|
||||
puts("isp not register ae lib!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (g_isp_lib[pipe].awb_lib == XMEDIA_FALSE) {
|
||||
puts("isp not register awb lib!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
ctx = malloc(sizeof(isp_context));
|
||||
if (ctx == XMEDIA_NULL) {
|
||||
puts("isp malloc ctx failed!\n");
|
||||
return XMEDIA_ERRCODE_NO_BUFFER_FREE;
|
||||
}
|
||||
g_isp_ctx[pipe] = ctx;
|
||||
g_isp_ctx[pipe]->lib_info = &g_isp_lib[pipe];
|
||||
|
||||
g_isp_ctx[pipe]->lib_info->sensor_info.isp_func.pfn_sensor_get_isp_black_level(
|
||||
g_isp_ctx[pipe]->lib_info->sensor_info.dev_id, &blc);
|
||||
|
||||
ae_param.balck_level[0] = blc.black_level[0];
|
||||
ae_param.balck_level[1] = blc.black_level[1];
|
||||
ae_param.balck_level[2] = blc.black_level[2];
|
||||
ae_param.balck_level[3] = blc.black_level[3];
|
||||
ae_param.sensor_id = 0;
|
||||
ae_param.wdr_mode = cfg->wdr_mode;
|
||||
ae_param.hdr_mode = cfg->wdr_mode;
|
||||
ae_param.fps = cfg->fps;
|
||||
ae_param.bayer_format = cfg->bayer_fmt;
|
||||
ae_param.blend_config.blend_en = XMEDIA_FALSE;
|
||||
ae_param.blend_config.blend_num = 0;
|
||||
if (cfg->mode_config.work_mode == XMEDIA_ISP_WORK_MODE_MASTER) {
|
||||
ae_param.blend_config.blend_en = cfg->mode_config.master_mode.blend_stat_enable;
|
||||
ae_param.blend_config.blend_num = cfg->mode_config.master_mode.slave_num + 1;
|
||||
}
|
||||
g_isp_ctx[pipe]->lib_info->ae_info.pfn_ae_init(g_isp_ctx[pipe]->lib_info->ae_info.alg_id, &ae_param);
|
||||
|
||||
awb_param.wdr_mode = cfg->wdr_mode;
|
||||
awb_param.init_iso = 100;
|
||||
if (cfg->mode_config.work_mode == XMEDIA_ISP_WORK_MODE_MASTER) {
|
||||
awb_param.blend_config.blend_en = cfg->mode_config.master_mode.blend_stat_enable;
|
||||
awb_param.blend_config.blend_num = cfg->mode_config.master_mode.slave_num + 1;
|
||||
}
|
||||
g_isp_ctx[pipe]->lib_info->awb_info.pfn_awb_init(g_isp_ctx[pipe]->lib_info->awb_info.alg_id, &awb_param);
|
||||
|
||||
ctx->result = (xmedia_sensor_init_param *)CONFIG_PARAM_MEM_START;
|
||||
memset(ctx->result, 0, sizeof(xmedia_sensor_init_param));
|
||||
|
||||
ret = hal_isp_init(pipe, cfg, &blc);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
puts("isp hal_isp_init failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (cfg->wdr_mode == XMEDIA_VIDEO_WDR_MODE_BUILT_IN ) {
|
||||
if (g_isp_ctx[pipe]->lib_info->sensor_info.isp_func.pfn_sensor_get_isp_default == XMEDIA_NULL ) {
|
||||
return XMEDIA_ERRCODE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
g_isp_ctx[pipe]->lib_info->sensor_info.isp_func.pfn_sensor_get_isp_default(
|
||||
g_isp_ctx[pipe]->lib_info->sensor_info.dev_id, &isp_default);
|
||||
ret = hal_isp_init_expander(pipe, isp_default.expander);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
puts("isp hal_isp_init_expander failed.\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
#if ISP_COST_TIME_DEBUG
|
||||
end = isp_get_time_stamp();
|
||||
puts("isp init cost time: ");
|
||||
putdec(end - start);
|
||||
puts(" us\n");
|
||||
#endif
|
||||
|
||||
#if ISP_COUNT_SIZE_DEBUG
|
||||
puts("isp_context size = ");
|
||||
putdec(sizeof(isp_context));
|
||||
puts("\n");
|
||||
puts("g_isp_ctx size = ");
|
||||
putdec(sizeof(g_isp_ctx));
|
||||
puts("\n");
|
||||
puts("g_isp_lib size = ");
|
||||
putdec(sizeof(g_isp_lib));
|
||||
puts("\n");
|
||||
puts("g_sensor_clk_ch size = ");
|
||||
putdec(sizeof(g_sensor_clk_ch));
|
||||
puts("\n");
|
||||
puts("g_sensor_rst_ch size = ");
|
||||
putdec(sizeof(g_sensor_rst_ch));
|
||||
puts("\n");
|
||||
#endif
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_isp_exit(xmedia_u32 pipe)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
puts("isp invalid param!\n");
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
if (ctx == XMEDIA_NULL) {
|
||||
puts("isp ctx not exist!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
g_isp_ctx[pipe]->lib_info->ae_info.pfn_ae_exit(g_isp_ctx[pipe]->lib_info->ae_info.alg_id);
|
||||
g_isp_ctx[pipe]->lib_info->awb_info.pfn_awb_exit(g_isp_ctx[pipe]->lib_info->awb_info.alg_id);
|
||||
|
||||
free(ctx);
|
||||
g_isp_ctx[pipe] = XMEDIA_NULL;
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_isp_start(xmedia_u32 pipe)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
puts("isp invalid param!\n");
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
if (ctx == XMEDIA_NULL) {
|
||||
puts("isp ctx not exist!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_isp_stop(xmedia_u32 pipe)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
puts("isp invalid param!\n");
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
if (ctx == XMEDIA_NULL) {
|
||||
puts("isp ctx not exist!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_isp_notifier(xmedia_u32 pipe, isp_irq_type irq_type)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
xmedia_s32 ret;
|
||||
|
||||
#if ISP_COST_TIME_DEBUG
|
||||
xmedia_u32 start, end;
|
||||
|
||||
start = isp_get_time_stamp();
|
||||
#endif
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
puts("isp invalid param!\n");
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
if (ctx == XMEDIA_NULL) {
|
||||
puts("isp ctx not exist!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (irq_type == ISP_IRQ_TYPE_BE_FRAME_END) {
|
||||
ret = hal_isp_format_statistics(pipe);
|
||||
#if ISP_COST_TIME_DEBUG
|
||||
end = isp_get_time_stamp();
|
||||
puts("isp ISP_IRQ_TYPE_BE_FRAME_END cost time: ");
|
||||
putdec(end - start);
|
||||
puts(" us\n");
|
||||
#endif
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
puts("isp hal_isp_format_statistics failed!\n");
|
||||
return ret;
|
||||
}
|
||||
} else if (irq_type == ISP_IRQ_TYPE_FE_FRAME_START) {
|
||||
ret = hal_isp_sync(pipe);
|
||||
#if ISP_COST_TIME_DEBUG
|
||||
end = isp_get_time_stamp();
|
||||
puts("isp ISP_IRQ_TYPE_FE_FRAME_START cost time: ");
|
||||
putdec(end - start);
|
||||
puts(" us\n");
|
||||
#endif
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
puts("isp hal_isp_sync failed!\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
// TODO: 统计耗时
|
||||
xmedia_s32 drv_isp_process(xmedia_u32 pipe)
|
||||
{
|
||||
isp_context *ctx = XMEDIA_NULL;
|
||||
xmedia_s32 ret;
|
||||
xmedia_isp_statistics isp_stat = { 0 };
|
||||
xmedia_isp_ae_info ae_info = { 0 };
|
||||
xmedia_isp_awb_info awb_info = { 0 };
|
||||
xmedia_isp_result isp_result = { 0 };
|
||||
xmedia_sensor_regs_info reg_info = { 0 };
|
||||
static xmedia_u64 last_frame_cnt = -1;
|
||||
xmedia_u64 sys_gain;
|
||||
xmedia_s32 i;
|
||||
|
||||
#if ISP_COST_TIME_DEBUG
|
||||
xmedia_u32 start, end;
|
||||
|
||||
start = isp_get_time_stamp();
|
||||
#endif
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
puts("isp invalid param!\n");
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ISP_GET_CTX(pipe, ctx);
|
||||
if (ctx == XMEDIA_NULL) {
|
||||
puts("isp ctx not exist!\n");
|
||||
return XMEDIA_ERRCODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
ret = hal_isp_stat(pipe, &isp_stat);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
puts("isp hal_isp_stat failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (last_frame_cnt == isp_stat.ae_stat.frame_cnt) {
|
||||
return XMEDIA_ERRCODE_NOT_READY;
|
||||
}
|
||||
last_frame_cnt = isp_stat.ae_stat.frame_cnt;
|
||||
|
||||
ae_info.frame_cnt = isp_stat.ae_stat.frame_cnt;
|
||||
ae_info.be_ae_stat_global_avg = &isp_stat.ae_stat.ae_stat_global_avg;
|
||||
ae_info.be_ae_stat_hist = isp_stat.ae_stat.ae_stat_hist;
|
||||
ctx->lib_info->ae_info.pfn_ae_run(ctx->lib_info->ae_info.alg_id, &ae_info, &isp_result.ae_result);
|
||||
|
||||
// awb分块统计信息是紧凑排布的,即行与行之间没有空白内存
|
||||
awb_info.frame_cnt = isp_stat.awb_stat.frame_cnt;
|
||||
awb_info.awb_zone_row = isp_stat.awb_stat.awb_zone_row_num;
|
||||
awb_info.awb_zone_col = isp_stat.awb_stat.awb_zone_col_num;
|
||||
awb_info.awb_width = isp_stat.awb_stat.awb_width;
|
||||
awb_info.awb_height = isp_stat.awb_stat.awb_height;
|
||||
awb_info.awb_stat_switch = XMEDIA_ISP_AE_SWITCH_AFTER_DGN2;
|
||||
awb_info.awb_stat_local_avg_r = (xmedia_isp_awb_stat_local_avg_r *)isp_stat.awb_stat.awb_zone_avg_r;
|
||||
awb_info.awb_stat_local_avg_g = (xmedia_isp_awb_stat_local_avg_g *)isp_stat.awb_stat.awb_zone_avg_g;
|
||||
awb_info.awb_stat_local_avg_b = (xmedia_isp_awb_stat_local_avg_b *)isp_stat.awb_stat.awb_zone_avg_b;
|
||||
awb_info.stat_local_valid_count = (xmedia_isp_awb_stat_local_valid_count *)isp_stat.awb_stat.awb_zone_valid_count;
|
||||
ctx->lib_info->awb_info.pfn_awb_run(ctx->lib_info->awb_info.alg_id, &awb_info, &isp_result.awb_result);
|
||||
|
||||
sys_gain = (xmedia_u64)isp_result.ae_result.again * isp_result.ae_result.dgain * isp_result.ae_result.isp_dgain /
|
||||
(1024 * 1024 * 256 / 64);
|
||||
ctx->result->exp_time = isp_result.ae_result.int_time[0];
|
||||
ctx->result->again = isp_result.ae_result.again;
|
||||
ctx->result->dgain = isp_result.ae_result.dgain;
|
||||
ctx->result->ispdgain = isp_result.ae_result.isp_dgain;
|
||||
ctx->result->init_iso = isp_result.ae_result.iso;
|
||||
ctx->result->exposure = (xmedia_u64)isp_result.ae_result.int_time[0] * sys_gain;
|
||||
ctx->result->wb_rgain = isp_result.awb_result.white_balance_gain[0];
|
||||
ctx->result->wb_ggain = isp_result.awb_result.white_balance_gain[1];
|
||||
ctx->result->wb_bgain = isp_result.awb_result.white_balance_gain[3];
|
||||
for (i = 0; i < XMEDIA_SENSOR_CCM_MATRIX_SIZE; i++) {
|
||||
if (isp_result.awb_result.color_matrix[i] < 0) {
|
||||
ctx->result->ccm[i] = CCM_MINUS_PARAM_TH - isp_result.awb_result.color_matrix[i];
|
||||
} else {
|
||||
ctx->result->ccm[i] = isp_result.awb_result.color_matrix[i];
|
||||
}
|
||||
}
|
||||
ctx->lib_info->sensor_info.isp_func.pfn_sensor_get_reg_info(ctx->lib_info->sensor_info.dev_id, ®_info);
|
||||
|
||||
ret = hal_isp_update(pipe, &isp_result, ®_info);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
puts("isp hal_isp_update failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
puts("debug dudu r");
|
||||
puthex(ctx->result->wb_rgain);
|
||||
puts(" g");
|
||||
puthex(ctx->result->wb_ggain);
|
||||
puts(" b");
|
||||
puthex(ctx->result->wb_bgain);
|
||||
puts("\n");
|
||||
puts("isp process frame count [");
|
||||
putdec(isp_stat.ae_stat.frame_cnt);
|
||||
puts("]\n");
|
||||
#endif
|
||||
|
||||
#if ISP_COST_TIME_DEBUG
|
||||
end = isp_get_time_stamp();
|
||||
puts("isp process cost time: ");
|
||||
putdec(end - start);
|
||||
puts(" us\n");
|
||||
#endif
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_isp_config(xmedia_u32 pipe)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
|
||||
#if ISP_COST_TIME_DEBUG
|
||||
xmedia_u32 start, end;
|
||||
|
||||
start = isp_get_time_stamp();
|
||||
#endif
|
||||
|
||||
if (pipe >= ISP_PIPE_MAX_NUM) {
|
||||
puts("isp invalid param!\n");
|
||||
return XMEDIA_ERRCODE_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret = hal_isp_config(pipe);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
puts("isp hal_isp_config failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if ISP_COST_TIME_DEBUG
|
||||
end = isp_get_time_stamp();
|
||||
puts("isp config cost time: ");
|
||||
putdec(end - start);
|
||||
puts(" us\n");
|
||||
#endif
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
Executable
+241
@@ -0,0 +1,241 @@
|
||||
#include "stdio.h"
|
||||
#include "defines.h"
|
||||
#include "interrupt.h"
|
||||
#include "drv_vi.h"
|
||||
#include "drv_isp.h"
|
||||
#include "hal_vi.h"
|
||||
#include <timer.h>
|
||||
|
||||
#define VICAP_IRQ_DEBUG 0
|
||||
#define VIPROC_IRQ_DEBUG 0
|
||||
|
||||
static xmedia_bool vi_vicap_is_report_int(xmedia_u32 fe_id, xmedia_u32 int_status)
|
||||
{
|
||||
xmedia_u32 fe_int_mask[VI_MAX_PHY_PIPE_NUM] = { 0x1 << 5, 0x1 << 6, 0x1 << 7, 0x1 << 8 };
|
||||
|
||||
if (int_status & fe_int_mask[fe_id]) {
|
||||
return XMEDIA_TRUE;
|
||||
}
|
||||
|
||||
return XMEDIA_FALSE;
|
||||
}
|
||||
|
||||
static xmedia_void vi_vicap_irq_callback_proc(xmedia_u32 vicap_wch, xmedia_u32 irq_status)
|
||||
{
|
||||
if (irq_status & VI_CAP_FRAME_START_INT) {
|
||||
drv_isp_notifier(vicap_wch, ISP_IRQ_TYPE_FE_FRAME_START);
|
||||
}
|
||||
|
||||
if (irq_status & VI_CAP_FRAME_EARLY_INT) {
|
||||
// vicap reg newer
|
||||
hal_vi_vicap_reg_newer(vicap_wch);
|
||||
}
|
||||
|
||||
if (irq_status & VI_CAP_FRAME_LOWDELAY_INT) {
|
||||
}
|
||||
|
||||
if (irq_status & VI_CAP_FRAME_END_INT) {
|
||||
drv_isp_notifier(vicap_wch, ISP_IRQ_TYPE_FE_FRAME_END);
|
||||
}
|
||||
|
||||
if (irq_status & VI_CAP_FRAME_TIMEOUT_INT) {
|
||||
puts("vicap timeout int!\n");
|
||||
}
|
||||
|
||||
if (irq_status & VI_CAP_FRAME_ERR_INT) {
|
||||
puthex(irq_status);
|
||||
puts("vicap err int!\n");
|
||||
}
|
||||
}
|
||||
|
||||
ATTRIBUTE_ISR xmedia_void vi_vicap_irq_route(xmedia_void)
|
||||
{
|
||||
xmedia_s32 vicap_wch;
|
||||
xmedia_u32 vicap_int_status;
|
||||
xmedia_u32 vicap_int_mask;
|
||||
xmedia_u32 irq_status;
|
||||
|
||||
vicap_int_status = hal_vi_vicap_get_top_int_status(0);
|
||||
vicap_int_mask = hal_vi_vicap_get_top_int_mask(0);
|
||||
vicap_int_status &= (~vicap_int_mask);
|
||||
|
||||
for (vicap_wch = VI_MAX_PHY_PIPE_NUM - 1; vicap_wch >= 0; vicap_wch--) {
|
||||
if (vi_vicap_is_report_int(vicap_wch, vicap_int_status) == XMEDIA_FALSE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
irq_status = hal_vi_vicap_get_chn_int_status(vicap_wch);
|
||||
hal_vi_vicap_clear_int(vicap_wch, irq_status);
|
||||
|
||||
#if VICAP_IRQ_DEBUG
|
||||
puts("vicap irq_status 0x");
|
||||
puthex(irq_status);
|
||||
puts("\n");
|
||||
#endif
|
||||
|
||||
vi_vicap_irq_callback_proc(vicap_wch, irq_status);
|
||||
}
|
||||
}
|
||||
|
||||
static xmedia_void vi_viproc_irq_callback_proc(xmedia_u32 pipe, xmedia_u32 irq_status)
|
||||
{
|
||||
if (irq_status & VI_PROC_FRAME_START_INT) {
|
||||
}
|
||||
|
||||
if (irq_status & VI_PROC_FRAME_EARLY_INT) {
|
||||
drv_isp_config(pipe); // 配置isp be算法寄存器
|
||||
hal_vi_viproc_reg_start(0);
|
||||
}
|
||||
|
||||
if (irq_status & VI_PROC_FRAME_END_INT || irq_status & VI_PROC_FRAME_LIST_INT) {
|
||||
drv_isp_notifier(pipe, ISP_IRQ_TYPE_BE_FRAME_END);
|
||||
}
|
||||
|
||||
if (irq_status & VI_PROC_LOWDELAY_INT) {
|
||||
}
|
||||
|
||||
if (irq_status & VI_PROC_FRAME_ERR_INT) {
|
||||
puts("viproc err int!\n");
|
||||
}
|
||||
|
||||
if (irq_status & VI_PROC_FRAME_TIMEOUT_INT) {
|
||||
puts("viproc timeout int!\n");
|
||||
}
|
||||
|
||||
if (irq_status & VI_PROC_FRAME_ERR_IGNORE_INT) {
|
||||
puts("viproc err ignore int!\n");
|
||||
}
|
||||
}
|
||||
|
||||
ATTRIBUTE_ISR xmedia_void vi_viproc_irq_route(xmedia_void)
|
||||
{
|
||||
xmedia_u32 pipe = 0; // 对外暂时仅支持pipe 0
|
||||
xmedia_u32 cl_irq_status;
|
||||
xmedia_u32 irq_status;
|
||||
xmedia_u32 irq_mask;
|
||||
xmedia_u32 early_mask;
|
||||
|
||||
irq_status = hal_viproc_get_reg_public_int_status(0); // viproc irq status
|
||||
irq_mask = hal_viproc_get_reg_public_int_mask(0); // irq mask
|
||||
early_mask = hal_viproc_common_get_reg_early_mask(0); // early irq mask
|
||||
|
||||
cl_irq_status = irq_status;
|
||||
irq_status &= (~(irq_mask | early_mask));
|
||||
|
||||
hal_viproc_clr_reg_int(0, cl_irq_status); // clear int
|
||||
|
||||
#if VIPROC_IRQ_DEBUG
|
||||
puts("viproc irq_status 0x");
|
||||
puthex(irq_status);
|
||||
puts("\n");
|
||||
#endif
|
||||
|
||||
vi_viproc_irq_callback_proc(pipe, irq_status);
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_void drv_mipi_init(xmedia_void)
|
||||
{
|
||||
hal_mipi_init();
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_s32 drv_mipi_enable(xmedia_s32 dev, xmedia_vi_dev_config *dev_config)
|
||||
{
|
||||
return hal_mipi_enable(dev, dev_config);
|
||||
}
|
||||
|
||||
xmedia_s32 drv_vi_init(xmedia_void)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
xmedia_u32 vicap_irq_num;
|
||||
xmedia_u32 viproc_irq_num;
|
||||
|
||||
// 注册vicap中断、viproc中断
|
||||
vicap_irq_num = hal_vi_get_vicap_irq_num(0);
|
||||
viproc_irq_num = hal_vi_get_viproc_irq_num(0);
|
||||
ret = drv_irq_register(vicap_irq_num, vi_vicap_irq_route);
|
||||
if (ret < 0) {
|
||||
puts("Fail to register vicap irq!\n");
|
||||
return ret;
|
||||
}
|
||||
ret = drv_irq_register(viproc_irq_num, vi_viproc_irq_route);
|
||||
if (ret < 0) {
|
||||
puts("Fail to register viproc irq!\n");
|
||||
drv_irq_unregister(vicap_irq_num);
|
||||
return ret;
|
||||
}
|
||||
|
||||
hal_vi_init();
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_vi_exit(xmedia_void)
|
||||
{
|
||||
xmedia_u32 vicap_irq_num;
|
||||
xmedia_u32 viproc_irq_num;
|
||||
|
||||
// 反注册中断
|
||||
vicap_irq_num = hal_vi_get_vicap_irq_num(0);
|
||||
viproc_irq_num = hal_vi_get_viproc_irq_num(0);
|
||||
drv_irq_unregister(vicap_irq_num);
|
||||
drv_irq_unregister(viproc_irq_num);
|
||||
|
||||
hal_vi_exit();
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_vi_enable_dev(xmedia_s32 dev)
|
||||
{
|
||||
return hal_vi_enable_dev(dev);
|
||||
}
|
||||
|
||||
xmedia_s32 drv_vi_disable_dev(xmedia_s32 dev, xmedia_vi_dev_config *dev_config)
|
||||
{
|
||||
hal_vi_disable_dev(dev, dev_config);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_vi_set_dev_bind_pipe(xmedia_s32 dev, xmedia_s32 pipe)
|
||||
{
|
||||
return hal_vi_set_dev_bind_pipe(dev, pipe);
|
||||
}
|
||||
|
||||
xmedia_s32 drv_vi_set_dev_unbind_pipe(xmedia_s32 dev, xmedia_s32 pipe)
|
||||
{
|
||||
hal_vi_set_dev_unbind_pipe(dev, pipe);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_vi_start_pipe(xmedia_s32 pipe, xmedia_vi_pipe_config *pipe_config)
|
||||
{
|
||||
xmedia_s32 ret;
|
||||
|
||||
ret = hal_vi_start_vicap(pipe, pipe_config);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
puts("start vicap failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 调用isp update be接口,配置第一帧算法参数
|
||||
drv_isp_config(pipe);
|
||||
|
||||
ret = hal_vi_start_viproc(pipe, pipe_config);
|
||||
if (ret != XMEDIA_SUCCESS) {
|
||||
puts("start viproc failed\n");
|
||||
hal_vi_stop_vicap(pipe);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 drv_vi_stop_pipe(xmedia_s32 pipe)
|
||||
{
|
||||
hal_vi_stop_viproc(pipe);
|
||||
hal_vi_stop_vicap(pipe);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
Executable
+2065
File diff suppressed because it is too large
Load Diff
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#ifndef _HAL_ISP_H_
|
||||
#define _HAL_ISP_H_
|
||||
|
||||
xmedia_void delay(xmedia_u32 us);
|
||||
xmedia_s32 hal_sensor_reset(xmedia_u32 ch, xmedia_bool enable);
|
||||
xmedia_s32 hal_sensor_read_mclk(xmedia_u32 ch, xmedia_u32 *clk);
|
||||
xmedia_s32 hal_sensor_set_mclk(xmedia_u32 ch, xmedia_u32 clk);
|
||||
xmedia_s32 hal_isp_init(xmedia_u32 pipe, xmedia_isp_config *cfg, xmedia_sensor_black_level *blc);
|
||||
xmedia_s32 hal_isp_init_expander(xmedia_u32 pipe, const xmedia_isp_expander_attr *attr);
|
||||
xmedia_s32 hal_isp_stat(xmedia_u32 pipe, xmedia_isp_statistics *stat);
|
||||
xmedia_s32 hal_isp_update(xmedia_u32 pipe, xmedia_isp_result *result, xmedia_sensor_regs_info *reg_info);
|
||||
xmedia_s32 hal_isp_format_statistics(xmedia_u32 pipe);
|
||||
xmedia_s32 hal_isp_config(xmedia_u32 pipe);
|
||||
xmedia_s32 hal_isp_sync(xmedia_u32 pipe);
|
||||
|
||||
#endif
|
||||
|
||||
Executable
+933
@@ -0,0 +1,933 @@
|
||||
#include "stdio.h"
|
||||
#include "xmedia_type.h"
|
||||
#include "xmedia_vi.h"
|
||||
#include "defines.h"
|
||||
#include "hal_vi.h"
|
||||
|
||||
/*
|
||||
* 系统控制寄存器,MISC_CTRL81
|
||||
* BIT [0] :
|
||||
* 0:MIPI_RX_PHY1连接MIPI_2L_RX0控制器
|
||||
* 1:MIPI_RX_PHY1连接MIPI_4L_RX0控制器
|
||||
* BIT [1] :
|
||||
* 0:MIPI_RX_PHY3连接MIPI_2L_RX1控制器
|
||||
* 1:MIPI_RX_PHY3连接MIPI_4L_RX1控制器
|
||||
* */
|
||||
#define MIPI_MISC_CTRL 0x12028900
|
||||
#define VIPROC_EXTERNAL_TIMING_EN_ADDR 0x1202899C
|
||||
#define CRG_REGS_ADDR 0x12010000
|
||||
|
||||
#define VICAP_IRQ_NUM 66
|
||||
#define VIPROC0_IRQ_NUM 63
|
||||
|
||||
#define VI_RESET_WAIT_CNT 100
|
||||
|
||||
typedef struct {
|
||||
xmedia_u32 phy0_data_lane0;
|
||||
xmedia_u32 phy0_data_lane1;
|
||||
xmedia_u32 phy1_data_lane0;
|
||||
xmedia_u32 phy1_data_lane1;
|
||||
xmedia_u32 phy0_clk_sel;
|
||||
xmedia_u32 phy1_clk_sel;
|
||||
} mipi_lane_swap_attr;
|
||||
|
||||
volatile xmedia_u32 g_vicap_all_reg[VICAP_IP_NUM] = { 0x11000000 };
|
||||
volatile xmedia_u32 g_viproc_all_reg[VIPROC_IP_NUM] = { 0x11200000 };
|
||||
STAGE1_GLOBAL volatile xmedia_u32 g_mipi_rx_reg[VI_MIPI_RX_NUM] = { 0x10fe0000, 0x11010000 };
|
||||
STAGE1_GLOBAL volatile xmedia_u32 g_mipi_phy_reg_addr = 0x12028900;
|
||||
|
||||
STAGE1_FUNC static xmedia_u32 vi_read_reg(volatile xmedia_uintptr_t addr)
|
||||
{
|
||||
return *(volatile xmedia_u32 *)(addr);
|
||||
}
|
||||
|
||||
STAGE1_FUNC static xmedia_void vi_write_reg(volatile xmedia_uintptr_t addr, xmedia_u32 val)
|
||||
{
|
||||
*(volatile xmedia_u32 *)(addr) = val;
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_void vi_reg_write_bit(xmedia_u32 addr, xmedia_u32 value, xmedia_u32 bit_pos)
|
||||
{
|
||||
xmedia_u32 t, mask;
|
||||
|
||||
mask = 1 << bit_pos;
|
||||
t = vi_read_reg(addr);
|
||||
t &= ~mask;
|
||||
t |= (value << bit_pos) & mask;
|
||||
vi_write_reg(addr, t);
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_void vi_reg_write_32(xmedia_u32 addr, xmedia_u32 value, xmedia_u32 bit_pos, xmedia_u32 bit_count)
|
||||
{
|
||||
xmedia_u32 t;
|
||||
xmedia_u32 mask;
|
||||
|
||||
t = vi_read_reg(addr);
|
||||
|
||||
mask = ((1U << bit_count) - 1) << bit_pos;
|
||||
t &= ~mask;
|
||||
t |= (value << bit_pos) & mask;
|
||||
|
||||
vi_write_reg(addr, t);
|
||||
}
|
||||
|
||||
static xmedia_s32 vi_dev_reset(xmedia_s32 dev, xmedia_bool reset)
|
||||
{
|
||||
xmedia_bool reset_state = 0;
|
||||
xmedia_u32 wait_cnt = 0;
|
||||
xmedia_u32 reg;
|
||||
|
||||
vi_reg_write_bit(CRG_REGS_ADDR + 0xf4, reset, 4 + dev); // 4 : pt0 offset
|
||||
|
||||
reg = vi_read_reg(CRG_REGS_ADDR + 0x1e4);
|
||||
reset_state = (reg & (0x1 << (8 + dev))) >> (8 + dev); // bit[8:12]: pt0-pt4 reset state
|
||||
|
||||
while (reset_state != reset) {
|
||||
sleep_us(1);
|
||||
wait_cnt++;
|
||||
reg = vi_read_reg(CRG_REGS_ADDR + 0x1e4);
|
||||
reset_state = (reg & (0x1 << (8 + dev))) >> (8 + dev); // bit[8:12]: pt0-pt4 reset state
|
||||
if (reset_state != reset && wait_cnt > VI_RESET_WAIT_CNT) {
|
||||
puts("dev reset err\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vi_vicap_fe_reset(xmedia_s32 fe_id, xmedia_bool reset)
|
||||
{
|
||||
xmedia_bool reset_state = 0;
|
||||
xmedia_u32 reg;
|
||||
xmedia_u32 wait_cnt = 0;
|
||||
|
||||
vi_reg_write_bit(CRG_REGS_ADDR + 0xf4, reset, 9 + fe_id); // 9 : fe0 offset
|
||||
|
||||
reg = vi_read_reg(CRG_REGS_ADDR + 0x1e4);
|
||||
reset_state = (reg & (0x1 << (13 + fe_id))) >> (13 + fe_id); // bit[13:20]: fe0-fe7 reset state
|
||||
|
||||
while (reset_state != reset) {
|
||||
sleep_us(1);
|
||||
wait_cnt++;
|
||||
reg = vi_read_reg(CRG_REGS_ADDR + 0x1e4);
|
||||
reset_state = (reg & (0x1 << (13 + fe_id))) >> (13 + fe_id); // bit[13:20]: fe0-fe7 reset state
|
||||
if (reset_state != reset && wait_cnt > VI_RESET_WAIT_CNT) {
|
||||
puts("vicap reset failed\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vi_viproc_reset_set(xmedia_u32 proc_id, xmedia_bool reset)
|
||||
{
|
||||
xmedia_bool reset_state = 0;
|
||||
xmedia_u32 wait_cnt = 0;
|
||||
xmedia_u32 reg;
|
||||
|
||||
vi_reg_write_bit(CRG_REGS_ADDR + 0xfc, reset, 4); // 4 : viproc reset offset
|
||||
|
||||
reg = vi_read_reg(CRG_REGS_ADDR + 0x1e4);
|
||||
reset_state = (reg & 0x80) >> 7; // bit[7]: viproc reset state
|
||||
|
||||
while (reset_state != reset) {
|
||||
sleep_us(1);
|
||||
wait_cnt++;
|
||||
reg = vi_read_reg(CRG_REGS_ADDR + 0x1e4);
|
||||
reset_state = (reg & 0x80) >> 7; // bit[7]: viproc reset state
|
||||
if (reset_state != reset && wait_cnt > VI_RESET_WAIT_CNT) {
|
||||
puts("viproc reset failed\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vi_vicap_all_reset(xmedia_bool reset)
|
||||
{
|
||||
xmedia_bool reset_state = 0;
|
||||
xmedia_u32 reg;
|
||||
xmedia_u32 wait_cnt = 0;
|
||||
|
||||
vi_reg_write_bit(CRG_REGS_ADDR + 0xf4, reset, 17); // [17] : vicap总软复位请求
|
||||
|
||||
reg = vi_read_reg(CRG_REGS_ADDR + 0x1e4);
|
||||
reset_state = (reg & (0x1 << 21)) >> 21; // bit[21]: vicap all state
|
||||
|
||||
while (reset_state != reset) {
|
||||
sleep_us(1);
|
||||
wait_cnt++;
|
||||
reg = vi_read_reg(CRG_REGS_ADDR + 0x1e4);
|
||||
reset_state = (reg & (0x1 << 21)) >> 21; // bit[21]: vicap all state
|
||||
if (reset_state != reset && wait_cnt > VI_RESET_WAIT_CNT) {
|
||||
puts("vicap reset failed\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_s32 vi_vicap_clk_reset_init(xmedia_u32 cap_id)
|
||||
{
|
||||
xmedia_s32 dev;
|
||||
xmedia_s32 fe;
|
||||
|
||||
vi_reg_write_bit(CRG_REGS_ADDR + 0xf4, XMEDIA_TRUE, 0); // enable vicap clk
|
||||
|
||||
sleep_us(5); // 等待时钟稳定
|
||||
|
||||
if (vi_vicap_all_reset(XMEDIA_FALSE) != XMEDIA_SUCCESS) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
for (dev = 0; dev < VI_MAX_DEV_NUM; dev++) {
|
||||
if (vi_dev_reset(dev, XMEDIA_TRUE) != 0) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
for (fe = 0; fe < VI_MAX_PHY_PIPE_NUM; fe++) {
|
||||
if (vi_vicap_fe_reset(fe, XMEDIA_TRUE) != 0) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
for (dev = 0; dev < VI_MAX_DEV_NUM; dev++) {
|
||||
if (vi_dev_reset(dev, XMEDIA_FALSE) != 0) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
for (fe = 0; fe < VI_MAX_PHY_PIPE_NUM; fe++) {
|
||||
if (vi_vicap_fe_reset(fe, XMEDIA_FALSE) != 0) {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_void vi_vicap_clk_reset_deinit(xmedia_u32 cap_id)
|
||||
{
|
||||
xmedia_s32 dev;
|
||||
xmedia_s32 fe;
|
||||
|
||||
for (dev = 0; dev < VI_MAX_DEV_NUM; dev++) {
|
||||
vi_dev_reset(dev, XMEDIA_TRUE);
|
||||
}
|
||||
|
||||
for (fe = 0; fe < VI_MAX_PHY_PIPE_NUM; fe++) {
|
||||
vi_vicap_fe_reset(fe, XMEDIA_TRUE);
|
||||
}
|
||||
|
||||
vi_vicap_all_reset(XMEDIA_TRUE);
|
||||
|
||||
vi_reg_write_bit(CRG_REGS_ADDR + 0xf4, 0, 0);
|
||||
}
|
||||
|
||||
static xmedia_s32 vi_viproc_clk_reset_init(xmedia_u32 proc_id)
|
||||
{
|
||||
vi_reg_write_bit(CRG_REGS_ADDR + 0xfc, XMEDIA_TRUE, 0);
|
||||
|
||||
sleep_us(5); // 等待时钟稳定
|
||||
|
||||
if (vi_viproc_reset_set(proc_id, XMEDIA_FALSE) != 0) {
|
||||
puts("viproc clk reset false failed\n");
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static xmedia_void vi_viproc_clk_reset_deinit(xmedia_u32 proc_id)
|
||||
{
|
||||
vi_viproc_reset_set(proc_id, XMEDIA_TRUE);
|
||||
vi_viproc_reset_set(proc_id, XMEDIA_FALSE);
|
||||
vi_reg_write_bit(CRG_REGS_ADDR + 0xfc, XMEDIA_FALSE, 0);
|
||||
}
|
||||
|
||||
STAGE1_FUNC static xmedia_void mipi_rx_set_misc_sel(xmedia_s32 dev_id, xmedia_vi_mipi_lane_divide_mode mipi_lane_num)
|
||||
{
|
||||
volatile xmedia_u32 mipi_misc_reg = MIPI_MISC_CTRL;
|
||||
|
||||
if (mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE) {
|
||||
if (dev_id == 0) {
|
||||
vi_reg_write_bit(mipi_misc_reg, 1, 0);
|
||||
} else {
|
||||
vi_reg_write_bit(mipi_misc_reg, 1, 1);
|
||||
}
|
||||
} else {
|
||||
if (dev_id == 0 || dev_id == 1) {
|
||||
vi_reg_write_bit(mipi_misc_reg, 0, 0);
|
||||
} else {
|
||||
vi_reg_write_bit(mipi_misc_reg, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static xmedia_void mipi_rx_phy_get_lane_swap(xmedia_s32 dev_id, const xmedia_vi_dev_config *dev_config,
|
||||
mipi_lane_swap_attr *lane_swap_mode)
|
||||
{
|
||||
/*
|
||||
* 默认phy与lane的链接关系:
|
||||
* mipi0-phy0-data0-lane0
|
||||
* mipi0-phy0-data1-lane1
|
||||
* mipi1-phy1-data0-lane2
|
||||
* mipi1-phy1-data1-lane3
|
||||
*/
|
||||
if (dev_config->mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE) {
|
||||
lane_swap_mode->phy0_data_lane0 = 0;
|
||||
lane_swap_mode->phy0_data_lane1 = 1;
|
||||
lane_swap_mode->phy1_data_lane0 = 2;
|
||||
lane_swap_mode->phy1_data_lane1 = 3;
|
||||
lane_swap_mode->phy0_clk_sel = 0;
|
||||
lane_swap_mode->phy1_clk_sel = 1;
|
||||
} else {
|
||||
if (dev_id == 0) {
|
||||
lane_swap_mode->phy0_data_lane0 = 0;
|
||||
lane_swap_mode->phy0_data_lane1 = 1;
|
||||
lane_swap_mode->phy0_clk_sel = 0;
|
||||
} else { // VI_DEV1
|
||||
lane_swap_mode->phy1_data_lane0 = 2;
|
||||
lane_swap_mode->phy1_data_lane1 = 3;
|
||||
lane_swap_mode->phy1_clk_sel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev_config->lane_config.enable != XMEDIA_TRUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 用户任意配置链接关系
|
||||
if (dev_config->mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE) {
|
||||
lane_swap_mode->phy0_data_lane0 = dev_config->lane_config.lane_cfg[0];
|
||||
lane_swap_mode->phy0_data_lane1 = dev_config->lane_config.lane_cfg[1];
|
||||
lane_swap_mode->phy1_data_lane0 = dev_config->lane_config.lane_cfg[2];
|
||||
lane_swap_mode->phy1_data_lane1 = dev_config->lane_config.lane_cfg[3];
|
||||
lane_swap_mode->phy0_clk_sel = 0;
|
||||
lane_swap_mode->phy1_clk_sel = 1;
|
||||
} else {
|
||||
if (dev_id == 0) {
|
||||
lane_swap_mode->phy0_data_lane0 = dev_config->lane_config.lane_cfg[0];
|
||||
lane_swap_mode->phy0_data_lane1 = dev_config->lane_config.lane_cfg[1];
|
||||
lane_swap_mode->phy0_clk_sel = (lane_swap_mode->phy0_data_lane0 > 1) ? 1 : 0;
|
||||
} else {
|
||||
lane_swap_mode->phy1_data_lane0 = dev_config->lane_config.lane_cfg[0];
|
||||
lane_swap_mode->phy1_data_lane1 = dev_config->lane_config.lane_cfg[1];
|
||||
lane_swap_mode->phy1_clk_sel = (lane_swap_mode->phy1_data_lane0 > 1) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static xmedia_void mipi_rx_phy_lane_swap(xmedia_s32 dev_id, xmedia_vi_mipi_lane_divide_mode lane_mode,
|
||||
mipi_lane_swap_attr *lane_swap)
|
||||
{
|
||||
volatile xmedia_u32 mipi_phy_addr = g_mipi_phy_reg_addr;
|
||||
|
||||
if (lane_mode == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE) {
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy0_data_lane0, 0, 2);
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy0_data_lane1, 2, 2);
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy1_data_lane0, 4, 2);
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy1_data_lane1, 6, 2);
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy0_clk_sel, 8, 1);
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy1_clk_sel, 9, 1);
|
||||
} else if (lane_mode == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_2_LANE) {
|
||||
if (dev_id == 0) {
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy0_data_lane0, 0, 2);
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy0_data_lane1, 2, 2);
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy0_clk_sel, 8, 1);
|
||||
} else { // VI_DEV1
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy1_data_lane0, 4, 2);
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy1_data_lane1, 6, 2);
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy1_clk_sel, 9, 1);
|
||||
}
|
||||
} else {
|
||||
if (dev_id == 0) {
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy0_data_lane0, 0, 2);
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy0_clk_sel, 8, 1);
|
||||
} else { // VI_DEV1
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy1_data_lane0, 4, 2);
|
||||
vi_reg_write_32(mipi_phy_addr + 0xac, lane_swap->phy1_clk_sel, 9, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STAGE1_FUNC static xmedia_void mipi_rx_phy_init(xmedia_s32 dev_id, xmedia_u32 mipi_rate,
|
||||
xmedia_vi_mipi_lane_divide_mode mipi_lane_num,
|
||||
mipi_lane_swap_attr *lane_swap)
|
||||
{
|
||||
volatile xmedia_u32 mipi_phy_addr = g_mipi_phy_reg_addr;
|
||||
xmedia_u32 data_rate;
|
||||
xmedia_u32 td_term_en_max;
|
||||
xmedia_u32 td_term_en;
|
||||
xmedia_u32 ths_settle_max;
|
||||
xmedia_u32 ths_settle;
|
||||
xmedia_u32 tclk_term_en_max;
|
||||
xmedia_u32 tclk_term_en;
|
||||
xmedia_u32 tclk_settle_max;
|
||||
xmedia_u32 tclk_settle;
|
||||
xmedia_u32 tx_clk_esc = 24; // 24MHz 晶振配置 (T-tx_clk_esc = 41.7 ns)
|
||||
|
||||
if (mipi_rate == 0) {
|
||||
puts("mipi_rate invalid");
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
if (mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE) {
|
||||
vi_reg_write_bit(mipi_phy_addr, 1, 0); // mipirxphy_sel
|
||||
} else {
|
||||
vi_reg_write_bit(mipi_phy_addr, 0, 0); // mipirxphy_sel
|
||||
}
|
||||
|
||||
mipi_rx_phy_lane_swap(dev_id, mipi_lane_num, lane_swap);
|
||||
|
||||
data_rate = mipi_rate;
|
||||
td_term_en_max = 35 + 4000 / data_rate;
|
||||
td_term_en = td_term_en_max * data_rate / 2000 - 1;
|
||||
ths_settle_max = 145 + 10 * 1000 / data_rate;
|
||||
ths_settle = (ths_settle_max - td_term_en * 2000 / data_rate) * data_rate / 2000 - 1;
|
||||
tclk_term_en_max = 38;
|
||||
tclk_term_en = (tx_clk_esc * tclk_term_en_max) / 1000;
|
||||
tclk_settle_max = 300;
|
||||
tclk_settle = (tclk_settle_max - tclk_term_en * 1000 / tx_clk_esc) * tx_clk_esc / 1000 - 1;
|
||||
|
||||
if (dev_id == 0) {
|
||||
vi_reg_write_32(mipi_phy_addr + 0xb4, td_term_en, 24, 8); // time_hs_term_en
|
||||
vi_reg_write_32(mipi_phy_addr + 0xb4, ths_settle, 16, 8); // time_hs_settle
|
||||
vi_reg_write_32(mipi_phy_addr + 0xb4, tclk_term_en, 8, 8); // time_ck_term_en
|
||||
vi_reg_write_32(mipi_phy_addr + 0xb4, tclk_settle, 0, 8); // time_ck_settle
|
||||
vi_reg_write_bit(mipi_phy_addr + 0xb0, XMEDIA_TRUE, 0); // cr_csi_en
|
||||
vi_reg_write_bit(mipi_phy_addr + 0xb0, XMEDIA_TRUE, 1); // dl0_enable
|
||||
vi_reg_write_bit(mipi_phy_addr + 0xb0, XMEDIA_TRUE, 2); // dl1_enable
|
||||
} else if (dev_id == 1) {
|
||||
vi_reg_write_32(mipi_phy_addr + 0xd4, td_term_en, 24, 8); // time_hs_term_en
|
||||
vi_reg_write_32(mipi_phy_addr + 0xd4, ths_settle, 16, 8); // time_hs_settle
|
||||
vi_reg_write_32(mipi_phy_addr + 0xd4, tclk_term_en, 8, 8); // time_ck_term_en
|
||||
vi_reg_write_32(mipi_phy_addr + 0xd4, tclk_settle, 0, 8); // time_ck_settle
|
||||
vi_reg_write_bit(mipi_phy_addr + 0xd0, XMEDIA_TRUE, 0); // cr_csi_en
|
||||
vi_reg_write_bit(mipi_phy_addr + 0xd0, XMEDIA_TRUE, 1); // dl0_enable
|
||||
vi_reg_write_bit(mipi_phy_addr + 0xd0, XMEDIA_TRUE, 2); // dl1_enable
|
||||
} else {
|
||||
puts("mipi phy num err, dev_id ");
|
||||
putdec(dev_id);
|
||||
puts("\n");
|
||||
}
|
||||
}
|
||||
|
||||
STAGE1_GLOBAL static xmedia_u32 ret_mipi_date_type[10] = { 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x27, 0x18, 0x1a, 0x1e };
|
||||
|
||||
STAGE1_FUNC xmedia_u32 mipi_rx_get_data_type(xmedia_intf_mipi_csi_data_type data_type)
|
||||
{
|
||||
return ret_mipi_date_type[data_type];
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_void mipi_rx_set_ipi_reg(xmedia_s32 dev_id, xmedia_intf_mipi_csi_data_type data_type)
|
||||
{
|
||||
volatile unsigned int mipi_rx_addr = g_mipi_rx_reg[dev_id];
|
||||
xmedia_u32 ipi_data_type;
|
||||
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x80, 1, 24); // ipi enable
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x80, 1, 16); // ipi_cut_through
|
||||
|
||||
// ipi_color_com
|
||||
if (data_type <= XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_16BIT) {
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x80, 1, 8);
|
||||
} else {
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x80, 0, 8);
|
||||
}
|
||||
|
||||
vi_reg_write_32(mipi_rx_addr + 0x84, 0, 0, 2); // ipi vc id
|
||||
|
||||
ipi_data_type = mipi_rx_get_data_type(data_type);
|
||||
vi_reg_write_32(mipi_rx_addr + 0x88, ipi_data_type, 0, 6); // ipi data type
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x88, 1, 8); // embedded_data[A]
|
||||
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x8c, 1, 8); // ipi mem auto flush
|
||||
vi_reg_write_32(mipi_rx_addr + 0x90, 0xa, 0, 12); // hsa
|
||||
vi_reg_write_32(mipi_rx_addr + 0x94, 0xa, 0, 12); // hbp
|
||||
vi_reg_write_32(mipi_rx_addr + 0x98, 0xa, 0, 12); // hsd
|
||||
|
||||
vi_reg_write_32(mipi_rx_addr + 0x9c, 0x898, 0, 15); // hline_time
|
||||
vi_reg_write_bit(mipi_rx_addr + 0xa0, 1, 0); // soft reset
|
||||
|
||||
// advanced feature
|
||||
vi_reg_write_bit(mipi_rx_addr + 0xac, 0, 0);
|
||||
vi_reg_write_32(mipi_rx_addr + 0xac, 0, 8, 6);
|
||||
vi_reg_write_bit(mipi_rx_addr + 0xac, 1, 16);
|
||||
vi_reg_write_bit(mipi_rx_addr + 0xac, 1, 17);
|
||||
vi_reg_write_bit(mipi_rx_addr + 0xac, 1, 18);
|
||||
vi_reg_write_bit(mipi_rx_addr + 0xac, 1, 19);
|
||||
vi_reg_write_bit(mipi_rx_addr + 0xac, 1, 20);
|
||||
vi_reg_write_bit(mipi_rx_addr + 0xac, 1, 21);
|
||||
vi_reg_write_bit(mipi_rx_addr + 0xac, 1, 22);
|
||||
vi_reg_write_bit(mipi_rx_addr + 0xac, 1, 24);
|
||||
}
|
||||
|
||||
xmedia_u32 vi_get_bit_width(xmedia_video_data_width data_width)
|
||||
{
|
||||
xmedia_u32 bit_width;
|
||||
|
||||
switch (data_width) {
|
||||
case XMEDIA_VIDEO_DATA_WIDTH_8:
|
||||
bit_width = 8;
|
||||
break;
|
||||
|
||||
case XMEDIA_VIDEO_DATA_WIDTH_10:
|
||||
bit_width = 10;
|
||||
break;
|
||||
|
||||
case XMEDIA_VIDEO_DATA_WIDTH_12:
|
||||
bit_width = 12;
|
||||
break;
|
||||
|
||||
case XMEDIA_VIDEO_DATA_WIDTH_14:
|
||||
bit_width = 14;
|
||||
break;
|
||||
|
||||
case XMEDIA_VIDEO_DATA_WIDTH_16:
|
||||
bit_width = 16;
|
||||
break;
|
||||
|
||||
default:
|
||||
bit_width = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
return bit_width;
|
||||
}
|
||||
|
||||
xmedia_u32 vi_viproc_get_bit_deepth(xmedia_video_data_width bit_width, xmedia_video_wdr_mode wdr_mode)
|
||||
{
|
||||
if (wdr_mode == XMEDIA_VIDEO_WDR_MODE_NONE) {
|
||||
return VI_PACK_12BIT;
|
||||
} else if (wdr_mode == XMEDIA_VIDEO_WDR_MODE_BUILT_IN) {
|
||||
if (bit_width == XMEDIA_VIDEO_DATA_WIDTH_8) {
|
||||
return VI_PACK_8BIT;
|
||||
} else if (bit_width == XMEDIA_VIDEO_DATA_WIDTH_10) {
|
||||
return VI_PACK_10BIT;
|
||||
} else if (bit_width == XMEDIA_VIDEO_DATA_WIDTH_12) {
|
||||
return VI_PACK_12BIT;
|
||||
} else if (bit_width == XMEDIA_VIDEO_DATA_WIDTH_14) {
|
||||
return VI_PACK_14BIT;
|
||||
} else if (bit_width == XMEDIA_VIDEO_DATA_WIDTH_16) {
|
||||
return VI_PACK_16BIT;
|
||||
} else {
|
||||
puts("viproc built-in wdr mode not support bit_width ");
|
||||
putdec(bit_width);
|
||||
puts("\n");
|
||||
return VI_PACK_12BIT;
|
||||
}
|
||||
} else {
|
||||
puts("viproc not support wdr_mode ");
|
||||
putdec(wdr_mode);
|
||||
puts("\n");
|
||||
return VI_PACK_12BIT;
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_void hal_vi_vicap_reg_newer(xmedia_s32 fe_id)
|
||||
{
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[0];
|
||||
|
||||
vi_reg_write_bit(vicap_addr + ((fe_id + 6) * 0x1000 + 0x48), 1, 0);
|
||||
}
|
||||
|
||||
xmedia_void hal_vi_vicap_online_config(xmedia_s32 fe_id, xmedia_vi_pipe_config *pipe_config)
|
||||
{
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[0];
|
||||
xmedia_u32 bit_width;
|
||||
|
||||
// input_size
|
||||
vi_reg_write_32(vicap_addr + ((fe_id + 6) * 0x1000 + 0x4), pipe_config->width, 0, 14);
|
||||
vi_reg_write_32(vicap_addr + ((fe_id + 6) * 0x1000 + 0x4), pipe_config->height, 16, 14);
|
||||
|
||||
// bit_width
|
||||
bit_width = vi_get_bit_width(pipe_config->bit_width);
|
||||
vi_reg_write_32(vicap_addr + ((fe_id + 6) * 0x1000 + 0x28), bit_width, 16, 6);
|
||||
|
||||
// output_size
|
||||
vi_reg_write_32(vicap_addr + ((fe_id + 6) * 0x1000 + 0x2c), pipe_config->width, 0, 14);
|
||||
vi_reg_write_32(vicap_addr + ((fe_id + 6) * 0x1000 + 0x2c), pipe_config->height, 16, 14);
|
||||
|
||||
// vicap reg newer
|
||||
hal_vi_vicap_reg_newer(fe_id);
|
||||
|
||||
// todo offline set_output_memory
|
||||
if (pipe_config->vi_work_mode == 1) {
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_u32 hal_vi_vicap_get_top_int_status(xmedia_u32 vicap_id)
|
||||
{
|
||||
xmedia_u32 top_int_status;
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[vicap_id];
|
||||
|
||||
top_int_status = vi_read_reg(vicap_addr + 0x10);
|
||||
|
||||
return top_int_status;
|
||||
}
|
||||
|
||||
xmedia_u32 hal_vi_vicap_get_top_int_mask(xmedia_u32 vicap_id)
|
||||
{
|
||||
xmedia_u32 top_int_mask;
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[vicap_id];
|
||||
|
||||
top_int_mask = vi_read_reg(vicap_addr + 0x14);
|
||||
|
||||
return top_int_mask;
|
||||
}
|
||||
|
||||
xmedia_u32 hal_vi_vicap_get_chn_int_status(xmedia_s32 fe_id)
|
||||
{
|
||||
xmedia_u32 irq_status;
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[0];
|
||||
|
||||
irq_status = vi_read_reg(vicap_addr + ((fe_id + 6) * 0x1000 + 0x40));
|
||||
return irq_status;
|
||||
}
|
||||
|
||||
xmedia_void hal_vi_vicap_clear_int(xmedia_s32 fe_id, xmedia_u32 mask)
|
||||
{
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[0];
|
||||
|
||||
vi_write_reg(vicap_addr + ((fe_id + 6) * 0x1000 + 0x40), mask); // clear int
|
||||
}
|
||||
xmedia_s32 hal_vi_get_vicap_irq_num(xmedia_u32 vicap_id)
|
||||
{
|
||||
return VICAP_IRQ_NUM;
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vi_get_viproc_irq_num(xmedia_u32 viproc_id)
|
||||
{
|
||||
return VIPROC0_IRQ_NUM;
|
||||
}
|
||||
|
||||
xmedia_u32 hal_viproc_get_reg_public_int_status(xmedia_u32 viproc_id)
|
||||
{
|
||||
xmedia_u32 int_status;
|
||||
xmedia_u32 viproc_addr = g_viproc_all_reg[viproc_id];
|
||||
|
||||
int_status = vi_read_reg(viproc_addr + 0x48);
|
||||
return int_status;
|
||||
}
|
||||
|
||||
xmedia_u32 hal_viproc_get_reg_public_int_mask(xmedia_u32 viproc_id)
|
||||
{
|
||||
xmedia_u32 int_mask;
|
||||
xmedia_u32 viproc_addr = g_viproc_all_reg[viproc_id];
|
||||
|
||||
int_mask = vi_read_reg(viproc_addr + 0x2c);
|
||||
return int_mask;
|
||||
}
|
||||
|
||||
xmedia_u32 hal_viproc_common_get_reg_early_mask(xmedia_u32 viproc_id)
|
||||
{
|
||||
xmedia_u32 int_mask;
|
||||
xmedia_u32 viproc_addr = g_viproc_all_reg[viproc_id];
|
||||
|
||||
int_mask = vi_read_reg(viproc_addr + 0x1e8);
|
||||
return int_mask;
|
||||
}
|
||||
|
||||
xmedia_void hal_viproc_clr_reg_int(xmedia_u32 viproc_id, xmedia_u32 mask)
|
||||
{
|
||||
xmedia_u32 viproc_addr = g_viproc_all_reg[viproc_id];
|
||||
|
||||
vi_write_reg(viproc_addr + 0x48, mask);
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_void hal_mipi_init(xmedia_void)
|
||||
{
|
||||
vi_reg_write_32(CRG_REGS_ADDR + 0xa0, 0, 0, 3); // bit[0:2]: mipi_rx_clk_sel
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_s32 hal_mipi_enable(xmedia_s32 dev, xmedia_vi_dev_config *dev_config)
|
||||
{
|
||||
xmedia_u32 mipi_lane_num = 0;
|
||||
xmedia_u32 mipi_rx_addr = g_mipi_rx_reg[dev];
|
||||
xmedia_u32 sys_config_addr = CRG_REGS_ADDR + 0xf8;
|
||||
mipi_lane_swap_attr lane_swap_mode = { 0 };
|
||||
|
||||
// mipi_rx mipi_phy clk enable
|
||||
vi_reg_write_bit(sys_config_addr, XMEDIA_TRUE, dev); // mipi_rx_cken
|
||||
if (dev_config->mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE) {
|
||||
vi_reg_write_bit(sys_config_addr, XMEDIA_TRUE, 3); // mipi_rx0_4line_cken
|
||||
}
|
||||
vi_reg_write_bit(sys_config_addr, XMEDIA_TRUE, 9); // mipi_phy0_cken
|
||||
|
||||
// 延时5 us,等待时钟稳定
|
||||
sleep_us(5);
|
||||
|
||||
// mipi_rx复位
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x8, XMEDIA_FALSE, 0);
|
||||
sleep_us(5);
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x8, XMEDIA_TRUE, 0);
|
||||
|
||||
if (dev_config->mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_1_LANE) {
|
||||
mipi_lane_num = 0x0;
|
||||
} else if (dev_config->mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_2_LANE) {
|
||||
mipi_lane_num = 0x1;
|
||||
} else if (dev_config->mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE) {
|
||||
mipi_lane_num = 0x3;
|
||||
} else {
|
||||
// mipi_lane错误参数
|
||||
puts("vi mipi lane is invalid\n");
|
||||
}
|
||||
|
||||
vi_reg_write_32(mipi_rx_addr + 0x4, mipi_lane_num, 0, 3); // mipi_lane
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x44, 1, 0); // mipi0_dphy_rstz
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x40, 1, 0); // mipi0_phy_shutdownz
|
||||
|
||||
mipi_rx_set_misc_sel(dev, dev_config->mipi_lane_num);
|
||||
|
||||
mipi_rx_phy_get_lane_swap(dev, dev_config, &lane_swap_mode);
|
||||
mipi_rx_phy_init(dev, dev_config->mipi_rate, dev_config->mipi_lane_num, &lane_swap_mode);
|
||||
if (dev_config->mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE) {
|
||||
mipi_rx_phy_init(dev + 1, dev_config->mipi_rate, dev_config->mipi_lane_num, &lane_swap_mode);
|
||||
}
|
||||
|
||||
sleep_us(5);
|
||||
|
||||
mipi_rx_set_ipi_reg(dev, dev_config->data_type); // ipi cfg, todo:暂不考虑wdr
|
||||
vi_reg_write_32(mipi_rx_addr + 0x640, 0, 0, 3); // hdr_data_mode,0:VC
|
||||
vi_reg_write_32(mipi_rx_addr + 0x654, 0x142, 0, 16); // rft_speeder
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vi_init(xmedia_void)
|
||||
{
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[0];
|
||||
xmedia_u32 viproc_addr = g_viproc_all_reg[0];
|
||||
|
||||
// 初始化mipi_rx、vicap、viproc时钟
|
||||
// vi_reg_write_32(CRG_REGS_ADDR + 0xa0, 0, 0, 3); // bit[0:2]: mipi_rx_clk_sel
|
||||
vi_reg_write_32(CRG_REGS_ADDR + 0xa0, 0, 3, 3); // bit[3:5]: vicap_clk_sel
|
||||
vi_reg_write_32(CRG_REGS_ADDR + 0xa0, 0, 6, 3); // bit[6:8]: viproc_clk_sel
|
||||
|
||||
// vicap时钟使能,dev、fe复位
|
||||
vi_vicap_clk_reset_init(0);
|
||||
|
||||
// viproc时钟使能、复位,init开启时钟,isp_init需要配置viproc算法寄存器
|
||||
vi_viproc_clk_reset_init(0);
|
||||
|
||||
// vicap viproc outstanding
|
||||
vi_reg_write_32(vicap_addr + 0x74, 0x88, 0, 9);
|
||||
vi_reg_write_32(viproc_addr + 0x10, 0x10, 8, 5); // wr outstanding
|
||||
vi_reg_write_32(viproc_addr + 0x10, 0x20, 16, 6); // rd outstanding
|
||||
|
||||
// 屏蔽中断
|
||||
vi_reg_write_32(vicap_addr + 0x14, 0x7fffff, 0, 23); // top mask
|
||||
}
|
||||
|
||||
xmedia_void hal_vi_exit(xmedia_void)
|
||||
{
|
||||
// viproc时钟去使能,dev、fe复位
|
||||
// vi_viproc_clk_reset_deinit(0);
|
||||
|
||||
// vicap时钟去使能,dev、fe复位
|
||||
vi_vicap_clk_reset_deinit(0);
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vi_enable_dev(xmedia_s32 dev)
|
||||
{
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[0];
|
||||
|
||||
// pt intf mode,todo :其他接口待适配
|
||||
if (dev == 0) {
|
||||
vi_reg_write_32(vicap_addr + 0xc, 0, 0, 2);
|
||||
} else if (dev == 1) {
|
||||
vi_reg_write_32(vicap_addr + 0xc, 0, 2, 2);
|
||||
} else if (dev == 2) {
|
||||
vi_reg_write_32(vicap_addr + 0xc, 0, 4, 3);
|
||||
} else {
|
||||
puts("dev_id is err ");
|
||||
putdec(dev);
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
// enable pt
|
||||
vi_reg_write_bit(vicap_addr, XMEDIA_TRUE, dev);
|
||||
|
||||
if (dev < 2) {
|
||||
vi_reg_write_bit(vicap_addr + ((dev + 1) * 0x1000), XMEDIA_TRUE, 0); // pt_timing_en
|
||||
vi_reg_write_bit(vicap_addr + ((dev + 1) * 0x1000), XMEDIA_TRUE, 4); // debug_en
|
||||
} else {
|
||||
vi_reg_write_bit(vicap_addr + ((dev + 1) * 0x1000), XMEDIA_TRUE, 0); // pt_timing_en
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vi_disable_dev(xmedia_s32 dev, xmedia_vi_dev_config *dev_config)
|
||||
{
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[0];
|
||||
|
||||
#if 0
|
||||
xmedia_u32 mipi_rx_addr = g_mipi_rx_reg[dev];
|
||||
xmedia_u32 sys_config_addr = CRG_REGS_ADDR + 0xf8;
|
||||
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x44, 0, 0); //mipi0_dphy_rstz
|
||||
vi_reg_write_bit(mipi_rx_addr + 0x40, 0, 0); //mipi0_phy_shutdownz
|
||||
|
||||
// mipi_rx mipi_phy clk disable
|
||||
vi_reg_write_bit(sys_config_addr, 0, dev); // diable mipi_rx clk
|
||||
vi_reg_write_bit(sys_config_addr, 0, 9 + dev); // diable mipi_rx phy clk
|
||||
if (dev_config->mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE) {
|
||||
vi_reg_write_bit(sys_config_addr, 0, 9 + dev + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// disable pt
|
||||
vi_reg_write_bit(vicap_addr, XMEDIA_FALSE, dev);
|
||||
|
||||
if (dev < 2) {
|
||||
vi_reg_write_bit(vicap_addr + ((dev + 1) * 0x1000), XMEDIA_FALSE, 0); // pt_timing_en
|
||||
vi_reg_write_bit(vicap_addr + ((dev + 1) * 0x1000), XMEDIA_FALSE, 4); // debug_en
|
||||
vi_reg_write_bit(vicap_addr + ((dev + 1) * 0x1000), XMEDIA_FALSE, 2); // ck_dyn_gt_en
|
||||
} else {
|
||||
vi_reg_write_bit(vicap_addr + ((dev + 1) * 0x1000), XMEDIA_FALSE, 0); // pt_timing_en
|
||||
vi_reg_write_bit(vicap_addr + ((dev + 1) * 0x1000) + 0x2c, XMEDIA_FALSE, 0); // ck_dyn_gt_en
|
||||
}
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vi_set_dev_bind_pipe(xmedia_s32 dev, xmedia_s32 fe_id)
|
||||
{
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[0];
|
||||
|
||||
vi_reg_write_32(vicap_addr + 0x4, dev, (fe_id * 3), 3);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vi_set_dev_unbind_pipe(xmedia_s32 dev, xmedia_s32 fe_id)
|
||||
{
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[0];
|
||||
|
||||
vi_reg_write_32(vicap_addr + 0x4, 0, (fe_id * 3), 3);
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vi_start_vicap(xmedia_s32 fe_id, xmedia_vi_pipe_config *pipe_config)
|
||||
{
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[0];
|
||||
|
||||
vi_vicap_fe_reset(fe_id, XMEDIA_FALSE);
|
||||
|
||||
// 打开对应fe上报中断开关、中断掩码
|
||||
vi_reg_write_bit(vicap_addr + 0x14, 0, fe_id + 5);
|
||||
vi_reg_write_32(vicap_addr + ((fe_id + 6) * 0x1000 + 0x3c), 0x6, 0, 16);
|
||||
|
||||
// 在线离线工作模式
|
||||
if (pipe_config->vi_work_mode == 0) {
|
||||
vi_reg_write_bit(vicap_addr + ((fe_id + 6) * 0x1000), XMEDIA_TRUE, 0); // online_en
|
||||
vi_reg_write_bit(VIPROC_EXTERNAL_TIMING_EN_ADDR, XMEDIA_TRUE, 1); // viproc_external_timing_en
|
||||
} else {
|
||||
vi_reg_write_bit(vicap_addr + ((fe_id + 6) * 0x1000), 0, 0);
|
||||
vi_reg_write_bit(VIPROC_EXTERNAL_TIMING_EN_ADDR, XMEDIA_FALSE, 1);
|
||||
}
|
||||
|
||||
// 设置early行号、early位置
|
||||
vi_reg_write_32(vicap_addr + ((fe_id + 6) * 0x1000 + 0x1c), 1, 0, 2);
|
||||
vi_reg_write_32(vicap_addr + ((fe_id + 6) * 0x1000 + 0x1c), (pipe_config->height * 4 / 5), 8, 13);
|
||||
|
||||
// clear_int
|
||||
vi_reg_write_32(vicap_addr + ((fe_id + 6) * 0x1000 + 0x40), 0xffff, 0, 16);
|
||||
|
||||
hal_vi_vicap_online_config(fe_id, pipe_config);
|
||||
|
||||
// enable fe
|
||||
vi_reg_write_bit(vicap_addr, XMEDIA_TRUE, fe_id + 5);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vi_viproc_reg_start(xmedia_u32 viproc_id)
|
||||
{
|
||||
xmedia_u32 viproc_addr = g_viproc_all_reg[viproc_id];
|
||||
|
||||
vi_reg_write_bit(viproc_addr + 0x14, XMEDIA_TRUE, 0); // ctl_up_finish_enable
|
||||
vi_reg_write_bit(viproc_addr + 0x14, XMEDIA_TRUE, 4); // filter_up_finish_enable
|
||||
}
|
||||
|
||||
xmedia_void hal_vi_viproc_online_config(xmedia_s32 fe_id, xmedia_vi_pipe_config *pipe_config)
|
||||
{
|
||||
xmedia_u32 bit_deepth;
|
||||
xmedia_u32 viproc_addr = g_viproc_all_reg[0];
|
||||
|
||||
// inch0_path_sel
|
||||
vi_reg_write_32(viproc_addr + 0x174, 0, 1, 2);
|
||||
|
||||
// list_mode_enable false
|
||||
vi_reg_write_bit(viproc_addr + 0x14, 0, 8);
|
||||
|
||||
// early line/location
|
||||
vi_reg_write_32(viproc_addr + 0x1dc, 1, 4, 2);
|
||||
vi_reg_write_32(viproc_addr + 0x1e0, (pipe_config->height * 4 / 5), 16, 14);
|
||||
|
||||
// inch0_en
|
||||
vi_reg_write_bit(viproc_addr + 0x174, XMEDIA_TRUE, 0);
|
||||
|
||||
// inch0_bit_deepth
|
||||
bit_deepth = vi_viproc_get_bit_deepth(pipe_config->bit_width, pipe_config->wdr_mode);
|
||||
vi_reg_write_32(viproc_addr + 0x174, bit_deepth, 16, 5);
|
||||
|
||||
// input_data_mode
|
||||
vi_reg_write_bit(viproc_addr + 0x16c, 0, 3);
|
||||
|
||||
// valid_in_width/height
|
||||
vi_reg_write_32(viproc_addr + 0x190, pipe_config->width, 0, 14);
|
||||
vi_reg_write_32(viproc_addr + 0x190, pipe_config->height, 16, 14);
|
||||
|
||||
// early mask
|
||||
vi_reg_write_32(viproc_addr + 0x1e8, 0x6, 0, 3);
|
||||
// todo:node id
|
||||
}
|
||||
|
||||
xmedia_s32 hal_vi_start_viproc(xmedia_s32 fe_id, xmedia_vi_pipe_config *pipe_config)
|
||||
{
|
||||
xmedia_u32 viproc_addr = g_viproc_all_reg[0];
|
||||
|
||||
// vi_viproc_clk_reset_init(0);
|
||||
|
||||
// viproc 中断掩码
|
||||
vi_reg_write_32(viproc_addr + 0x2c, 0x20, 0, 32);
|
||||
|
||||
// viproc clear int
|
||||
vi_reg_write_32(viproc_addr + 0x48, 0xffffffff, 0, 32);
|
||||
|
||||
hal_vi_viproc_online_config(fe_id, pipe_config);
|
||||
|
||||
// ctl_up_finish_enable/filter_up_finish_enable
|
||||
hal_vi_viproc_reg_start(0);
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_void hal_vi_stop_viproc(xmedia_s32 fe_id)
|
||||
{
|
||||
vi_viproc_clk_reset_deinit(0);
|
||||
}
|
||||
|
||||
xmedia_void hal_vi_stop_vicap(xmedia_s32 fe_id)
|
||||
{
|
||||
xmedia_u32 vicap_addr = g_vicap_all_reg[0];
|
||||
|
||||
// disable fe
|
||||
vi_reg_write_bit(vicap_addr, XMEDIA_FALSE, fe_id + 5);
|
||||
|
||||
// ck_dyn_gt_en_enable
|
||||
vi_reg_write_bit(vicap_addr + ((fe_id + 6) * 0x1000 + 0xa0), XMEDIA_FALSE, 0);
|
||||
|
||||
// int none mask
|
||||
vi_reg_write_32(vicap_addr + ((fe_id + 6) * 0x1000 + 0x3c), 0xffff, 0, 16);
|
||||
|
||||
// clear int
|
||||
vi_reg_write_32(vicap_addr + ((fe_id + 6) * 0x1000 + 0x40), 0xffff, 0, 16);
|
||||
|
||||
vi_vicap_fe_reset(fe_id, XMEDIA_TRUE);
|
||||
vi_vicap_fe_reset(fe_id, XMEDIA_FALSE);
|
||||
}
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#ifndef __HAL_VI_H_
|
||||
#define __HAL_VI_H_
|
||||
|
||||
#include "xmedia_type.h"
|
||||
#include "xmedia_vi.h"
|
||||
#include "compile.h"
|
||||
|
||||
#define VI_CAP_FRAME_START_INT (0x1 << 6)
|
||||
#define VI_CAP_FRAME_LOWDELAY_INT (0x1 << 1)
|
||||
#define VI_CAP_FRAME_EARLY_INT (0x1 << 0)
|
||||
#define VI_CAP_FRAME_END_INT (0x1 << 7)
|
||||
#define VI_CAP_FRAME_END_INT_TIMING (0x1 << 11)
|
||||
#define VI_CAP_FRAME_ERR_INT ((0x1 << 8) | (0x1 << 12) | (0x1 << 3) | (0x1 << 4) | (0x1 << 13))
|
||||
#define VI_CAP_FRAME_TIMEOUT_INT ((0x1 << 9) | (0x1 << 10))
|
||||
|
||||
#define VI_PROC_FRAME_LIST_INT (0x1 << 5)
|
||||
#define VI_PROC_FRAME_START_INT (0x1 << 3)
|
||||
#define VI_PROC_FRAME_EARLY_INT (0x1)
|
||||
#define VI_PROC_LOWDELAY_INT (0x1 << 1)
|
||||
#define VI_PROC_FRAME_END_INT (0x1 << 4)
|
||||
#define VI_PROC_FRAME_ERR_INT \
|
||||
((0x1 << 6) | (0x1 << 7) | (0x1 << 8) | (0x1 << 9) | (0x1 << 13) | (0x1 << 14) | (0x1 << 15) | (0x1 << 16) | \
|
||||
(0x1 << 17) | (0x1 << 18) | (0x1 << 19) | (0x1 << 20) | (0x1 << 21) | (0x1 << 22) | (0x1 << 27) | (0x1 << 28) | \
|
||||
(0x1 << 29) | (0x1 << 30) | (0x1 << 31))
|
||||
#define VI_PROC_FRAME_TIMEOUT_INT ((0x1 << 19) | (0x1 << 20))
|
||||
#define VI_PROC_FRAME_ERR_IGNORE_INT (0x7 << 10)
|
||||
|
||||
#define sleep_us(x) \
|
||||
do { \
|
||||
for (xmedia_s32 i = x; i > 0; i--) { \
|
||||
asm("nop"); \
|
||||
asm("nop"); \
|
||||
asm("nop"); \
|
||||
asm("nop"); \
|
||||
asm("nop"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
typedef enum {
|
||||
VI_PACK_8BIT = 8,
|
||||
VI_PACK_10BIT = 10,
|
||||
VI_PACK_12BIT = 12,
|
||||
VI_PACK_14BIT = 14,
|
||||
VI_PACK_16BIT = 16,
|
||||
VI_PACK_MAX,
|
||||
} vi_pack_bit_width;
|
||||
|
||||
xmedia_void hal_vi_vicap_reg_newer(xmedia_s32 fe_id);
|
||||
xmedia_void hal_vi_vicap_online_config(xmedia_s32 fe_id, xmedia_vi_pipe_config *pipe_config);
|
||||
xmedia_u32 hal_vi_vicap_get_top_int_status(xmedia_u32 vicap_id);
|
||||
xmedia_u32 hal_vi_vicap_get_top_int_mask(xmedia_u32 vicap_id);
|
||||
xmedia_u32 hal_vi_vicap_get_chn_int_status(xmedia_s32 fe_id);
|
||||
xmedia_void hal_vi_vicap_clear_int(xmedia_s32 fe_id, xmedia_u32 mask);
|
||||
xmedia_s32 hal_vi_get_vicap_irq_num(xmedia_u32 vicap_id);
|
||||
xmedia_s32 hal_vi_get_viproc_irq_num(xmedia_u32 viproc_id);
|
||||
xmedia_u32 hal_viproc_get_reg_public_int_status(xmedia_u32 viproc_id);
|
||||
xmedia_u32 hal_viproc_get_reg_public_int_mask(xmedia_u32 viproc_id);
|
||||
xmedia_u32 hal_viproc_common_get_reg_early_mask(xmedia_u32 viproc_id);
|
||||
xmedia_void hal_viproc_clr_reg_int(xmedia_u32 viproc_id, xmedia_u32 mask);
|
||||
xmedia_void hal_vi_init(xmedia_void);
|
||||
xmedia_void hal_vi_exit(xmedia_void);
|
||||
xmedia_s32 hal_vi_enable_dev(xmedia_s32 dev);
|
||||
xmedia_void hal_mipi_init(xmedia_void);
|
||||
xmedia_s32 hal_mipi_enable(xmedia_s32 dev, xmedia_vi_dev_config *dev_config);
|
||||
xmedia_void hal_vi_disable_dev(xmedia_s32 dev, xmedia_vi_dev_config *dev_config);
|
||||
xmedia_s32 hal_vi_set_dev_bind_pipe(xmedia_s32 dev, xmedia_s32 fe_id);
|
||||
xmedia_void hal_vi_set_dev_unbind_pipe(xmedia_s32 dev, xmedia_s32 fe_id);
|
||||
xmedia_s32 hal_vi_start_vicap(xmedia_s32 fe_id, xmedia_vi_pipe_config *pipe_config);
|
||||
xmedia_void hal_vi_viproc_online_config(xmedia_s32 fe_id, xmedia_vi_pipe_config *pipe_config);
|
||||
xmedia_void hal_vi_viproc_reg_start(xmedia_u32 viproc_id);
|
||||
xmedia_s32 hal_vi_start_viproc(xmedia_s32 fe_id, xmedia_vi_pipe_config *pipe_config);
|
||||
xmedia_void hal_vi_stop_viproc(xmedia_s32 fe_id);
|
||||
xmedia_void hal_vi_stop_vicap(xmedia_s32 fe_id);
|
||||
|
||||
#endif
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
#ifndef _ISP_DEF_H_
|
||||
#define _ISP_DEF_H_
|
||||
|
||||
#include "compile.h"
|
||||
|
||||
#define ISP_SUPPORT_PIPE_NUM 1
|
||||
|
||||
#if CONFIG_MEDIA_PIPE_NUM > ISP_SUPPORT_PIPE_NUM
|
||||
#error "NOT supportted CONFIG_MEDIA_PIPE_NUM > 1.\n"
|
||||
#endif
|
||||
|
||||
#define ISP_PIPE_MAX_NUM CONFIG_MEDIA_PIPE_NUM
|
||||
|
||||
#define ISP_COST_TIME_DEBUG 0
|
||||
#define ISP_COUNT_SIZE_DEBUG 0
|
||||
|
||||
typedef struct {
|
||||
xmedia_u32 frame_cnt;
|
||||
xmedia_isp_awb_stat_global awb_stat_global;
|
||||
// xmedia_isp_awb_stat_local_avg_r awb_stat_local_avg_r;
|
||||
// xmedia_isp_awb_stat_local_avg_g awb_stat_local_avg_g;
|
||||
// xmedia_isp_awb_stat_local_avg_b awb_stat_local_avg_b;
|
||||
// xmedia_isp_awb_stat_local_valid_count stat_local_valid_count;
|
||||
|
||||
xmedia_u32 *awb_zone_avg_r;
|
||||
xmedia_u32 *awb_zone_avg_g;
|
||||
xmedia_u32 *awb_zone_avg_b;
|
||||
xmedia_u32 *awb_zone_valid_count;
|
||||
|
||||
xmedia_u8 awb_gain_switch;
|
||||
xmedia_u8 awb_stat_switch;
|
||||
xmedia_u32 wdr_wb_gain[XMEDIA_ISP_BAYER_PATTERN_NUM];
|
||||
xmedia_u8 awb_zone_row_num;
|
||||
xmedia_u8 awb_zone_col_num;
|
||||
xmedia_u16 awb_width;
|
||||
xmedia_u16 awb_height;
|
||||
} xmedia_isp_awb_stat;
|
||||
|
||||
typedef xmedia_isp_be_ae_stat_hist xmedia_isp_ae_stat_hist;
|
||||
typedef xmedia_isp_be_ae_stat_global_avg xmedia_isp_ae_stat_global_avg;
|
||||
typedef xmedia_isp_be_ae_stat_zone_avg xmedia_isp_ae_stat_zone_avg;
|
||||
|
||||
typedef struct {
|
||||
xmedia_u64 frame_cnt;
|
||||
// xmedia_u8 ae_zone_row_num;
|
||||
// xmedia_u8 ae_zone_col_num;
|
||||
|
||||
xmedia_isp_ae_stat_hist ae_stat_hist;
|
||||
xmedia_isp_ae_stat_global_avg ae_stat_global_avg;
|
||||
// xmedia_isp_ae_stat_zone_avg ae_stat_zone_avg;
|
||||
} xmedia_isp_ae_stat;
|
||||
|
||||
typedef struct{
|
||||
xmedia_isp_ae_stat ae_stat;
|
||||
xmedia_isp_awb_stat awb_stat;
|
||||
}xmedia_isp_statistics;
|
||||
|
||||
typedef struct{
|
||||
xmedia_isp_ae_result ae_result;
|
||||
xmedia_isp_awb_result awb_result;
|
||||
}xmedia_isp_result;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../../source/gmp/include/common.h
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../../source/gmp/include/defines.h
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#ifndef _DRV_ISP_H_
|
||||
#define _DRV_ISP_H_
|
||||
|
||||
#include "xmedia_isp.h"
|
||||
|
||||
typedef enum {
|
||||
ISP_IRQ_TYPE_PT_FRAME_START,
|
||||
ISP_IRQ_TYPE_PT_FRAME_END,
|
||||
ISP_IRQ_TYPE_FE_FRAME_START,
|
||||
ISP_IRQ_TYPE_FE_FRAME_END,
|
||||
ISP_IRQ_TYPE_BE_FRAME_START,
|
||||
ISP_IRQ_TYPE_BE_FRAME_END,
|
||||
ISP_IRQ_TYPE_MAX,
|
||||
} isp_irq_type;
|
||||
|
||||
xmedia_s32 drv_sensor_init(xmedia_u32 pipe, xmedia_sensor_config *cfg);
|
||||
xmedia_s32 drv_sensor_exit(xmedia_u32 pipe);
|
||||
xmedia_s32 drv_sensor_resume(xmedia_u32 pipe);
|
||||
xmedia_s32 drv_sensor_start(xmedia_u32 pipe);
|
||||
xmedia_s32 drv_sensor_stop(xmedia_u32 pipe);
|
||||
xmedia_s32 drv_sensor_set_mipi_lanes(xmedia_u32 pipe, const xmedia_sensor_mipi_lanes mipi_lanes);
|
||||
xmedia_s32 drv_sensor_set_attr(xmedia_u32 pipe, const xmedia_sensor_attr *sns_attr);
|
||||
xmedia_s32 drv_sensor_set_init_param(xmedia_u32 pipe, const xmedia_sensor_init_param *init_param);
|
||||
xmedia_s32 drv_isp_init(xmedia_u32 pipe, xmedia_isp_config *cfg);
|
||||
xmedia_s32 drv_isp_exit(xmedia_u32 pipe);
|
||||
xmedia_s32 drv_isp_start(xmedia_u32 pipe);
|
||||
xmedia_s32 drv_isp_stop(xmedia_u32 pipe);
|
||||
xmedia_s32 drv_isp_notifier(xmedia_u32 pipe, isp_irq_type irq_type);
|
||||
xmedia_s32 drv_isp_process(xmedia_u32 pipe);
|
||||
xmedia_s32 drv_isp_config(xmedia_u32 pipe);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#ifndef __DRV_VI_H_
|
||||
#define __DRV_VI_H_
|
||||
|
||||
#include "xmedia_type.h"
|
||||
#include "xmedia_vi.h"
|
||||
#include "compile.h"
|
||||
|
||||
xmedia_s32 drv_vi_init(xmedia_void);
|
||||
xmedia_s32 drv_vi_exit(xmedia_void);
|
||||
|
||||
xmedia_void drv_mipi_init(xmedia_void);
|
||||
xmedia_s32 drv_mipi_enable(xmedia_s32 dev, xmedia_vi_dev_config *dev_config);
|
||||
|
||||
xmedia_s32 drv_vi_enable_dev(xmedia_s32 dev);
|
||||
xmedia_s32 drv_vi_disable_dev(xmedia_s32 dev, xmedia_vi_dev_config *dev_config);
|
||||
|
||||
xmedia_s32 drv_vi_set_dev_bind_pipe(xmedia_s32 dev, xmedia_s32 pipe);
|
||||
xmedia_s32 drv_vi_set_dev_unbind_pipe(xmedia_s32 dev, xmedia_s32 pipe);
|
||||
|
||||
xmedia_s32 drv_vi_start_pipe(xmedia_s32 pipe, xmedia_vi_pipe_config *pipe_config);
|
||||
xmedia_s32 drv_vi_stop_pipe(xmedia_s32 pipe);
|
||||
|
||||
#endif
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#ifndef _I2C_DEV_H_
|
||||
#define _I2C_DEV_H_
|
||||
|
||||
#include "xmedia_type.h"
|
||||
|
||||
static __inline__ xmedia_s32 i2c_open(xmedia_u8 i2c_dev)
|
||||
{
|
||||
return i2c_dev;
|
||||
}
|
||||
|
||||
static __inline__ xmedia_s32 i2c_close(xmedia_s32 fd)
|
||||
{
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
static __inline__ xmedia_s32 i2c_set_slave_addr(xmedia_s32 fd, xmedia_u16 slave_addr)
|
||||
{
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 i2c_read(xmedia_s32 fd, xmedia_u16 slave_addr, xmedia_u32 read_addr,
|
||||
xmedia_u8 addr_width, xmedia_u8 *buff, xmedia_u32 length);
|
||||
xmedia_s32 i2c_write(xmedia_s32 fd, xmedia_u16 slave_addr, xmedia_u8 *buff, xmedia_u32 length);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#ifndef __MEDIA_SAMPLE_H__
|
||||
#define __MEDIA_SAMPLE_H__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xmedia_type.h"
|
||||
#include "drv_vi.h"
|
||||
#include "drv_isp.h"
|
||||
#include "xmedia_ae.h"
|
||||
#include "xmedia_awb.h"
|
||||
#include "i2c_dev.h"
|
||||
#include "i2c.h"
|
||||
#include "compile.h"
|
||||
|
||||
#define MEDIA_ERROR 1
|
||||
#define MEDIA_PRINTF 1
|
||||
|
||||
#define MEDIA_ERR(fmt...) \
|
||||
do {\
|
||||
if(MEDIA_ERROR == 1)\
|
||||
{\
|
||||
puts(fmt);\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define MEDIA_PRT(fmt...) \
|
||||
do {\
|
||||
if(MEDIA_PRINTF == 1)\
|
||||
{\
|
||||
puts(fmt);\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define MEDIA_STAGE1_ERR(fmt...) \
|
||||
do {\
|
||||
if(MEDIA_ERROR == 1)\
|
||||
{\
|
||||
puts(STAGE1_STR(fmt));\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
|
||||
//#define SENSOR_SC485SL_2LANE_SUPPORT 1
|
||||
//#define SENSOR_SC485SL_4LANE_SUPPORT
|
||||
#define SENSOR_SC485SL_4LANE_60FPS_SUPPORT
|
||||
//#define SENSOR_SC235HAI_2LANE_60FPS_SUPPORT
|
||||
|
||||
#ifdef CONFIG_MEDIA_SAMPLE_QUICKSTART
|
||||
xmedia_s32 quickstart_media_preinit(void);
|
||||
xmedia_s32 quickstart_media_start(void);
|
||||
#endif
|
||||
|
||||
#endif /*__MEDIA_SAMPLE_H__*/
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../../source/gmp/include/sns_comm.h
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../../source/gmp/include/xmedia_ae.h
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../../source/gmp/include/xmedia_af.h
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../../source/gmp/include/xmedia_awb.h
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#ifndef _XMEDIA_DEBUG_H_
|
||||
#define _XMEDIA_DEBUG_H_
|
||||
|
||||
#define MODULE_DBG_EMERG 0
|
||||
#define MODULE_DBG_ALERT 1
|
||||
#define MODULE_DBG_CRIT 2
|
||||
#define MODULE_DBG_ERR 3
|
||||
#define MODULE_DBG_WARN 4
|
||||
#define MODULE_DBG_NOTICE 5
|
||||
#define MODULE_DBG_INFO 6
|
||||
#define MODULE_DBG_DEBUG 7
|
||||
|
||||
|
||||
#define XMEDIA_ASSERT(expr)
|
||||
#define MODULE_TRACE(level, mod_id, fmt...)
|
||||
|
||||
#endif
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../source/gmp/include/xmedia_errcode.h
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../source/gmp/include/xmedia_intf_common.h
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../../source/gmp/include/xmedia_isp.h
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../../source/gmp/include/xmedia_type.h
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
#ifndef __XMEDIA_VI_H__
|
||||
#define __XMEDIA_VI_H__
|
||||
|
||||
#include "xmedia_video_common.h"
|
||||
#include "xmedia_intf_common.h"
|
||||
#include "xmedia_type.h"
|
||||
|
||||
#define VI_MIPI_DATA_LANE_MAX_NUM 4
|
||||
|
||||
typedef enum {
|
||||
XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_1_LANE = 0,
|
||||
XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_2_LANE,
|
||||
XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE,
|
||||
XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_MAX
|
||||
} xmedia_vi_mipi_lane_divide_mode;
|
||||
|
||||
typedef struct {
|
||||
xmedia_bool enable;
|
||||
xmedia_u32 lane_cfg[VI_MIPI_DATA_LANE_MAX_NUM];
|
||||
} xmedia_vi_mipi_lane_config;
|
||||
|
||||
typedef struct {
|
||||
xmedia_vi_mipi_lane_divide_mode mipi_lane_num;
|
||||
xmedia_intf_mipi_csi_data_type data_type;
|
||||
xmedia_u32 mipi_rate; // 单位:Mbps
|
||||
xmedia_vi_mipi_lane_config lane_config;
|
||||
} xmedia_vi_dev_config;
|
||||
|
||||
typedef struct {
|
||||
xmedia_video_data_width bit_width;
|
||||
xmedia_u32 width;
|
||||
xmedia_u32 height;
|
||||
xmedia_u32 vi_work_mode; // 0:在线 1:离线
|
||||
xmedia_video_wdr_mode wdr_mode;
|
||||
} xmedia_vi_pipe_config;
|
||||
|
||||
#endif
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../source/gmp/include/xmedia_video_common.h
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
SRCS-$(CONFIG_MEDIA_SAMPLE_QUICKSTART) += media_quickstart.c
|
||||
Executable
+412
@@ -0,0 +1,412 @@
|
||||
#include <malloc.h>
|
||||
#include <timer.h>
|
||||
#include <pwm.h>
|
||||
#include <common.h>
|
||||
|
||||
#include "media_sample.h"
|
||||
|
||||
#define MCU_CPU_SYNC_REG 0x1202014c
|
||||
#define MCU_END_VALUE 0xbeef0002
|
||||
#define MCU_EXIT_VALUE 0xbeef0003
|
||||
//#define INFRARED_SUPPORT 1
|
||||
|
||||
#ifdef INFRARED_SUPPORT
|
||||
#define PWM_R_LED_NUM 8
|
||||
#define PWM_R_LED_REG 0x11980014
|
||||
#define PWM_R_LED_VALUE 0x401
|
||||
#define PWM_ENABLE_REG 0x11980018
|
||||
#endif
|
||||
|
||||
#ifdef SENSOR_SC485SL_2LANE_SUPPORT
|
||||
#define MCU_SENSOR_WIDTH 2560
|
||||
#define MCU_SENSOR_HEIGHT 1440
|
||||
#elif defined (SENSOR_SC485SL_4LANE_SUPPORT)
|
||||
#define MCU_SENSOR_WIDTH 2688
|
||||
#define MCU_SENSOR_HEIGHT 1520
|
||||
#elif defined (SENSOR_SC485SL_4LANE_60FPS_SUPPORT)
|
||||
#define MCU_SENSOR_WIDTH 2560
|
||||
#define MCU_SENSOR_HEIGHT 1440
|
||||
#elif defined (SENSOR_SC235HAI_2LANE_60FPS_SUPPORT)
|
||||
#define MCU_SENSOR_WIDTH 1920
|
||||
#define MCU_SENSOR_HEIGHT 1080
|
||||
#else
|
||||
#define MCU_SENSOR_WIDTH 2688
|
||||
#define MCU_SENSOR_HEIGHT 1520
|
||||
#endif
|
||||
|
||||
STAGE1_FUNC xmedia_void media_comm_write_reg(xmedia_u32 addr, xmedia_u32 value)
|
||||
{
|
||||
*((xmedia_u32 *)addr) = value;
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_u32 media_comm_read_reg(xmedia_u32 addr)
|
||||
{
|
||||
return *((xmedia_u32 *)addr);
|
||||
}
|
||||
|
||||
xmedia_bool media_comm_get_mcu_end_signal()
|
||||
{
|
||||
if (MCU_END_VALUE == media_comm_read_reg(MCU_CPU_SYNC_REG))
|
||||
{
|
||||
return XMEDIA_TRUE;
|
||||
}
|
||||
|
||||
return XMEDIA_FALSE;
|
||||
}
|
||||
|
||||
xmedia_void media_comm_set_mcu_exit_signal()
|
||||
{
|
||||
media_comm_write_reg(MCU_CPU_SYNC_REG, MCU_EXIT_VALUE);
|
||||
}
|
||||
|
||||
#ifdef INFRARED_SUPPORT
|
||||
xmedia_s32 media_comm_infrared_init()
|
||||
{
|
||||
xmedia_s32 s32Ret = XMEDIA_FAILURE;
|
||||
//set pinmux
|
||||
media_comm_write_reg(PWM_R_LED_REG, PWM_R_LED_VALUE);
|
||||
|
||||
//duty_cycle_us > 0, is smaller the light brighter
|
||||
s32Ret = pwm_config(PWM_R_LED_NUM, 1, 100);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("pwm config fail \n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 media_comm_set_infrared(LIGHT_STATUS state)
|
||||
{
|
||||
xmedia_s32 s32Ret = XMEDIA_FAILURE;
|
||||
|
||||
if (state == LIGHT_STATUS_NIGHT) {
|
||||
media_comm_write_reg(PWM_ENABLE_REG, 1 << 8);
|
||||
return pwm_enable(PWM_R_LED_NUM);
|
||||
} else if (state == LIGHT_STATUS_DAY) {
|
||||
return pwm_disable(PWM_R_LED_NUM);
|
||||
}
|
||||
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
xmedia_s32 media_comm_set_ir_cut_state(xmedia_s32 vi_dev, LIGHT_STATUS state)
|
||||
{
|
||||
if (vi_dev == 0 || vi_dev == 1) {
|
||||
media_comm_write_reg(0x112C00BC,0x1400);
|
||||
media_comm_write_reg(0x112C00C0,0x1400);
|
||||
|
||||
if (state == LIGHT_STATUS_DAY) {
|
||||
media_comm_write_reg(0x120B2400,0x03);
|
||||
media_comm_write_reg(0x120B200C,0x02);
|
||||
} else if (state == LIGHT_STATUS_NIGHT){
|
||||
media_comm_write_reg(0x120B2400,0x03);
|
||||
media_comm_write_reg(0x120B200C,0x01);
|
||||
} else {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
} else if (vi_dev == 2 || vi_dev == 3) {
|
||||
media_comm_write_reg(0x112C00C8,0x1400);
|
||||
media_comm_write_reg(0x112C00CC,0x1400);
|
||||
|
||||
if (state == LIGHT_STATUS_DAY) {
|
||||
media_comm_write_reg(0x120B5400,0x03);
|
||||
media_comm_write_reg(0x120B500C,0x02);
|
||||
} else if (state == LIGHT_STATUS_NIGHT){
|
||||
media_comm_write_reg(0x120B5400,0x03);
|
||||
media_comm_write_reg(0x120B500C,0x01);
|
||||
} else {
|
||||
return XMEDIA_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (vi_dev == 0 || vi_dev == 1) {
|
||||
media_comm_write_reg(0x120B2400,0x00);
|
||||
media_comm_write_reg(0x120B200C,0x00);
|
||||
} else if (vi_dev == 2 || vi_dev == 3) {
|
||||
media_comm_write_reg(0x120B5400,0x00);
|
||||
media_comm_write_reg(0x120B500C,0x00);
|
||||
}
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
STAGE1_FUNC static xmedia_void quickstart_sensor_register(xmedia_s32 isp_pipe)
|
||||
{
|
||||
#if defined(SENSOR_SC485SL_2LANE_SUPPORT) || defined(SENSOR_SC485SL_4LANE_SUPPORT) || defined(SENSOR_SC485SL_4LANE_60FPS_SUPPORT)
|
||||
XMEDIA_SENSOR_REGISTER_DRIVER(isp_pipe, sc485sl);
|
||||
#elif defined(SENSOR_SC235HAI_2LANE_60FPS_SUPPORT)
|
||||
XMEDIA_SENSOR_REGISTER_DRIVER(isp_pipe, sc235hai);
|
||||
#else
|
||||
#error "should define sensor type first"
|
||||
#endif
|
||||
}
|
||||
|
||||
STAGE1_FUNC static xmedia_void quickstart_sensor_unregister(xmedia_s32 isp_pipe)
|
||||
{
|
||||
#if defined(SENSOR_SC485SL_2LANE_SUPPORT) || defined(SENSOR_SC485SL_4LANE_SUPPORT)
|
||||
XMEDIA_SENSOR_UNREGISTER_DRIVER(isp_pipe, sc485sl);
|
||||
#elif defined(SENSOR_SC485SL_4LANE_60FPS_SUPPORT)
|
||||
XMEDIA_SENSOR_UNREGISTER_DRIVER(isp_pipe, sc485sl);
|
||||
#elif defined(SENSOR_SC235HAI_2LANE_60FPS_SUPPORT)
|
||||
XMEDIA_SENSOR_UNREGISTER_DRIVER(isp_pipe, sc235hai);
|
||||
#else
|
||||
#error "should define sensor type first"
|
||||
#endif
|
||||
}
|
||||
|
||||
STAGE1_FUNC static xmedia_void quickstart_vi_get_devcfg(xmedia_vi_dev_config *vi_dev_cfg)
|
||||
{
|
||||
#if defined(SENSOR_SC485SL_2LANE_SUPPORT)
|
||||
vi_dev_cfg->mipi_lane_num = XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_2_LANE;
|
||||
vi_dev_cfg->data_type = XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_12BIT;
|
||||
vi_dev_cfg->mipi_rate = 1080;
|
||||
#elif defined(SENSOR_SC485SL_4LANE_SUPPORT)
|
||||
vi_dev_cfg->mipi_lane_num = XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE;
|
||||
vi_dev_cfg->data_type = XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_12BIT;
|
||||
vi_dev_cfg->mipi_rate = 1126;
|
||||
#elif defined(SENSOR_SC485SL_4LANE_60FPS_SUPPORT)
|
||||
vi_dev_cfg->mipi_lane_num = XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE;
|
||||
vi_dev_cfg->data_type = XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_12BIT;
|
||||
vi_dev_cfg->mipi_rate = 864;
|
||||
#elif defined(SENSOR_SC235HAI_2LANE_60FPS_SUPPORT)
|
||||
vi_dev_cfg->mipi_lane_num = XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_2_LANE;
|
||||
vi_dev_cfg->data_type = XMEDIA_INTF_MIPI_CSI_DATA_TYPE_RAW_10BIT;
|
||||
vi_dev_cfg->mipi_rate = 756;
|
||||
#else
|
||||
#error "should define sensor type first"
|
||||
#endif
|
||||
}
|
||||
|
||||
STAGE1_FUNC static xmedia_sensor_mipi_lanes quickstart_from_vi_get_mipi_lanes(xmedia_vi_dev_config *vi_dev_cfg)
|
||||
{
|
||||
xmedia_sensor_mipi_lanes mipi_lanes = XMEDIA_SENSOR_MIPI_LANES_2L;
|
||||
if (vi_dev_cfg->mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_1_LANE) {
|
||||
mipi_lanes = XMEDIA_SENSOR_MIPI_LANES_1L;
|
||||
} else if (vi_dev_cfg->mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_2_LANE) {
|
||||
mipi_lanes = XMEDIA_SENSOR_MIPI_LANES_2L;
|
||||
} else if (vi_dev_cfg->mipi_lane_num == XMEDIA_VI_MIPI_LANE_DIVIDE_MODE_4_LANE) {
|
||||
mipi_lanes = XMEDIA_SENSOR_MIPI_LANES_4L;
|
||||
}
|
||||
|
||||
return mipi_lanes;
|
||||
}
|
||||
|
||||
STAGE1_FUNC xmedia_s32 quickstart_media_preinit(void)
|
||||
{
|
||||
xmedia_s32 s32Ret = XMEDIA_FAILURE;
|
||||
xmedia_s32 isp_pipe = 0;
|
||||
xmedia_s32 vi_dev = 0;
|
||||
xmedia_vi_dev_config vi_dev_cfg = {0};
|
||||
xmedia_sensor_config sensor_cfg = {0};
|
||||
xmedia_sensor_attr sensor_attr = {0};
|
||||
xmedia_sensor_mipi_lanes mipi_lanes = XMEDIA_SENSOR_MIPI_LANES_2L;
|
||||
|
||||
sensor_cfg.comm_bus.type = XMEDIA_SENSOR_BUS_TYPE_I2C;
|
||||
sensor_cfg.init_mode = XMEDIA_SENSOR_INIT_MODE_NORMAL;
|
||||
sensor_cfg.comm_bus.i2c_dev = 0;
|
||||
sensor_cfg.ctrl_sig.clk_ch = 0;
|
||||
sensor_cfg.ctrl_sig.rst_ch = 0;
|
||||
|
||||
s32Ret = i2c_init(sensor_cfg.comm_bus.i2c_dev);
|
||||
if (s32Ret != 0) {
|
||||
MEDIA_STAGE1_ERR("i2c init error\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
drv_mipi_init();
|
||||
|
||||
quickstart_vi_get_devcfg(&vi_dev_cfg);
|
||||
|
||||
s32Ret = drv_mipi_enable(vi_dev, &vi_dev_cfg);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_STAGE1_ERR("mipi enable fail \n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
quickstart_sensor_register(isp_pipe);
|
||||
|
||||
s32Ret = drv_sensor_init(isp_pipe, &sensor_cfg);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_STAGE1_ERR("sensor init fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
mipi_lanes = quickstart_from_vi_get_mipi_lanes(&vi_dev_cfg);
|
||||
drv_sensor_set_mipi_lanes(isp_pipe, mipi_lanes);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_STAGE1_ERR("sensor set mipi lanes fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
sensor_attr.width = MCU_SENSOR_WIDTH;
|
||||
sensor_attr.height = MCU_SENSOR_HEIGHT;
|
||||
sensor_attr.wdr_mode = 0;
|
||||
s32Ret = drv_sensor_set_attr(isp_pipe, &sensor_attr);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_STAGE1_ERR("sensor set attr fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = drv_sensor_start(isp_pipe);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("sensor start fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
#ifdef CONFIG_STOPWATCH_SUPPORT
|
||||
stopwatch_trigger();
|
||||
#endif
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
|
||||
xmedia_s32 quickstart_media_start(void)
|
||||
{
|
||||
xmedia_s32 s32Ret = XMEDIA_FAILURE;
|
||||
xmedia_s32 isp_pipe = 0;
|
||||
xmedia_s32 vi_dev = 0;
|
||||
xmedia_s32 vi_pipe = 0;
|
||||
xmedia_vi_dev_config vi_dev_cfg = {0};
|
||||
xmedia_vi_pipe_config vi_pipe_cfg = {0};
|
||||
xmedia_isp_config isp_cfg = {0};
|
||||
|
||||
quickstart_vi_get_devcfg(&vi_dev_cfg);
|
||||
|
||||
s32Ret = drv_vi_init();
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("vi init fail \n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = drv_vi_enable_dev(vi_dev);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("vi enable dev fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = drv_vi_set_dev_bind_pipe(vi_dev, vi_pipe);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("vi dev bind pipe fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
quickstart_vi_get_devcfg(&vi_dev_cfg);
|
||||
|
||||
vi_pipe_cfg.bit_width = vi_dev_cfg.data_type;
|
||||
vi_pipe_cfg.width = MCU_SENSOR_WIDTH;
|
||||
vi_pipe_cfg.height = MCU_SENSOR_HEIGHT;
|
||||
vi_pipe_cfg.vi_work_mode = 0;
|
||||
vi_pipe_cfg.wdr_mode = XMEDIA_VIDEO_WDR_MODE_NONE;
|
||||
|
||||
s32Ret = xmedia_awb_register(isp_pipe);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("awb init fail\n");
|
||||
puthex(s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = xmedia_ae_register(isp_pipe);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("ae init fail\n");
|
||||
puthex(s32Ret);
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
isp_cfg.size.width = MCU_SENSOR_WIDTH;
|
||||
isp_cfg.size.height = MCU_SENSOR_HEIGHT;
|
||||
#if defined(SENSOR_SC485SL_4LANE_60FPS_SUPPORT) ||defined(SENSOR_SC235HAI_2LANE_60FPS_SUPPORT)
|
||||
isp_cfg.fps = 60;
|
||||
#else
|
||||
isp_cfg.fps = 30;
|
||||
#endif
|
||||
isp_cfg.wdr_mode = XMEDIA_VIDEO_WDR_MODE_NONE;
|
||||
isp_cfg.bayer_fmt = XMEDIA_VIDEO_BAYER_FMT_BGGR;
|
||||
isp_cfg.pixel_fmt = XMEDIA_VIDEO_PIXEL_FMT_RAW;
|
||||
isp_cfg.mode_config.work_mode = XMEDIA_ISP_WORK_MODE_MASTER;
|
||||
isp_cfg.mode_config.master_mode.blend_stat_enable = XMEDIA_FALSE;
|
||||
isp_cfg.mode_config.master_mode.slave_num = 0;
|
||||
|
||||
s32Ret = drv_isp_init(isp_pipe, &isp_cfg);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("isp init fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = drv_vi_start_pipe(vi_pipe, &vi_pipe_cfg);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("vi start pipe fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = drv_isp_start(isp_pipe);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("isp start fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
s32Ret = drv_isp_process(isp_pipe);
|
||||
if (s32Ret == XMEDIA_SUCCESS ) {
|
||||
if (XMEDIA_TRUE == media_comm_get_mcu_end_signal()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_STOPWATCH_SUPPORT
|
||||
stopwatch_trigger();
|
||||
#endif
|
||||
s32Ret = drv_isp_stop(isp_pipe);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("isp stop fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = drv_vi_stop_pipe(vi_pipe);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("isp stop fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = drv_isp_exit(isp_pipe);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("isp exit fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = xmedia_ae_unregister(isp_pipe);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("ae exit fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = xmedia_awb_unregister(isp_pipe);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("awb exit fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
quickstart_sensor_unregister(isp_pipe);
|
||||
|
||||
s32Ret = drv_vi_set_dev_unbind_pipe(vi_dev, vi_pipe);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("vi dev unbind pipe fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = drv_vi_disable_dev(vi_dev, &vi_dev_cfg);
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("vi disable dev fail\n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
s32Ret = drv_vi_exit();
|
||||
if (s32Ret != XMEDIA_SUCCESS) {
|
||||
MEDIA_ERR("vi exit fail \n");
|
||||
return s32Ret;
|
||||
}
|
||||
|
||||
media_comm_set_mcu_exit_signal();
|
||||
|
||||
return XMEDIA_SUCCESS;
|
||||
}
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../source/gmp/usr/isp/sensor/
|
||||
Executable
+166
@@ -0,0 +1,166 @@
|
||||
CROSS_COMPILE ?= riscv64-unknown-elf-
|
||||
O ?= $(shell pwd)/out
|
||||
ARCH ?= riscv
|
||||
|
||||
CONFIG_INC := $(O)/include/autoconf.h
|
||||
CONFIG_MAKE := $(O)/.makefile
|
||||
CONFIG_FILE := $(O)/.config
|
||||
export CONFIG_FILE CONFIG_INC
|
||||
|
||||
sinclude $(CONFIG_FILE)
|
||||
|
||||
TOPDIR := $(shell pwd)
|
||||
export TOPDIR
|
||||
CC := $(CROSS_COMPILE)gcc
|
||||
AR := $(CROSS_COMPILE)ar
|
||||
LD := $(CROSS_COMPILE)ld
|
||||
OBJCOPY := $(CROSS_COMPILE)objcopy
|
||||
SIZE := $(CROSS_COMPILE)size
|
||||
STRIP := $(CROSS_COMPILE)strip
|
||||
OBJDUMP := $(CROSS_COMPILE)objdump
|
||||
RM := $(shell if [ -x "/bin/rm" ]; then echo /bin/rm; else type -P rm; fi)
|
||||
LS := $(shell if [ -x "/bin/ls" ]; then echo /bin/ls; else type -P ls; fi)
|
||||
MCU := mcu
|
||||
RM := $(RM) -f
|
||||
|
||||
export CC AR LD OBJCOPY RM TOPDIR MCU SIZE STRIP LS
|
||||
|
||||
include $(TOPDIR)/scripts/Makefile.define
|
||||
|
||||
V ?= 0
|
||||
|
||||
ifeq ($(V),1)
|
||||
Q :=
|
||||
QUIET :=
|
||||
else
|
||||
Q := @
|
||||
QUIET := -s
|
||||
endif
|
||||
|
||||
MKFLAGS := $(QUIET) -f $(TOPDIR)/scripts/Makefile.build
|
||||
CLFLAGS := $(QUIET) -f $(TOPDIR)/scripts/Makefile.clean
|
||||
|
||||
export MKFLAGS CLFLAGS Q QUIET
|
||||
|
||||
MKDEP := .mkdep
|
||||
export MKDEP
|
||||
|
||||
ARFLAGS += rcs
|
||||
LDFLAGS +=
|
||||
|
||||
CFLAGS += -fno-builtin -fno-common -ffreestanding -nostdinc \
|
||||
-I$(shell pwd)/include -I$(O)/include -I$(TOPDIR) -pipe -g -gdwarf-4 -Wall -Werror \
|
||||
-DCONFIG_$(strip $(call upper, $(ARCH)))_ARCH
|
||||
|
||||
GC_ENABLE ?= y
|
||||
CFLAGS += $(if $(GC_ENABLE),-fdata-sections -ffunction-sections)
|
||||
CFLAGS += $(shell echo $(CONFIG_CFLAGS))
|
||||
LDFLAGS += $(shell echo $(CONFIG_LDFLAGS))
|
||||
|
||||
ARCH_DIR := $(ARCH)/
|
||||
|
||||
CFLAGS += -I$(TOPDIR)/$(ARCH_DIR)include
|
||||
|
||||
ASFLAGS += $(CFLAGS) -D__ASSEMBLY__
|
||||
|
||||
export ARFLAGS LDFLAGS CFLAGS ASFLAGS
|
||||
|
||||
LIB_DIRS := init/ libs/ drivers/ common/
|
||||
|
||||
ifdef CONFIG_MEDIA_SUPPORT
|
||||
MEDIA = $(if $(wildcard $(TOPDIR)/media/Makefile),y,)
|
||||
endif
|
||||
|
||||
LIB_DIRS-stage2 += $(call is_enabled, MEDIA,media/,)
|
||||
CFLAGS += $(call is_enabled, MEDIA,-I$(TOPDIR)/media/include,)
|
||||
|
||||
ifeq ($(strip $(CONFIG_UT_ENABLE)),y)
|
||||
LIB_DIRS-stage2 += test/
|
||||
endif
|
||||
|
||||
LIBS := $(foreach LIB,$(LIB_DIRS),$(LIB)lib$(LIB:/=).a)
|
||||
LIBS-stage2 := $(foreach LIB,$(LIB_DIRS-stage2),$(LIB)lib$(LIB:/=).a)
|
||||
|
||||
################################################################################
|
||||
sinclude $(CONFIG_MAKE)
|
||||
|
||||
PHONYS += help
|
||||
help:
|
||||
@echo "Usage: make [config]"
|
||||
@echo " make clean"
|
||||
@echo " make distclean"
|
||||
@echo " make help"
|
||||
@echo " make"
|
||||
@echo " support configs:"
|
||||
@for ix in $(notdir $(wildcard $(TOPDIR)/configs/*)); do ( \
|
||||
echo " $${ix}"; \
|
||||
) done
|
||||
@echo;
|
||||
|
||||
PHONYS += $(MCU).bin
|
||||
$(MCU).bin: $(MCU).elf
|
||||
$(call show_cmd,OBJCOPY,$@)
|
||||
$(Q)$(OBJCOPY) -R .comment --gap-fill=0xff -O binary $(O)/$< $(O)/$@
|
||||
$(call show_cmd,MCU,$@)
|
||||
$(Q)$(OBJDUMP) -D $(O)/$(MCU).elf > $(O)/mcu.asm
|
||||
@echo "Config File: $(CONFIG_PLATFORM)_defconfig"
|
||||
@echo "Entry Point: $(CONFIG_TEXT_BASE)"
|
||||
@MSG=$$(cd $(O); $(LS) -gG --time-style=long-iso $@); \
|
||||
echo "Image Size: $$(echo $${MSG} | awk '{print $$3}') Bytes"; \
|
||||
echo "Create: $$(echo $${MSG} | awk '{print $$4" "$$5}')"
|
||||
@echo "Output Path: $(O)"
|
||||
@echo " Image $(@) is ready"
|
||||
|
||||
PHONYS += $(MCU).bin
|
||||
$(MCU).elf: $(LIBS) $(LIBS-stage2)
|
||||
$(Q)$(MAKE) $(MKFLAGS) SRCDIR="$(ARCH_DIR)" LIBS="$(LIBS)" LIBS-stage2="$(LIBS-stage2)" O="$(O)/" $(@)
|
||||
|
||||
PHONYS += $(LIBS) $(LIBS-stage2)
|
||||
$(LIBS): $(O)/$(MKDEP) force
|
||||
@touch init/main.c
|
||||
$(Q)$(MAKE) $(MKFLAGS) -C $(TOPDIR)/$(@D)/ SRCDIR="$(@D)/" O="$(O)/" $(@F)
|
||||
|
||||
$(LIBS-stage2): $(O)/$(MKDEP) force
|
||||
$(Q)$(MAKE) $(MKFLAGS) -C $(TOPDIR)/$(@D)/ SRCDIR="$(@D)/" O="$(O)/" $(@F)
|
||||
|
||||
|
||||
%: $(TOPDIR)/configs/%
|
||||
$(call show_cmd,GEN,$(notdir $(CONFIG_MAKE)))
|
||||
$(call checkdir,$(dir $(CONFIG_MAKE)))
|
||||
$(Q)(echo "# auto produce, don't modify this ") > $(CONFIG_MAKE)
|
||||
$(Q)(echo "all: $(MCU).bin";) >> $(CONFIG_MAKE)
|
||||
$(call show_cmd,GEN,$(notdir $(CONFIG_FILE)))
|
||||
$(call checkdir,$(dir $(CONFIG_FILE)))
|
||||
$(Q)cp "$<" "$(CONFIG_FILE)"
|
||||
$(call show_cmd,GEN,$(notdir $(CONFIG_INC)))
|
||||
$(call checkdir,$(dir $(CONFIG_INC)))
|
||||
$(Q)(echo "/* auto produce, don't modify this */") > $(CONFIG_INC)
|
||||
$(Q)set -e; cat $(CONFIG_FILE) | sed -n -f $(TOPDIR)/scripts/env2inc.sed >> $(CONFIG_INC)
|
||||
|
||||
force:;
|
||||
|
||||
$(O)/$(MKDEP): $(TOPDIR)/Makefile
|
||||
@touch $@
|
||||
|
||||
PHONYS += clean
|
||||
clean: $(addsuffix .clean,$(LIBS) $(ARCH_DIR))
|
||||
$(Q)$(RM) -f $(O)/{$(MCU).bin,$(MCU).elf,$(MCU).map,$(MKDEP)}
|
||||
|
||||
$(addsuffix .clean,$(LIBS) $(ARCH_DIR)):
|
||||
$(call show_cmd,ENTRY,$(TOPDIR)/$(@D))
|
||||
$(Q)$(MAKE) $(CLFLAGS) SRCDIR="$(@D)/" O="$(O)/" clean
|
||||
|
||||
PHONYS += distclean
|
||||
distclean:
|
||||
$(Q)$(RM) -rf $(O)
|
||||
$(Q)$(RM) -rf cscope.files cscope.in.out cscope.out cscope.po.out tags
|
||||
|
||||
PHONYS += cscope
|
||||
cscope:
|
||||
$(Q)find -name "*.S" -o -name "*.c" -o -name "*.h" -o -name "*.s" >cscope.files
|
||||
$(Q)cscope -bkq -i ./cscope.files
|
||||
$(Q)ctags -R
|
||||
|
||||
################################################################################
|
||||
.PHONY: $(PHONYS)
|
||||
################################################################################
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
|
||||
CFLAGS_start += -DTEXT_BASE=$(CONFIG_TEXT_BASE)
|
||||
CFLAGS_start += -DSTACK_TOP=$(CONFIG_STACK_TOP)
|
||||
CFLAGS += -DSTACK_TOP=$(CONFIG_STACK_TOP)
|
||||
ASFLAGS += -DSTACK_TOP=$(CONFIG_STACK_TOP)
|
||||
|
||||
LINKLDS := firmware.lds
|
||||
START = start.S
|
||||
TAIL = tail.S
|
||||
SRCS-y += chip.c
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
void reset_cpu(void)
|
||||
{
|
||||
}
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
#include <config.h>
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = CONFIG_TEXT_BASE;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text : {
|
||||
. = ALIGN(4);
|
||||
__text_start = .;
|
||||
start.o (.text)
|
||||
*(.text)
|
||||
__text_end = .;
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : {
|
||||
__data_start = .;
|
||||
*(.data)
|
||||
__data_end = .;
|
||||
}
|
||||
|
||||
.tail : {
|
||||
tail.o(.tail)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.bss : {
|
||||
__bss_start = .;
|
||||
*(.bss)
|
||||
__bss_end = .;
|
||||
ASSERT(((__bss_end - __bss_start) == 0), "All global and static
|
||||
variables MUST be initialized with non-zero value!");
|
||||
}
|
||||
|
||||
_end = .;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
#ifndef __BARRIERS_H__
|
||||
#define __BARRIERS_H__
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define ISB asm volatile ("isb sy" : : : "memory")
|
||||
#define DSB asm volatile ("dsb sy" : : : "memory")
|
||||
#define DMB asm volatile ("dmb sy" : : : "memory")
|
||||
|
||||
#define isb() ISB
|
||||
#define dsb() DSB
|
||||
#define dmb() DMB
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __BARRIERS_H__ */
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
#ifndef __ASM_ARM_IO_H
|
||||
#define __ASM_ARM_IO_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <barriers.h>
|
||||
|
||||
#define __arch_getl(a) (*(volatile unsigned int *)(a))
|
||||
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
|
||||
|
||||
#define mb() dsb()
|
||||
#define __iormb() dmb()
|
||||
#define __iowmb() dmb()
|
||||
|
||||
#ifdef REG_IORW_DEBUG
|
||||
#include <serial.h>
|
||||
#define writel(v,c) ({ u32 __v = v; __iowmb(); serial_puts("REG W: 0x"); serial_put_hex(c); serial_puts(", 0x"); serial_put_hex(__v); serial_puts("\n"); __arch_putl(__v,c); __v; })
|
||||
#define readl(c) ({ u32 __v; serial_puts("REG R: 0x"); serial_put_hex(c); __v = __arch_getl(c); __iormb(); serial_puts(", 0x"); serial_put_hex(__v); serial_puts("\n"); __v; })
|
||||
#else
|
||||
#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; })
|
||||
#define readl(c) ({ u32 __v = __arch_getl(c); __iormb(); __v; })
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_ARM_IO_H */
|
||||
Executable
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#ifndef __CHIP_REGS_H__
|
||||
#define __CHIP_REGS_H__
|
||||
|
||||
#define BIT(nr) (1 << (nr))
|
||||
|
||||
#define RAM_START_ADRS 0x04010500
|
||||
#define STACK_TRAINING 0x04018000
|
||||
|
||||
#define DDR_DDRT_REG_BASE 0x11330000
|
||||
#define TIMER0_REG_BASE 0x12000000
|
||||
#define TIMER1_REG_BASE 0x12000020
|
||||
#define TIMER2_REG_BASE 0x12001000
|
||||
#define TIMER3_REG_BASE 0x12001020
|
||||
#define REG_TIMER_RELOAD 0x0
|
||||
#define REG_TIMER_VALUE 0x4
|
||||
#define REG_TIMER_CONTROL 0x8
|
||||
|
||||
#define CRG_REG_BASE 0x12010000
|
||||
|
||||
#define SYS_CTRL_REG_BASE 0x12020000
|
||||
#define REG_BASE_SCTL SYS_CTRL_REG_BASE
|
||||
#define REG_SC_CTRL 0
|
||||
#define REMAPCLEAR BIT(8)
|
||||
#define REMAPCLEAR_SHIFT 8
|
||||
#define TIME0_CLK_SEL BIT(16)
|
||||
#define TIME0_CLK_SEL_SHIFT 16
|
||||
#define TIME0_CLK_SEL_3M 0x0
|
||||
#define TIME0_CLK_SEL_APB 0x1
|
||||
|
||||
#define REG_SC_SYSRES 0x8
|
||||
#define REG_SYSSTAT 0x008C
|
||||
|
||||
#define REG_OTP_PO_BIT2 0x88
|
||||
|
||||
/* Generic register */
|
||||
#define REG_SC_DDRT0 0x90
|
||||
#define REG_SC_DDRT1 0x94
|
||||
#define REG_SC_DDRT2 0x98
|
||||
#define REG_SC_DDRT3 0x9c
|
||||
#define REG_SC_DDRT4 0xa0
|
||||
#define REG_SC_DDRT5 0xa4
|
||||
#define REG_SC_DDRT6 0xa8
|
||||
#define REG_SC_DDRT7 0xac
|
||||
#define REG_SC_DDRT8 0xb0
|
||||
#define REG_SC_DDRT9 0xb4
|
||||
#define REG_SC_DDRT10 0xb8
|
||||
#define REG_SC_DDRT11 0xbc
|
||||
#define REG_SC_DDRT12 0xc0
|
||||
#define REG_SC_DDRT13 0xc4
|
||||
#define REG_SC_DDRT14 0xc8
|
||||
#define REG_SC_DDRT15 0xcc
|
||||
#define REG_SC_SYSBOOT0 0x130
|
||||
#define REG_SC_SYSBOOT1 0x134
|
||||
#define REG_SC_SYSBOOT2 0x138
|
||||
#define REG_SC_SYSBOOT3 0x13c
|
||||
#define REG_SC_SYSBOOT4 0x140
|
||||
#define REG_SC_SYSBOOT5 0x144
|
||||
#define REG_SC_SYSBOOT6 0x148
|
||||
#define REG_SC_SYSBOOT7 0x14c
|
||||
#define REG_SC_SYSBOOT8 0x150
|
||||
#define REG_SC_SYSBOOT9 0x154
|
||||
#define REG_SC_SYSBOOT10 0x158
|
||||
#define REG_SC_SYSBOOT11 0x15c
|
||||
#define REG_SC_SYSBOOT12 0x160
|
||||
#define REG_SC_SYSBOOT13 0x164
|
||||
#define REG_SC_SYSBOOT14 0x168
|
||||
#define REG_SC_SYSBOOT15 0x16c
|
||||
|
||||
#define DDRCA_UPDATE (SYS_CTRL_REG_BASE + 0x8034)
|
||||
#define DDRCA_RANDOM0 (SYS_CTRL_REG_BASE + 0x8600)
|
||||
#define DDRCA_RANDOM1 (SYS_CTRL_REG_BASE + 0x8604)
|
||||
#define DDRCA_RANDOM2 (SYS_CTRL_REG_BASE + 0x8608)
|
||||
#define DDRCA_RANDOM3 (SYS_CTRL_REG_BASE + 0x860c)
|
||||
|
||||
#define MISC_REG_BASE 0x12028000
|
||||
#define DDRC0_REG_BASE 0x11330000
|
||||
#define UART0_REG_BASE 0x12040000
|
||||
#define FMC_MEM_BASE 0x14000000
|
||||
#define DDR_MEM_BASE 0x40000000
|
||||
#define TIMER0_BASE 0x12000000
|
||||
|
||||
#define SERIAL_BASE UART0_REG_BASE
|
||||
|
||||
#define UART_PL01x_DR 0x00
|
||||
#define UART_PL01x_RSR 0x04
|
||||
#define UART_PL01x_ECR 0x04
|
||||
#define UART_PL01x_FR 0x18
|
||||
|
||||
#define UART_PL01x_FR_TXFE 0x80
|
||||
#define UART_PL01x_FR_RXFF 0x40
|
||||
#define UART_PL01x_FR_TXFF 0x20
|
||||
#define UART_PL01x_FR_RXFE 0x10
|
||||
#define UART_PL01x_FR_BUSY 0x08
|
||||
#define UART_PL01x_FR_TMSK (UART_PL01x_FR_TXFF + UART_PL01x_FR_BUSY)
|
||||
|
||||
#define START_MAGIC 0x444f574e
|
||||
|
||||
#define SUCCESS 0
|
||||
#define FAILURE -1
|
||||
|
||||
#define REG_OTP_PO_BIT0 0x12020080
|
||||
|
||||
/* i2c0 reg */
|
||||
#define REG_I2C_BASE (0x12060000)
|
||||
/* clk reg control */
|
||||
#define CRG_I2C (CRG_REG_BASE + 0x1B8)
|
||||
#define I2C_CKEN BIT(16)
|
||||
#define I2C_SRST BIT(24)
|
||||
|
||||
#endif
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#include <platform.h>
|
||||
|
||||
.arm
|
||||
.globl _start
|
||||
_start:
|
||||
push {r4-r11, lr}
|
||||
bl main
|
||||
pop {r4-r11, pc}
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
b . /* bug here */
|
||||
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#include <platform.h>
|
||||
|
||||
.section .tail,#alloc
|
||||
|
||||
.fill 0x200,1,0
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
SRCS-y += common.c
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <common.h>
|
||||
#include <time.h>
|
||||
|
||||
void wait_stage2_ready(void)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
while (readl(REG_SC_SYSBOOT7) != 0xbeef0001) {
|
||||
udelay(1);
|
||||
if (c > 0 && (c % (1000 * 1000 * 2)) == 0) {
|
||||
puts("Waiting firmware ready!\n");
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
int run_stage2_func(int (*func)(void))
|
||||
{
|
||||
int ret;
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
puts("Check firmware...\n");
|
||||
|
||||
wait_stage2_ready();
|
||||
|
||||
rv32_dcache_disable();
|
||||
rv32_icache_disable();
|
||||
|
||||
|
||||
if (readl((ulong *)__bin_end_pad) != CONFIG_BIN_END_PAD) {
|
||||
puts("Firmware ERROR!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv32_icache_enable();
|
||||
rv32_dcache_enable();
|
||||
|
||||
puts("Run 0x");puthex((u32)func);puts("\n");
|
||||
ret = func();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
CONFIG_PLATFORM = xmfalcon
|
||||
CONFIG_PLATFORM_XMFALCON = y
|
||||
CONFIG_CFLAGS = "-march=rv32imafc -mabi=ilp32f -mtune=e906 -Wall -Os"
|
||||
CONFIG_LDFLAGS = "--oformat=elf32-littleriscv -lm -L$(shell $(CC) -print-sysroot)/lib/rv32imafc/ilp32f/ -lgcc -L$(dir $(shell $(CC) $(CFLAGS) -print-libgcc-file-name))"
|
||||
|
||||
CONFIG_PRINT = y
|
||||
#CONFIG_PRINTF = y
|
||||
#CONFIG_SERIAL_DISABLE = y
|
||||
#CONFIG_DEBUG_INFO = y
|
||||
CONFIG_MALLOC = y
|
||||
CONFIG_MCU_FW_MAGIC = 0x57465652
|
||||
CONFIG_MCU_FW_VERSION = 1
|
||||
CONFIG_MCU_SRAM_SIZE = 256*1024
|
||||
CONFIG_MCU_HEAD_SIZE = 64
|
||||
CONFIG_TEXT_BASE = 0x4020000
|
||||
CONFIG_STAGE2_START = 0x4028000
|
||||
CONFIG_STACK_SIZE = 8192
|
||||
CONFIG_PARAM_MEM_SIZE = 4096
|
||||
CONFIG_RESERVED_MEM_SIZE = (1 * 1024 * 1024)
|
||||
CONFIG_FPGA = y
|
||||
CONFIG_I2C = y
|
||||
CONFIG_BIN_END_PAD = 0xdeadbeef
|
||||
CONFIG_PWM = y
|
||||
#CONFIG_SIMPILE_SHELL = y
|
||||
##CONFIG_UT_ENABLE = y
|
||||
#CONFIG_XTHEAD_ISA_EXT = y
|
||||
CONFIG_MEDIA_SUPPORT = y
|
||||
CONFIG_MEDIA_PIPE_NUM = 1
|
||||
#CONFIG_MEDIA_SAMPLE_AOV = y
|
||||
#CONFIG_MEDIA_SAMPLE_QUICKSTART = y
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
CONFIG_PLATFORM = xmorca
|
||||
CONFIG_PLATFORM_XMORCA = y
|
||||
CONFIG_CFLAGS = "-march=rv32imafc -mabi=ilp32f -mtune=e906 -Wall -Os"
|
||||
CONFIG_LDFLAGS = "--oformat=elf32-littleriscv -lm -L$(shell $(CC) -print-sysroot)/lib/rv32imafc/ilp32f/ -lgcc -L$(dir $(shell $(CC) $(CFLAGS) -print-libgcc-file-name))"
|
||||
|
||||
CONFIG_PRINT = y
|
||||
#CONFIG_PRINTF = y
|
||||
#CONFIG_SERIAL_DISABLE = y
|
||||
#CONFIG_DEBUG_INFO = y
|
||||
CONFIG_MALLOC = y
|
||||
CONFIG_MCU_FW_MAGIC = 0x57465652
|
||||
CONFIG_MCU_FW_VERSION = 1
|
||||
CONFIG_MCU_SRAM_SIZE = 208*1024
|
||||
CONFIG_MCU_HEAD_SIZE = 64
|
||||
CONFIG_TEXT_BASE = 0x401C000
|
||||
CONFIG_STAGE2_START = 0x4028000
|
||||
CONFIG_STACK_SIZE = 8192
|
||||
CONFIG_PARAM_MEM_SIZE = 4096
|
||||
CONFIG_RESERVED_MEM_SIZE = (1 * 1024 * 1024)
|
||||
#CONFIG_FPGA = y
|
||||
CONFIG_I2C = y
|
||||
CONFIG_BIN_END_PAD = 0xdeadbeef
|
||||
CONFIG_PWM = y
|
||||
#CONFIG_SIMPILE_SHELL = y
|
||||
##CONFIG_UT_ENABLE = y
|
||||
#CONFIG_XTHEAD_ISA_EXT = y
|
||||
CONFIG_MEDIA_SUPPORT = y
|
||||
#CONFIG_STOPWATCH_SUPPORT = y
|
||||
CONFIG_MEDIA_PIPE_NUM = 1
|
||||
#CONFIG_MEDIA_SAMPLE_QUICKSTART = y
|
||||
@@ -0,0 +1,7 @@
|
||||
SRCS-y += timer/
|
||||
SRCS-y += serial/
|
||||
SRCS-y += gpio/
|
||||
SRCS-y += stopwatch/
|
||||
SRCS-$(CONFIG_I2C) += i2c/
|
||||
SRCS-$(CONFIG_PWM) += pwm/
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
SRCS-y += gpio.c
|
||||
@@ -0,0 +1,26 @@
|
||||
/* #define REG_IORW_DEBUG */
|
||||
#include <io.h>
|
||||
#include <platform.h>
|
||||
|
||||
unsigned long get_gpio_base(int group)
|
||||
{
|
||||
return GPIO0_BASE + (group << 12);
|
||||
}
|
||||
|
||||
|
||||
void gpio_set_dir(int group, int bit, int dir)
|
||||
{
|
||||
unsigned long base = get_gpio_base(group);
|
||||
unsigned int v = readl(base + GPIO_DIR);
|
||||
v &= ~(1 << bit);
|
||||
v |= dir << bit;
|
||||
writel(v, base + GPIO_DIR);
|
||||
}
|
||||
|
||||
void gpio_set_data(int group, int bit, int data)
|
||||
{
|
||||
unsigned long base = get_gpio_base(group);
|
||||
unsigned long data_addr = (base + (1 << (bit + 2)));
|
||||
|
||||
writel(data << bit, data_addr);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
SRCS-y += i2c.c
|
||||
@@ -0,0 +1,600 @@
|
||||
#include <io.h>
|
||||
#include <timer.h>
|
||||
#include "i2c.h"
|
||||
|
||||
struct platform_i2c {
|
||||
unsigned int msg_buf_ptr;
|
||||
int status;
|
||||
#define I2C_WAIT_RESPOND (1 << 0)
|
||||
};
|
||||
|
||||
struct i2c_platform_data {
|
||||
unsigned int freq;
|
||||
unsigned int clk;
|
||||
};
|
||||
|
||||
struct i2c_msg {
|
||||
unsigned short addr; /* slave address */
|
||||
unsigned short flags;
|
||||
#define I2C_M_TEN 0x0010
|
||||
#define I2C_M_RD 0x0001
|
||||
#define I2C_M_STOP 0x8000
|
||||
#define I2C_M_NOSTART 0x4000
|
||||
#define I2C_M_REV_DIR_ADDR 0x2000
|
||||
#define I2C_M_IGNORE_NAK 0x1000
|
||||
#define I2C_M_NO_RD_ACK 0x0800
|
||||
#define I2C_M_RECV_LEN 0x0400
|
||||
#define I2C_M_16BIT_DATA 0x0008
|
||||
#define I2C_M_16BIT_REG 0x0002
|
||||
unsigned short len; /* msg length */
|
||||
unsigned char *buf; /* pointer to msg data */
|
||||
};
|
||||
|
||||
struct i2c_driver_data {
|
||||
unsigned int reg_base;
|
||||
unsigned int freq;
|
||||
unsigned int irq;
|
||||
unsigned int clk;
|
||||
struct i2c_msg *msgs;
|
||||
unsigned int msg_num;
|
||||
unsigned int msg_idx;
|
||||
unsigned int lock;
|
||||
void *private;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_LOTUS_FPGA
|
||||
#define CLK_LIMIT_DEFAULT 40000
|
||||
#else
|
||||
#define CLK_LIMIT_DEFAULT 400000
|
||||
#endif
|
||||
#define write_reg_bit(value, offset, addr) ({ \
|
||||
unsigned long t, mask; \
|
||||
mask = 1 << (offset); \
|
||||
t = readl(addr); \
|
||||
t &= ~mask; \
|
||||
t |= (value << (offset)) & mask; \
|
||||
writel(t, addr); \
|
||||
})
|
||||
|
||||
#define I2C_WAIT_TIMEOUT (100 * 3)
|
||||
#define I2C_TIMEOUT_COUNT 0x10000
|
||||
#define I2C_BUF_SIZE 8
|
||||
#define I2C_INTERRUPT_NUM 0
|
||||
|
||||
#if defined(CONFIG_PLATFORM_XMFALCON) || defined(CONFIG_PLATFORM_XMORCA)
|
||||
|
||||
#ifdef CONFIG_LOTUS_FPGA
|
||||
#define get_bus_clk() 25000000
|
||||
#else
|
||||
#define get_bus_clk() 50000000
|
||||
#endif
|
||||
#define get_host_clock(i2c_num) ({ get_bus_clk(); })
|
||||
|
||||
static struct platform_i2c g_i2c_platform_data[I2C_NUM] = {0};
|
||||
static int g_i2c_host_cfg[I2C_NUM] = {0, 1, 2, 3, 4, 5, 6, 7}; /* i2c index */
|
||||
static struct i2c_driver_data g_i2c_data[I2C_NUM] = {
|
||||
{I2C0_REG_BASE, CLK_LIMIT_DEFAULT, I2C_INTERRUPT_NUM},
|
||||
{I2C1_REG_BASE, CLK_LIMIT_DEFAULT, I2C_INTERRUPT_NUM},
|
||||
{I2C2_REG_BASE, CLK_LIMIT_DEFAULT, I2C_INTERRUPT_NUM},
|
||||
{I2C3_REG_BASE, CLK_LIMIT_DEFAULT, I2C_INTERRUPT_NUM},
|
||||
{I2C4_REG_BASE, CLK_LIMIT_DEFAULT, I2C_INTERRUPT_NUM},
|
||||
{I2C5_REG_BASE, CLK_LIMIT_DEFAULT, I2C_INTERRUPT_NUM},
|
||||
{I2C6_REG_BASE, CLK_LIMIT_DEFAULT, I2C_INTERRUPT_NUM},
|
||||
{I2C7_REG_BASE, CLK_LIMIT_DEFAULT, I2C_INTERRUPT_NUM},
|
||||
};
|
||||
|
||||
#elif defined(CONFIG_TARGET_XM720XXX)
|
||||
|
||||
#define get_bus_clk() 50000000
|
||||
#define get_host_clock(i2c_num) ({ get_bus_clk(); })
|
||||
|
||||
static struct platform_i2c g_i2c_platform_data[I2C_NUM] = {0};
|
||||
static int g_i2c_host_cfg[I2C_NUM] = {0, 1, 2}; /* 0,1,2: i2c index */
|
||||
static struct i2c_driver_data g_i2c_data[I2C_NUM] = {
|
||||
{I2C0_REG_BASE, CLK_LIMIT_DEFAULT, I2C_INTERRUPT_NUM},
|
||||
{I2C1_REG_BASE, CLK_LIMIT_DEFAULT, I2C_INTERRUPT_NUM},
|
||||
{I2C2_REG_BASE, CLK_LIMIT_DEFAULT, I2C_INTERRUPT_NUM},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void i2c_disable(const struct i2c_driver_data *i2c);
|
||||
static void i2c_cfg_irq(const struct i2c_driver_data *i2c, unsigned int flag);
|
||||
static unsigned int i2c_clr_irq(const struct i2c_driver_data *i2c);
|
||||
|
||||
static void i2c_rescue(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
i2c_disable(i2c);
|
||||
i2c_cfg_irq(i2c, 0);
|
||||
i2c_clr_irq(i2c);
|
||||
|
||||
unsigned int val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) |
|
||||
(0x1 << FORCE_SDA_OEN_SHIFT);
|
||||
writel(val, i2c->reg_base + I2C_CTRL2);
|
||||
|
||||
unsigned int time_cnt = 0;
|
||||
do {
|
||||
for (int index = 0; index < 9; index++) { /* shift:9 */
|
||||
val = (0x1 << GPIO_MODE_SHIFT) | 0x1;
|
||||
writel(val, i2c->reg_base + I2C_CTRL2);
|
||||
udelay(5); /* delay: 5 us */
|
||||
val = (0x1 << GPIO_MODE_SHIFT) |
|
||||
(0x1 << FORCE_SCL_OEN_SHIFT) |
|
||||
(0x1 << FORCE_SDA_OEN_SHIFT);
|
||||
writel(val, i2c->reg_base + I2C_CTRL2);
|
||||
udelay(5); /* delay: 5 us */
|
||||
}
|
||||
|
||||
time_cnt++;
|
||||
if (time_cnt > I2C_WAIT_TIMEOUT) {
|
||||
goto disable_rescue;
|
||||
}
|
||||
|
||||
val = readl(i2c->reg_base + I2C_CTRL2);
|
||||
} while (!(val & (0x1 << CHECK_SDA_IN_SHIFT)));
|
||||
|
||||
val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) |
|
||||
(0x1 << FORCE_SDA_OEN_SHIFT);
|
||||
writel(val, i2c->reg_base + I2C_CTRL2);
|
||||
val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT);
|
||||
writel(val, i2c->reg_base + I2C_CTRL2);
|
||||
udelay(10); /* delay: 10 us */
|
||||
val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) |
|
||||
(0x1 << FORCE_SDA_OEN_SHIFT);
|
||||
writel(val, i2c->reg_base + I2C_CTRL2);
|
||||
|
||||
disable_rescue:
|
||||
val = (0x1 << FORCE_SCL_OEN_SHIFT) | 0x1;
|
||||
writel(val, i2c->reg_base + I2C_CTRL2);
|
||||
}
|
||||
|
||||
static void i2c_disable(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
unsigned int val = readl(i2c->reg_base + I2C_GLB);
|
||||
val &= ~GLB_EN_MASK;
|
||||
writel(val, i2c->reg_base + I2C_GLB);
|
||||
}
|
||||
|
||||
static void i2c_disable_irq(const struct i2c_driver_data *i2c, unsigned int flag)
|
||||
{
|
||||
unsigned int val = readl(i2c->reg_base + I2C_INTR_EN);
|
||||
val &= ~flag;
|
||||
writel(val, i2c->reg_base + I2C_INTR_EN);
|
||||
}
|
||||
|
||||
static unsigned int i2c_clr_irq(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
unsigned int val = readl(i2c->reg_base + I2C_INTR_STAT);
|
||||
writel(INTR_ALL_MASK, i2c->reg_base + I2C_INTR_RAW);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void i2c_set_freq(struct i2c_driver_data *i2c)
|
||||
{
|
||||
unsigned int val;
|
||||
unsigned int freq = i2c->freq;
|
||||
unsigned int clk_rate = i2c->clk;
|
||||
unsigned int max_freq = clk_rate >> 1;
|
||||
|
||||
if (freq > max_freq) {
|
||||
i2c->freq = max_freq;
|
||||
freq = i2c->freq;
|
||||
}
|
||||
|
||||
if (freq <= 100000) { /* 100000:100KHz */
|
||||
val = clk_rate / (freq * 2); /* 1/2:0.5 */
|
||||
writel(val, i2c->reg_base + I2C_SCL_H);
|
||||
writel(val, i2c->reg_base + I2C_SCL_L);
|
||||
} else {
|
||||
val = (clk_rate * 36) / (freq * 100); /* 36/100:0.36 */
|
||||
writel(val, i2c->reg_base + I2C_SCL_H);
|
||||
val = (clk_rate * 64) / (freq * 100); /* 64/100:0.64 */
|
||||
writel(val, i2c->reg_base + I2C_SCL_L);
|
||||
}
|
||||
val = readl(i2c->reg_base + I2C_GLB);
|
||||
val &= ~GLB_SDA_HOLD_MASK;
|
||||
val |= ((0xa << GLB_SDA_HOLD_SHIFT) & GLB_SDA_HOLD_MASK);
|
||||
writel(val, i2c->reg_base + I2C_GLB);
|
||||
}
|
||||
|
||||
/*
|
||||
* set i2c controller TX and RX FIFO water
|
||||
*/
|
||||
static void i2c_set_water(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
writel(I2C_TXF_WATER, i2c->reg_base + I2C_TX_WATER);
|
||||
writel(I2C_RXF_WATER, i2c->reg_base + I2C_RX_WATER);
|
||||
}
|
||||
|
||||
static void i2c_enable_clk(unsigned char i2c_num)
|
||||
{
|
||||
const unsigned int clk_start_bit = 16 + i2c_num; /* 16: i2c clk start bit */
|
||||
const unsigned int rst_start_bit = 24 + i2c_num; /* 24: i2c rst start bit */
|
||||
const unsigned int enable_clck = 1;
|
||||
const unsigned int enable_rst = 0;
|
||||
write_reg_bit(enable_clck, clk_start_bit, (uintptr_t)I2C_CRG_REG_BASE);
|
||||
write_reg_bit(enable_rst, rst_start_bit, (uintptr_t)I2C_CRG_REG_BASE);
|
||||
}
|
||||
|
||||
/*
|
||||
* initialise the controller, set i2c bus interface freq
|
||||
*/
|
||||
static void i2c_init_cfg(const struct i2c_driver_data *i2c, unsigned char i2c_num)
|
||||
{
|
||||
i2c_enable_clk(i2c_num);
|
||||
i2c_disable(i2c);
|
||||
i2c_disable_irq(i2c, INTR_ALL_MASK);
|
||||
i2c_set_freq((struct i2c_driver_data *)i2c);
|
||||
i2c_set_water(i2c);
|
||||
}
|
||||
|
||||
static void i2c_cmdreg_set(const struct i2c_driver_data *i2c, unsigned int cmd,
|
||||
unsigned int *offset)
|
||||
{
|
||||
writel(cmd, i2c->reg_base + I2C_CMD_BASE + (*offset) * 4); /* 4: bytes */
|
||||
(*offset)++;
|
||||
}
|
||||
|
||||
static void i2c_cfg_cmd(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
struct i2c_msg *msg = i2c->msgs;
|
||||
unsigned int offset = 0;
|
||||
|
||||
if (i2c->msg_idx == 0)
|
||||
i2c_cmdreg_set(i2c, CMD_TX_S, &offset);
|
||||
else
|
||||
i2c_cmdreg_set(i2c, CMD_TX_RS, &offset);
|
||||
|
||||
if (msg->flags & I2C_M_TEN) {
|
||||
if (i2c->msg_idx == 0) {
|
||||
i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset);
|
||||
i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset);
|
||||
i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset);
|
||||
} else {
|
||||
i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset);
|
||||
}
|
||||
} else {
|
||||
i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset);
|
||||
}
|
||||
|
||||
if (msg->flags & I2C_M_IGNORE_NAK)
|
||||
i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset);
|
||||
else
|
||||
i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset);
|
||||
|
||||
if (msg->flags & I2C_M_RD) {
|
||||
if (msg->len >= 2) { /* msg len:2 */
|
||||
writel(offset, i2c->reg_base + I2C_DST1);
|
||||
writel(msg->len - 2, i2c->reg_base + I2C_LOOP1); /* 2: max len */
|
||||
i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset);
|
||||
i2c_cmdreg_set(i2c, CMD_TX_ACK, &offset);
|
||||
i2c_cmdreg_set(i2c, CMD_JMP1, &offset);
|
||||
}
|
||||
i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset);
|
||||
i2c_cmdreg_set(i2c, CMD_TX_NACK, &offset);
|
||||
} else {
|
||||
writel(offset, i2c->reg_base + I2C_DST1);
|
||||
writel(msg->len - 1, i2c->reg_base + I2C_LOOP1);
|
||||
i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset);
|
||||
i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset);
|
||||
|
||||
if (msg->flags & I2C_M_IGNORE_NAK) {
|
||||
i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset);
|
||||
}
|
||||
else {
|
||||
i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset);
|
||||
}
|
||||
i2c_cmdreg_set(i2c, CMD_JMP1, &offset);
|
||||
}
|
||||
|
||||
if ((i2c->msg_idx == (i2c->msg_num - 1)) || (msg->flags & I2C_M_STOP)) {
|
||||
i2c_cmdreg_set(i2c, CMD_TX_P, &offset);
|
||||
}
|
||||
|
||||
i2c_cmdreg_set(i2c, CMD_EXIT, &offset);
|
||||
}
|
||||
|
||||
static void i2c_enable(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
unsigned int val = readl(i2c->reg_base + I2C_GLB);
|
||||
val |= GLB_EN_MASK;
|
||||
writel(val, i2c->reg_base + I2C_GLB);
|
||||
}
|
||||
|
||||
/*
|
||||
* config i2c slave addr
|
||||
*/
|
||||
static void i2c_set_addr(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
struct i2c_msg *msg = i2c->msgs;
|
||||
unsigned int addr;
|
||||
|
||||
if (msg->flags & I2C_M_TEN) {
|
||||
/* first byte is 11110XX0 where XX is upper 2 bits */
|
||||
addr = ((msg->addr & 0x300) << 1) | 0xf000;
|
||||
if (msg->flags & I2C_M_RD) {
|
||||
addr |= 1 << 8; /* shift:8 */
|
||||
}
|
||||
|
||||
/* second byte is the remaining 8 bits */
|
||||
addr |= msg->addr & 0xff;
|
||||
} else {
|
||||
addr = (msg->addr & 0x7f) << 1;
|
||||
if (msg->flags & I2C_M_RD) {
|
||||
addr |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
writel(addr, i2c->reg_base + I2C_DATA1);
|
||||
}
|
||||
|
||||
/*
|
||||
* start command sequence
|
||||
*/
|
||||
static void i2c_start_cmd(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
unsigned int val = readl(i2c->reg_base + I2C_CTRL1);
|
||||
val |= CTRL1_CMD_START_MASK;
|
||||
writel(val, i2c->reg_base + I2C_CTRL1);
|
||||
}
|
||||
|
||||
static int i2c_wait_rx_noempty(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
unsigned int time_cnt = 0;
|
||||
unsigned int val;
|
||||
|
||||
do {
|
||||
val = readl(i2c->reg_base + I2C_STAT);
|
||||
if (val & STAT_RXF_NOE_MASK) {
|
||||
return 0;
|
||||
}
|
||||
udelay(50); /* delay:50 us */
|
||||
time_cnt++;
|
||||
} while (time_cnt < I2C_TIMEOUT_COUNT);
|
||||
|
||||
i2c_rescue(i2c);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int i2c_wait_tx_nofull(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
unsigned int time_cnt = 0;
|
||||
unsigned int val;
|
||||
|
||||
do {
|
||||
val = readl(i2c->reg_base + I2C_STAT);
|
||||
if (val & STAT_TXF_NOF_MASK) {
|
||||
return 0;
|
||||
}
|
||||
udelay(50); /* delay:50 us */
|
||||
time_cnt++;
|
||||
} while (time_cnt < I2C_TIMEOUT_COUNT);
|
||||
|
||||
i2c_rescue(i2c);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int i2c_wait_idle(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
unsigned int time_cnt = 0;
|
||||
unsigned int val;
|
||||
|
||||
do {
|
||||
val = readl(i2c->reg_base + I2C_INTR_RAW);
|
||||
if (val & (INTR_ABORT_MASK)) {
|
||||
//printf("i2c wait idle 1,val==0x%x\n",val);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (val & INTR_CMD_DONE_MASK) {
|
||||
return 0;
|
||||
}
|
||||
udelay(50); /* delay:50 us */
|
||||
time_cnt++;
|
||||
} while (time_cnt < I2C_WAIT_TIMEOUT);
|
||||
|
||||
i2c_rescue(i2c);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int i2c_polling_xfer_one_msg(const struct i2c_driver_data *i2c)
|
||||
{
|
||||
int status;
|
||||
unsigned int val;
|
||||
struct i2c_msg *msg = i2c->msgs;
|
||||
unsigned int msg_buf_ptr = 0;
|
||||
|
||||
i2c_enable(i2c);
|
||||
i2c_clr_irq(i2c);
|
||||
i2c_set_addr(i2c);
|
||||
i2c_cfg_cmd(i2c);
|
||||
i2c_start_cmd(i2c);
|
||||
|
||||
if (msg->flags & I2C_M_RD) {
|
||||
while (msg_buf_ptr < msg->len) {
|
||||
status = i2c_wait_rx_noempty(i2c);
|
||||
if (status) {
|
||||
goto end;
|
||||
}
|
||||
val = readl(i2c->reg_base + I2C_RXF);
|
||||
msg->buf[msg_buf_ptr] = val;
|
||||
msg_buf_ptr++;
|
||||
}
|
||||
} else {
|
||||
while (msg_buf_ptr < msg->len) {
|
||||
status = i2c_wait_tx_nofull(i2c);
|
||||
if (status) {
|
||||
goto end;
|
||||
}
|
||||
val = msg->buf[msg_buf_ptr];
|
||||
writel(val, i2c->reg_base + I2C_TXF);
|
||||
msg_buf_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
status = i2c_wait_idle(i2c);
|
||||
end:
|
||||
i2c_disable(i2c);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void i2c_cfg_irq(const struct i2c_driver_data *i2c, unsigned int flag)
|
||||
{
|
||||
writel(flag, i2c->reg_base + I2C_INTR_EN);
|
||||
}
|
||||
|
||||
static int i2c_xfer(unsigned char i2c_num, const struct i2c_msg *msgs, int num)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
if (msgs == NULL) {
|
||||
//printf("[error] msg pointer is null.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct i2c_driver_data *i2c = &g_i2c_data[i2c_num];
|
||||
struct platform_i2c *hpi = &g_i2c_platform_data[i2c_num];
|
||||
|
||||
i2c->clk = get_host_clock(0);
|
||||
i2c->private = (void *)(hpi);
|
||||
|
||||
i2c->msgs = (struct i2c_msg *)msgs;
|
||||
i2c->msg_num = (unsigned int)num;
|
||||
i2c->msg_idx = 0;
|
||||
|
||||
while (i2c->msg_idx < i2c->msg_num) {
|
||||
status = i2c_polling_xfer_one_msg(i2c);
|
||||
if (status) {
|
||||
break;
|
||||
}
|
||||
|
||||
i2c->msgs++;
|
||||
i2c->msg_idx++;
|
||||
}
|
||||
|
||||
if (!status || i2c->msg_idx > 0) {
|
||||
status = i2c->msg_idx;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int i2c_check_enable(unsigned char i2c_num)
|
||||
{
|
||||
if (i2c_num >= I2C_NUM) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return g_i2c_host_cfg[i2c_num];
|
||||
}
|
||||
|
||||
static int hal_i2c_recv_inner(const struct i2c_client *client, unsigned char *buf,
|
||||
unsigned int count)
|
||||
{
|
||||
struct i2c_msg msg[I2C_BUF_SIZE] = {0};
|
||||
unsigned char reg_addr[2] = {0};
|
||||
|
||||
if (client->reg_width == 2) { /* reg_width:2 */
|
||||
reg_addr[0] = (client->reg_addr >> 8) & 0xff; /* shift:8 */
|
||||
reg_addr[1] = client->reg_addr & 0xff;
|
||||
} else {
|
||||
reg_addr[0] = client->reg_addr & 0xff;
|
||||
}
|
||||
|
||||
msg[0].addr = client->dev_addr;
|
||||
msg[0].flags = 0;
|
||||
msg[0].len = client->reg_width;
|
||||
msg[0].buf = reg_addr;
|
||||
|
||||
msg[1].addr = client->dev_addr;
|
||||
msg[1].flags = 0;
|
||||
msg[1].flags |= I2C_M_RD;
|
||||
msg[1].len = count;
|
||||
msg[1].buf = buf;
|
||||
|
||||
return i2c_xfer(client->i2c_num, msg, 2); /* msg num:2 */
|
||||
}
|
||||
|
||||
static int hal_i2c_send_inner(unsigned char i2c_num, unsigned short dev_addr, const char *buf,
|
||||
unsigned int count)
|
||||
{
|
||||
struct i2c_msg msg = {0};
|
||||
msg.addr = dev_addr;
|
||||
msg.flags = 0;
|
||||
msg.len = count;
|
||||
msg.buf = (unsigned char *)buf;
|
||||
int ret = i2c_xfer(i2c_num, &msg, 1);
|
||||
return (ret == 1) ? count : ret;
|
||||
}
|
||||
|
||||
static int hal_i2c_init_inner(unsigned char i2c_num)
|
||||
{
|
||||
struct i2c_driver_data *i2c = NULL;
|
||||
struct platform_i2c *hpi = NULL;
|
||||
|
||||
int ret = i2c_check_enable(i2c_num);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
i2c = &g_i2c_data[i2c_num];
|
||||
hpi = &g_i2c_platform_data[i2c_num];
|
||||
i2c->clk = get_host_clock(i2c_num);
|
||||
i2c->private = (void *)(hpi);
|
||||
i2c->irq = 0;
|
||||
i2c_init_cfg(i2c, i2c_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_recv(const struct i2c_client *client, unsigned char *buf,
|
||||
unsigned int count)
|
||||
{
|
||||
if ((client == NULL) || (buf == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (client->i2c_num >= I2C_NUM) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (count > I2C_BUF_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return hal_i2c_recv_inner(client, buf, count);
|
||||
}
|
||||
|
||||
int i2c_send(unsigned char i2c_num, unsigned short dev_addr, const char *buf,
|
||||
unsigned int count)
|
||||
{
|
||||
if (i2c_num >= I2C_NUM) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (count > I2C_BUF_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return hal_i2c_send_inner(i2c_num, dev_addr, buf, count);
|
||||
}
|
||||
|
||||
int i2c_init(unsigned char i2c_num)
|
||||
{
|
||||
if (i2c_num >= I2C_NUM) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return hal_i2c_init_inner(i2c_num);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
SRCS-y += pwm.c
|
||||
@@ -0,0 +1,80 @@
|
||||
#include <io.h>
|
||||
#include "pwm.h"
|
||||
|
||||
static void pwm_set_bits(void* base, u32 offset, unsigned int mask, u32 data)
|
||||
{
|
||||
void *address = base + offset;
|
||||
unsigned int value;
|
||||
|
||||
value = readl(address);
|
||||
value &= ~mask;
|
||||
value |= (data & mask);
|
||||
writel(value, address);
|
||||
}
|
||||
|
||||
static void get_pwm_clk(unsigned int *clk)
|
||||
{
|
||||
void *pwm_clock_addr = (void *)PWM_CLOCK_ADDR_BASE;
|
||||
unsigned int val = readl(pwm_clock_addr);
|
||||
|
||||
val = (val >> 8) & 0x3;
|
||||
switch (val) {
|
||||
case 0:
|
||||
*clk = PWM_CLOCK_3M;
|
||||
break;
|
||||
case 1:
|
||||
*clk = PWM_CLOCK_50M;
|
||||
break;
|
||||
default:
|
||||
*clk = PWM_CLOCK_24M;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int pwm_enable(int pwm_id)
|
||||
{
|
||||
if (pwm_id > PWM_MAX_NUM)
|
||||
return -1;
|
||||
|
||||
pwm_set_bits((void *)PWM_ADDR_BASE, PWM_CTRL_ADDR(pwm_id), PWM_ENABLE_MASK, (0x1 << PWM_ENABLE_SHIFT));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pwm_disable(int pwm_id)
|
||||
{
|
||||
if (pwm_id > PWM_MAX_NUM)
|
||||
return -1;
|
||||
|
||||
pwm_set_bits((void *)PWM_ADDR_BASE, PWM_CTRL_ADDR(pwm_id), PWM_ENABLE_MASK, (0x0 << PWM_ENABLE_SHIFT));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pwm_config(int pwm_id, int duty_cycle_us, int period_us)
|
||||
{
|
||||
unsigned int duty;
|
||||
unsigned int period, freq;
|
||||
unsigned int clk;
|
||||
|
||||
if ((pwm_id > PWM_MAX_NUM) || (duty_cycle_us > period_us))
|
||||
return -1;
|
||||
|
||||
get_pwm_clk(&clk);
|
||||
|
||||
freq = clk/1000000;
|
||||
|
||||
period = freq * period_us;
|
||||
duty = period * duty_cycle_us/period_us;
|
||||
|
||||
if ((period < 2) || (duty < 1))
|
||||
return -1;
|
||||
|
||||
pwm_set_bits((void *)PWM_ADDR_BASE, PWM_CFG_CYCLE_ADDR(pwm_id), PWM_PERIOD_MASK, period);
|
||||
|
||||
pwm_set_bits((void *)PWM_ADDR_BASE, PWM_CFG_HLINT_ADDR(pwm_id), PWM_DUTY_MASK, duty);
|
||||
|
||||
pwm_set_bits((void *)PWM_ADDR_BASE, PWM_CTRL_ADDR(pwm_id),
|
||||
PWM_KEEP_MASK, (0x1 << PWM_KEEP_SHIFT));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
SRCS-y += serial.c
|
||||
Executable
+199
@@ -0,0 +1,199 @@
|
||||
|
||||
/* serial.c - print to uart */
|
||||
#include <platform.h>
|
||||
#include <serial.h>
|
||||
#include <common.h>
|
||||
|
||||
|
||||
static int serial_test_enable(void)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_DISABLE
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void pl01x_putc(char c)
|
||||
{
|
||||
/* Wait until there is space in the FIFO */
|
||||
while (readl(UART_PL01x_FR) & UART_PL01x_FR_TXFF);
|
||||
|
||||
/* Send the character */
|
||||
writel(c, UART_PL01x_DR);
|
||||
}
|
||||
|
||||
static u32 pl01x_getc(void)
|
||||
{
|
||||
u32 data;
|
||||
|
||||
while (readl(UART_PL01x_FR) & UART_PL01x_FR_RXFE) {
|
||||
/* Wait until there is data in the FIFO */
|
||||
}
|
||||
|
||||
data = readl(UART_PL01x_DR);
|
||||
|
||||
/* Check for an error flag */
|
||||
if (data & 0xFFFFFF00) {
|
||||
/* Clear the error */
|
||||
writel(0xFFFFFFFF, UART_PL01x_ECR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
void serial_putc(const char c)
|
||||
{
|
||||
if (!serial_test_enable())
|
||||
return;
|
||||
|
||||
if (c == '\n')
|
||||
pl01x_putc('\r');
|
||||
|
||||
pl01x_putc(c);
|
||||
}
|
||||
|
||||
char serial_getc(void)
|
||||
{
|
||||
return (pl01x_getc() & 0xFF);
|
||||
}
|
||||
|
||||
void serial_puts(const char *s)
|
||||
{
|
||||
if (!serial_test_enable())
|
||||
return;
|
||||
|
||||
if (s == NULL)
|
||||
return;
|
||||
while (*s) {
|
||||
serial_putc(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
void serial_puts_always(const char *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
while (*s) {
|
||||
if (*s == '\n')
|
||||
pl01x_putc('\r');
|
||||
|
||||
pl01x_putc(*s);
|
||||
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
void serial_put_dec(u32 dec)
|
||||
{
|
||||
u32 num = dec;
|
||||
char c[20] = {0}; /* size 20 */
|
||||
int i = 0;
|
||||
|
||||
if (!serial_test_enable())
|
||||
return;
|
||||
|
||||
if (num == 0) {
|
||||
pl01x_putc('0');
|
||||
return;
|
||||
}
|
||||
|
||||
while (num) {
|
||||
c[i] = '0' + (num % 10); /* bit size 10 */
|
||||
++i;
|
||||
num /= 10; /* bit size 10 */
|
||||
}
|
||||
|
||||
for (i -= 1; i >= 0; --i)
|
||||
pl01x_putc(c[i]);
|
||||
}
|
||||
|
||||
void serial_put_hex(u32 hex)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
|
||||
if (!serial_test_enable())
|
||||
return;
|
||||
|
||||
for (i = 28; i >= 0; i -= 4) { /* bit size 28 4 */
|
||||
c = ((unsigned int)hex >> (unsigned int)i) & 0x0F;
|
||||
if (c < 10) /* bit size 10 */
|
||||
c += '0';
|
||||
else
|
||||
c += 'A' - 10; /* bit size 10 */
|
||||
pl01x_putc(c);
|
||||
}
|
||||
}
|
||||
|
||||
void serial_put_hex_always(u32 hex)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
|
||||
for (i = 28; i >= 0; i -= 4) { /* bit size 28 4 */
|
||||
c = ((unsigned int)hex >> (unsigned int)i) & 0x0F;
|
||||
if (c < 10) /* bit size 10 */
|
||||
c += '0';
|
||||
else
|
||||
c += 'A' - 10; /* bit size 10 */
|
||||
pl01x_putc(c);
|
||||
}
|
||||
}
|
||||
|
||||
static void _serial_crg_init(void)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
/* configure pinmux of uart */
|
||||
/* writel(0x1502, 0x112C00F0);
|
||||
* writel(0x1402, 0x119800E0); */
|
||||
|
||||
/* enable uart clock */
|
||||
tmp = readl(REG_PERI_CRG110);
|
||||
tmp |= 1 << 3;
|
||||
writel(tmp, REG_PERI_CRG110);
|
||||
|
||||
/* cancel uart reset */
|
||||
tmp = readl(REG_PERI_CRG110);
|
||||
tmp &= ~(1 << 11);
|
||||
writel(tmp, REG_PERI_CRG110);
|
||||
}
|
||||
|
||||
void serial_init(void)
|
||||
{
|
||||
u32 tmp;
|
||||
u32 divider;
|
||||
u32 remainder;
|
||||
u32 fraction;
|
||||
|
||||
_serial_crg_init();
|
||||
|
||||
/* first, disable everything */
|
||||
writel(0, UART_PL01x_CR);
|
||||
|
||||
/*
|
||||
* Set baud rate
|
||||
*
|
||||
* IBRD = UART_CLK / (16 * BAUD_RATE)
|
||||
* FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE)))
|
||||
* / (16 * BAUD_RATE))
|
||||
*/
|
||||
tmp = 16 * UART_BAUDRATE;
|
||||
divider = UART_CLOCK / tmp;
|
||||
remainder = UART_CLOCK % tmp;
|
||||
tmp = (8 * remainder) / UART_BAUDRATE;
|
||||
fraction = (tmp >> 1) + (tmp & 1);
|
||||
|
||||
writel(divider, UART_PL01x_IBRD);
|
||||
writel(fraction, UART_PL01x_FBRD);
|
||||
|
||||
writel(UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN, UART_PL01x_LCRH);
|
||||
/* Finally, enable the UART */
|
||||
writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE |
|
||||
UART_PL011_CR_RXE, UART_PL01x_CR);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
SRCS-y += stopwatch.c
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <platform.h>
|
||||
#include <io.h>
|
||||
|
||||
typedef union {
|
||||
u32 value;
|
||||
struct {
|
||||
/* [0] timer trigger */
|
||||
u32 timer_trigger : 1;
|
||||
/* [2] timer clear */
|
||||
u32 timer_clear : 1;
|
||||
/* [3] running timer trigger */
|
||||
u32 running_timer_trigger : 1;
|
||||
/* [3:31] reserved */
|
||||
u32 reserved : 29;
|
||||
};
|
||||
} stopwatch_cfg;
|
||||
|
||||
void stopwatch_trigger(void)
|
||||
{
|
||||
stopwatch_cfg cfg = {0};
|
||||
|
||||
cfg.timer_clear = 0; /* false */
|
||||
cfg.timer_trigger = 1; /* true */
|
||||
writel(cfg.value, (STOPWATCH_CTRL_REG2));
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
SRCS-y += timer.c
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <timer.h>
|
||||
|
||||
#define TIMER_LOAD 0
|
||||
#define TIMER_VALUE 0x4
|
||||
#define TIMER_CONTROL 0x8
|
||||
|
||||
#define CFG_TIMER_CTRL 0xc0
|
||||
|
||||
#define TIMER_FEQ 24000000
|
||||
|
||||
#define TIMER_DIV 1
|
||||
|
||||
#define TIMER_NOR_DIVIDER_US (TIMER_FEQ / TIMER_DIV / 1000000)
|
||||
|
||||
#define UDELAY_US_MAX (61 * 1000 * 1000UL)
|
||||
|
||||
#define REG_TIMER_BASE TIMER3_REG_BASE
|
||||
|
||||
#define timer_reg_get(offset) readl(REG_TIMER_BASE + (offset))
|
||||
#define timer_reg_set(offset, val) writel(val, REG_TIMER_BASE + (offset))
|
||||
|
||||
static u8 g_timer_init = 0;
|
||||
|
||||
ulong timer_get_val(void)
|
||||
{
|
||||
return ~1UL - timer_reg_get(TIMER_VALUE);
|
||||
}
|
||||
|
||||
void udelay(ulong us)
|
||||
{
|
||||
ulong cur, start, end;
|
||||
ulong count;
|
||||
|
||||
if (us == 0)
|
||||
return;
|
||||
|
||||
assert(g_timer_init == 1);
|
||||
|
||||
start = timer_get_val();
|
||||
|
||||
if (us >= UDELAY_US_MAX) {
|
||||
puts("WARNING: long udelay, use ");
|
||||
putdec(UDELAY_US_MAX);
|
||||
puts("us instead!\n");
|
||||
count = UDELAY_US_MAX * TIMER_NOR_DIVIDER_US;
|
||||
} else
|
||||
count = us * TIMER_NOR_DIVIDER_US;
|
||||
|
||||
end = start + count;
|
||||
|
||||
while (1) {
|
||||
cur = timer_get_val();
|
||||
if ((end >= start && cur >= end ) ||
|
||||
(end < start && cur >= end && cur < start))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mdelay(u32 msec)
|
||||
{
|
||||
assert(g_timer_init == 1);
|
||||
|
||||
udelay(msec * 1000);
|
||||
}
|
||||
|
||||
void timer_init(void)
|
||||
{
|
||||
timer_reg_set(TIMER_CONTROL, 0);
|
||||
timer_reg_set(TIMER_LOAD, 0xffffffff);
|
||||
timer_reg_set(TIMER_CONTROL, CFG_TIMER_CTRL);
|
||||
|
||||
g_timer_init = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
#ifndef _ASSERT_H_
|
||||
#define _ASSERT_H_
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#define assert(x) ASSERT(x)
|
||||
|
||||
#endif /* _ASSERT_H_ */
|
||||
@@ -0,0 +1,63 @@
|
||||
|
||||
#ifndef __COMMON_H_
|
||||
#define __COMMON_H_
|
||||
#include <config.h>
|
||||
#include <sys/types.h>
|
||||
#include <io.h>
|
||||
#include <serial.h>
|
||||
#include <stdio.h>
|
||||
#include <compile.h>
|
||||
#include <core.h>
|
||||
#include <debug.h>
|
||||
#include <assert.h>
|
||||
#include <timer.h>
|
||||
#include <string.h>
|
||||
#include <reserved_mem.h>
|
||||
|
||||
extern char g_base_irqstack[];
|
||||
extern char g_top_irqstack[];
|
||||
|
||||
extern u32 g_heap_start;
|
||||
extern u32 g_heap_end;
|
||||
|
||||
extern char _start[];
|
||||
extern char _end[];
|
||||
|
||||
extern char __text_start[];
|
||||
extern char __text_end[];
|
||||
|
||||
extern char __rodata_start[];
|
||||
extern char __rodata_end[];
|
||||
|
||||
extern char __data_start[];
|
||||
extern char __data_end[];
|
||||
|
||||
extern char __text2_start[];
|
||||
extern char __text2_end[];
|
||||
|
||||
extern char __rodata2_start[];
|
||||
extern char __rodata2_end[];
|
||||
|
||||
extern char __data2_start[];
|
||||
extern char __data2_end[];
|
||||
|
||||
extern char __bss_start[];
|
||||
extern char __bss_end[];
|
||||
|
||||
extern char __bin_end_pad[];
|
||||
extern char __bin_end[];
|
||||
|
||||
extern char __param_start[];
|
||||
extern char __param_end[];
|
||||
|
||||
u32 start_shell(void);
|
||||
|
||||
int run_stage2_func(int (*func)(void));
|
||||
|
||||
u64 get_ddr_size(void);
|
||||
|
||||
ulong get_reserved_ddr(u32 size);
|
||||
|
||||
void stopwatch_trigger(void);
|
||||
|
||||
#endif /*__COMMON_H_*/
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
#ifndef _COMPILE_H_
|
||||
#define _COMPILE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define __FILENAME__ (__builtin_strrchr(__FILE__, '/')? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
|
||||
|
||||
#define array_size(x) (sizeof(x) / sizeof(*(x)))
|
||||
|
||||
#define swap32(_x) ((uint32)( \
|
||||
((((uint32)(_x)) & 0x000000FF) << 24) | \
|
||||
((((uint32)(_x)) & 0x0000FF00) << 8) | \
|
||||
((((uint32)(_x)) & 0xFF000000) >> 24) | \
|
||||
((((uint32)(_x)) & 0x00FF0000) >> 8)))
|
||||
|
||||
#define swap16(_x) ((uint16)( \
|
||||
((((uint16)(_x)) & 0xFF00) >> 8) | \
|
||||
((((uint16)(_x)) & 0x00FF) << 8)))
|
||||
|
||||
#define around(size, align) (((size) + (align) - 1) & (~((align) - 1)))
|
||||
|
||||
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
|
||||
|
||||
#define STAGE1_FUNC __attribute__((section(".text.stage1")))
|
||||
#define STAGE1_GLOBAL __attribute__((section(".data.stage1")))
|
||||
#define STAGE1_CONST_GLOBAL __attribute__((section(".rodata.stage1"))) const
|
||||
#define STAGE1_STR(str) \
|
||||
({ \
|
||||
static const char _str_##__COUNTER__[] \
|
||||
__attribute__((section(".rodata.stage1"))) = str; \
|
||||
_str_##__COUNTER__; \
|
||||
})
|
||||
|
||||
#define STAGE2_FUNC __attribute__((section(".text.stage2")))
|
||||
#define STAGE2_GLOBAL __attribute__((section(".data.stage2")))
|
||||
#define STAGE2_CONST_GLOBAL __attribute__((section(".rodata.stage2"))) const
|
||||
#define STAGE2_STR(str) \
|
||||
({ \
|
||||
static const char _str_##__COUNTER__[] \
|
||||
__attribute__((section(".rodata.stage2"))) = str; \
|
||||
_str_##__COUNTER__; \
|
||||
})
|
||||
|
||||
#endif /* _COMPILE_H_ */
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#ifndef CONFIGH
|
||||
#define CONFIGH
|
||||
#include <autoconf.h>
|
||||
#include <platform.h>
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_CTYPE_H_
|
||||
#define _SYS_CTYPE_H_
|
||||
|
||||
#define isspace(c) ((c) == ' ' || ((c) >= '\t' && (c) <= '\r'))
|
||||
#define isascii(c) (((c) & ~0x7f) == 0)
|
||||
#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
|
||||
#define islower(c) ((c) >= 'a' && (c) <= 'z')
|
||||
#define isalpha(c) (isupper(c) || islower(c))
|
||||
#define isdigit(c) ((c) >= '0' && (c) <= '9')
|
||||
#define isxdigit(c) (isdigit(c) \
|
||||
|| ((c) >= 'A' && (c) <= 'F') \
|
||||
|| ((c) >= 'a' && (c) <= 'f'))
|
||||
#define isprint(c) ((c) >= ' ' && (c) <= '~')
|
||||
#define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z')))
|
||||
#define tolower(c) ((c) + 0x20 * (((c) >= 'A') && ((c) <= 'Z')))
|
||||
|
||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define min_t(t, x, y) ((t)((t)(x) < (t)(y) ? (x) : (y)))
|
||||
|
||||
#define tohex(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
|
||||
(((c) >= 'a' && (c) <= 'f') ? ((c) - 'a' + 10) : \
|
||||
(((c) >= 'A' && (c) <= 'F') ? ((c) - 'A' + 10) : -1)))
|
||||
|
||||
#endif /* !_SYS_CTYPE_H_ */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA 2021. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DEBUG_H_
|
||||
#define _DEBUG_H_
|
||||
/******************************************************************************/
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <lib.h>
|
||||
|
||||
/* #define ASSERT(_p) if (!(_p)) { \
|
||||
* printf("%s(%s,%d):assert:(%s)\n", __FILE__, __FUNCTION__, __LINE__, #_p);
|
||||
*
|
||||
* #define ASSERT1(_p, _fmt, args...) if (!(_p)) { \
|
||||
* printf("%s(%s,%d):assert:(%s)\n" _fmt, __FILE__, __FUNCTION__, __LINE__, #_p, ##args); */
|
||||
|
||||
#define ASSERT(_condition) do { \
|
||||
if (!(_condition)) { \
|
||||
puts("ASSERT "); \
|
||||
putchar('['); \
|
||||
puts(__FILE__); \
|
||||
putchar(','); \
|
||||
putdec(__LINE__); \
|
||||
puts("]: "); \
|
||||
puts(#_condition); \
|
||||
puts("\n"); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define __PRINT_MACRO(x) #x
|
||||
#define PRINT_MARCO(x) #x"="__PRINT_MACRO(x)
|
||||
/* #pragma message(PRINT_MARCO(MACRO_NAME_XXX)) */
|
||||
|
||||
int dump_hex(u32 addr, char *buf, u32 sz_buf, u32 width);
|
||||
|
||||
/******************************************************************************/
|
||||
#endif /* _DEBUG_H_ */
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
#ifndef _DIV64_H_
|
||||
#define _DIV64_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
|
||||
|
||||
#define do_div(n, base) ({ \
|
||||
uint32_t __base = (base); \
|
||||
uint32_t __rem; \
|
||||
if (((n) >> 32) == 0) { \
|
||||
__rem = (uint32_t)(n) % __base; \
|
||||
(n) = (uint32_t)(n) / __base; \
|
||||
} else \
|
||||
__rem = __div64_32(&(n), __base); \
|
||||
__rem; \
|
||||
})
|
||||
|
||||
#endif /* _DIV64_H_ */
|
||||
@@ -0,0 +1,153 @@
|
||||
|
||||
#ifndef _ERRNO_H_
|
||||
#define _ERRNO_H_
|
||||
|
||||
/****************************************************************************
|
||||
* Error Number Definitions
|
||||
****************************************************************************/
|
||||
#define EPERM 1 /* Operation not permitted */
|
||||
#define ENOENT 2 /* No such file or directory */
|
||||
#define ESRCH 3 /* No such process */
|
||||
#define EINTR 4 /* Interrupted system call */
|
||||
#define EIO 5 /* I/O error */
|
||||
#define ENXIO 6 /* No such device or address */
|
||||
#define E2BIG 7 /* Argument list too long */
|
||||
#define ENOEXEC 8 /* Exec format error */
|
||||
#define EBADF 9 /* Bad file number */
|
||||
#define ECHILD 10 /* No child processes */
|
||||
#define EAGAIN 11 /* Try again */
|
||||
#define ENOMEM 12 /* Out of memory */
|
||||
#define EACCES 13 /* Permission denied */
|
||||
#define EFAULT 14 /* Bad address */
|
||||
#define ENOTBLK 15 /* Block device required */
|
||||
#define EBUSY 16 /* Device or resource busy */
|
||||
#define EEXIST 17 /* File exists */
|
||||
#define EXDEV 18 /* Cross-device link */
|
||||
#define ENODEV 19 /* No such device */
|
||||
#define ENOTDIR 20 /* Not a directory */
|
||||
#define EISDIR 21 /* Is a directory */
|
||||
#define EINVAL 22 /* Invalid argument */
|
||||
#define ENFILE 23 /* File table overflow */
|
||||
#define EMFILE 24 /* Too many open files */
|
||||
#define ENOTTY 25 /* Not a typewriter */
|
||||
#define ETXTBSY 26 /* Text file busy */
|
||||
#define EFBIG 27 /* File too large */
|
||||
#define ENOSPC 28 /* No space left on device */
|
||||
#define ESPIPE 29 /* Illegal seek */
|
||||
#define EROFS 30 /* Read-only file system */
|
||||
#define EMLINK 31 /* Too many links */
|
||||
#define EPIPE 32 /* Broken pipe */
|
||||
#define EDOM 33 /* Math argument out of domain of func */
|
||||
#define ERANGE 34 /* Math result not representable */
|
||||
#define EDEADLK 35 /* Resource deadlock would occur */
|
||||
#define ENAMETOOLONG 36 /* File name too long */
|
||||
#define ENOLCK 37 /* No record locks available */
|
||||
|
||||
#define ENOSYS 38 /* Invalid system call number */
|
||||
|
||||
#define ENOTEMPTY 39 /* Directory not empty */
|
||||
#define ELOOP 40 /* Too many symbolic links encountered */
|
||||
#define EWOULDBLOCK EAGAIN /* Operation would block */
|
||||
#define ENOMSG 42 /* No message of desired type */
|
||||
#define EIDRM 43 /* Identifier removed */
|
||||
#define ECHRNG 44 /* Channel number out of range */
|
||||
#define EL2NSYNC 45 /* Level 2 not synchronized */
|
||||
#define EL3HLT 46 /* Level 3 halted */
|
||||
#define EL3RST 47 /* Level 3 reset */
|
||||
#define ELNRNG 48 /* Link number out of range */
|
||||
#define EUNATCH 49 /* Protocol driver not attached */
|
||||
#define ENOCSI 50 /* No CSI structure available */
|
||||
#define EL2HLT 51 /* Level 2 halted */
|
||||
#define EBADE 52 /* Invalid exchange */
|
||||
#define EBADR 53 /* Invalid request descriptor */
|
||||
#define EXFULL 54 /* Exchange full */
|
||||
#define ENOANO 55 /* No anode */
|
||||
#define EBADRQC 56 /* Invalid request code */
|
||||
#define EBADSLT 57 /* Invalid slot */
|
||||
|
||||
#define EDEADLOCK EDEADLK
|
||||
|
||||
#define EBFONT 59 /* Bad font file format */
|
||||
#define ENOSTR 60 /* Device not a stream */
|
||||
#define ENODATA 61 /* No data available */
|
||||
#define ETIME 62 /* Timer expired */
|
||||
#define ENOSR 63 /* Out of streams resources */
|
||||
#define ENONET 64 /* Machine is not on the network */
|
||||
#define ENOPKG 65 /* Package not installed */
|
||||
#define EREMOTE 66 /* Object is remote */
|
||||
#define ENOLINK 67 /* Link has been severed */
|
||||
#define EADV 68 /* Advertise error */
|
||||
#define ESRMNT 69 /* Srmount error */
|
||||
#define ECOMM 70 /* Communication error on send */
|
||||
#define EPROTO 71 /* Protocol error */
|
||||
#define EMULTIHOP 72 /* Multihop attempted */
|
||||
#define EDOTDOT 73 /* RFS specific error */
|
||||
#define EBADMSG 74 /* Not a data message */
|
||||
#define EOVERFLOW 75 /* Value too large for defined data type */
|
||||
#define ENOTUNIQ 76 /* Name not unique on network */
|
||||
#define EBADFD 77 /* File descriptor in bad state */
|
||||
#define EREMCHG 78 /* Remote address changed */
|
||||
#define ELIBACC 79 /* Can not access a needed shared library */
|
||||
#define ELIBBAD 80 /* Accessing a corrupted shared library */
|
||||
#define ELIBSCN 81 /* .lib section in a.out corrupted */
|
||||
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
|
||||
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
|
||||
#define EILSEQ 84 /* Illegal byte sequence */
|
||||
#define ERESTART 85 /* Interrupted system call should be restarted */
|
||||
#define ESTRPIPE 86 /* Streams pipe error */
|
||||
#define EUSERS 87 /* Too many users */
|
||||
#define ENOTSOCK 88 /* Socket operation on non-socket */
|
||||
#define EDESTADDRREQ 89 /* Destination address required */
|
||||
#define EMSGSIZE 90 /* Message too long */
|
||||
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
|
||||
#define ENOPROTOOPT 92 /* Protocol not available */
|
||||
#define EPROTONOSUPPORT 93 /* Protocol not supported */
|
||||
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
|
||||
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||
#define EPFNOSUPPORT 96 /* Protocol family not supported */
|
||||
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
|
||||
#define EADDRINUSE 98 /* Address already in use */
|
||||
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
|
||||
#define ENETDOWN 100 /* Network is down */
|
||||
#define ENETUNREACH 101 /* Network is unreachable */
|
||||
#define ENETRESET 102 /* Network dropped connection because of reset */
|
||||
#define ECONNABORTED 103 /* Software caused connection abort */
|
||||
#define ECONNRESET 104 /* Connection reset by peer */
|
||||
#define ENOBUFS 105 /* No buffer space available */
|
||||
#define EISCONN 106 /* Transport endpoint is already connected */
|
||||
#define ENOTCONN 107 /* Transport endpoint is not connected */
|
||||
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
|
||||
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
|
||||
#define ETIMEDOUT 110 /* Connection timed out */
|
||||
#define ECONNREFUSED 111 /* Connection refused */
|
||||
#define EHOSTDOWN 112 /* Host is down */
|
||||
#define EHOSTUNREACH 113 /* No route to host */
|
||||
#define EALREADY 114 /* Operation already in progress */
|
||||
#define EINPROGRESS 115 /* Operation now in progress */
|
||||
#define ESTALE 116 /* Stale file handle */
|
||||
#define EUCLEAN 117 /* Structure needs cleaning */
|
||||
#define ENOTNAM 118 /* Not a XENIX named type file */
|
||||
#define ENAVAIL 119 /* No XENIX semaphores available */
|
||||
#define EISNAM 120 /* Is a named type file */
|
||||
#define EREMOTEIO 121 /* Remote I/O error */
|
||||
#define EDQUOT 122 /* Quota exceeded */
|
||||
|
||||
#define ENOMEDIUM 123 /* No medium found */
|
||||
#define EMEDIUMTYPE 124 /* Wrong medium type */
|
||||
#define ECANCELED 125 /* Operation Canceled */
|
||||
#define ENOKEY 126 /* Required key not available */
|
||||
#define EKEYEXPIRED 127 /* Key has expired */
|
||||
#define EKEYREVOKED 128 /* Key has been revoked */
|
||||
#define EKEYREJECTED 129 /* Key was rejected by service */
|
||||
|
||||
/* for robust mutexes */
|
||||
#define EOWNERDEAD 130 /* Owner died */
|
||||
#define ENOTRECOVERABLE 131 /* State not recoverable */
|
||||
|
||||
#define ERFKILL 132 /* Operation not possible due to RF-kill */
|
||||
|
||||
#define EHWPOISON 133 /* Memory page has hardware error */
|
||||
|
||||
#define ENOTSUP 134 /* Not supported */
|
||||
|
||||
#endif /* _ERRNO_H_ */
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
#ifndef _FLOAT_H_
|
||||
#define _FLOAT_H_
|
||||
|
||||
#undef FLT_MAX
|
||||
#define FLT_MAX __FLT_MAX__
|
||||
|
||||
#undef DBL_MAX
|
||||
#define DBL_MAX __DBL_MAX__
|
||||
|
||||
#undef FLT_MIN
|
||||
#define FLT_MIN __FLT_MIN__
|
||||
|
||||
#undef DBL_MIN
|
||||
#define DBL_MIN __DBL_MIN__
|
||||
|
||||
#undef FLT_EPSILON
|
||||
#define FLT_EPSILON __FLT_EPSILON__
|
||||
|
||||
#undef DBL_EPSILON
|
||||
#define DBL_EPSILON __DBL_EPSILON__
|
||||
|
||||
#endif /* ifndef _FLOAT_H_ */
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
#ifndef _GPIO_H_
|
||||
#define _GPIO_H_
|
||||
|
||||
void gpio_set_dir(int group, int bit, int dir);
|
||||
void gpio_set_data(int group, int bit, int data);
|
||||
|
||||
#endif /* _GPIO_H_ */
|
||||
@@ -0,0 +1,147 @@
|
||||
|
||||
#ifndef _HLIST_H_
|
||||
#define _HLIST_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
* 该结构体用于嵌入到业务数据结构体中(entry),用于实现链表
|
||||
* 例:
|
||||
* struct Entry { // 你的业务数据结构体
|
||||
* ...
|
||||
* struct node node; // 嵌入其中,位置任意
|
||||
* ...
|
||||
* };
|
||||
*/
|
||||
struct node {
|
||||
struct node *next, *prev;
|
||||
};
|
||||
|
||||
/*
|
||||
* 由成员变量 node 地址获取结构体 entry 地址
|
||||
* 例:
|
||||
* struct Entry entry;
|
||||
* struct node *n = &entry.node;
|
||||
* struct Entry *p = node_entry(n, struct Entry, node);
|
||||
* 此时 p 指向 entry
|
||||
*/
|
||||
#define node_entry(node, type, member) \
|
||||
((type*)((char*)(node) - (size_t)&((type*)0)->member))
|
||||
|
||||
/* 带哨兵节点的双向链表 */
|
||||
struct list {
|
||||
struct node base;
|
||||
};
|
||||
|
||||
static inline void list_init(struct list *list)
|
||||
{
|
||||
list->base.next = &list->base;
|
||||
list->base.prev = &list->base;
|
||||
}
|
||||
|
||||
static inline bool list_empty(const struct list *list)
|
||||
{
|
||||
return list->base.next == &list->base;
|
||||
}
|
||||
|
||||
static inline bool list_is_head(const struct list *list, const struct node *node)
|
||||
{
|
||||
return list->base.next == node;
|
||||
}
|
||||
|
||||
static inline bool list_is_tail(const struct list *list, const struct node *node)
|
||||
{
|
||||
return list->base.prev == node;
|
||||
}
|
||||
|
||||
/* node 插入到 pos 后面 */
|
||||
static inline void list_insert_backward(struct node *pos, struct node *node)
|
||||
{
|
||||
node->prev = pos;
|
||||
node->next = pos->next;
|
||||
node->prev->next = node;
|
||||
node->next->prev = node;
|
||||
}
|
||||
|
||||
/* node 插入到 pos 前面 */
|
||||
static inline void list_insert(struct node *pos, struct node *node)
|
||||
{
|
||||
node->prev = pos->prev;
|
||||
node->next = pos;
|
||||
node->prev->next = node;
|
||||
node->next->prev = node;
|
||||
}
|
||||
|
||||
static inline void list_add_tail(struct list *list, struct node *node)
|
||||
{
|
||||
list_insert(&list->base, node);
|
||||
}
|
||||
|
||||
static inline void list_add_head(struct list *list, struct node *node)
|
||||
{
|
||||
list_insert(list->base.next, node);
|
||||
}
|
||||
|
||||
static inline void list_remove(struct node *node)
|
||||
{
|
||||
node->prev->next = node->next;
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
|
||||
static inline void list_remove_tail(struct list *list)
|
||||
{
|
||||
list_remove(list->base.prev);
|
||||
}
|
||||
|
||||
static inline void list_remove_head(struct list *list)
|
||||
{
|
||||
list_remove(list->base.next);
|
||||
}
|
||||
|
||||
static inline void list_replace(struct node *old, struct node *node)
|
||||
{
|
||||
node->next = old->next;
|
||||
node->next->prev = node;
|
||||
node->prev = old->prev;
|
||||
node->prev->next = node;
|
||||
}
|
||||
|
||||
#define list_for_each(node, list) \
|
||||
for (node = (list)->base.next; node != &(list)->base; node = (node)->next)
|
||||
|
||||
#define list_for_each_safe(node, tmp, list) \
|
||||
for (node = (list)->base.next, tmp = (node)->next; node != &(list)->base; node = tmp, tmp = (node)->next)
|
||||
|
||||
/* 获取头结点,或空 */
|
||||
#define list_head_entry(list, type, member) \
|
||||
(list_empty(list) ? NULL : node_entry((list)->base.next, type, member))
|
||||
|
||||
/* 获取尾结点,或空 */
|
||||
#define list_tail_entry(list, type, member) \
|
||||
(list_empty(list) ? NULL : node_entry((list)->base.prev, type, member))
|
||||
|
||||
/* 获取下一结点,或空 */
|
||||
#define list_next_entry(entry, list, type, member) \
|
||||
(list_is_tail(list, &(entry)->member) ? \
|
||||
NULL : \
|
||||
node_entry((entry)->member.next, type, member))
|
||||
|
||||
/* 获取上一结点,或空 */
|
||||
#define list_prev_entry(entry, list, type, member) \
|
||||
(list_is_head(list, &(entry)->member) ? \
|
||||
NULL : \
|
||||
node_entry((entry)->member.prev, type, member))
|
||||
|
||||
/* 遍历链表;过程中如需操作链表,请使用 _SAFE 版本 */
|
||||
#define list_for_each_entry(entry, list, type, member) \
|
||||
for (entry = node_entry((list)->base.next, type, member); \
|
||||
&(entry)->member != &(list)->base; \
|
||||
entry = node_entry((entry)->member.next, type, member))
|
||||
|
||||
#define list_for_each_entry_safe(entry, tmp, list, type, member) \
|
||||
for (entry = node_entry((list)->base.next, type, member), \
|
||||
tmp = node_entry((entry)->member.next, type, member); \
|
||||
&(entry)->member != &(list)->base; \
|
||||
entry = tmp, tmp = node_entry((entry)->member.next, type, member))
|
||||
|
||||
#endif /* _HLIST_H_ */
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef _I2C_H_
|
||||
#define _I2C_H_
|
||||
|
||||
#include <platform.h>
|
||||
#include <sys/types.h>
|
||||
#include <io.h>
|
||||
#include <lib.h>
|
||||
|
||||
struct i2c_client {
|
||||
unsigned char i2c_num;
|
||||
unsigned short dev_addr;
|
||||
unsigned long int reg_addr;
|
||||
unsigned int reg_width;
|
||||
};
|
||||
|
||||
int i2c_init(unsigned char i2c_num);
|
||||
int i2c_recv(const struct i2c_client *client, unsigned char *buf, unsigned int count);
|
||||
int i2c_send(unsigned char i2c_num, unsigned short dev_addr, const char *buf,unsigned int count);
|
||||
|
||||
|
||||
#endif
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
|
||||
#ifndef _IMAGE_H_
|
||||
#define _IMAGE_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct mcu_fw_head {
|
||||
u32 j_instruction; /* Jump to real excutable entry */
|
||||
u32 fw_magic; /* MCU Firmware magic */
|
||||
u32 fw_ver; /* MCU Firmware version */
|
||||
u32 fw_total_size; /* MCU Firmware total size */
|
||||
u32 fw_stage1_size; /* MCU Stage1 size */
|
||||
u8 resv[CONFIG_MCU_HEAD_SIZE - 20]; /* Reserved */
|
||||
};
|
||||
|
||||
#endif /* _IMAGE_H_ */
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
#ifndef _INTERRUPT_H_
|
||||
#define _INTERRUPT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ATTRIBUTE_ISR __attribute__ ((interrupt ("machine")))
|
||||
|
||||
void drv_irq_enable(uint32_t irq_num);
|
||||
void drv_irq_disable(uint32_t irq_num);
|
||||
int drv_irq_register(uint32_t irq_num, void *irq_handler);
|
||||
void drv_irq_unregister(uint32_t irq_num);
|
||||
int irq_init(void);
|
||||
|
||||
#endif /* ifndef _INTERRUPT_H_ */
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
#ifdef CONFIG_ARM_ARCH
|
||||
#include <arm/include/io.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RISCV_ARCH
|
||||
#include <riscv/include/io.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef __LIB_H__
|
||||
#define __LIB_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <config.h>
|
||||
|
||||
#define SECUREC_MEM_MAX_LEN (0x100000) //1MB
|
||||
|
||||
void reset_cpu(void);
|
||||
|
||||
int memset_s(void* dest, size_t destMax, unsigned char c, size_t count);
|
||||
int memcpy_s(void* dest, size_t destMax, const void* src, size_t count);
|
||||
unsigned short crc16(unsigned char *data, unsigned int length);
|
||||
#endif /*__LIB_H__*/
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
#ifndef _MALLOC_H_
|
||||
#define _MALLOC_H_
|
||||
|
||||
#include <config.h>
|
||||
#include <stddef.h>
|
||||
|
||||
void malloc_init(uint32 start, uint32 len);
|
||||
#ifdef CONFIG_MALLOC
|
||||
void *malloc(uint32 bytes); /* not thread safe */
|
||||
void *memalign(uint32 alignment, uint32 bytes);
|
||||
void free(void *ptr);
|
||||
void show_memnode(unsigned int);
|
||||
#else
|
||||
void *__malloc(uint32 bytes, const char *file, int line);
|
||||
void *__memalign(uint32 alignment, uint32 bytes, const char *file, int line);
|
||||
void __free(const void *mem, const char *file, int line);
|
||||
#define malloc(bytes) __malloc(bytes, __FILE__, __LINE__)
|
||||
#define memalign(alignment, bytes) __memalign(alignment, bytes, __FILE__, __LINE__)
|
||||
#define free(mem) __free(mem, __FILE__, __LINE__)
|
||||
#endif
|
||||
#endif /* _MALLOC_H_ */
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
|
||||
#ifndef _MATH_H_
|
||||
#define _MATH_H_
|
||||
|
||||
#define FP_NAN 0
|
||||
#define FP_INFINITE 1
|
||||
#define FP_ZERO 2
|
||||
#define FP_SUBNORMAL 3
|
||||
#define FP_NORMAL 4
|
||||
|
||||
# ifndef HUGE_VALF
|
||||
# define HUGE_VALF (__builtin_huge_valf())
|
||||
# endif
|
||||
|
||||
# ifndef INFINITY
|
||||
# define INFINITY (__builtin_inff())
|
||||
# endif
|
||||
|
||||
# ifndef NAN
|
||||
# define NAN (__builtin_nanf(""))
|
||||
# endif
|
||||
|
||||
#define fpclassify(__x) (__builtin_fpclassify (FP_NAN, FP_INFINITE, \
|
||||
FP_NORMAL, FP_SUBNORMAL, \
|
||||
FP_ZERO, __x))
|
||||
#ifndef isfinite
|
||||
#define isfinite(__x) (__builtin_isfinite (__x))
|
||||
#endif
|
||||
#ifndef isinf
|
||||
#define isinf(__x) (__builtin_isinf_sign (__x))
|
||||
#endif
|
||||
#ifndef isnan
|
||||
#define isnan(__x) (__builtin_isnan (__x))
|
||||
#endif
|
||||
#define isnormal(__x) (__builtin_isnormal (__x))
|
||||
|
||||
float logf(float x);
|
||||
float sqrtf(float x);
|
||||
float powf(float x, float y);
|
||||
float fabsf(float x);
|
||||
float sinf(float x);
|
||||
float cosf(float x);
|
||||
|
||||
#undef log
|
||||
#define log(x) logf(x)
|
||||
#undef pow
|
||||
#define pow(x, y) powf(x, y)
|
||||
#undef abs
|
||||
#define abs(x) fabsf(x)
|
||||
#undef fabs
|
||||
#define fabs(x) fabsf(x)
|
||||
#undef sqrt
|
||||
#define sqrt(x) sqrtf(x)
|
||||
#undef sin
|
||||
#define sin(x) sinf(x)
|
||||
#undef cos
|
||||
#define cos(x) cosf(x)
|
||||
|
||||
|
||||
#endif /* _MATH_H_ */
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef _PWM_H_
|
||||
#define _PWM_H_
|
||||
|
||||
#include <platform.h>
|
||||
#include <sys/types.h>
|
||||
#include <io.h>
|
||||
#include <lib.h>
|
||||
|
||||
int pwm_enable(int pwm_id);
|
||||
int pwm_disable(int pwm_id);
|
||||
int pwm_config(int pwm_id, int duty_cycle_us, int period_us);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
#ifndef _RESERVED_MEM_H_
|
||||
#define _RESERVED_MEM_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <compile.h>
|
||||
|
||||
void rsv_mem_init(uint32 start, uint32 len);
|
||||
void *__rsv_mem_alloc(uint32 bytes, const char *file, int line);
|
||||
#define reserved_mem_alloc(bytes) \
|
||||
__rsv_mem_alloc(bytes, __FILENAME__, __LINE__)
|
||||
void *__rsv_mem_align(uint32 alignment, uint32 bytes, const char *file, int line);
|
||||
#define reserved_mem_align(alignment, bytes) \
|
||||
__rsv_mem_align(alignment, bytes, __FILENAME__, __LINE__)
|
||||
|
||||
void dump_rsv_mem_info(void);
|
||||
|
||||
#endif /* ifndef _RESERVED_MEM_H_ */
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __SERIAL_H__
|
||||
#define __SERIAL_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* serial interface
|
||||
------------------------------------------------------------------*/
|
||||
void serial_init(void);
|
||||
void serial_putc(const char c);
|
||||
void serial_puts(const char *s);
|
||||
void serial_puts_always(const char *s);
|
||||
void serial_put_dec(u32 dec);
|
||||
void serial_put_hex(u32 hex);
|
||||
void serial_put_hex_always(u32 hex);
|
||||
char serial_getc(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
#ifndef _STDARG_H_
|
||||
#define _STDARG_H_
|
||||
/******************************************************************************/
|
||||
|
||||
typedef __builtin_va_list va_list;
|
||||
|
||||
#define va_start(v,l) __builtin_va_start(v,l)
|
||||
#define va_end(v) __builtin_va_end(v)
|
||||
#define va_arg(v,l) __builtin_va_arg(v,l)
|
||||
|
||||
/******************************************************************************/
|
||||
#endif /* _STDARG_H_ */
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
#ifndef _STDBOOL_H_
|
||||
#define _STDBOOL_H_
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#endif /* ifndef _STDBOOL_H_ */
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __STDDEFH__
|
||||
#define __STDDEFH__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define _1K (0x400)
|
||||
#define _2K (0x800)
|
||||
#define _4K (0x1000)
|
||||
#define _8K (0x2000)
|
||||
#define _16K (0x4000)
|
||||
#define _32K (0x8000)
|
||||
#define _64K (0x10000)
|
||||
#define _128K (0x20000)
|
||||
#define _256K (0x40000)
|
||||
#define _512K (0x80000)
|
||||
#define _1M (0x100000)
|
||||
#define _2M (0x200000)
|
||||
#define _4M (0x400000)
|
||||
#define _8M (0x800000)
|
||||
#define _16M (0x1000000)
|
||||
#define _32M (0x2000000)
|
||||
#define _64M (0x4000000)
|
||||
#define _128M (0x8000000)
|
||||
#define _256M (0x10000000)
|
||||
#define _512M (0x20000000)
|
||||
#define _1G (0x40000000)
|
||||
#define _2G (0x80000000)
|
||||
#define _3G (0xC0000000)
|
||||
#define _4G (0x100000000ULL)
|
||||
#define _8G (0x200000000ULL)
|
||||
#define _16G (0x400000000ULL)
|
||||
#define _32G (0x800000000ULL)
|
||||
#define _64G (0x1000000000ULL)
|
||||
|
||||
#endif /* __STDDEFH__ */
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
#ifndef _STDINT_H_
|
||||
#define _STDINT_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
#ifndef _STDIO_H_
|
||||
#define _STDIO_H_
|
||||
/******************************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int sprintf(char *buf, const char *cfmt, ...);
|
||||
int snprintf(char *str, size_t size, const char *format, ...);
|
||||
|
||||
int getchar(void);
|
||||
void puts_always(const char *s);
|
||||
void puthex_always(unsigned int hex);
|
||||
|
||||
#ifdef CONFIG_PRINT
|
||||
#ifdef CONFIG_PRINTF
|
||||
int printf(const char *cfmt, ...);
|
||||
#else
|
||||
# define printf(_cfmt, ...)
|
||||
#endif
|
||||
int putchar(int c);
|
||||
int puts(const char *s);
|
||||
void puthex(unsigned int hex);
|
||||
void putdec(unsigned int dec);
|
||||
#else
|
||||
# define printf(_cfmt, ...)
|
||||
# define putchar(c)
|
||||
# define puts(_s)
|
||||
# define puthex(hex)
|
||||
# define putdec(dec)
|
||||
#endif
|
||||
|
||||
#ifndef MOULE_NAME
|
||||
#define MOULE_NAME ""
|
||||
#endif
|
||||
|
||||
#define pr_error(_fmt, args...) printf(MOULE_NAME _fmt, ##args)
|
||||
#define pr_warn(_fmt, args...) printf(MOULE_NAME _fmt, ##args)
|
||||
#define pr_info(_fmt, args...) printf(MOULE_NAME _fmt, ##args)
|
||||
|
||||
#ifdef PR_DEBUG
|
||||
# define pr_debug(_fmt, args...) printf(MOULE_NAME _fmt, ##args)
|
||||
#else
|
||||
# define pr_debug(_fmt, args...)
|
||||
#endif /* pr_debug */
|
||||
|
||||
#define bug(_fmt, args...) { \
|
||||
printf(MOULE_NAME "%s(%d): "_fmt, __FILE__, __LINE__, ##args); \
|
||||
while (1); }
|
||||
|
||||
/******************************************************************************/
|
||||
#endif /* _STDIO_H_ */
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
#ifndef _STDLIB_H_
|
||||
#define _STDLIB_H_
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
#endif /* _STDLIB_H_ */
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
#ifndef _STRING_H_
|
||||
#define _STRING_H_
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
extern char const hex2ascii_data[];
|
||||
|
||||
#define hex2ascii(hex) (hex2ascii_data[hex])
|
||||
|
||||
#define imax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
|
||||
|
||||
#define bcpy(src, dst, len) memcpy((dst), (src), (len))
|
||||
#define bzero(buf, size) memset((buf), 0, (size))
|
||||
#define bcmp(b1, b2, len) (memcmp((b1), (b2), (len)) != 0)
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t size);
|
||||
void *memcpy(void *dst, const void *src, size_t len);
|
||||
void *memset(void *b, int c, size_t len);
|
||||
int memcmp(const void *b1, const void *b2, size_t len);
|
||||
int strncmp(const char *s1, const char *s2, size_t len);
|
||||
uint32_t strnlen(const char *s, uint32_t len);
|
||||
unsigned long strtoul(const char *nptr, char **endptr, int base);
|
||||
uint64_t strtoull(const char *nptr, char **endptr, int base);
|
||||
char *strncpy(char * dst, const char * src, size_t n);
|
||||
uint64_t memparse(const char *ptr, char **retptr);
|
||||
char *strndup(const char *str, size_t n);
|
||||
char *strtok(char *s, const char *delim);
|
||||
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
void strcpy(char *dst, const char *src);
|
||||
void strcat(char *dst, const char *src);
|
||||
char *strncat(char *dst, const char *src, size_t n);
|
||||
char *strchr(const char *s, char ch);
|
||||
char *strdup(const char *s);
|
||||
size_t strlen(const char *s);
|
||||
char *strstr(const char *s1, const char *s2);
|
||||
|
||||
/******************************************************************************/
|
||||
#endif /* _STRING_H_ */
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) XMEDIA. All rights reserved.
|
||||
*/
|
||||
#ifndef __TYPES_H__
|
||||
#define __TYPES_H__
|
||||
|
||||
|
||||
typedef signed char s8;
|
||||
typedef unsigned char u8;
|
||||
typedef signed short s16;
|
||||
typedef unsigned short u16;
|
||||
typedef signed int s32;
|
||||
typedef unsigned int u32;
|
||||
typedef signed long long s64;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef long long intmax_t;
|
||||
typedef unsigned long long uintmax_t;
|
||||
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned char uint8;
|
||||
typedef char int8;
|
||||
typedef unsigned short uint16;
|
||||
typedef short int16;
|
||||
typedef unsigned int uint32;
|
||||
typedef int int32;
|
||||
|
||||
typedef unsigned long uintptr_t;
|
||||
typedef unsigned int size_t;
|
||||
|
||||
#define BITS_PER_LONG 32
|
||||
|
||||
#undef NULL
|
||||
#define NULL ((void *)0)
|
||||
|
||||
typedef int bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define ERROR -1
|
||||
#define OK 0
|
||||
|
||||
#define SZ_4M 0x400000
|
||||
#define SZ_8M 0x800000
|
||||
#define SZ_16M 0x1000000
|
||||
#define SZ_128M 0x8000000
|
||||
#define SZ_256M 0x10000000
|
||||
#define SZ_512M 0x20000000
|
||||
#define SZ_750M 0x30000000
|
||||
#define SZ_1G 0x40000000
|
||||
#define SZ_2G 0x80000000
|
||||
#define SZ_3G 0xc0000000
|
||||
#define SZ_4G 0x100000000
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
#ifndef _TIME_H_
|
||||
#define _TIME_H_
|
||||
|
||||
#include <timer.h>
|
||||
|
||||
#endif /* _TIME_H_ */
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <io.h>
|
||||
#include <lib.h>
|
||||
|
||||
void timer_init(void);
|
||||
void timer_start(void);
|
||||
ulong timer_get_val(void);
|
||||
|
||||
void udelay(ulong us);
|
||||
void mdelay(u32 msec);
|
||||
|
||||
#endif /* _TIMER_H_ */
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
#ifndef _UT_CASE_H_
|
||||
#define _UT_CASE_H_
|
||||
|
||||
void test_math(void);
|
||||
void test_libc(void);
|
||||
void test_time(void);
|
||||
void test_multi_stage_in_stage1(void);
|
||||
void test_multi_stage_in_stage2(void);
|
||||
void test_submakefile1(void);
|
||||
void test_reserved_mem(void);
|
||||
int run_ut_in_stage1(void);
|
||||
int run_ut_in_stage2(void);
|
||||
|
||||
#endif /* ifndef _UT_CASE_H_ */
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
#ifndef __VERSION_H__
|
||||
#define __VERSION_H__
|
||||
|
||||
#define MCU_VERSION "v1.00"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
SRCS-y += main.c
|
||||
SRCS-$(CONFIG_SIMPILE_SHELL) += shell.c
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
#include <platform.h>
|
||||
#include <sys/types.h>
|
||||
#include <common.h>
|
||||
#include <version.h>
|
||||
#include <timer.h>
|
||||
#include <image.h>
|
||||
#include <i2c.h>
|
||||
#include <ut_case.h>
|
||||
#include "media_sample.h"
|
||||
|
||||
int *__errno(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void show_version(void)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_INFO
|
||||
puts("\nRISC-V MCU code - ");
|
||||
puts(MCU_VERSION"\n");
|
||||
puts("Build: ");
|
||||
puts(__DATE__" - "__TIME__"\n");
|
||||
puts("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int main(void)
|
||||
{
|
||||
__attribute__((unused)) int ret;
|
||||
show_version();
|
||||
#ifdef CONFIG_MEDIA_SAMPLE_QUICKSTART
|
||||
quickstart_media_preinit();
|
||||
|
||||
ret = run_stage2_func(quickstart_media_start);
|
||||
if (ret != 0) {
|
||||
puts("UT is Failed\n");
|
||||
goto sleep;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_UT_ENABLE
|
||||
ret = run_ut_in_stage1();
|
||||
if (ret != 0) {
|
||||
puts("UT in stage1 Failed\n");
|
||||
goto sleep;
|
||||
}
|
||||
|
||||
ret = run_stage2_func(run_ut_in_stage2);
|
||||
if (ret != 0) {
|
||||
puts("UT in stage2 Failed\n");
|
||||
goto sleep;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_SIMPILE_SHELL
|
||||
start_shell();
|
||||
#endif
|
||||
|
||||
sleep: __attribute__((unused))
|
||||
while(1) {
|
||||
__WFI();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Executable
+289
@@ -0,0 +1,289 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <config.h>
|
||||
#include <lib.h>
|
||||
#include <timer.h>
|
||||
#include <serial.h>
|
||||
|
||||
|
||||
#define CMD_BUFF_LEN 16
|
||||
#define REV_BUFF_LEN 128
|
||||
|
||||
typedef enum {
|
||||
CMD_0 = 0,
|
||||
CMD_1,
|
||||
CMD_2,
|
||||
CMD_3,
|
||||
CMD_4,
|
||||
CMD_5,
|
||||
CMD_6,
|
||||
CMD_7,
|
||||
CMD_8,
|
||||
CMD_9,
|
||||
CMD_10,
|
||||
CMD_11,
|
||||
CMD_12,
|
||||
CMD_13,
|
||||
CMD_14,
|
||||
CMD_15,
|
||||
CMD_16
|
||||
} cmd_len;
|
||||
|
||||
static void show_help(void)
|
||||
{
|
||||
puts("usage: \n");
|
||||
puts(" help -- show command infomation \n");
|
||||
puts(" mw [addr] [value] -- write [value] to [addr] \n");
|
||||
puts(" both need be hex and start with 0x or 0X \n");
|
||||
puts(" md [addr] [length] -- read from [addr] and print to the console \n");
|
||||
puts(" total read [length] bytes data \n");
|
||||
puts(" both need be hex and start with 0x or 0X \n");
|
||||
}
|
||||
|
||||
static u32 read_line(u8 *buff, u32 buff_len)
|
||||
{
|
||||
u32 recv_len = 0;
|
||||
char c = 0;
|
||||
|
||||
while (1) {
|
||||
c = getchar();
|
||||
if (c == '\n' || c == '\r') {
|
||||
serial_putc('\n');
|
||||
break;
|
||||
}
|
||||
if (recv_len < buff_len) {
|
||||
serial_putc(c);
|
||||
buff[recv_len++] = c;
|
||||
} else {
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (recv_len < (buff_len - 1)) {
|
||||
buff[recv_len + 1] = '\0';
|
||||
}
|
||||
|
||||
return recv_len;
|
||||
}
|
||||
|
||||
/* return value : index is started from 0 */
|
||||
static u32 str_get_pos(u8 *buff, u32 buff_len, char c)
|
||||
{
|
||||
u32 index = 0;
|
||||
|
||||
for (; index < buff_len; index++) {
|
||||
if (c == buff[index]) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == buff_len) {
|
||||
return index;
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/* find the cmd dilived by the space */
|
||||
static u32 get_cmd(u8 *cmd, u32 cmd_buff_len, u8 *buff, u32 buff_len)
|
||||
{
|
||||
u32 cmd_len = 0;
|
||||
|
||||
/* the cmd is divided by space */
|
||||
cmd_len = str_get_pos(buff, buff_len, ' ');
|
||||
if (cmd_len == 0 || cmd_len == FAILURE || cmd_len > cmd_buff_len) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < cmd_len; i++) {
|
||||
cmd[i] = buff[i];
|
||||
}
|
||||
|
||||
if (cmd_len < (cmd_buff_len - 1)) {
|
||||
cmd[cmd_len + 1] = '\0';
|
||||
}
|
||||
|
||||
return cmd_len;
|
||||
}
|
||||
|
||||
static u8 char_to_hex(u8 value)
|
||||
{
|
||||
if((value <= '9') && (value >= '0')) {
|
||||
return (value - '0');
|
||||
} else if ((value <= 'f') && ((value >= 'a'))) {
|
||||
return (value - 'a' + 0x0a);
|
||||
} else if ((value <= 'F') && (value >= 'A')) {
|
||||
return (value - 'A' + 0x0a);
|
||||
} else {
|
||||
puts("Data format error!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 pow_t(u32 v, u32 n)
|
||||
{
|
||||
u32 value = v;
|
||||
|
||||
if (n == 0) {
|
||||
return 1;
|
||||
} else if (n == 1) {
|
||||
return v;
|
||||
}
|
||||
|
||||
for (u32 i = 1; i < n; i++) {
|
||||
value = value * v;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static u32 str_to_hex(u8 *str, u32 str_len)
|
||||
{
|
||||
u32 hex = 0;
|
||||
|
||||
for (int i = 0; i < str_len; i++) {
|
||||
hex += char_to_hex(str[i]) * pow_t(16, (str_len - i - 1));
|
||||
}
|
||||
|
||||
return hex;
|
||||
}
|
||||
|
||||
static u32 get_params(u8 * buff, u32 buff_Len, u32 *param_len)
|
||||
{
|
||||
u8 param_s[10];
|
||||
|
||||
*param_len = get_cmd(param_s, 10, buff, buff_Len);
|
||||
if (*param_len < 2 || *param_len == FAILURE) {
|
||||
puts("command error, too few params!\n");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (param_s[0] != '0' && (param_s[1] != 'x' || param_s[1] != 'X')) {
|
||||
puts("command error, params should start with 0x or 0X\n");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return str_to_hex(param_s + 2, *param_len - 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* input: [addr] [value]
|
||||
*/
|
||||
void memory_write(u8 *buff, u32 buff_Len)
|
||||
{
|
||||
u32 addr_len = 0;
|
||||
u32 value_len = 0;
|
||||
u32 addr = 0;
|
||||
u32 value = 0;
|
||||
|
||||
/* get address */
|
||||
addr = get_params(buff, buff_Len, &addr_len);
|
||||
if (addr == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get value */
|
||||
value = get_params(buff + addr_len + 1, buff_Len - addr_len - 1, &value_len);
|
||||
if (value == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
puts("write address=0x");
|
||||
serial_put_hex(addr);
|
||||
puts(" value=0x");
|
||||
serial_put_hex(value);
|
||||
puts("\n");
|
||||
|
||||
writel(value, addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* input: [addr] [length]
|
||||
*/
|
||||
void memory_read(u8 *buff, u32 buff_Len)
|
||||
{
|
||||
u32 addr_len = 0;
|
||||
u32 length_len = 0;
|
||||
u32 addr = 0;
|
||||
u32 length = 0;
|
||||
u32 value = 0;
|
||||
|
||||
/* get address */
|
||||
addr = get_params(buff, buff_Len, &addr_len);
|
||||
if (addr == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get length */
|
||||
length = get_params(buff + addr_len + 1, buff_Len - addr_len - 1, &length_len);
|
||||
if (length == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (length % 4 != 0) {
|
||||
puts("error: length should be align with 4\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* read and print */
|
||||
for (u32 i = 0; i < length / 4; i++) {
|
||||
value = readl(addr + i * 4);
|
||||
if (i % 4 == 0) {
|
||||
serial_put_hex(addr + i * 4);
|
||||
puts(": ");
|
||||
}
|
||||
serial_put_hex(value);
|
||||
puts(" ");
|
||||
if (i % 4 == 3) {
|
||||
puts("\n");
|
||||
}
|
||||
}
|
||||
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
u32 start_shell(void)
|
||||
{
|
||||
u8 buff[REV_BUFF_LEN];
|
||||
u32 recv_len = 0;
|
||||
u8 cmd[CMD_BUFF_LEN];
|
||||
u32 cmd_len = 0;
|
||||
|
||||
puts("\n## Micro shell ##\n");
|
||||
|
||||
/* cmd [param1] [param2] ... */
|
||||
while (1) {
|
||||
puts("# ");
|
||||
memset_s(buff, REV_BUFF_LEN, 0, REV_BUFF_LEN);
|
||||
memset_s(cmd, CMD_BUFF_LEN, 0, CMD_BUFF_LEN);
|
||||
recv_len = read_line(buff, REV_BUFF_LEN);
|
||||
if (recv_len == 0 || recv_len == FAILURE) {
|
||||
continue;
|
||||
}
|
||||
cmd_len = get_cmd(cmd, CMD_BUFF_LEN, buff, recv_len);
|
||||
if (cmd_len == FAILURE) {
|
||||
continue;
|
||||
}
|
||||
switch (cmd_len) {
|
||||
case CMD_2:
|
||||
if (memcmp(cmd, "mw", CMD_2) == SUCCESS) {
|
||||
/* mw [addr] [value]; addr and value should start with 0x/0X */
|
||||
memory_write(buff + cmd_len + 1, recv_len - cmd_len - 1);
|
||||
} else if (memcmp(cmd, "md", CMD_2) == SUCCESS) {
|
||||
/* md [addr] [length]; addr and length should start with 0x/0X */
|
||||
memory_read(buff + cmd_len + 1, recv_len - cmd_len - 1);
|
||||
}
|
||||
break;
|
||||
case CMD_4:
|
||||
if (memcmp(cmd, "help", CMD_4) == SUCCESS) {
|
||||
show_help();
|
||||
}
|
||||
default:
|
||||
puts("Unknown command!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
SRCS-y += lib.c stdio.c div64.c
|
||||
SRCS-$(CONFIG_PRINTF) += printf.c
|
||||
ifdef CONFIG_MALLOC
|
||||
SRCS-y += malloc.c memlib.c
|
||||
else
|
||||
SRCS-y += simple_malloc.c
|
||||
endif
|
||||
SRCS-y += reserved_mem.c
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
uint32_t __div64_32(uint64_t *n, uint32_t base)
|
||||
{
|
||||
uint64_t rem = *n;
|
||||
uint64_t b = base;
|
||||
uint64_t res, d = 1;
|
||||
uint32_t high = rem >> 32;
|
||||
|
||||
res = 0;
|
||||
if (high >= base) {
|
||||
high /= base;
|
||||
res = (uint64_t) high << 32;
|
||||
rem -= (uint64_t) (high * base) << 32;
|
||||
}
|
||||
|
||||
while ((int64_t)b > 0 && b < rem) {
|
||||
b = b + b;
|
||||
d = d + d;
|
||||
}
|
||||
|
||||
do {
|
||||
if (rem >= b) {
|
||||
rem -= b;
|
||||
res += d;
|
||||
}
|
||||
b >>= 1;
|
||||
d >>= 1;
|
||||
} while (d);
|
||||
|
||||
*n = res;
|
||||
return rem;
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <lib.h>
|
||||
#include <serial.h>
|
||||
|
||||
int memset_s(void* dest, size_t destMax, unsigned char c, size_t count)
|
||||
{
|
||||
unsigned char *__dest = (unsigned char *)dest;
|
||||
|
||||
if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (__dest == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (count > destMax) {
|
||||
while (destMax--)
|
||||
*__dest++ = (unsigned char)c; /*set entire buffer to value c*/
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
while (count--)
|
||||
*__dest++ = (unsigned char)c;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int memset(void* dest, unsigned char c, size_t count)
|
||||
{
|
||||
return memset_s(dest, SECUREC_MEM_MAX_LEN, c, count);
|
||||
}
|
||||
|
||||
int memcpy_s(void* dest, size_t destMax, const void* src, size_t count)
|
||||
{
|
||||
unsigned char *__dest = (unsigned char *)dest;
|
||||
unsigned char *__src = (unsigned char *)src;
|
||||
|
||||
if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN ) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (__dest == NULL || __src == NULL) {
|
||||
if (__dest != NULL ) {
|
||||
while (destMax--)
|
||||
*__dest++ = 0; /*set entire buffer to value 0 */
|
||||
return FAILURE;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (count > destMax) {
|
||||
while (destMax--)
|
||||
*__dest++ = 0; /*set entire buffer to value 0 */
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (__dest == __src) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if ((__dest > __src && __dest < ((u8*)__src + count)) ||
|
||||
(__src > __dest && __src < ((u8*)__dest + count)) ) {
|
||||
while (destMax--)
|
||||
*__dest++ = 0; /*set entire buffer to value 0 */
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
while (count--)
|
||||
*__dest++ = *__src++;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t len)
|
||||
{
|
||||
if(SUCCESS == memcpy_s(dst, len, src, len))
|
||||
return dst;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int memcmp(const void *b1, const void *b2, size_t len)
|
||||
{
|
||||
int res = 0;
|
||||
const char *d = b1;
|
||||
const char *s = b2;
|
||||
|
||||
if (b1 == NULL || b2 == NULL) {
|
||||
puts("memcmp : Invalid args\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
res = *d - *s;
|
||||
if (res != 0)
|
||||
break;
|
||||
d++;
|
||||
s++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
u32 strlen(const char * s)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for (sc = s; *sc != '\0'; ++sc)
|
||||
/* nothing */;
|
||||
return sc - s;
|
||||
}
|
||||
|
||||
char *strcat(char *dest, const char *src)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while (*dest)
|
||||
dest++;
|
||||
while ((*dest++ = *src++) != '\0')
|
||||
;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char *strcpy(char *dest, const char*src)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while (*src != '\0') {
|
||||
*dest = *src;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
char *strncpy(char *dest, char *src, size_t n)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while (n > 0 && *src != '\0') {
|
||||
*dest = *src;
|
||||
dest++;
|
||||
src++;
|
||||
n--;
|
||||
}
|
||||
|
||||
while (n > 0) {
|
||||
*dest = '\0';
|
||||
dest++;
|
||||
n--;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2) {
|
||||
while (*s1 && (*s1 == *s2)) {
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, size_t n) {
|
||||
if (n == 0)
|
||||
return 0;
|
||||
do {
|
||||
if (*s1 != *s2++)
|
||||
return *(const unsigned char*)s1 - *(const unsigned char*)--s2;
|
||||
if (*s1++ == 0)
|
||||
break;
|
||||
} while (--n != 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* for gcc -fstack-protector-all */
|
||||
unsigned long __stack_chk_guard = 0x000a0dff;
|
||||
|
||||
void __stack_chk_fail(void)
|
||||
{
|
||||
serial_puts("Stack is corrupted\n");
|
||||
while (1) {
|
||||
reset_cpu();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short crc16(unsigned char *data, unsigned int length)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned short crc_table;
|
||||
unsigned short crc = 0xffff;
|
||||
unsigned char inter1;
|
||||
unsigned char inter2;
|
||||
|
||||
if (data == NULL)
|
||||
return (crc);
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
inter1 = data[i] ^ ((unsigned char) crc);
|
||||
inter2 = (unsigned char) (inter1 ^ (inter1 << 4)); /* bit size 4 */
|
||||
crc_table = (inter2 << 8) ^ (inter2 << 3) ^ (inter2 >> 4); /* bit size 8 3 4 */
|
||||
crc = (crc >> 8) ^ crc_table; /* bit size 8 */
|
||||
}
|
||||
crc ^= 0xffff;
|
||||
return (crc);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <hlist.h>
|
||||
#include "memlib.h"
|
||||
|
||||
static struct list g_malloc_list = {0};
|
||||
|
||||
void malloc_init(unsigned int base, unsigned int size)
|
||||
{
|
||||
if ((g_malloc_list.base.next != NULL) && (g_malloc_list.base.prev != NULL)) {
|
||||
return;
|
||||
}
|
||||
memlib_init(&g_malloc_list, base, size);
|
||||
}
|
||||
|
||||
void *malloc(uint32 bytes)
|
||||
{
|
||||
if ((g_malloc_list.base.next == NULL) || (g_malloc_list.base.prev == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
return memlib_malloc(&g_malloc_list, bytes);
|
||||
}
|
||||
|
||||
void *memalign(uint32 alignment, uint32 bytes)
|
||||
{
|
||||
if ((g_malloc_list.base.next == NULL) || (g_malloc_list.base.prev == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
return memlib_memalign(&g_malloc_list, alignment, bytes);
|
||||
}
|
||||
|
||||
void free(void *ptr)
|
||||
{
|
||||
if ((g_malloc_list.base.next == NULL) || (g_malloc_list.base.prev == NULL)) {
|
||||
return;
|
||||
}
|
||||
memlib_free(&g_malloc_list, ptr);
|
||||
}
|
||||
|
||||
void show_memnode(unsigned int cnt)
|
||||
{
|
||||
if ((g_malloc_list.base.next == NULL) || (g_malloc_list.base.prev == NULL)) {
|
||||
return;
|
||||
}
|
||||
memlib_show_memnode(&g_malloc_list, cnt);
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <hlist.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MEM_ALLOC_MAGIC_NUM 0xACCA5995
|
||||
typedef struct _mem_node {
|
||||
uint32 magicnum;
|
||||
struct node nodeinfo;
|
||||
/* Size & flag of the current node (the high two bits represent a flag,and the rest bits specify the size) */
|
||||
uint32 size_flag;
|
||||
}mem_node;
|
||||
|
||||
uint32 g_heap_start = 0;
|
||||
uint32 g_heap_end = 0;
|
||||
|
||||
#define around(size, align) (((size) + (align) - 1) & (~((align) - 1)))
|
||||
|
||||
#define MEM_NODE_HEAD_SIZE sizeof(struct _mem_node)
|
||||
#define MEM_ALIGN_SIZE 4
|
||||
#define MEM_NODE_USED_FLAG 0x80000000U
|
||||
#define MEM_NODE_ALIGNED_FLAG 0x40000000U
|
||||
#define MEM_NODE_ALIGNED_AND_USED_FLAG (MEM_NODE_USED_FLAG | MEM_NODE_ALIGNED_FLAG)
|
||||
|
||||
#define mem_node_get_used_flag(size_flag) ((size_flag) & MEM_NODE_USED_FLAG)
|
||||
#define mem_node_set_used_flag(size_flag) ((size_flag) = ((size_flag) | MEM_NODE_USED_FLAG))
|
||||
#define mem_node_get_aligned_gapsize(sizeAndFlag) ((sizeAndFlag) & ~MEM_NODE_ALIGNED_FLAG)
|
||||
#define mem_node_get_aligned_flag(size_flag) ((size_flag) & MEM_NODE_ALIGNED_FLAG)
|
||||
#define mem_node_set_aligned_flag(size_flag) ((size_flag) = ((size_flag) | MEM_NODE_ALIGNED_FLAG))
|
||||
#define mem_node_get_size(size_flag) ((size_flag) & ~MEM_NODE_ALIGNED_AND_USED_FLAG)
|
||||
|
||||
#define mem_node_clear_used_aligned_flag(size_flag) ((size_flag) = (size_flag) & (~ (MEM_NODE_ALIGNED_AND_USED_FLAG)))
|
||||
|
||||
#define is_pow_two(value) ((((uintptr_t)(value)) & ((uintptr_t)(value) - 1)) == 0)
|
||||
#define is_aligned(value, alignSize) ((((uintptr_t)(value)) & ((uintptr_t)((alignSize) - 1))) == 0)
|
||||
|
||||
void memlib_init(struct list *listhead, unsigned int base, unsigned int size)
|
||||
{
|
||||
mem_node *firstnode = (mem_node *)(uintptr_t)(base);
|
||||
if (mem_node_get_used_flag(size) || mem_node_get_aligned_flag(size)) {
|
||||
printf("malloc init failed, size:0x%x\n", size);
|
||||
return;
|
||||
}
|
||||
list_init(listhead);
|
||||
firstnode->magicnum = MEM_ALLOC_MAGIC_NUM;
|
||||
firstnode->size_flag = size;
|
||||
list_add_tail(listhead, &firstnode->nodeinfo);
|
||||
g_heap_start = base;
|
||||
g_heap_end = base + size;
|
||||
#ifdef CONFIG_DEBUG_INFO
|
||||
puts("malloc init,base: 0x");puthex(g_heap_start);puts(", size: ");putdec(size);puts("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *mem_find_freeblock(struct list *listhead, uint32 allocsize)
|
||||
{
|
||||
mem_node *entry = NULL;
|
||||
mem_node *tmp = NULL;
|
||||
mem_node *newnode = NULL;
|
||||
unsigned int nodesize;
|
||||
list_for_each_entry_safe(entry, tmp, listhead, mem_node, nodeinfo) {
|
||||
nodesize = mem_node_get_size(entry->size_flag);
|
||||
if ((!mem_node_get_used_flag(entry->size_flag)) && nodesize >= allocsize) {
|
||||
if ((nodesize - allocsize) < (MEM_NODE_HEAD_SIZE + MEM_ALIGN_SIZE)) {
|
||||
mem_node_set_used_flag(entry->size_flag);
|
||||
return entry + 1;
|
||||
} else {
|
||||
newnode = (mem_node *)((uintptr_t)entry + allocsize);
|
||||
newnode->magicnum = MEM_ALLOC_MAGIC_NUM;
|
||||
newnode->size_flag = entry->size_flag - allocsize;
|
||||
entry->size_flag = allocsize;
|
||||
mem_node_set_used_flag(entry->size_flag);
|
||||
list_insert_backward(&entry->nodeinfo, &newnode->nodeinfo); /* newnode 插入到 entry 后面 */
|
||||
return entry + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("no suitable free mem block\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *memlib_malloc(struct list *listhead, uint32 bytes)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
if (bytes == 0) {
|
||||
return NULL;
|
||||
}
|
||||
uint32 allocsize = around(bytes + MEM_NODE_HEAD_SIZE, MEM_ALIGN_SIZE);
|
||||
ptr = mem_find_freeblock(listhead, allocsize);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *memlib_memalign(struct list *listhead, uint32 alignment, uint32 bytes)
|
||||
{
|
||||
uint32 gap_size;
|
||||
uint32 use_size;
|
||||
void *ptr = NULL;
|
||||
void *align_ptr = NULL;
|
||||
mem_node *node = NULL;
|
||||
if (bytes == 0 || alignment == 0 || !is_pow_two(alignment) || !is_aligned(alignment, sizeof(void*))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* sizeof(gap_size) bytes stores offset between align_ptr and ptr,
|
||||
* the ptr has been OS_MEM_ALIGN_SIZE(4 or 8) aligned, so maximum
|
||||
* offset between alignedPtr and ptr is alignment - OS_MEM_ALIGN_SIZE
|
||||
*/
|
||||
if ((alignment - sizeof(gap_size)) > ((uint32)(-1) - bytes)) {
|
||||
return NULL;
|
||||
}
|
||||
use_size = around(bytes + MEM_NODE_HEAD_SIZE + alignment - sizeof(gap_size), MEM_ALIGN_SIZE);
|
||||
if (mem_node_get_used_flag(use_size) || mem_node_get_aligned_flag(use_size)) {
|
||||
printf("size is too large:0x%x\n", use_size);
|
||||
return NULL;
|
||||
}
|
||||
ptr = mem_find_freeblock(listhead, use_size);
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
align_ptr = (void *)around((uintptr_t)ptr, alignment);
|
||||
if (ptr == align_ptr) {
|
||||
return ptr;
|
||||
}
|
||||
gap_size = (uintptr_t)align_ptr - (uintptr_t)ptr;
|
||||
mem_node_set_aligned_flag(gap_size);
|
||||
node = (mem_node *)ptr - 1;
|
||||
mem_node_set_aligned_flag(node->size_flag);
|
||||
*(uint32 *)((uintptr_t)align_ptr - sizeof(gap_size)) = gap_size;
|
||||
ptr = align_ptr;
|
||||
return ptr;
|
||||
}
|
||||
void *memptr_to_node(void *ptr)
|
||||
{
|
||||
uint32 gapsize;
|
||||
if (((uintptr_t)ptr) & (MEM_ALIGN_SIZE - 1)) {
|
||||
printf("ptr not align by 4byte\n");
|
||||
return NULL;
|
||||
}
|
||||
gapsize = *(uint32 *)((uintptr_t)ptr - sizeof(uint32));
|
||||
if (mem_node_get_aligned_flag(gapsize) && mem_node_get_used_flag(gapsize)) {
|
||||
printf("gapsize:0x%x error\n", gapsize);
|
||||
return NULL;
|
||||
}
|
||||
if (mem_node_get_aligned_flag(gapsize)) {
|
||||
gapsize = mem_node_get_aligned_gapsize(gapsize);
|
||||
if ((gapsize & (MEM_ALIGN_SIZE - 1)) || (gapsize > ((uintptr_t)ptr - MEM_NODE_HEAD_SIZE))) {
|
||||
return NULL;
|
||||
}
|
||||
ptr = (void *)((uintptr_t)ptr - gapsize);
|
||||
}
|
||||
return (void *)((uintptr_t)ptr - MEM_NODE_HEAD_SIZE);
|
||||
}
|
||||
|
||||
void memlib_free(struct list *listhead, void *ptr)
|
||||
{
|
||||
mem_node *entry = NULL;
|
||||
mem_node *next_entry = NULL;
|
||||
mem_node *pre_entry = NULL;
|
||||
if (ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
entry = (mem_node *)memptr_to_node(ptr);
|
||||
if (entry == NULL) {
|
||||
return;
|
||||
}
|
||||
if (entry->magicnum != MEM_ALLOC_MAGIC_NUM) {
|
||||
printf("MAGIC NUM is wrong! magicnum:0x%x\n", entry->magicnum);
|
||||
return;
|
||||
}
|
||||
if (!mem_node_get_used_flag(entry->size_flag)) {
|
||||
return;
|
||||
}
|
||||
mem_node_clear_used_aligned_flag(entry->size_flag);
|
||||
next_entry = list_next_entry(entry, listhead, mem_node, nodeinfo);
|
||||
if (next_entry != NULL) {
|
||||
if (!mem_node_get_used_flag(next_entry->size_flag)) {
|
||||
entry->size_flag += next_entry->size_flag;
|
||||
next_entry->magicnum = 0;
|
||||
list_remove(&next_entry->nodeinfo);
|
||||
}
|
||||
}
|
||||
pre_entry = list_prev_entry(entry, listhead, mem_node, nodeinfo);
|
||||
if (pre_entry != NULL) {
|
||||
if (!mem_node_get_used_flag(pre_entry->size_flag)) {
|
||||
pre_entry->size_flag += entry->size_flag;
|
||||
entry->magicnum = 0;
|
||||
list_remove(&entry->nodeinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void memlib_show_memnode(struct list *listhead, unsigned int cnt)
|
||||
{
|
||||
mem_node *entry = NULL;
|
||||
uint32 i = 0;
|
||||
list_for_each_entry(entry, listhead, mem_node, nodeinfo) {
|
||||
printf("%d:entry, magic:0x%x, size: %d, used:0x%x, aligned:0x%x\n", i++, entry->magicnum,
|
||||
mem_node_get_size(entry->size_flag), mem_node_get_used_flag(entry->size_flag),
|
||||
mem_node_get_aligned_flag(entry->size_flag));
|
||||
if (cnt != 0 && i == cnt) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user