12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412 |
- /**************************************************************************//**
- *
- * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2021-4-16 Wayne First version
- *
- ******************************************************************************/
- #include "rtthread.h"
- #include "NuMicro.h"
- #include "nu_jpeg.h"
- #include "drv_sys.h"
- struct nu_jpeg
- {
- struct rt_device dev;
- char *name;
- IRQn_Type irqn;
- E_SYS_IPRST rstidx;
- E_SYS_IPCLK clkidx;
- struct rt_mutex lock;
- };
- typedef struct nu_jpeg *nu_jpeg_t;
- static BOOL volatile g_bWait = FALSE, g_jpegError = FALSE, g_bScale = FALSE, g_OutputWait = FALSE, g_InputWait = FALSE, g_u32WindowDec = FALSE, g_bEncThumbnailDownScale = FALSE, g_bEncPrimaryDownScale = FALSE;
- static UINT32 volatile g_u32Stride, g_u32ScaleWidth, g_u32ScaleHeight, g_u32OpMode, g_u32EncRotate = 0;
- static UINT32 volatile g_u32BufferCount, g_u32DecInputWaitAddr;
- static UINT16 volatile g_u16BufferSize, g_u16ReserveSize;
- static UINT32 volatile g_u32OutputFormat, g_u32windowSizeX, g_u32windowSizeY;
- static PFN_JPEG_CALLBACK pfnJpegDecodeComplete = NULL;
- static PFN_JPEG_CALLBACK pfnJpegDecodeError = NULL;
- static PFN_JPEG_CALLBACK pfnJpegEncodeComplete = NULL;
- static PFN_JPEG_HEADERDECODE_CALLBACK pfnJpegHeaderDecode = NULL;
- static PFN_JPEG_DECWAIT_CALLBACK pfnJpegDecInputWait = NULL;
- static PFN_JPEG_DECWAIT_CALLBACK pfnJpegDecOutputWait = NULL;
- static JPEG_INFO_T jpegInfo;
- /* Default Quantization-Table 0 ~ 2 */
- static UINT8 g_au8QTable0[64] = { 0x06, 0x04, 0x04, 0x05, 0x04, 0x04, 0x06, 0x05,
- 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x08, 0x0E,
- 0x09, 0x08, 0x08, 0x08, 0x08, 0x11, 0x0C, 0x0D,
- 0x0A, 0x0E, 0x14, 0x11, 0x15, 0x14, 0x13, 0x11,
- 0x13, 0x13, 0x16, 0x18, 0x1F, 0x1A, 0x16, 0x17,
- 0x1D, 0x17, 0x13, 0x13, 0x1B, 0x25, 0x1B, 0x1D,
- 0x20, 0x21, 0x23, 0x23, 0x23, 0x15, 0x1A, 0x26,
- 0x29, 0x26, 0x22, 0x28, 0x1F, 0x22, 0x23, 0x21
- },
- g_au8QTable1[64] = { 0x06, 0x06, 0x06, 0x08, 0x07, 0x08, 0x10, 0x09,
- 0x09, 0x10, 0x21, 0x16, 0x13, 0x16, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21
- };
- static struct nu_jpeg g_sNuJpeg =
- {
- .name = "jpegcodec",
- .irqn = JPEG_IRQn,
- .rstidx = JPEGRST,
- .clkidx = JPEGCKEN
- };
- /* Interrupt Service Routine for H/W JPEG CODEC */
- static void nu_jpeg_isr(int vector, void *param)
- {
- UINT32 u32interruptStatus;
- /* Get the interrupt status */
- u32interruptStatus = JPEG_GET_INT_STATUS();
- /* It's Header Decode Complete Interrupt */
- if (u32interruptStatus & DHE_INTS)
- {
- UINT32 u32YuvFormat;
- UINT16 u16Height, u16Width, UVHeight, UVWidth;
- UINT16 u16WidthTmp, u16HeightTmp;
- /* Get the JPEG format */
- u32YuvFormat = JPEG_DEC_GET_DECODED_IMAGE_FORMAT();
- /* Get the decoded image dimension */
- jpegGetDecodedDimension(&u16Height, &u16Width);
- jpegInfo.jpeg_width = u16Width;
- jpegInfo.jpeg_height = u16Height;
- jpegInfo.yuvformat = u32YuvFormat;
- if (pfnJpegHeaderDecode != NULL)
- {
- if (!pfnJpegHeaderDecode())
- {
- jpegInit();
- g_bWait = FALSE;
- return;
- }
- }
- if (g_bScale)
- {
- UINT16 u16RatioH, u16RatioW;
- if (jpegCalScalingFactor(
- g_u32OpMode, //Up / Down Scaling
- u16Height, //Original Height
- u16Width, //Original Width
- g_u32ScaleHeight, //Scaled Height
- g_u32ScaleWidth, //Scaled Width
- &u16RatioH, //Horizontal Ratio
- &u16RatioW //Vertical Ratio
- ) != E_SUCCESS)
- {
- g_bWait = FALSE;
- g_jpegError = TRUE;
- }
- else
- {
- jpegSetScalingFactor(g_u32OpMode, u16RatioH, u16RatioW);
- u16Width = g_u32ScaleWidth;
- u16Height = g_u32ScaleHeight;
- }
- }
- else
- {
- if (u32YuvFormat == JPEG_DEC_YUV411)
- {
- /* 32-pixel alignment for YUV411 raw data */
- if (u16Width % 32)
- u16Width = (u16Width & 0xFFFFFFE0) + 32;
- }
- else if ((u32YuvFormat == JPEG_DEC_YUV444) || (u32YuvFormat == JPEG_DEC_YUV422T))
- {
- /* 8-pixel alignment for YUV444 raw data */
- if (u16Width % 8)
- u16Width = (u16Width & 0xFFFFFFF8) + 8;
- }
- else
- {
- /* 16-pixel alignment for YUV422 or YUV420 raw data */
- if (u16Width % 16)
- u16Width = (u16Width & 0xFFFFFFF0) + 16;
- }
- }
- if (g_u32Stride >= u16Width)
- {
- jpegInfo.stride = g_u32Stride;
- g_u32Stride = g_u32Stride - u16Width;
- JPEG_SET_YSTRIDE(g_u32Stride);
- u16Width = jpegInfo.stride;
- }
- else
- {
- g_u32Stride = 0;
- JPEG_SET_YSTRIDE(0);
- jpegInfo.stride = 0;
- }
- if (g_u32OutputFormat == JPEG_DEC_PRIMARY_PLANAR_YUV || g_u32OutputFormat == JPEG_DEC_THUMBNAIL_PLANAR_YUV)
- {
- if (g_u32WindowDec)
- {
- u16WidthTmp = u16Width;
- u16HeightTmp = u16Height;
- u16Width = g_u32windowSizeX;
- u16Height = g_u32windowSizeY;
- }
- if (u32YuvFormat == JPEG_DEC_YUV411)
- {
- /* For YUV411 raw data */
- UVWidth = u16Width / 4;
- }
- else if ((u32YuvFormat == JPEG_DEC_YUV444) || (u32YuvFormat == JPEG_DEC_YUV422T))
- {
- /* For YUV444 raw data */
- UVWidth = u16Width;
- }
- /* Set the U-component and V-componente width for YUV422 or YUV420 raw data */
- else if (u16Width % 2)
- UVWidth = u16Width / 2 + 1;
- else
- UVWidth = u16Width / 2;
- /* Sets the height of U and V for YUV420 image */
- if (u32YuvFormat == JPEG_DEC_YUV420)
- {
- /* 16-pixel alignment for YUV422 or YUV420 raw data */
- if (u16Height % 16)
- u16Height = (u16Height & 0xFFFFFFF0) + 16;
- UVHeight = u16Height / 2;
- }
- else if (u32YuvFormat == JPEG_DEC_YUV422)
- {
- /* 8-pixel alignment for YUV444 raw data */
- if (u16Height % 8)
- u16Height = (u16Height & 0xFFFFFFF8) + 8;
- UVHeight = u16Height;
- }
- else if (u32YuvFormat == JPEG_DEC_YUV444)
- {
- /* 8-pixel alignment for YUV444 raw data */
- if (u16Height % 8)
- u16Height = (u16Height & 0xFFFFFFF8) + 8;
- UVHeight = u16Height;
- }
- else if (u32YuvFormat == JPEG_DEC_YUV411)
- {
- /* 8-pixel alignment for YUV411 raw data */
- if (u16Height % 8)
- u16Height = (u16Height & 0xFFFFFFF8) + 8;
- UVHeight = u16Height;
- }
- else if (u32YuvFormat == JPEG_DEC_YUV422T)
- {
- /* 16-pixel alignment for YUV422 or YUV420 raw data */
- if (u16Height % 16)
- u16Height = (u16Height & 0xFFFFFFF0) + 16;
- UVHeight = u16Height / 2;
- }
- else
- {
- /* 8-pixel alignment for raw data */
- if (u16Height % 8)
- u16Height = (u16Height & 0xFFFFFFF8) + 8;
- UVHeight = u16Height;
- }
- JPEG_SET_UADDR(JPEG_GET_YADDR() + u16Width * u16Height);
- JPEG_SET_VADDR(JPEG_GET_UADDR() + UVWidth * UVHeight);
- if (u32YuvFormat == JPEG_DEC_GRAY)
- jpegInfo.image_size[0] = u16Width * u16Height;
- else
- jpegInfo.image_size[0] = u16Width * u16Height + 2 * UVWidth * UVHeight;
- if (g_u32WindowDec)
- {
- u16Width = u16WidthTmp;
- u16Height = u16HeightTmp;
- }
- }
- else
- {
- if (g_u32WindowDec)
- {
- u16WidthTmp = u16Width;
- u16HeightTmp = u16Height;
- u16Width = g_u32windowSizeX;
- u16Height = g_u32windowSizeY;
- }
- if (jpegInfo.stride)
- jpegInfo.image_size[0] = jpegInfo.stride * u16Height;
- else
- jpegInfo.image_size[0] = u16Width * u16Height;
- if (g_u32OutputFormat == JPEG_DEC_PRIMARY_PACKET_RGB888)
- jpegInfo.image_size[0] = 4 * jpegInfo.image_size[0];
- else
- jpegInfo.image_size[0] = 2 * jpegInfo.image_size[0];
- if (g_u32WindowDec)
- {
- u16Width = u16WidthTmp;
- u16Height = u16HeightTmp;
- }
- }
- /* Set the image dimension */
- jpegSetDimension(u16Height, u16Width);
- outp32(JITCR, inp32(JITCR) | Dec_Scatter_Gather);
- /* Clear interrupt status */
- JPEG_CLEAR_INT(DHE_INTS);
- }
- /* It's Decode Output Wait Interrupt */
- else if (u32interruptStatus & JPG_DOW_INTS)
- {
- if (pfnJpegDecOutputWait != NULL)
- {
- pfnJpegDecOutputWait(inp32(JYADDR0), inp32(JDOWFBS));
- }
- JPEG_CLEAR_INT(JPG_DOW_INTS);
- outp32(JITCR, inp32(JITCR) | Dec_Scatter_Gather);
- }
- /* It's Encode Complete Interrupt */
- else if (u32interruptStatus & ENC_INTS)
- {
- /* Get the Encode Bit stream length */
- jpegInfo.image_size[0] = JPEG_GET_ENC_PRIMARY_BITSTREAM_SIZE();
- jpegInfo.image_size[1] = JPEG_GET_ENC_THUMBNAIL_BITSTREAM_SIZE();
- /* Clear interrupt status */
- JPEG_CLEAR_INT(ENC_INTS);
- g_bWait = FALSE;
- if (pfnJpegEncodeComplete != NULL)
- pfnJpegEncodeComplete();
- }
- /* It's Decode Complete Interrupt */
- else if (u32interruptStatus & DEC_INTS)
- {
- UINT16 imageWidth, imageHeight;
- /* Get the image dimension */
- jpegGetDimension(&imageHeight, &imageWidth);
- if (g_u32Stride != 0)
- {
- imageWidth = imageWidth - g_u32Stride;
- }
- jpegInfo.width = imageWidth;
- jpegInfo.height = imageHeight;
- /* Clear interrupt status */
- JPEG_CLEAR_INT(DEC_INTS);
- JPEG_CLEAR_INT(JPG_DOW_INTS);
- g_bWait = FALSE;
- if (pfnJpegDecodeComplete != NULL)
- pfnJpegDecodeComplete();
- }
- /* It's Decode Error Interrupt */
- else if (u32interruptStatus & DER_INTS)
- {
- /* Clear interrupt status */
- JPEG_CLEAR_INT(DER_INTS);
- g_bWait = FALSE;
- g_jpegError = TRUE;
- if (pfnJpegDecodeError != NULL)
- pfnJpegDecodeError();
- }
- else if (u32interruptStatus & IPW_INTS)
- {
- /* Clear interrupt status */
- JPEG_CLEAR_INT(IPW_INTS);
- JPEG_DEC_RESUME_INPUT_WAIT();
- if (pfnJpegDecInputWait != NULL)
- {
- if (!pfnJpegDecInputWait((g_u32DecInputWaitAddr + (g_u32BufferCount % 2) * g_u16BufferSize), g_u16BufferSize))
- {
- jpegInit();
- g_bWait = FALSE;
- return;
- }
- g_u32BufferCount++;
- }
- else
- while (1);
- }
- }
- static INT jpegAdjustQTAB(UINT8 u8Mode, UINT8 u8Qadjust, UINT8 u8Qscaling)
- {
- UINT32 u32Addr;
- if (u8Mode == JPEG_ENC_PRIMARY)
- u32Addr = REG_JPRIQC;
- else if (u8Mode == JPEG_ENC_THUMBNAIL)
- u32Addr = REG_JTHBQC;
- else
- return E_JPEG_INVALID_PARAM;
- outp32(u32Addr, ((u8Qadjust & 0xF) << 4) | (u8Qscaling & 0xF));
- return E_SUCCESS;
- }
- #if 0
- //Poll the interrupt status and get if the interrupt is generated
- static BOOL jpegPollInt(UINT32 u32Intflag)
- {
- if (JPEG_GET_INT_STATUS() & u32Intflag)
- return 1;
- else
- return 0;
- }
- static UINT32 jpegPower(UINT32 u32Index, UINT32 u32Exp)
- {
- if (u32Exp == 0)
- return 1;
- else
- {
- UINT32 u32Idx;
- for (u32Idx = 1; u32Idx < u32Exp; u32Idx = u32Idx + 1)
- {
- u32Index = 2 * u32Index;
- }
- }
- return u32Index;
- }
- static VOID jpegGetScalingFactor(
- UINT8 u8Mode, //Up / Down Scaling
- PUINT16 pu16FactorH, //Vertical Scaling Factor
- PUINT16 pu16FactorW //Horizontal Scaling Factor
- )
- {
- if (u8Mode == JPEG_DEC_PLANAR_DOWNSCALE_MODE)
- {
- *pu16FactorH = inp32(REG_JPSCALD) & 0x3F;
- *pu16FactorW = (inp32(REG_JPSCALD) >> 8) & 0x1F;
- }
- else
- {
- *pu16FactorH = (inp32(REG_JUPRAT) >> 16) & 0x3FFF;
- *pu16FactorW = inp32(REG_JUPRAT) & 0x3FFF;
- }
- }
- #endif
- static INT jpegSetEncodeMode(UINT8 u8SourceFormat, UINT16 u16JpegFormat)
- {
- UINT8 u8Gray = 0;
- switch (u16JpegFormat)
- {
- case JPEG_ENC_PRIMARY_YUV420:
- case JPEG_ENC_PRIMARY_YUV422:
- case JPEG_ENC_THUMBNAIL_YUV420:
- case JPEG_ENC_THUMBNAIL_YUV422:
- case (JPEG_ENC_PRIMARY_YUV420 | JPEG_ENC_THUMBNAIL_YUV420):
- case (JPEG_ENC_PRIMARY_YUV422 | JPEG_ENC_THUMBNAIL_YUV422):
- outp32(REG_JMCR, (inp32(REG_JMCR) & WIN_DEC) | u16JpegFormat);
- u8Gray = 0;
- break;
- case JPEG_ENC_PRIMARY_GRAY:
- case JPEG_ENC_THUMBNAIL_GRAY:
- case (JPEG_ENC_PRIMARY_GRAY | JPEG_ENC_THUMBNAIL_GRAY):
- if (u8SourceFormat == JPEG_ENC_SOURCE_PACKET)
- return E_JPEG_INVALID_PARAM;
- else
- {
- if (u16JpegFormat == (JPEG_ENC_PRIMARY_GRAY | JPEG_ENC_THUMBNAIL_GRAY))
- outp32(REG_JMCR, 0xB0);
- else
- outp32(REG_JMCR, 0xA0);
- }
- u8Gray = EY_ONLY;
- break;
- default:
- return E_JPEG_INVALID_PARAM;
- }
- g_u32OpMode = JPEG_ENC_UPSCALE_MODE;
- if (g_bEncPrimaryDownScale)
- g_u32OpMode = JPEG_ENC_PLANAR_PRIMARY_DOWNSCALE_MODE;
- if (g_bEncThumbnailDownScale)
- g_u32OpMode = JPEG_ENC_PLANAR_THUMBNAIL_DOWNSCALE_MODE;
- if (u8SourceFormat == JPEG_ENC_SOURCE_PLANAR)
- outp32(REG_JITCR, (inp32(REG_JITCR) & (0x8 | ROTATE)) | PLANAR_ON | u8Gray);
- else if (u8SourceFormat == JPEG_ENC_SOURCE_PACKET)
- outp32(REG_JITCR, inp32(REG_JITCR) & ~(PLANAR_ON | ROTATE));
- else
- return E_JPEG_INVALID_PARAM;
- return E_SUCCESS;
- }
- static INT jpegSetDecodeMode(UINT32 u32OutputFormat)
- {
- switch (u32OutputFormat)
- {
- case JPEG_DEC_PRIMARY_PLANAR_YUV:
- case JPEG_DEC_PRIMARY_PACKET_YUV422:
- case JPEG_DEC_PRIMARY_PACKET_RGB555:
- case JPEG_DEC_PRIMARY_PACKET_RGB555R1:
- case JPEG_DEC_PRIMARY_PACKET_RGB555R2:
- case JPEG_DEC_THUMBNAIL_PLANAR_YUV:
- case JPEG_DEC_THUMBNAIL_PACKET_YUV422:
- case JPEG_DEC_THUMBNAIL_PACKET_RGB555:
- case JPEG_DEC_PRIMARY_PACKET_RGB565:
- case JPEG_DEC_PRIMARY_PACKET_RGB565R1:
- case JPEG_DEC_PRIMARY_PACKET_RGB565R2:
- case JPEG_DEC_PRIMARY_PACKET_RGB888:
- outp32(REG_JITCR, u32OutputFormat);
- outp32(REG_JMCR, inp32(REG_JMCR) & ~ENC_DEC);
- g_u32OpMode = JPEG_DEC_PACKET_DOWNSCALE_MODE;
- g_u32OutputFormat = u32OutputFormat;
- if (u32OutputFormat == JPEG_DEC_PRIMARY_PLANAR_YUV || u32OutputFormat == JPEG_DEC_THUMBNAIL_PLANAR_YUV)
- g_u32OpMode = JPEG_DEC_PLANAR_DOWNSCALE_MODE;
- break;
- default:
- return E_JPEG_INVALID_PARAM;
- }
- return E_SUCCESS;
- }
- static VOID jpegDecodeTrigger(void)
- {
- g_bWait = TRUE;
- g_jpegError = FALSE;
- rt_memset(&jpegInfo, 0, sizeof(jpegInfo));
- /* Decode Complete /Decode Header End/Decode Error Interrupt Enable and clear the Decode Complete /Decode Header End/Decode Error Interrupt */
- if (g_InputWait)
- {
- g_u32BufferCount = 0;
- g_u32DecInputWaitAddr = JPEG_GET_BITSTREAM_ADDR();
- if (g_OutputWait)
- JPEG_INT_ENABLE(DEC_INTE | DER_INTE | DHE_INTE | IPW_INTE | JPG_DOW_INTE);
- else
- JPEG_INT_ENABLE(DEC_INTE | DER_INTE | DHE_INTE | IPW_INTE);
- }
- else if (g_OutputWait)
- {
- JPEG_INT_ENABLE(DEC_INTE | DER_INTE | DHE_INTE | JPG_DOW_INTE);
- }
- else
- JPEG_INT_ENABLE(DEC_INTE | DER_INTE | DHE_INTE);
- JPEG_CLEAR_INT(DEC_INTS | JPEG_DER_INTS | JPEG_DHE_INTS | JPEG_IPW_INTS | JPG_DOW_INTS);
- outp32(REG_JMCR, JPG_EN | inp32(REG_JMCR));
- outp32(REG_JMCR, ~JPG_EN & inp32(REG_JMCR));
- }
- static VOID jpegEncodeTrigger(void)
- {
- g_bWait = TRUE;
- g_jpegError = FALSE;
- g_u32OpMode = JPEG_ENC_UPSCALE_MODE;
- if (g_bEncPrimaryDownScale)
- g_u32OpMode = JPEG_ENC_PLANAR_PRIMARY_DOWNSCALE_MODE;
- if (g_bEncThumbnailDownScale)
- g_u32OpMode = JPEG_ENC_PLANAR_THUMBNAIL_DOWNSCALE_MODE;
- rt_memset(&jpegInfo, 0, sizeof(jpegInfo));
- if (g_u32EncRotate != 0)
- {
- UINT16 u16Height, u16Width;
- if (((inp32(REG_JITCR) & (PLANAR_ON | EY_ONLY)) != (PLANAR_ON)) && ((inp32(REG_JMCR) & EY422) != 0))
- {
- g_jpegError = TRUE;
- g_bWait = FALSE;
- return;
- }
- jpegGetDimension(&u16Width, &u16Height);
- if (g_u32EncRotate == JPEG_IOCTL_SET_ENCODE_PRIMARY_ROTATE_LEFT)
- {
- JPEG_SET_YADDR((JPEG_GET_YADDR() + (u16Width - 1)));
- JPEG_SET_UADDR((JPEG_GET_UADDR() + (u16Width / 2 - 1)));
- JPEG_SET_VADDR((JPEG_GET_VADDR() + (u16Width / 2 - 1)));
- }
- else
- {
- JPEG_SET_YADDR((JPEG_GET_YADDR() + ((u16Height - 1) * u16Width)));
- u16Width = JPEG_GET_USTRIDE();
- JPEG_SET_UADDR((JPEG_GET_UADDR() + ((u16Height - 2) * u16Width / 2)));
- JPEG_SET_VADDR((JPEG_GET_VADDR() + ((u16Height - 2) * u16Width / 2)));
- }
- }
- if (g_bScale)
- {
- UINT16 u16Height, u16Width, u16ratioH, u16ratioW;
- if (g_u32EncRotate != 0)
- jpegGetDimension(&u16Width, &u16Height);
- else
- jpegGetDimension(&u16Height, &u16Width);
- if (jpegCalScalingFactor(
- g_u32OpMode, //Up / Down Scaling
- u16Height, //Original Height
- u16Width, //Original Width
- g_u32ScaleHeight, //Scaled Height
- g_u32ScaleWidth, //Scaled Width
- &u16ratioH, //Horizontal Ratio
- &u16ratioW //Vertical Ratio
- ) != E_SUCCESS)
- {
- g_jpegError = TRUE;
- g_bWait = FALSE;
- return;
- }
- else
- {
- jpegSetScalingFactor(g_u32OpMode, u16ratioH, u16ratioW);
- if (g_bEncThumbnailDownScale)
- outp32(REG_JTHBWH, ((g_u32ScaleHeight & 0x1FFF) << 16) | (g_u32ScaleWidth & 0x1FFF));
- else
- {
- if (g_u32EncRotate != 0)
- jpegSetDimension(g_u32ScaleWidth, g_u32ScaleHeight);
- else
- jpegSetDimension(g_u32ScaleHeight, g_u32ScaleWidth);
- }
- }
- }
- /* Encode Complete Interrupt Enable and clear the Encode Complete Interrupt */
- JPEG_INT_ENABLE(ENC_INTE);
- JPEG_CLEAR_INT(ENC_INTS);
- outp32(REG_JMCR, JPG_EN | inp32(REG_JMCR));
- outp32(REG_JMCR, ~JPG_EN & inp32(REG_JMCR));
- }
- static INT jpegCalScalingFactor(
- UINT8 u8Mode, //Up / Down Scaling
- UINT16 u16Height, //Original Height
- UINT16 u16Width, //Original Width
- UINT16 u16ScalingHeight, //Scaled Height
- UINT16 u16ScalingWidth, //Scaled Width
- PUINT16 pu16RatioH, //Horizontal Ratio
- PUINT16 pu16RatioW //Vertical Ratio
- )
- {
- if (u8Mode == JPEG_ENC_UPSCALE_MODE)
- {
- if (u16ScalingHeight < u16Height || u16ScalingWidth < u16Width)
- return E_JPEG_INVALID_PARAM;
- *pu16RatioW = (UINT32)((float)(u16ScalingWidth - 1) / (float)(u16Width - 2) * 1024);
- *pu16RatioH = (UINT32)((float)(u16ScalingHeight - 1) / (float)(u16Height - 2) * 1024);
- }
- else if (u8Mode == JPEG_DEC_PACKET_DOWNSCALE_MODE)
- {
- if (u16ScalingHeight > u16Height || u16ScalingWidth > u16Width)
- return E_JPEG_INVALID_PARAM;
- *pu16RatioW = (UINT32)(((float)(u16ScalingWidth) / (u16Width - 1) * 8192));
- if (*pu16RatioW > 8192)
- *pu16RatioW = 8192;
- *pu16RatioH = (UINT32)((float)(u16ScalingHeight) / (u16Height - 1) * 8192);
- if (*pu16RatioH > 8192)
- *pu16RatioH = 8192;
- }
- else if (u8Mode == JPEG_DEC_PLANAR_DOWNSCALE_MODE || u8Mode == JPEG_ENC_PLANAR_PRIMARY_DOWNSCALE_MODE || u8Mode == JPEG_ENC_PLANAR_THUMBNAIL_DOWNSCALE_MODE)
- {
- UINT16 u16RatioW, u16RatioH;
- if (u16ScalingHeight > u16Height || u16ScalingWidth > u16Width)
- return E_JPEG_INVALID_PARAM;
- if (u16Height % u16ScalingHeight)
- return E_JPEG_INVALID_PARAM;
- if (u16Width % u16ScalingWidth)
- return E_JPEG_INVALID_PARAM;
- u16RatioW = u16Width / u16ScalingWidth;
- u16RatioW = u16RatioW / 2 - 1;
- if ((u16RatioW != 0) && (u16RatioW != 1) && (u16RatioW != 3))
- return E_JPEG_INVALID_PARAM;
- u16RatioH = u16Height / u16ScalingHeight - 1;
- if ((u16RatioH != 0) && (u16RatioH != 1) && (u16RatioH != 3) && (u16RatioH != 7))
- return E_JPEG_INVALID_PARAM;
- *pu16RatioW = u16RatioW;
- *pu16RatioH = u16RatioH;
- }
- else
- return E_JPEG_INVALID_PARAM;
- return E_SUCCESS;
- }
- static INT jpegSetScalingFactor(
- UINT8 u8Mode, //Up / Down Scaling
- UINT16 u16FactorH, //Vertical Scaling Factor
- UINT16 u16FactorW //Horizontal Scaling Factor
- )
- {
- if (u8Mode == JPEG_ENC_UPSCALE_MODE)
- {
- JPEG_DEC_DISABLE_DOWNSCALING();
- JPEG_ENC_ENABLE_UPSCALING();
- }
- else if (u8Mode == JPEG_DEC_PACKET_DOWNSCALE_MODE || u8Mode == JPEG_DEC_PLANAR_DOWNSCALE_MODE || u8Mode == JPEG_ENC_PLANAR_PRIMARY_DOWNSCALE_MODE)
- {
- JPEG_DEC_ENABLE_DOWNSCALING();
- JPEG_ENC_DISABLE_UPSCALING();
- }
- else if (u8Mode == JPEG_ENC_PLANAR_THUMBNAIL_DOWNSCALE_MODE)
- {
- outp32(REG_JTSCALD, TSX_ON);
- }
- if (u8Mode == JPEG_DEC_PLANAR_DOWNSCALE_MODE || u8Mode == JPEG_ENC_PLANAR_PRIMARY_DOWNSCALE_MODE)
- outp32(REG_JPSCALD, (inp32(REG_JPSCALD) & ~(PSCALX_F | PSCALY_F)) | ((u16FactorW & 0x1F) << 8) | (u16FactorH & 0x1F));
- else if (u8Mode == JPEG_ENC_PLANAR_THUMBNAIL_DOWNSCALE_MODE)
- outp32(REG_JTSCALD, (inp32(REG_JTSCALD) & ~(TSCALX_F | TSCALY_F)) | ((u16FactorW & 0x1F) << 8) | (u16FactorH & 0x1F));
- else
- {
- outp32(REG_JPSCALD, inp32(REG_JPSCALD) & ~(PSCALX_F | PSCALY_F));
- outp32(REG_JUPRAT, ((u16FactorH & 0x3FFF) << 16) | (u16FactorW & 0x3FFF));
- }
- return E_SUCCESS;
- }
- static VOID jpegGetDecodedDimension(
- PUINT16 pu16Height, //Decode/Encode Height
- PUINT16 pu16Width //Decode/Encode Width
- )
- {
- *pu16Width = inp32(REG_JDECWH) & 0x0000FFFF;
- *pu16Height = inp32(REG_JDECWH) >> 16;
- }
- static VOID jpegSetDimension(
- UINT16 u16Height, //Decode/Encode Height
- UINT16 u16Width //Decode/Encode Width
- )
- {
- outp32(REG_JPRIWH, ((u16Height & 0x1FFF) << 16) | (u16Width & 0x1FFF));
- }
- static VOID jpegGetDimension(
- PUINT16 pu16Height, //Decoded Height from bit stream
- PUINT16 pu16Width //Decoded Width from bit stream
- )
- {
- *pu16Height = inp32(REG_JPRIWH) >> 16;
- *pu16Width = inp32(REG_JPRIWH) & 0x1FFF;
- }
- static INT jpegSetWindowDecode(
- UINT16 u16StartMCUX, //Start X MCU
- UINT16 u16StartMCUY, //Horizontal Scaling Factor
- UINT16 u16EndMCUX, //Vertical Scaling Factor
- UINT16 u16EndMCUY, //Horizontal Scaling Factor
- UINT32 u32Stride //Decode Output Stride
- )
- {
- if (u16StartMCUX >= u16EndMCUX || u16StartMCUY >= u16EndMCUY)
- return E_JPEG_INVALID_PARAM;
- outp32(REG_JWINDEC0, u16StartMCUY << 16 | u16StartMCUX);
- outp32(REG_JWINDEC1, u16EndMCUY << 16 | u16EndMCUX);
- outp32(REG_JWINDEC2, u32Stride);
- outp32(REG_JMCR, WIN_DEC);
- //sysprintf("\tJWINDEC0 0x%X\n", inp32(REG_JWINDEC0));
- //sysprintf("\tJWINDEC1 0x%X\n", inp32(REG_JWINDEC1));
- //sysprintf("\tJWINDEC2 0x%X\n", inp32(REG_JWINDEC2));
- return E_SUCCESS;
- }
- /**
- * @brief The function is used to set JPEG Q Table.
- *
- * @param[in] puQTable0: Q Table 0
- * @param[in] puQTable1: Q Table 1
- * @param[in] puQTable2: Q Table 2
- * @param[in] u8num: Q Table number
- *
- * @return E_JPEG_TIMEOUT: Time-out \n
- * E_SUCCESS: success
- */
- static INT _jpegSetQTAB(PUINT8 puQTable0, PUINT8 puQTable1, PUINT8 puQTable2, UINT8 u8num)
- {
- UINT32 u32value;
- UINT32 u32TimeOut;
- int i;
- u32TimeOut = 0xFFFFFF;
- for (i = 0; i < 64; i = i + 4)
- {
- while ((inp32(REG_JMCR) & QT_BUSY) & u32TimeOut)
- u32TimeOut--;
- if (!u32TimeOut)
- return E_JPEG_TIMEOUT;
- u32value = puQTable0[i] | (puQTable0[i + 1] << 8) | (puQTable0[i + 2] << 16) | (puQTable0[i + 3] << 24);
- outp32((REG_JQTAB0 + i), u32value);
- }
- u32TimeOut = 0xFFFFFF;
- for (i = 0; i < 64; i = i + 4)
- {
- while ((inp32(REG_JMCR) & QT_BUSY) & u32TimeOut)
- u32TimeOut--;
- if (!u32TimeOut)
- return E_JPEG_TIMEOUT;
- u32value = puQTable1[i] | (puQTable1[i + 1] << 8) | (puQTable1[i + 2] << 16) | (puQTable1[i + 3] << 24);
- outp32((REG_JQTAB1 + i), u32value);
- }
- if (u8num < 3)
- return E_SUCCESS;
- outp32(JITCR, inp32(JITCR) | 0x8);
- u32TimeOut = 0xFFFFFF;
- for (i = 0; i < 64; i = i + 4)
- {
- while ((inp32(REG_JMCR) & QT_BUSY) & u32TimeOut)
- u32TimeOut--;
- if (!u32TimeOut)
- return E_JPEG_TIMEOUT;
- u32value = puQTable2[i] | (puQTable2[i + 1] << 8) | (puQTable2[i + 2] << 16) | (puQTable2[i + 3] << 24);
- outp32((REG_JQTAB2 + i), u32value);
- }
- u32TimeOut = 0xFFFFFF;
- while ((inp32(REG_JMCR) & QT_BUSY) & u32TimeOut)
- u32TimeOut--;
- if (!u32TimeOut)
- return E_JPEG_TIMEOUT;
- else
- return E_SUCCESS;
- }
- INT jpegSetQTAB(PUINT8 puQTable0, PUINT8 puQTable1, PUINT8 puQTable2, UINT8 u8num)
- {
- INT ret = 0;
- struct nu_jpeg_ioctl sNuJpegIoctl = {0};
- struct nu_jpeg_qtab sNuJpegQTab = {0};
- sNuJpegQTab.puQTable0 = puQTable0;
- sNuJpegQTab.puQTable1 = puQTable1;
- sNuJpegQTab.puQTable2 = puQTable2;
- sNuJpegQTab.u8num = u8num;
- sNuJpegIoctl.arg0 = (UINT32)&sNuJpegQTab;
- sNuJpegIoctl.arg1 = (UINT32)&ret;
- rt_device_control(&g_sNuJpeg.dev, JPEG_IOCTL_SET_QTAB, (void *)&sNuJpegIoctl);
- return ret;
- }
- /// @endcond HIDDEN_SYMBOLS
- /** @addtogroup N9H30_JPEG_EXPORTED_FUNCTIONS JPEG Exported Functions
- @{
- */
- /**
- * @brief The function is used to initial device parameters and register.
- *
- * @return 0
- */
- static VOID _jpegInit(void)
- {
- /* Set the default values of the JPEG registers */
- g_bScale = FALSE;
- g_u32Stride = 0;
- g_u32BufferCount = 0;
- g_u16ReserveSize = 0;
- g_u32WindowDec = FALSE;
- g_u32windowSizeX = 0;
- g_u32windowSizeY = 0;
- g_InputWait = FALSE;
- g_bEncThumbnailDownScale = FALSE;
- g_bEncPrimaryDownScale = FALSE;
- g_OutputWait = FALSE;
- g_u32EncRotate = 0;
- pfnJpegHeaderDecode = NULL;
- pfnJpegDecInputWait = NULL;
- pfnJpegDecOutputWait = NULL;
- outp32(REG_JPRIQC, 0x000000F4);
- outp32(REG_JTHBQC, 0x000000F4);
- outp32(REG_JPRST, 0x00000004);
- outp32(REG_JTRST, 0x00000004);
- outp32(REG_JITCR, 0x00000000);
- outp32(REG_JINTCR, 0x00000000);
- outp32(JDOWFBS, 0xFFFFFFFF);
- // Disable the Primary Up-scaling & Scaling-down
- outp32(REG_JPSCALU, 0x00000000);
- outp32(REG_JPSCALD, 0x00000000);
- // Reset JUPRAT and JSRCH
- outp32(REG_JUPRAT, 0x00000000);
- outp32(REG_JSRCH, 0x00000FFF);
- //-------------------------------------------
- /* Reset JPEG (JMCR [1]) */
- outp32(REG_JMCR, 0x00000002);
- outp32(REG_JMCR, 0x00000000);
- outp32(REG_JMACR, 0x00400000); //Can't use single buffer
- }
- VOID jpegInit(void)
- {
- rt_device_control(&g_sNuJpeg.dev, JPEG_IOCTL_INITIAL_CODEC, (void *)RT_NULL);
- }
- /**
- * @brief The function is used to check JPEG engine not busy.
- *
- * @return TRUE: JPEG engine busy \n
- * FALSE: JPEG engine not busy
- */
- static BOOL _jpegIsReady(void)
- {
- if (g_bWait == FALSE)
- return TRUE;
- else
- return FALSE;
- }
- BOOL jpegIsReady(void)
- {
- UINT32 u32IsReady = 0;
- struct nu_jpeg_ioctl sNuJpegIoctl = {0};
- sNuJpegIoctl.arg0 = (UINT32)&u32IsReady;
- rt_device_control(&g_sNuJpeg.dev, JPEG_IOCTL_IS_READY, (void *)&sNuJpegIoctl);
- return (BOOL)u32IsReady;
- }
- /**
- * @brief The function is used to get JPEG information.
- *
- * @param[out] *info: JPEG encode/decode information.
- *
- * @return 0
- */
- static VOID _jpegGetInfo(JPEG_INFO_T *info)
- {
- rt_memcpy(info, &jpegInfo, sizeof(JPEG_INFO_T));
- }
- VOID jpegGetInfo(JPEG_INFO_T *info)
- {
- struct nu_jpeg_ioctl sNuJpegIoctl = {0};
- sNuJpegIoctl.arg0 = (UINT32)info;
- rt_device_control(&g_sNuJpeg.dev, JPEG_IOCTL_GET_INFO, (void *)&sNuJpegIoctl);
- }
- /**
- * @brief The function is used to wait JPEG engine, until JPEG engine not busy.
- *
- * @return E_SUCCESS: JPEG engine encode/decode complete \n
- * FALSE: JPEG engine error
- */
- static INT _jpegWait(void)
- {
- while (1)
- {
- if (g_bWait == FALSE)
- break;
- }
- if (g_jpegError)
- return E_FAIL;
- return E_SUCCESS;
- }
- INT jpegWait(void)
- {
- INT ret = 0;
- struct nu_jpeg_ioctl sNuJpegIoctl;
- sNuJpegIoctl.arg0 = (UINT32)&ret;
- sNuJpegIoctl.arg1 = 0;
- rt_device_control(&g_sNuJpeg.dev, JPEG_IOCTL_WAITDONE, (void *)&sNuJpegIoctl);
- return ret;
- }
- /**
- * @brief The function is used to config and reset JPEG IP.
- *
- * @return E_SUCCESS: success
- */
- INT jpegOpen(void)
- {
- return (rt_device_open(&g_sNuJpeg.dev, RT_DEVICE_FLAG_RDWR) == RT_EOK) ? E_SUCCESS : E_FAIL;
- }
- /**
- * @brief Support some JPEG driver commands for application.
- *
- * @param[in] cmd: Command.
- *
- * @param[in] arg0: Arguments for the command.
- *
- * @param[in] arg1: Arguments for the command.
- *
- * @return 0
- *
- */
- VOID jpegIoctl(UINT32 cmd, UINT32 arg0, UINT32 arg1)
- {
- struct nu_jpeg_ioctl sNuJpegIoctl;
- sNuJpegIoctl.arg0 = arg0;
- sNuJpegIoctl.arg1 = arg1;
- rt_device_control(&g_sNuJpeg.dev, cmd, (void *)&sNuJpegIoctl);
- }
- /**
- * @brief JPEG function close.
- *
- * @return 0
- *
- */
- VOID jpegClose(void)
- {
- rt_device_close(&g_sNuJpeg.dev);
- }
- static rt_err_t nu_jpeg_init(rt_device_t dev)
- {
- UINT32 u32JPGDiv = 0;
- UINT32 u32JPGSource;
- UINT32 u32HclkHz;
- nu_jpeg_t psNuJpeg = (nu_jpeg_t)dev;
- RT_ASSERT(dev != RT_NULL);
- /* Set JPEG engine clock */
- u32HclkHz = sysGetClock(SYS_HCLK234) * 1000000;
- u32JPGSource = u32HclkHz / (((inp32(REG_CLK_DIVCTL3) & 0xf0000000) >> 28) + 1);
- if (u32JPGSource > 75000000)
- {
- if (u32JPGSource % 75000000)
- {
- u32JPGDiv = (u32JPGSource / 75000000);
- }
- else
- u32JPGDiv = (u32JPGSource / 75000000) - 1;
- }
- outp32(REG_CLK_DIVCTL3, (inp32(REG_CLK_DIVCTL3) & ~(0xf0000000)) | ((u32JPGDiv & 0xf) << 28));
- rt_kprintf("JPEG Engine clock frequency is %d MHz\n", u32JPGSource / (u32JPGDiv + 1) / 1000000);
- /* Register ISR and Response JPEG Interrupt. */
- rt_hw_interrupt_install(psNuJpeg->irqn, nu_jpeg_isr, (void *)psNuJpeg, psNuJpeg->name);
- rt_hw_interrupt_umask(psNuJpeg->irqn);
- return RT_EOK;
- }
- static rt_err_t nu_jpeg_open(rt_device_t dev, rt_uint16_t oflag)
- {
- rt_err_t result;
- nu_jpeg_t psNuJpeg = (nu_jpeg_t)dev;
- result = rt_mutex_take(&psNuJpeg->lock, RT_WAITING_FOREVER);
- RT_ASSERT(result == RT_EOK);
- /* Enable JPEG engine clock */
- nu_sys_ipclk_enable(psNuJpeg->clkidx);
- /* Reset JPEG codec and internal variables. */
- nu_sys_ip_reset(psNuJpeg->rstidx);
- jpegInit();
- result = rt_mutex_release(&psNuJpeg->lock);
- RT_ASSERT(result == RT_EOK);
- return RT_EOK;
- }
- static rt_err_t nu_jpeg_close(rt_device_t dev)
- {
- rt_err_t result;
- nu_jpeg_t psNuJpeg = (nu_jpeg_t)dev;
- RT_ASSERT(dev != RT_NULL);
- result = rt_mutex_take(&psNuJpeg->lock, RT_WAITING_FOREVER);
- RT_ASSERT(result == RT_EOK);
- /* Reset JPEG (JMCR [1]) */
- outp32(REG_JMCR, 0x00000002);
- outp32(REG_JMCR, 0x00000000);
- /* Disable JPEG engine clock */
- nu_sys_ipclk_disable(psNuJpeg->clkidx);
- result = rt_mutex_release(&psNuJpeg->lock);
- RT_ASSERT(result == RT_EOK);
- return RT_EOK;
- }
- static rt_err_t nu_jpeg_control(rt_device_t dev, int cmd, void *args)
- {
- JPEG_WINDOW_DECODE_T *winDecode;
- PUINT32 pu32Tmp;
- UINT32 arg0 = 0, arg1 = 0;
- rt_err_t result;
- nu_jpeg_t psNuJpeg = (nu_jpeg_t)dev;
- nu_jpeg_ioctl_t psNuJpegIoctl = (nu_jpeg_ioctl_t)args;
- RT_ASSERT(dev != RT_NULL);
- result = rt_mutex_take(&psNuJpeg->lock, RT_WAITING_FOREVER);
- RT_ASSERT(result == RT_EOK);
- if (psNuJpegIoctl != RT_NULL)
- {
- arg0 = psNuJpegIoctl->arg0;
- arg1 = psNuJpegIoctl->arg1;
- }
- switch (cmd)
- {
- case JPEG_IOCTL_SET_YADDR:
- JPEG_SET_YADDR(arg0);
- break;
- case JPEG_IOCTL_SET_UADDR:
- JPEG_SET_UADDR(arg0);
- break;
- case JPEG_IOCTL_SET_VADDR:
- JPEG_SET_VADDR(arg0);
- break;
- case JPEG_IOCTL_SET_YSTRIDE:
- JPEG_SET_YSTRIDE(arg0);
- break;
- case JPEG_IOCTL_SET_USTRIDE:
- JPEG_SET_USTRIDE(arg0);
- break;
- case JPEG_IOCTL_SET_VSTRIDE:
- JPEG_SET_VSTRIDE(arg0);
- break;
- case JPEG_IOCTL_SET_BITSTREAM_ADDR:
- JPEG_SET_BITSTREAM_ADDR(arg0);
- break;
- case JPEG_IOCTL_SET_SOURCE_IMAGE_HEIGHT:
- JPEG_SET_SOURCE_IMAGE_HEIGHT(arg0);
- break;
- case JPEG_IOCTL_ENC_SET_HEADER_CONTROL:
- JPEG_ENC_SET_HEADER_CONTROL(arg0);
- break;
- case JPEG_IOCTL_SET_DEFAULT_QTAB:
- jpegSetQTAB(g_au8QTable0, g_au8QTable1, 0, 2);
- break;
- case JPEG_IOCTL_SET_DECODE_MODE:
- jpegSetDecodeMode(arg0);
- break;
- case JPEG_IOCTL_SET_ENCODE_MODE:
- jpegSetEncodeMode(arg0, arg1);
- break;
- case JPEG_IOCTL_SET_DIMENSION:
- jpegSetDimension(arg0, arg1);
- break;
- case JPEG_IOCTL_ENCODE_TRIGGER:
- jpegEncodeTrigger();
- if (g_u16ReserveSize != 0)
- {
- UINT32 u32Addr = JPEG_GET_BITSTREAM_ADDR();
- outp8(u32Addr + 2, 0xFF);
- outp8(u32Addr + 3, 0xE0);
- outp8(u32Addr + 4, ((g_u16ReserveSize - 4) & 0xFF00) >> 8);
- outp8(u32Addr + 5, (g_u16ReserveSize - 4) & 0xFF);
- }
- break;
- case JPEG_IOCTL_DECODE_TRIGGER:
- jpegDecodeTrigger();
- break;
- case JPEG_IOCTL_WINDOW_DECODE:
- winDecode = (JPEG_WINDOW_DECODE_T *)arg0;
- jpegSetWindowDecode(winDecode->u16StartMCUX, winDecode->u16StartMCUY,
- winDecode->u16EndMCUX, winDecode->u16EndMCUY, winDecode->u32Stride);
- g_u32WindowDec = TRUE;
- g_u32windowSizeX = winDecode->u32Stride;
- g_u32windowSizeY = 16 * (winDecode->u16EndMCUY - winDecode->u16StartMCUY + 1);
- break;
- case JPEG_IOCTL_SET_DECODE_STRIDE:
- g_u32Stride = arg0;
- break;
- case JPEG_IOCTL_SET_DECODE_DOWNSCALE:
- g_bScale = TRUE;
- g_u32ScaleWidth = arg1;
- g_u32ScaleHeight = arg0;
- break;
- case JPEG_IOCTL_SET_ENCODE_UPSCALE:
- g_bScale = TRUE;
- g_u32ScaleWidth = arg1;
- g_u32ScaleHeight = arg0;
- break;
- case JPEG_IOCTL_SET_HEADERDECODE_CALBACKFUN:
- pfnJpegHeaderDecode = (PFN_JPEG_HEADERDECODE_CALLBACK) arg0;
- break;
- case JPEG_IOCTL_SET_DECINPUTWAIT_CALBACKFUN:
- g_InputWait = TRUE;
- pfnJpegDecInputWait = (PFN_JPEG_DECWAIT_CALLBACK) arg0;
- JPEG_DEC_SET_INPUT_WAIT(((UINT16) arg1 / 2048));
- g_u16BufferSize = arg1 / 2;
- break;
- case JPEG_IOCTL_ADJUST_QTAB:
- jpegAdjustQTAB(arg0, ((arg1 & 0xFF00) >> 4), (arg1 & 0xFF));
- break;
- case JPEG_IOCTL_ENC_RESERVED_FOR_SOFTWARE:
- if (arg0 > 0)
- {
- UINT32 u32Tmp;
- u32Tmp = arg0 + 4;
- if (u32Tmp % 2)
- u32Tmp++;
- if ((u32Tmp % 4) == 0)
- u32Tmp += 2;
- if (u32Tmp >= 0xFFFF)
- u32Tmp = 65534;
- outp32(REG_JPSCALU, inp32(REG_JPSCALU) | A_JUMP);
- outp32(JRESERVE, u32Tmp);
- g_u16ReserveSize = u32Tmp;
- }
- break;
- case JPEG_IOCTL_SET_ENCODE_PRIMARY_RESTART_INTERVAL:
- outp32(REG_JPRST, arg0);
- break;
- case JPEG_IOCTL_SET_ENCODE_THUMBNAIL_RESTART_INTERVAL:
- outp32(REG_JTRST, arg0);
- break;
- case JPEG_IOCTL_GET_ENCODE_PRIMARY_RESTART_INTERVAL:
- pu32Tmp = (PUINT32) arg0;
- *pu32Tmp = inp32(REG_JPRST);
- break;
- case JPEG_IOCTL_GET_ENCODE_THUMBNAIL_RESTART_INTERVAL:
- pu32Tmp = (PUINT32) arg0;
- *pu32Tmp = inp32(REG_JTRST);
- break;
- case JPEG_IOCTL_SET_THUMBNAIL_DIMENSION:
- outp32(REG_JTHBWH, ((arg0 & 0x1FFF) << 16) | (arg1 & 0x1FFF));
- break;
- case JPEG_IOCTL_SET_ENCODE_SW_OFFSET:
- outp32(REG_JOFFSET, arg0);
- break;
- case JPEG_IOCTL_GET_THUMBNAIL_DIMENSION:
- pu32Tmp = (PUINT32) arg0;
- *pu32Tmp = inp32(REG_JTHBWH) >> 16;
- pu32Tmp = (PUINT32) arg1;
- *pu32Tmp = inp32(REG_JTHBWH) & 0x1FFF;
- break;
- case JPEG_IOCTL_GET_ENCODE_SW_OFFSET:
- pu32Tmp = (PUINT32) arg0;
- *pu32Tmp = inp32(REG_JOFFSET);
- break;
- case JPEG_IOCTL_SET_ENCODE_PRIMARY_DOWNSCALE:
- g_bScale = TRUE;
- g_bEncPrimaryDownScale = TRUE;
- g_u32ScaleWidth = arg1;
- g_u32ScaleHeight = arg0;
- break;
- case JPEG_IOCTL_SET_ENCODE_THUMBNAIL_DOWNSCALE:
- g_bScale = TRUE;
- g_bEncThumbnailDownScale = TRUE;
- g_u32ScaleWidth = arg1;
- g_u32ScaleHeight = arg0;
- break;
- case JPEG_IOCTL_SET_ENCODE_PRIMARY_ROTATE_RIGHT:
- g_u32EncRotate = JPEG_IOCTL_SET_ENCODE_PRIMARY_ROTATE_RIGHT;
- outp32(REG_JITCR, (inp32(REG_JITCR) & ~ROTATE) | ROTATE);
- break;
- case JPEG_IOCTL_SET_ENCODE_PRIMARY_ROTATE_LEFT:
- g_u32EncRotate = JPEG_IOCTL_SET_ENCODE_PRIMARY_ROTATE_LEFT;
- outp32(REG_JITCR, (inp32(REG_JITCR) & ~ROTATE) | 0x1000);
- break;
- case JPEG_IOCTL_SET_ENCODE_PRIMARY_ROTATE_NORMAL:
- g_u32EncRotate = 0;
- outp32(REG_JITCR, (inp32(REG_JITCR) & ~ROTATE));
- break;
- case JPEG_IOCTL_SET_DECOUTPUTWAIT_CALBACKFUN:
- pfnJpegDecOutputWait = (PFN_JPEG_DECWAIT_CALLBACK) arg0;
- break;
- case JPEG_IOCTL_SET_DECOUTPUTWAIT:
- outp32(JYADDR0, arg0);
- outp32(JDOWFBS, arg1);
- g_OutputWait = TRUE;
- break;
- case JPEG_IOCTL_GET_DECOUTPUTWAIT_ADDR:
- pu32Tmp = (PUINT32) arg0;
- *pu32Tmp = inp32(JYADDR0);
- break;
- case JPEG_IOCTL_GET_DECOUTPUTWAIT_SIZE:
- pu32Tmp = (PUINT32) arg0;
- *pu32Tmp = inp32(JDOWFBS);
- break;
- case JPEG_IOCTL_SET_DECODE_COMPLETE_CALBACKFUN:
- pfnJpegDecodeComplete = (PFN_JPEG_CALLBACK) arg0;
- break;
- case JPEG_IOCTL_SET_ENCODE_COMPLETE_CALBACKFUN:
- pfnJpegEncodeComplete = (PFN_JPEG_CALLBACK) arg0;
- break;
- case JPEG_IOCTL_SET_DECODE_ERROR_CALBACKFUN:
- pfnJpegDecodeError = (PFN_JPEG_CALLBACK) arg0;
- break;
- /* Extended IOCTL command */
- case JPEG_IOCTL_SET_QTAB:
- {
- nu_jpeg_qtab_t psJpegQtab = (nu_jpeg_qtab_t)arg0;
- INT *pi32ret = (INT *)arg1;
- *pi32ret = _jpegSetQTAB(psJpegQtab->puQTable0, psJpegQtab->puQTable1, psJpegQtab->puQTable2, psJpegQtab->u8num);
- }
- break;
- case JPEG_IOCTL_INITIAL_CODEC:
- _jpegInit();
- break;
- case JPEG_IOCTL_GET_INFO:
- _jpegGetInfo((JPEG_INFO_T *)arg0);
- break;
- case JPEG_IOCTL_IS_READY:
- {
- UINT32 *pu32ret = (UINT32 *)arg0;
- *pu32ret = _jpegIsReady();
- }
- break;
- case JPEG_IOCTL_WAITDONE:
- {
- INT *pi32ret = (INT *)arg0;
- *pi32ret = _jpegWait();
- }
- break;
- default:
- break;
- }
- result = rt_mutex_release(&psNuJpeg->lock);
- RT_ASSERT(result == RT_EOK);
- return RT_EOK;
- }
- /* Hardward JPEG codec init */
- static int rt_hw_jpeg_init(void)
- {
- rt_err_t ret = RT_EOK;
- /* Register sdcard device */
- g_sNuJpeg.dev.type = RT_Device_Class_Miscellaneous;
- g_sNuJpeg.dev.init = nu_jpeg_init;
- g_sNuJpeg.dev.open = nu_jpeg_open;
- g_sNuJpeg.dev.close = nu_jpeg_close;
- g_sNuJpeg.dev.read = RT_NULL;
- g_sNuJpeg.dev.write = RT_NULL;
- g_sNuJpeg.dev.control = nu_jpeg_control;
- /* Private */
- g_sNuJpeg.dev.user_data = (void *)&g_sNuJpeg;
- ret = rt_mutex_init(&g_sNuJpeg.lock, "jpeg_lock", RT_IPC_FLAG_PRIO);
- RT_ASSERT(ret == RT_EOK);
- /* Only support single opening. */
- ret = rt_device_register(&g_sNuJpeg.dev, g_sNuJpeg.name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
- RT_ASSERT(ret == RT_EOK);
- return (int)ret;
- }
- INIT_DEVICE_EXPORT(rt_hw_jpeg_init);
|