468 lines
18 KiB
C
468 lines
18 KiB
C
#include "app_config.h"
|
||
#include "system/includes.h"
|
||
#include "device/device.h"
|
||
#include "asm/spi.h"
|
||
#include "camera.h"
|
||
#include "device/gpio.h"
|
||
#include "device/device.h"//u8
|
||
#include "storage_device.h"//SD
|
||
#include "server/video_dec_server.h"//fopen
|
||
#include "system/includes.h"//GPIO
|
||
#include "asm/clock.h"
|
||
#include "asm/pwm.h"
|
||
#include "lcd_config.h"//LCD_h
|
||
#include "system/includes.h"//late_initcall
|
||
#include "yuv_soft_scalling.h"//YUV420p_Soft_Scaling
|
||
#include "get_yuv_data.h"//get_yuv_init
|
||
#include "lcd_drive.h"
|
||
#include "yuv_to_rgb.h"
|
||
#include "spi_video.h"
|
||
#include "lcd_data_driver.h"
|
||
|
||
#ifdef USE_DevKitBoard_TEST_DEMO
|
||
|
||
static struct spi_video *hdl;
|
||
|
||
struct lbuf_test_head {
|
||
u8 data[0];
|
||
};
|
||
|
||
static void *lbuf_ptr = NULL;
|
||
static struct lbuff_head *lbuf_handle = NULL;
|
||
static struct lbuff_head *lib_system_lbuf_init(u32 buf_size)
|
||
{
|
||
struct lbuff_head *lbuf = NULL;
|
||
lbuf_ptr = malloc(buf_size);
|
||
if (lbuf_ptr == NULL) {
|
||
printf("lbuf malloc buf err");
|
||
return NULL;
|
||
}
|
||
lbuf = lbuf_init(lbuf_ptr, buf_size, 4, sizeof(struct lbuf_test_head));
|
||
|
||
return lbuf;
|
||
}
|
||
|
||
static ___interrupt void spi_irq_cb(void); //中断函数,指定在内部sram
|
||
static void Calculation_frame(void)
|
||
{
|
||
static u32 tstart = 0, tdiff = 0;
|
||
static u8 fps_cnt = 0;
|
||
fps_cnt++ ;
|
||
if (!tstart) {
|
||
tstart = timer_get_ms();
|
||
} else {
|
||
tdiff = timer_get_ms() - tstart;
|
||
if (tdiff >= 1000) {
|
||
printf("\n [MSG]spi_video_fps_count = %d\n", fps_cnt * 1000 / tdiff);
|
||
tstart = 0;
|
||
fps_cnt = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
/********保存YUV数据到SD卡中************/
|
||
static void save_YUV_date_ontime(u8 *buf, u32 len)
|
||
{
|
||
if (storage_device_ready()) {
|
||
char file_name[64];//定义路径存储
|
||
snprintf(file_name, 64, CONFIG_ROOT_PATH"YUV/YUV***.bin");
|
||
FILE *fd = fopen(file_name, "wb+");
|
||
fwrite(buf, 1, len, fd);
|
||
fclose(fd);
|
||
printf("YUV save ok name=YUV\r\n");
|
||
}
|
||
}
|
||
|
||
static void debug_io_init(void)
|
||
{
|
||
#ifdef SPI_IO_DBG
|
||
DBG_PORT->DIR &= ~DBG_PORT_BIT;
|
||
DBG_PORT->PU &= ~DBG_PORT_BIT;
|
||
DBG_PORT->PD &= ~DBG_PORT_BIT;
|
||
DBG_PORT->OUT &= ~DBG_PORT_BIT;
|
||
#endif
|
||
}
|
||
|
||
static void *pwm_dev = NULL;
|
||
static void spi_xclk_open(void)
|
||
{
|
||
struct pwm_platform_data pwm = {0};
|
||
if (!pwm_dev) {
|
||
pwm_dev = dev_open("pwm1", &pwm);
|
||
}
|
||
if (!pwm_dev) {
|
||
printf("open spi_xclk pwm fail\r\n");
|
||
return;
|
||
}
|
||
}
|
||
static void spi_xclk_close(void)
|
||
{
|
||
struct pwm_platform_data pwm = {0};
|
||
|
||
if (!pwm_dev) {
|
||
printf("spi_xclk pwm no open\r\n");
|
||
return;
|
||
}
|
||
dev_ioctl(pwm_dev, PWM_REMOV_CHANNEL, (u32)&pwm);
|
||
dev_ioctl(pwm_dev, PWM_STOP, (u32)&pwm);
|
||
dev_close(pwm_dev);
|
||
pwm_dev = NULL;
|
||
}
|
||
|
||
const short Table_fv1[256] = { -180, -179, -177, -176, -174, -173, -172, -170, -169, -167, -166, -165, -163, -162, -160, -159, -158, -156, -155, -153, -152, -151, -149, -148, -146, -145, -144, -142, -141, -139, -138, -137, -135, -134, -132, -131, -130, -128, -127, -125, -124, -123, -121, -120, -118, -117, -115, -114, -113, -111, -110, -108, -107, -106, -104, -103, -101, -100, -99, -97, -96, -94, -93, -92, -90, -89, -87, -86, -85, -83, -82, -80, -79, -78, -76, -75, -73, -72, -71, -69, -68, -66, -65, -64, -62, -61, -59, -58, -57, -55, -54, -52, -51, -50, -48, -47, -45, -44, -43, -41, -40, -38, -37, -36, -34, -33, -31, -30, -29, -27, -26, -24, -23, -22, -20, -19, -17, -16, -15, -13, -12, -10, -9, -8, -6, -5, -3, -2, 0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 14, 15, 16, 18, 19, 21, 22, 23, 25, 26, 28, 29, 30, 32, 33, 35, 36, 37, 39, 40, 42, 43, 44, 46, 47, 49, 50, 51, 53, 54, 56, 57, 58, 60, 61, 63, 64, 65, 67, 68, 70, 71, 72, 74, 75, 77, 78, 79, 81, 82, 84, 85, 86, 88, 89, 91, 92, 93, 95, 96, 98, 99, 100, 102, 103, 105, 106, 107, 109, 110, 112, 113, 114, 116, 117, 119, 120, 122, 123, 124, 126, 127, 129, 130, 131, 133, 134, 136, 137, 138, 140, 141, 143, 144, 145, 147, 148, 150, 151, 152, 154, 155, 157, 158, 159, 161, 162, 164, 165, 166, 168, 169, 171, 172, 173, 175, 176, 178 };
|
||
const short Table_fv2[256] = { -92, -91, -91, -90, -89, -88, -88, -87, -86, -86, -85, -84, -83, -83, -82, -81, -81, -80, -79, -78, -78, -77, -76, -76, -75, -74, -73, -73, -72, -71, -71, -70, -69, -68, -68, -67, -66, -66, -65, -64, -63, -63, -62, -61, -61, -60, -59, -58, -58, -57, -56, -56, -55, -54, -53, -53, -52, -51, -51, -50, -49, -48, -48, -47, -46, -46, -45, -44, -43, -43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -36, -35, -34, -33, -33, -32, -31, -31, -30, -29, -28, -28, -27, -26, -26, -25, -24, -23, -23, -22, -21, -21, -20, -19, -18, -18, -17, -16, -16, -15, -14, -13, -13, -12, -11, -11, -10, -9, -8, -8, -7, -6, -6, -5, -4, -3, -3, -2, -1, 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24, 25, 25, 26, 27, 27, 28, 29, 30, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 37, 38, 39, 40, 40, 41, 42, 42, 43, 44, 45, 45, 46, 47, 47, 48, 49, 50, 50, 51, 52, 52, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 62, 63, 64, 65, 65, 66, 67, 67, 68, 69, 70, 70, 71, 72, 72, 73, 74, 75, 75, 76, 77, 77, 78, 79, 80, 80, 81, 82, 82, 83, 84, 85, 85, 86, 87, 87, 88, 89, 90, 90 };
|
||
const short Table_fu1[256] = { -44, -44, -44, -43, -43, -43, -42, -42, -42, -41, -41, -41, -40, -40, -40, -39, -39, -39, -38, -38, -38, -37, -37, -37, -36, -36, -36, -35, -35, -35, -34, -34, -33, -33, -33, -32, -32, -32, -31, -31, -31, -30, -30, -30, -29, -29, -29, -28, -28, -28, -27, -27, -27, -26, -26, -26, -25, -25, -25, -24, -24, -24, -23, -23, -22, -22, -22, -21, -21, -21, -20, -20, -20, -19, -19, -19, -18, -18, -18, -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -11, -11, -11, -10, -10, -10, -9, -9, -9, -8, -8, -8, -7, -7, -7, -6, -6, -6, -5, -5, -5, -4, -4, -4, -3, -3, -3, -2, -2, -2, -1, -1, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43 };
|
||
const short Table_fu2[256] = { -227, -226, -224, -222, -220, -219, -217, -215, -213, -212, -210, -208, -206, -204, -203, -201, -199, -197, -196, -194, -192, -190, -188, -187, -185, -183, -181, -180, -178, -176, -174, -173, -171, -169, -167, -165, -164, -162, -160, -158, -157, -155, -153, -151, -149, -148, -146, -144, -142, -141, -139, -137, -135, -134, -132, -130, -128, -126, -125, -123, -121, -119, -118, -116, -114, -112, -110, -109, -107, -105, -103, -102, -100, -98, -96, -94, -93, -91, -89, -87, -86, -84, -82, -80, -79, -77, -75, -73, -71, -70, -68, -66, -64, -63, -61, -59, -57, -55, -54, -52, -50, -48, -47, -45, -43, -41, -40, -38, -36, -34, -32, -31, -29, -27, -25, -24, -22, -20, -18, -16, -15, -13, -11, -9, -8, -6, -4, -2, 0, 1, 3, 5, 7, 8, 10, 12, 14, 15, 17, 19, 21, 23, 24, 26, 28, 30, 31, 33, 35, 37, 39, 40, 42, 44, 46, 47, 49, 51, 53, 54, 56, 58, 60, 62, 63, 65, 67, 69, 70, 72, 74, 76, 78, 79, 81, 83, 85, 86, 88, 90, 92, 93, 95, 97, 99, 101, 102, 104, 106, 108, 109, 111, 113, 115, 117, 118, 120, 122, 124, 125, 127, 129, 131, 133, 134, 136, 138, 140, 141, 143, 145, 147, 148, 150, 152, 154, 156, 157, 159, 161, 163, 164, 166, 168, 170, 172, 173, 175, 177, 179, 180, 182, 184, 186, 187, 189, 191, 193, 195, 196, 198, 200, 202, 203, 205, 207, 209, 211, 212, 214, 216, 218, 219, 221, 223, 225 };
|
||
|
||
#define TIME_DEBUG 0
|
||
void yuyv422_soft_rgb565(u8 *in_yuyv422, u8 *out_rgb_565, int sw, int sh, int dw, int dh) sec(.volatile_ram_code)
|
||
{
|
||
#if TIME_DEBUG
|
||
u32 time1 = timer_get_ms();
|
||
#endif
|
||
|
||
float Qw = sw / dh;
|
||
float Qh = sh / dw;
|
||
u8 *yuyv422;
|
||
u8 *rgb565;
|
||
u8 y, u, v;
|
||
int r, g, b;
|
||
u16 i, j;
|
||
static u8 count_flag = 0;
|
||
yuyv422 = in_yuyv422;
|
||
rgb565 = (u8 *)out_rgb_565;
|
||
|
||
//图像会镜像 可以调整屏的镜像 或者 摄像头镜像处理
|
||
for (j = 0; j < dh / 2; j++) {
|
||
for (i = 0; i < dw; i++) {
|
||
y = yuyv422[(sw * (u16)(i * Qh) + (u16)(j * Qw)) * 2];
|
||
u = yuyv422[(sw * (u16)(i * Qh) + (u16)(j * Qw) - (j % 2)) * 2 + 1];
|
||
v = yuyv422[(sw * (u16)(i * Qh) + (u16)(j * Qw) - (j % 2)) * 2 + 3];
|
||
r = y + Table_fv1[v];
|
||
g = y - Table_fu1[u] - Table_fv2[v];
|
||
b = y + Table_fu2[u];
|
||
r = r < 0 ? 0 : (r > 255 ? 255 : r);
|
||
g = g < 0 ? 0 : (g > 255 ? 255 : g);
|
||
b = b < 0 ? 0 : (b > 255 ? 255 : b);
|
||
*rgb565++ = ((r & 0xf8) | ((g & 0xe0) >> 5));
|
||
*rgb565++ = (((g & 0x1c) << 3) | (b & 0xf8) >> 3);
|
||
}
|
||
}
|
||
|
||
#if TIME_DEBUG
|
||
u32 time2 = timer_get_ms();
|
||
printf("[msg]>>>>>>>>>>>time2-time1=%d", time2 - time1);
|
||
#endif
|
||
}
|
||
|
||
void yuyv422_soft_rgb565_1(u8 *in_yuyv422, u8 *out_rgb_565, int sw, int sh, int dw, int dh) sec(.volatile_ram_code)
|
||
{
|
||
#if TIME_DEBUG
|
||
u32 time1 = timer_get_ms();
|
||
#endif
|
||
float Qw = sw / dh;
|
||
float Qh = sh / dw;
|
||
u8 *yuyv422;
|
||
u8 *rgb565;
|
||
u8 y, u, v;
|
||
int r, g, b;
|
||
u16 i, j;
|
||
static u8 count_flag = 0;
|
||
yuyv422 = in_yuyv422;
|
||
rgb565 = (u8 *)out_rgb_565;
|
||
|
||
rgb565 = rgb565 + dh * dw;
|
||
for (j = dh / 2; j < dh; j++) {
|
||
for (i = 0; i < dw; i++) {
|
||
y = yuyv422[(sw * (u16)(i * Qh) + (u16)(j * Qw)) * 2];
|
||
u = yuyv422[(sw * (u16)(i * Qh) + (u16)(j * Qw) - (j % 2)) * 2 + 1];
|
||
v = yuyv422[(sw * (u16)(i * Qh) + (u16)(j * Qw) - (j % 2)) * 2 + 3];
|
||
r = y + Table_fv1[v];
|
||
g = y - Table_fu1[u] - Table_fv2[v];
|
||
b = y + Table_fu2[u];
|
||
r = r < 0 ? 0 : (r > 255 ? 255 : r);
|
||
g = g < 0 ? 0 : (g > 255 ? 255 : g);
|
||
b = b < 0 ? 0 : (b > 255 ? 255 : b);
|
||
*rgb565++ = ((r & 0xf8) | ((g & 0xe0) >> 5));
|
||
*rgb565++ = (((g & 0x1c) << 3) | (b & 0xf8) >> 3);
|
||
}
|
||
}
|
||
|
||
#if TIME_DEBUG
|
||
u32 time2 = timer_get_ms();
|
||
printf("[msg11]>>>>>>>>>>>time2-time1=%d", time2 - time1);
|
||
#endif
|
||
}
|
||
|
||
static u8 test_buf1[640 * 480 * 2];
|
||
|
||
static void rgb565_task1(void *p)
|
||
{
|
||
while (1) {
|
||
os_sem_pend(&hdl->rgb1, 0);
|
||
yuyv422_soft_rgb565(hdl->get_frame, test_buf1, 640, 480, 320, 480);
|
||
os_sem_post(&hdl->rgb1_ok);
|
||
}
|
||
}
|
||
|
||
static void rgb565_task2(void *p)
|
||
{
|
||
while (1) {
|
||
os_sem_pend(&hdl->rgb2, 0);
|
||
yuyv422_soft_rgb565_1(hdl->get_frame, test_buf1, 640, 480, 320, 480);
|
||
os_sem_post(&hdl->rgb2_ok);
|
||
}
|
||
}
|
||
static int spi_camera_open(void)
|
||
{
|
||
//1.申请全局结构体内存
|
||
hdl = ram_malloc(sizeof(struct spi_video));
|
||
if (hdl == NULL) {
|
||
printf("[error]>>>>>>>>>>>>malloc fail");
|
||
goto exit;
|
||
}
|
||
os_sem_create(&hdl->rgb1, 0);
|
||
os_sem_create(&hdl->rgb2, 0);
|
||
os_sem_create(&hdl->rgb1_ok, 0);
|
||
os_sem_create(&hdl->rgb2_ok, 0);
|
||
|
||
hdl->buf = ram_malloc(LINE_LBUF_SIZE);
|
||
if (!hdl->buf) {
|
||
printf("err spi no buf \n");
|
||
goto exit;
|
||
}
|
||
|
||
lbuf_handle = lib_system_lbuf_init(YUV422_LBUF_LEN + 128);
|
||
if (!lbuf_handle) {
|
||
printf("err lbuf_handle no buf \n");
|
||
goto exit;
|
||
}
|
||
|
||
|
||
hdl->yuv422_buf = malloc(YUV422_LBUF_LEN);
|
||
if (!hdl->buf) {
|
||
printf("err spi no buf \n");
|
||
goto exit;
|
||
}
|
||
|
||
hdl->recv_move_cnt = 0;
|
||
hdl->frame_addr_move_cnt = 0;
|
||
hdl->camera_reinit = 0;
|
||
hdl->kill = 0;
|
||
|
||
//这里需要注意顺序 需要先开摄像头 再开spi
|
||
gpio_output_channle(CAM_XCLK_PORT, CH1_PLL_24M);
|
||
/* spi_xclk_open(); */
|
||
hdl->video = dev_open("video1.0", NULL);
|
||
os_time_dly(20);//过滤异常数据包
|
||
|
||
hdl->spi = dev_open(JL_SPI_NAME, NULL);
|
||
if (!hdl->spi) {
|
||
printf("spi open err \n");
|
||
goto exit;
|
||
} else {
|
||
dev_ioctl(hdl->spi, IOCTL_SPI_SET_IRQ_FUNC, (u32)spi_irq_cb);
|
||
JL_SPI->CON &= ~BIT(2);
|
||
JL_SPI->CON &= ~BIT(11);
|
||
JL_SPI->CON |= BIT(10);
|
||
JL_SPI->CON |= BIT(12);//接收模式
|
||
JL_SPI->CON |= BIT(13);//开启中断
|
||
JL_SPI->CON |= BIT(1);//从机模式
|
||
JL_SPI->CON |= BIT(0);//开启SPI
|
||
}
|
||
|
||
|
||
//用于触发逻辑分析仪检测
|
||
#ifdef SPI_IO_DBG
|
||
DBG_PORT->OUT ^= DBG_PORT_BIT;
|
||
DBG_PORT->OUT ^= DBG_PORT_BIT;
|
||
DBG_PORT->OUT ^= DBG_PORT_BIT;
|
||
DBG_PORT->OUT ^= DBG_PORT_BIT;
|
||
#endif
|
||
os_task_create(rgb565_task1, NULL, 20, 1024, 0, "rgb565_task1");
|
||
os_task_create(rgb565_task2, NULL, 20, 1024, 0, "rgb565_task2");
|
||
printf("camera open ok\n");
|
||
return 0;
|
||
exit:
|
||
return 0;
|
||
}
|
||
static int spi_camera_close(void)
|
||
{
|
||
|
||
extern void GC0310_in_sleep_mode(void);
|
||
GC0310_in_sleep_mode();
|
||
|
||
task_kill("rgb565_task1");
|
||
task_kill("rgb565_task2");
|
||
dev_close(hdl->spi);
|
||
gpio_clear_output_channle(CAM_XCLK_PORT, CH1_PLL_24M);
|
||
dev_close(hdl->video);
|
||
os_sem_del(&hdl->rgb1, 0);
|
||
os_sem_del(&hdl->rgb2, 0);
|
||
os_sem_del(&hdl->rgb1_ok, 0);
|
||
os_sem_del(&hdl->rgb2_ok, 0);
|
||
free(hdl->yuv422_buf);
|
||
lbuf_clear(lbuf_handle);
|
||
free(lbuf_ptr);
|
||
ram_free(hdl->buf);
|
||
ram_free(hdl);
|
||
return 0;
|
||
}
|
||
|
||
//该中断的所有数据均要在内部ram进行处理 在SDRAM可能概率收错
|
||
//并将将中断函数里面要尽可能精简 高效 行间隔只有100us只有 PCLK24M
|
||
//PCLK80M xclk40M FPS20fps 两线spi
|
||
static ___interrupt void spi_irq_cb(void) sec(.volatile_ram_code)
|
||
{
|
||
static u16 recv_cnt = 2;//从第二行开始处理
|
||
u32 recv_len;
|
||
JL_SPI->CON |= BIT(14);//清除中断标记
|
||
u32 id = 0;
|
||
|
||
#ifdef SPI_IO_DBG
|
||
DBG_PORT->OUT ^= DBG_PORT_BIT;
|
||
#endif
|
||
|
||
//////////处理上一次收到的数据///////////
|
||
if (recv_cnt == 1) { //开始新的一轮帧接收
|
||
if (*(u32 *)hdl->irq_recv_buf != CAM_LSTART_VALUE) { //校验数据
|
||
goto recv_err;
|
||
}
|
||
hdl->cpy_addr = hdl->next_frame_addr;
|
||
hdl->real_data_addr = hdl->irq_last_recv_buf + CAM_FHEAD_SIZE;
|
||
/* 告诉lbuf这个数据包完整了 */
|
||
/* id = dma_copy_async(hdl->cpy_addr, hdl->real_data_addr, CAM_LINE_SIZE); */
|
||
/* dma_copy_async_wait(id);//硬件DMA的要等待DMA是否完成 */
|
||
lbuf_push(hdl->next_frame_addr, BIT(0));//把数据块推送更新到lbuf的通道0
|
||
/* 开始行的一轮buf */
|
||
if (lbuf_free_space(lbuf_handle) < YUV422_PACK_LEN) { //查询LBUF空闲数据块是否有足够长度
|
||
//如果内存不足直接读一个buf块释放
|
||
hdl->next_frame_addr = lbuf_pop(lbuf_handle, BIT(0));//从lbuf的通道0读取数据块
|
||
lbuf_free(hdl->next_frame_addr);
|
||
}
|
||
hdl->next_frame_addr = lbuf_alloc(lbuf_handle, YUV422_PACK_LEN); //lbuf内申请一块空间
|
||
} else if (recv_cnt == 2) { //只有第一行有帧头 取余都是去行头
|
||
hdl->cpy_addr = hdl->next_frame_addr;
|
||
hdl->real_data_addr = hdl->irq_last_recv_buf + CAM_FHEAD_SIZE + CAM_LHEAD_SIZE;
|
||
} else {
|
||
hdl->cpy_addr = hdl->cpy_addr + CAM_LINE_SIZE;
|
||
hdl->real_data_addr = hdl->irq_last_recv_buf + CAM_LHEAD_SIZE;
|
||
}
|
||
|
||
//使用DMA拷贝数据减缓CPU开销
|
||
//使用行缓存拷贝需要十分注意一点 需要确保行间隔足够长 不然会追尾
|
||
//使用行缓存拷贝会存在一个问题 就是图像模糊
|
||
//dma 拷贝速度 128us 拷贝 1280个数据极限速度
|
||
//这个地方使用了DMA拷贝别的地方就不能使用只有一个DMA拷贝模块
|
||
dma_copy_async(hdl->cpy_addr, hdl->real_data_addr, CAM_LINE_SIZE);
|
||
|
||
//////////处理下一次数据的接收///////////
|
||
//行缓存
|
||
hdl->irq_recv_buf = hdl->buf + hdl->recv_move_cnt * DATA_FIRST_PACK_SIZE;
|
||
hdl->recv_move_cnt = ++hdl->recv_move_cnt % RECV_DATA_LINE_PACK_TIME;
|
||
if (recv_cnt == 1) { //接收第1行
|
||
JL_SPI->CNT = DATA_FIRST_PACK_SIZE;
|
||
} else if (recv_cnt < CAMERA_H) { //接收2~479行
|
||
JL_SPI->CNT = DATA_LINE_PACK_SIZE;
|
||
} else if (recv_cnt == CAMERA_H) { //接收480行
|
||
JL_SPI->CNT = DATA_END_PACK_SIZE;
|
||
}// 0-479 一共480行
|
||
JL_SPI->ADR = hdl->irq_recv_buf;
|
||
|
||
//保存一下当前接收地址下一次进中断就能知道上一次的接收地址
|
||
hdl->irq_last_recv_buf = hdl->irq_recv_buf;
|
||
|
||
recv_cnt = ++recv_cnt % (CAMERA_H + 1); //0~481循环
|
||
if (recv_cnt == 0) { //去除0 从1开始计数 就是1~480循环
|
||
recv_cnt = 1;
|
||
}
|
||
return;
|
||
|
||
recv_err:
|
||
hdl->camera_reinit = 1;
|
||
}
|
||
|
||
|
||
static void spi_video_task(void *p)
|
||
{
|
||
start:
|
||
debug_io_init();
|
||
if (spi_camera_open()) {
|
||
goto exit;
|
||
}
|
||
|
||
hdl->irq_recv_buf = hdl->buf;
|
||
hdl->irq_last_recv_buf = hdl->irq_recv_buf;
|
||
//第一次buf使用可以不用检测里面有无内存 肯定是有的 刚刚申请
|
||
hdl->next_frame_addr = lbuf_alloc(lbuf_handle, YUV422_PACK_LEN); //lbuf内申请一块空间
|
||
|
||
JL_SPI->ADR = hdl->irq_recv_buf;
|
||
JL_SPI->CNT = DATA_FIRST_PACK_SIZE;
|
||
|
||
while (1) {
|
||
if (hdl->camera_reinit) {
|
||
goto restart;
|
||
}
|
||
if (hdl->kill) {
|
||
goto exit;
|
||
}
|
||
if (!lbuf_empty(lbuf_handle)) { //查询LBUF内是否有数据帧 处理数据
|
||
hdl->get_frame = lbuf_pop(lbuf_handle, BIT(0));//从lbuf的通道0读取数据块
|
||
lcd_interface_non_block_wait();
|
||
os_sem_post(&hdl->rgb1);
|
||
os_sem_post(&hdl->rgb2);
|
||
os_sem_pend(&hdl->rgb1_ok, 0);
|
||
os_sem_pend(&hdl->rgb2_ok, 0);
|
||
lcd_show_frame_to_dev(test_buf1, 320 * 480 * 2);
|
||
Calculation_frame();
|
||
lbuf_free(hdl->get_frame);
|
||
}
|
||
}
|
||
restart:
|
||
spi_camera_close();
|
||
hdl->camera_reinit = 0;
|
||
goto start;
|
||
exit:
|
||
printf("\n [msg] %s -[kill_spi_video] %d\n", __FUNCTION__, __LINE__);
|
||
spi_camera_close();
|
||
hdl->kill = 0;
|
||
while (1) { //等待其他任务杀此任务
|
||
os_time_dly(10);//
|
||
}
|
||
}
|
||
|
||
int spi_video_task_kill(void)
|
||
{
|
||
set_lcd_show_data_mode(UI);
|
||
printf("---> spi_video_task_kill\n");
|
||
hdl->kill = 1;
|
||
while (hdl->kill) {
|
||
os_time_dly(10);
|
||
}
|
||
task_kill("spi_video_task");
|
||
|
||
return 0;
|
||
}
|
||
|
||
int init_spi_video(void)
|
||
{
|
||
set_lcd_show_data_mode(CAMERA);
|
||
os_task_create(spi_video_task, NULL, 1, 1024, 0, "spi_video_task");
|
||
return 0;
|
||
}
|
||
|
||
static int reinit_spi_video(void)
|
||
{
|
||
spi_video_task_kill();
|
||
os_task_create(spi_video_task, NULL, 1, 1024, 0, "spi_video_task");
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
#endif
|
||
|
||
|
||
|
||
|