📄 s3c6410_tv_scaler.c
字号:
#include <windows.h>
#include <bsp_cfg.h>
#include <s3c6410.h>
#include "s3c6410_tv_scaler.h"
#include "s3c6410_tv_scaler_macro.h"
#ifdef REMOVE_BEFORE_RELEASE
#define TVSC_MSG(x)
#define TVSC_INF(x)
#define TVSC_ERR(x) RETAILMSG(TRUE, x)
#else
//#define TVSC_MSG(x) RETAILMSG(TRUE, x)
#define TVSC_MSG(x)
#define TVSC_INF(x) RETAILMSG(TRUE, x)
//#define TVSC_INF(x)
#define TVSC_ERR(x) RETAILMSG(TRUE, x)
//#define TVSC_ERR(x)
#endif
static volatile S3C6410_TVSC_REG *g_pTVSCReg = NULL;
static tTVScalerConfig g_TVSCConfig;
TVSC_ERROR TVSC_initialize_register_address(void *pTVSCReg)
{
TVSC_ERROR error = TVSC_SUCCESS;
TVSC_MSG((_T("[TVSC]++TVSC_initialize_register_address(0x%08x)\n\r"), pTVSCReg));
if (pTVSCReg == NULL)
{
TVSC_ERR((_T("[TVSC:ERR] TVSC_initialize_register_address() : NULL pointer parameter\n\r")));
error = TVSC_ERROR_NULL_PARAMETER;
}
else
{
g_pTVSCReg = (S3C6410_TVSC_REG *)pTVSCReg;
TVSC_INF((_T("[TVSC:INF] g_pTVSCReg = 0x%08x\n\r"), g_pTVSCReg));
}
memset((void *)(&g_TVSCConfig), 0x0, sizeof(tTVScalerConfig));
TVSC_MSG((_T("[TVSC]--TVSC_initialize_register_address() : %d\n\r"), error));
return error;
}
TVSC_ERROR TVSC_initialize(TVSC_OP_MODE Mode, TVSC_SCAN_MODE Scan,
TVSC_SRC_TYPE SrcType, unsigned int SrcBaseWidth, unsigned int SrcBaseHeight,
unsigned int SrcWidth, unsigned int SrcHeight, unsigned int SrcOffsetX, unsigned int SrcOffsetY,
TVSC_DST_TYPE DstType, unsigned int DstBaseWidth, unsigned int DstBaseHeight,
unsigned int DstWidth, unsigned int DstHeight, unsigned int DstOffsetX, unsigned int DstOffsetY)
{
TVSC_ERROR error = TVSC_SUCCESS;
TVSC_MSG((_T("[TVSC]++TVSC_initialize(%d, %d, %d, [%d, %d, %d, %d, %d, %d], %d, [%d, %d, %d, %d, %d, %d])\n\r"),
Mode, Scan, SrcType, SrcBaseWidth, SrcBaseHeight, SrcWidth, SrcHeight, SrcOffsetX, SrcOffsetY,
DstType, DstBaseWidth, DstBaseHeight, DstWidth, DstHeight, DstOffsetX, DstOffsetY));
error = TVSC_set_mode(Mode, Scan, SrcType, DstType);
if (error == TVSC_SUCCESS)
{
error = TVSC_set_source_size(SrcBaseWidth, SrcBaseHeight, SrcWidth, SrcHeight, SrcOffsetX, SrcOffsetY);
if (error == TVSC_SUCCESS)
{
error = TVSC_set_destination_size(DstBaseWidth, DstBaseHeight, DstWidth, DstHeight, DstOffsetX, DstOffsetY);
if (error == TVSC_SUCCESS)
{
error = TVSC_update_condition();
}
}
}
TVSC_MSG((_T("[TVSC]--TVSC_initialize() : %d\n\r"), error));
return error;
}
TVSC_ERROR TVSC_set_source_buffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
TVSC_ERROR error = TVSC_SUCCESS;
TVSC_MSG((_T("[TVSC]++TVSC_set_source_buffer(0x%08x, 0x%08x, 0x%08x)\n\r"), AddrY, AddrCb, AddrCr));
if (g_TVSCConfig.SrcType == TVSC_SRC_FIFO)
{
TVSC_ERR((_T("[TVSC:ERR] TVSC_set_source_buffer() : FIFO Mode does Not use DMA\n\r")));
error = TVSC_ERROR_ILLEGAL_PARAMETER;
}
else
{
error = TVSC_set_dma_address(TVSC_SRC_ADDRESS, AddrY, AddrCb, AddrCr);
}
TVSC_MSG((_T("[TVSC]--TVSC_set_source_buffer() : %d\n\r"), error));
return error;
}
TVSC_ERROR TVSC_set_next_source_buffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
TVSC_ERROR error = TVSC_SUCCESS;
TVSC_MSG((_T("[TVSC]++TVSC_set_next_source_buffer(0x%08x, 0x%08x, 0x%08x)\n\r"), AddrY, AddrCb, AddrCr));
if (g_TVSCConfig.SrcType == TVSC_SRC_FIFO)
{
TVSC_ERR((_T("[TVSC:ERR] TVSC_set_next_source_buffer() : FIFO Mode does Not use DMA\n\r")));
error = TVSC_ERROR_ILLEGAL_PARAMETER;
}
else
{
error = TVSC_set_dma_address(TVSC_NEXT_SRC_ADDRESS, AddrY, AddrCb, AddrCr);
}
TVSC_MSG((_T("[TVSC]--TVSC_set_next_source_buffer() : %d\n\r"), error));
return error;
}
TVSC_ERROR TVSC_set_destination_buffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
TVSC_ERROR error = TVSC_SUCCESS;
TVSC_MSG((_T("[TVSC]++TVSC_set_destination_buffer(0x%08x, 0x%08x, 0x%08x)\n\r"), AddrY, AddrCb, AddrCr));
if (g_TVSCConfig.DstType == TVSC_DST_FIFO_RGB888 || g_TVSCConfig.DstType == TVSC_DST_FIFO_YUV444)
{
TVSC_ERR((_T("[TVSC:ERR] TVSC_set_destination_buffer() : FIFO Mode does Not use DMA\n\r")));
error = TVSC_ERROR_ILLEGAL_PARAMETER;
}
else
{
error = TVSC_set_dma_address(TVSC_DST_ADDRESS, AddrY, AddrCb, AddrCr);
}
TVSC_MSG((_T("[TVSC]--TVSC_set_destination_buffer() : %d\n\r"), error));
return error;
}
TVSC_ERROR TVSC_set_next_destination_buffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
TVSC_ERROR error = TVSC_SUCCESS;
TVSC_MSG((_T("[TVSC]++TVSC_set_next_destination_buffer(0x%08x, 0x%08x, 0x%08x)\n\r"), AddrY, AddrCb, AddrCr));
if (g_TVSCConfig.DstType == TVSC_DST_FIFO_RGB888 || g_TVSCConfig.DstType == TVSC_DST_FIFO_YUV444)
{
TVSC_ERR((_T("[TVSC:ERR] TVSC_set_next_destination_buffer() : FIFO Mode does Not use DMA\n\r")));
error = TVSC_ERROR_ILLEGAL_PARAMETER;
}
else
{
error = TVSC_set_dma_address(TVSC_NEXT_DST_ADDRESS, AddrY, AddrCb, AddrCr);
}
TVSC_MSG((_T("[TVSC]--TVSC_set_next_destination_buffer() : %d\n\r"), error));
return error;
}
void TVSC_processing_start(void)
{
TVSC_MSG((_T("[TVSC]++TVSC_processing_start()\n\r")));
if (g_TVSCConfig.Mode == TVSC_FREE_RUN_MODE) // for FIFO output mode
{
g_pTVSCReg->MODE |= AUTOLOAD_ENABLE;
}
g_pTVSCReg->POSTENVID |= TVSC_ENVID;
TVSC_MSG((_T("[TVSC]--TVSC_processing_start()\n\r")));
}
TVSC_ERROR TVSC_processing_stop(void)
{
TVSC_ERROR error = TVSC_SUCCESS;
TVSC_MSG((_T("[TVSC]++TVSC_processing_stop()\n\r")));
if (g_pTVSCReg->MODE & AUTOLOAD_ENABLE) // for FIFO output mode
{
// FIFO mode should be stopped by autoload disable
g_pTVSCReg->MODE &= ~AUTOLOAD_ENABLE;
}
g_pTVSCReg->POSTENVID &= ~TVSC_ENVID;
TVSC_MSG((_T("[TVSC]--TVSC_processing_stop() : %d\n\r"), error));
return error;
}
void TVSC_autoload_disable(void)
{
TVSC_MSG((_T("[TVSC]++TVSC_autoload_disable()\n\r")));
g_pTVSCReg->MODE &= ~AUTOLOAD_ENABLE;
TVSC_MSG((_T("[TVSC]--TVSC_autoload_disable()\n\r")));
}
TVSC_STATE TVSC_get_processing_state(void)
{
TVSC_STATE state;
TVSC_MSG((_T("[TVSC]++TVSC_get_processing_state()\n\r")));
if (g_pTVSCReg->POSTENVID & TVSC_ENVID)
{
state = TVSC_BUSY;
}
else
{
state = TVSC_IDLE;
}
TVSC_MSG((_T("[TVSC]--TVSC_get_processing_state() = %d\n\r"), state));
return state;
}
void TVSC_enable_interrupt(void)
{
TVSC_MSG((_T("[TVSC]++TVSC_enable_interrupt()\n\r")));
g_TVSCConfig.bIntEnable = TRUE;
g_pTVSCReg->MODE &= ~TVSCINT_PEND; // Pending Clear
g_pTVSCReg->MODE |= TVSCINT_ENABLE; // Interrupt Enable
TVSC_MSG((_T("[TVSC]--TVSC_enable_interrupt()\n\r")));
}
void TVSC_disable_interrupt(void)
{
TVSC_MSG((_T("[TVSC]++TVSC_disable_interrupt()\n\r")));
g_TVSCConfig.bIntEnable = FALSE;
g_pTVSCReg->MODE &= ~TVSCINT_ENABLE; // Interrupt Disable
g_pTVSCReg->MODE &= ~TVSCINT_PEND; // Pending Clear
TVSC_MSG((_T("[TVSC]--TVSC_disable_interrupt()\n\r")));
}
BOOL TVSC_clear_interrupt_pending(void)
{
BOOL IntPend = FALSE;
TVSC_MSG((_T("[TVSC]++TVSC_clear_interrupt_pending()\n\r")));
if (g_pTVSCReg->MODE & TVSCINT_PEND)
{
g_pTVSCReg->MODE &= ~TVSCINT_PEND; // Pending Clear
IntPend = TRUE;
}
TVSC_MSG((_T("[TVSC]--TVSC_clear_interrupt_pending()\n\r")));
return IntPend;
}
static TVSC_ERROR TVSC_set_mode(TVSC_OP_MODE Mode, TVSC_SCAN_MODE Scan, TVSC_SRC_TYPE SrcType, TVSC_DST_TYPE DstType)
{
TVSC_ERROR error = TVSC_SUCCESS;
TVSC_MSG((_T("[TVSC]++TVSC_set_mode(%d, %d, %d, %d)\n\r"), Mode, Scan, SrcType, DstType));
g_TVSCConfig.Mode = Mode;
g_TVSCConfig.Scan = Scan;
g_TVSCConfig.SrcType = SrcType;
g_TVSCConfig.DstType = DstType;
// TODO: May be need to optimization for CLK : CLKVAL_F(0) | CLKDIR_DIRECT -> CLKVAL_F(1) | CLKDIR_DIVIDED
g_pTVSCReg->MODE = CLKVALUP_ALWAYS | CLKVAL_F(0) | CLKDIR_DIRECT | CLKSEL_F_HCLK | CSC_R2Y_WIDE | CSC_Y2R_WIDE | IRQ_LEVEL;
//g_pTVSCReg->MODE = CLKVALUP_ALWAYS | CLKVAL_F(2) | CLKDIR_DIVIDED | CLKSEL_F_HCLK | CSC_R2Y_NARROW | CSC_Y2R_NARROW | IRQ_LEVEL; // Clock = HCLK/2
if (g_TVSCConfig.bIntEnable)
{
g_pTVSCReg->MODE |= TVSCINT_ENABLE;
}
if (Mode == TVSC_PER_FRAME_MODE)
{
g_pTVSCReg->MODE |= AUTOLOAD_DISABLE;
}
else if (Mode == TVSC_FREE_RUN_MODE)
{
g_pTVSCReg->MODE |= AUTOLOAD_ENABLE;
}
else
{
TVSC_ERR((_T("[TVSC:ERR] TVSC_set_mode() : Unknown Operation Mode %d)\n\r"), Mode));
error = TVSC_ERROR_ILLEGAL_PARAMETER;
}
if (Scan == TVSC_PROGRESSIVE)
{
g_pTVSCReg->MODE |= PROGRESSIVE;
}
else if (Mode == TVSC_INTERLACE)
{
g_pTVSCReg->MODE |= INTERLACE;
}
else
{
TVSC_ERR((_T("[TVSC:ERR] TVSC_set_mode() : Unknown Scan Mode %d)\n\r"), Scan));
error = TVSC_ERROR_ILLEGAL_PARAMETER;
}
switch(SrcType)
{
case TVSC_SRC_RGB16:
g_pTVSCReg->MODE |= SRCFMT_RGB | SRCRGB_RGB565 | SRCYUV_YUV422 | SRC_INTERLEAVE;
break;
case TVSC_SRC_RGB24:
g_pTVSCReg->MODE |= SRCFMT_RGB | SRCRGB_RGB24 | SRCYUV_YUV422 | SRC_INTERLEAVE;
break;
case TVSC_SRC_YUV420:
g_pTVSCReg->MODE |= SRCFMT_YUV | SRCRGB_RGB24 | SRCYUV_YUV420 | SRC_NOT_INTERLEAVE;
break;
case TVSC_SRC_YUV422_YCBYCR:
g_pTVSCReg->MODE |= SRCFMT_YUV | SRCRGB_RGB24 | SRCYUV_YUV422 | SRC_INTERLEAVE | SRCYUV_YCBYCR;
break;
case TVSC_SRC_YUV422_CBYCRY:
g_pTVSCReg->MODE |= SRCFMT_YUV | SRCRGB_RGB24 | SRCYUV_YUV422 | SRC_INTERLEAVE | SRCYUV_CBYCRY;
break;
case TVSC_SRC_YUV422_YCRYCB:
g_pTVSCReg->MODE |= SRCFMT_YUV | SRCRGB_RGB24 | SRCYUV_YUV422 | SRC_INTERLEAVE | SRCYUV_YCRYCB;
break;
case TVSC_SRC_YUV422_CRYCBY:
g_pTVSCReg->MODE |= SRCFMT_YUV | SRCRGB_RGB24 | SRCYUV_YUV422 | SRC_INTERLEAVE | SRCYUV_CRYCBY;
break;
case TVSC_SRC_FIFO:
g_pTVSCReg->MODE |= FIFO_IN_ENABLE;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -