📄 rotator.c
字号:
/**************************************************************************************
*
* Project Name : S3C6400 Validation
*
* Copyright 2006 by Samsung Electronics, Inc.
* All rights reserved.
*
* Project Description :
* This software is only for validating functions of the S3C6400.
* Anybody can use this software without our permission.
*
*--------------------------------------------------------------------------------------
*
* File Name : rotator.c
*
* File Description : This file includes the API functions for rotator.
*
* Author : Sekwang Kim
* Dept. : AP Development Team
* Created Date : 2007/01/25
* Version : 0.1a
*
* History
* -
* -
*
**************************************************************************************/
#include "system.h"
#include "lcd.h"
#include "glib.h"
#include "glib_font.h"
#include "rotator.h"
#include "camera.h"
#include "post.h"
#include "timer.h"
#include "intc.h"
// Header file for text drawing
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#define rROTATOR_CTRLCFG (ROTATOR_BASE+0x00)
#define rROTATOR_SRCADDRREG0 (ROTATOR_BASE+0x04)
#define rROTATOR_SRCADDRREG1 (ROTATOR_BASE+0x08)
#define rROTATOR_SRCADDRREG2 (ROTATOR_BASE+0x0c)
#define rROTATOR_SRCSIZEREG (ROTATOR_BASE+0x10)
#define rROTATOR_DESTADDRREG0 (ROTATOR_BASE+0x18)
#define rROTATOR_DESTADDRREG1 (ROTATOR_BASE+0x1c)
#define rROTATOR_DESTADDRREG2 (ROTATOR_BASE+0x20)
#define rROTATOR_STATCFG (ROTATOR_BASE+0x2c)
ROTATOR oROTATOR;
volatile bool bRotatorDone;
volatile bool bPostIntOccured;
static POST oPost;
static POST oSc;
void ROTATOR_GetFrmSz(u16 *usRotHorSize, u16 *usRotVerSize)
{
u32 uSize;
uSize=Inp32(rROTATOR_SRCSIZEREG);
*usRotHorSize=(u16)(uSize&0xffff);
*usRotVerSize=(u16)((uSize>>16)&0xffff);
}
void ROTATOR_GetFbAddr(u32 *uRotSrcAddr, u32 *uRotDstAddr)
{
*uRotSrcAddr=Inp32(rROTATOR_SRCADDRREG0);
*uRotDstAddr=Inp32(rROTATOR_DESTADDRREG0);
}
void ROTATOR_GetBppMode(CSPACE *eBpp)
{
u32 uCTRLCFG;
uCTRLCFG=Inp32(rROTATOR_CTRLCFG);
switch((uCTRLCFG)&(0x7<<13)) {
case ROTATOR_BIT_IN_YC420:
*eBpp=YC420;
break;
case ROTATOR_BIT_IN_YC422:
// *eBpp=YC422;
*eBpp=YCBYCR;
break;
case ROTATOR_BIT_IN_RGB565:
*eBpp=RGB16;
break;
case ROTATOR_BIT_IN_RGB888:
*eBpp=RGB24;
break;
default:
Assert(0);
break;
}
}
void ROTATOR_GetLcdFbAddr(u32 *uLcdFbAddr0, u32 *uLcdFbAddr1)
{
*uLcdFbAddr0=oROTATOR.m_uLcdFbAddr0;
*uLcdFbAddr1=oROTATOR.m_uLcdFbAddr1;
}
void ROTATOR_DrawImage(CSPACE eBpp, u16 usRotHorSize, u16 usRotVerSize, u32 uRotSrcAddr)
{
#ifdef NATURALIMAGE
u32 i,j,k;
#endif
GLIB_InitInstance(uRotSrcAddr, usRotHorSize, usRotVerSize, eBpp);
#ifdef NATURALIMAGE
k=0;
switch(eBpp) {
case YC420:
break;
case YCBYCR:
case YCRYCB:
case CBYCRY:
break;
case RGB16:
if(usRotHorSize==240) {
for(j=0; j<usRotVerSize; j++)
for(i=0; i<usRotHorSize; i++)
GLIB_PutPixel2(i, j, sun240320_16bpp[k++]);
}
else if(usRotHorSize==320) {
for(j=0; j<usRotVerSize; j++)
for(i=0; i<usRotHorSize; i++)
GLIB_PutPixel2(i, j, sun320240_16bpp[k++]);
}
else ;
break;
case RGB24:
if(usRotHorSize==240) {
for(j=0; j<usRotVerSize; j++)
for(i=0; i<usRotHorSize; i++)
GLIB_PutPixel2(i, j, sun240320_24bpp[k++]);
}
else if(usRotHorSize==320) {
for(j=0; j<usRotVerSize; j++)
for(i=0; i<usRotHorSize; i++)
GLIB_PutPixel2(i, j, sun320240_24bpp[k++]);
}
else ;
break;
default:
Assert(0);
break;
}
#else
GLIB_DrawPattern(usRotHorSize, usRotVerSize);
#endif
}
bool ROTATOR_CompFbData(CSPACE eBpp, ROTATOR_ROT_TYPE eRotType, u32 uSrcWidth, u32 uSrcHeight, u32 uInX, u32 uInY,
u32 uRotWidth, u32 uRotHeight, u32 uRotX, u32 uRotY, u32 uSrcFbAddr, u32 uRotFbAddr)
{
u32 uOrgData, uRotData;
u8 ucOrgDataY, ucOrgDataCb0, ucOrgDataCr0;
u8 ucOrgDataCb1, ucOrgDataCr1;
u8 ucRotDataY, ucRotDataCb, ucRotDataCr;
u32 uTempData0, uTempData1;
uOrgData=uRotData=0;
switch(eBpp) {
case RGB16:
uOrgData = (u32)(*(volatile unsigned short *)(uSrcFbAddr + (uInY*uSrcWidth +uInX)*2));
uRotData = (u32)(*(volatile unsigned short *)(uRotFbAddr + (uRotY*uRotWidth +uRotX)*2));
break;
case RGB24:
uOrgData = *(volatile unsigned int *)(uSrcFbAddr + (uInY*uSrcWidth +uInX)*4);
uRotData = *(volatile unsigned int *)(uRotFbAddr + (uRotY*uRotWidth +uRotX)*4);
break;
case YC420:
ucOrgDataY = *(volatile unsigned char *)(uSrcFbAddr + (uInY*uSrcWidth +uInX));
ucOrgDataCb0 = *(volatile unsigned char *)(uSrcFbAddr + uSrcWidth*uSrcHeight + (uInY/2*uSrcWidth/2 +uInX/2));
ucOrgDataCr0 = *(volatile unsigned char *)(uSrcFbAddr + uSrcWidth*uSrcHeight + uSrcWidth*uSrcHeight/4 +(uInY/2*uSrcWidth/2 +uInX/2));
uOrgData=(ucOrgDataY<<16)|(ucOrgDataCb0<<8)|(ucOrgDataCr0);
ucRotDataY = *(volatile unsigned char *)(uRotFbAddr + (uRotY*uRotWidth +uRotX));
ucRotDataCb = *(volatile unsigned char *)(uRotFbAddr + uRotWidth*uRotHeight + (uRotY/2*uRotWidth/2 +uRotX/2));
ucRotDataCr = *(volatile unsigned char *)(uRotFbAddr + uRotWidth*uRotHeight + uRotWidth*uRotHeight/4 +(uRotY/2*uRotWidth/2 +uRotX/2));
uRotData=(ucRotDataY<<16)|(ucRotDataCb<<8)|(ucRotDataCr);
break;
case YCRYCB:
case YCBYCR:
case CBYCRY:
if(eRotType == ROTATOR_TYPE_ROT_90 || eRotType==ROTATOR_TYPE_ROT_270) {
uTempData0 = *(volatile unsigned int *)(uSrcFbAddr + (uInY*uSrcWidth/2 +uInX/2)*4);
uTempData1 = (uInY%2) ? *(volatile unsigned int *)(uSrcFbAddr + ((uInY-1)*uSrcWidth/2 +uInX/2)*4) :
*(volatile unsigned int *)(uSrcFbAddr + ((uInY+1)*uSrcWidth/2 +uInX/2)*4);
ucOrgDataY = (uTempData0>>((((uInX)%2)*16)))&0xff;
ucOrgDataCb0= (uTempData0>>24)&0xff;
ucOrgDataCr0= (uTempData0>>8)&0xff;
ucOrgDataCb1= (uTempData1>>24)&0xff;
ucOrgDataCr1= (uTempData1>>8)&0xff;
uOrgData=(ucOrgDataY<<16)|(((ucOrgDataCb0+ucOrgDataCb1)/2)<<8)|((ucOrgDataCr0+ucOrgDataCr1)/2);
uTempData0 = *(volatile unsigned int *)(uRotFbAddr + (uRotY*uRotWidth/2 +uRotX/2)*4);
ucRotDataY = (uTempData0>>((((uRotX)%2)*16)))&0xff;
ucRotDataCb= (uTempData0>>24)&0xff;
ucRotDataCr= (uTempData0>>8)&0xff;
uRotData=(ucRotDataY<<16)|(ucRotDataCb<<8)|(ucRotDataCr);
}
else {
uTempData0 = *(volatile unsigned int *)(uSrcFbAddr + (uInY*uSrcWidth/2 +uInX/2)*4);
ucOrgDataY = (uTempData0>>((((uInX)%2)*16)))&0xff;
ucOrgDataCb0= (uTempData0>>24)&0xff;
ucOrgDataCr0= (uTempData0>>8)&0xff;
uOrgData=(ucOrgDataY<<16)|(ucOrgDataCb0<<8)|(ucOrgDataCr0);
uTempData0 = *(volatile unsigned int *)(uRotFbAddr + (uRotY*uRotWidth/2 +uRotX/2)*4);
ucRotDataY = (uTempData0>>((((uRotX)%2)*16)))&0xff;
ucRotDataCb= (uTempData0>>24)&0xff;
ucRotDataCr= (uTempData0>>8)&0xff;
uRotData=(ucRotDataY<<16)|(ucRotDataCb<<8)|(ucRotDataCr);
}
break;
default:
break;
}
if(uOrgData != uRotData) {
printf("[0x%x, 0x%x]=0x%x, [0x%x,0x%x]=0x%x\n", uInX, uInY, uOrgData, uRotX, uRotY, uRotData);
return false;
}
else return true;
}
void ROTATOR_GetRotateCoordinate(u32 uSrcX, u32 uSrcY, u32 uSrcWidth, u32 uSrcHeight, ROTATOR_ROT_TYPE eRotType,
u32 *uRotX, u32 *uRotY, u32 *uRotWidth, u32 *uRotHeight)
{
switch(eRotType) {
case ROTATOR_TYPE_ROT_90 : // No Rotate. bypass.
*uRotX = uSrcHeight-1-uSrcY;
*uRotY = uSrcX;
*uRotWidth=uSrcHeight;
*uRotHeight=uSrcWidth;
break;
case ROTATOR_TYPE_ROT_180 : // 90 degree Rotation
*uRotX = uSrcWidth-1-uSrcX;
*uRotY = uSrcHeight-1-uSrcY;
*uRotWidth=uSrcWidth;
*uRotHeight=uSrcHeight;
break;
case ROTATOR_TYPE_ROT_270 : // 180 degree Rotation
*uRotX = uSrcY;
*uRotY = uSrcWidth-1-uSrcX;
*uRotWidth=uSrcHeight;
*uRotHeight=uSrcWidth;
break;
case ROTATOR_TYPE_FLIP_HOR: // 270 degree Rotation
*uRotX = uSrcWidth-1-uSrcX;
*uRotY = uSrcY;
*uRotWidth=uSrcWidth;
*uRotHeight=uSrcHeight;
break;
case ROTATOR_TYPE_FLIP_VER: // X-flip
*uRotX = uSrcX;
*uRotY = uSrcHeight-1-uSrcY;
*uRotWidth=uSrcWidth;
*uRotHeight=uSrcHeight;
break;
default :
Assert(0);
break;
}
}
bool ROTATOR_AuditOperation(CSPACE eBpp, u32 uWidth, u32 uHeight, ROTATOR_ROT_TYPE eRotType,
u32 uInFbAddr, u32 uOutFbAddr)
{
u32 i,j;
u32 uRotX, uRotY;
u32 uRotWidth, uRotHeight;
for(j=0; j<uHeight; j++)
for(i=0; i<uWidth; i++) {
ROTATOR_GetRotateCoordinate(i, j, uWidth, uHeight, eRotType, &uRotX, &uRotY, &uRotWidth, &uRotHeight);
if(!ROTATOR_CompFbData(eBpp, eRotType, uWidth, uHeight, i, j, uRotWidth, uRotHeight, uRotX, uRotY, uInFbAddr, uOutFbAddr)) return false;
}
return true;
}
void __irq ROTATOR_PostISR(void)
{
bPostIntOccured = TRUE;
POST_ClearPending(&oPost);
INTC_ClearVectAddr();
}
void ROTATOR_ConvertColorSpace(CSPACE eInFmt, u32 uInFbAddr, u32 uWidth, u32 uHeight, CSPACE eOutFmt, u32 uOutFbAddr)
{
INTC_Enable(9);
INTC_SetVectAddr(9, ROTATOR_PostISR);
POST_EnableInterrupt(POST_LEVEL_INT, &oPost);
bPostIntOccured=0;
POST_InitIpForDmaInDmaOut(uWidth, uHeight, uInFbAddr, eInFmt,
uWidth, uHeight, uOutFbAddr, eOutFmt,
1, FALSE, ONE_SHOT, &oPost);
//POST_InitIpForDmaInDmaOut( uImgHSz, uImgVSz, uGlibStAddr, eSrcDataFmt,
// uLcdHSz, uLcdVSz, uPostStAddr, eMidDataFmt,
// 1, FALSE, ONE_SHOT, &oPost);
POST_StartProcessing(&oPost);
while(!bPostIntOccured);
bPostIntOccured=0;
POST_DisableInterrupt(&oPost);
POST_ClearPending(&oPost);
INTC_Disable(9);
}
void ROTATOR_SetAddr (CSPACE eBpp, u32 uFbAddr, u16 usHorSize, u16 usVerSize)
{
u32 uOffset;
Outp32(rROTATOR_SRCADDRREG0, uFbAddr);
oROTATOR.m_uSrcAddr0=uFbAddr;
uOffset=usHorSize*usVerSize;
switch(eBpp) {
case YC420:
Outp32(rROTATOR_SRCADDRREG1, uFbAddr+uOffset);
Outp32(rROTATOR_SRCADDRREG2, uFbAddr+uOffset+uOffset/4);
Outp32(rROTATOR_DESTADDRREG0, uFbAddr+uOffset+uOffset/2);
Outp32(rROTATOR_DESTADDRREG1, uFbAddr+uOffset*2+uOffset/2);
Outp32(rROTATOR_DESTADDRREG2, uFbAddr+uOffset*2+uOffset/2+uOffset/4);
oROTATOR.m_uSrcAddr1=uFbAddr+uOffset;
oROTATOR.m_uSrcAddr2=uFbAddr+uOffset+uOffset/4;
oROTATOR.m_uDstAddr0=uFbAddr+uOffset+uOffset/2;
oROTATOR.m_uDstAddr1=uFbAddr+uOffset*2+uOffset/2;
oROTATOR.m_uDstAddr2=uFbAddr+uOffset*2+uOffset/2+uOffset/4;
break;
case YCRYCB:
case YCBYCR:
case CBYCRY:
Outp32(rROTATOR_SRCADDRREG1, 0);
Outp32(rROTATOR_SRCADDRREG2, 0);
Outp32(rROTATOR_DESTADDRREG0, uFbAddr+uOffset*2);
Outp32(rROTATOR_DESTADDRREG1, 0);
Outp32(rROTATOR_DESTADDRREG2, 0);
oROTATOR.m_uSrcAddr1=0;
oROTATOR.m_uSrcAddr2=0;
oROTATOR.m_uDstAddr0=uFbAddr+uOffset*2;
oROTATOR.m_uDstAddr1=0;
oROTATOR.m_uDstAddr2=0;
break;
case RGB16:
Outp32(rROTATOR_SRCADDRREG1, 0);
Outp32(rROTATOR_SRCADDRREG2, 0);
Outp32(rROTATOR_DESTADDRREG0, uFbAddr+uOffset*2);
Outp32(rROTATOR_DESTADDRREG1, 0);
Outp32(rROTATOR_DESTADDRREG2, 0);
oROTATOR.m_uSrcAddr1=0;
oROTATOR.m_uSrcAddr2=0;
oROTATOR.m_uDstAddr0=uFbAddr+uOffset*2;
oROTATOR.m_uDstAddr1=0;
oROTATOR.m_uDstAddr2=0;
break;
case RGB24:
Outp32(rROTATOR_SRCADDRREG1, 0);
Outp32(rROTATOR_SRCADDRREG2, 0);
Outp32(rROTATOR_DESTADDRREG0, uFbAddr+uOffset*4);
Outp32(rROTATOR_DESTADDRREG1, 0);
Outp32(rROTATOR_DESTADDRREG2, 0);
oROTATOR.m_uSrcAddr1=0;
oROTATOR.m_uSrcAddr2=0;
oROTATOR.m_uDstAddr0=uFbAddr+uOffset*4;
oROTATOR.m_uDstAddr1=0;
oROTATOR.m_uDstAddr2=0;
break;
default:
Assert(0);
break;
}
}
void ROTATOR_SetSrcAddr(CSPACE eBpp, u32 uFbAddr, u16 usHorSize, u16 usVerSize)
{
u32 uOffset;
Outp32(rROTATOR_SRCADDRREG0, uFbAddr);
oROTATOR.m_uSrcAddr0=uFbAddr;
uOffset=usHorSize*usVerSize;
switch(eBpp) {
case YC420:
Outp32(rROTATOR_SRCADDRREG1, uFbAddr+uOffset);
Outp32(rROTATOR_SRCADDRREG2, uFbAddr+uOffset+uOffset/4);
oROTATOR.m_uSrcAddr1=uFbAddr+uOffset;
oROTATOR.m_uSrcAddr2=uFbAddr+uOffset+uOffset/4;
break;
case YCRYCB:
case YCBYCR:
case CBYCRY:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -