/***************************************************************************** Name: GotoAddress Parameters: x Line number for display y Column number for display controller [1,2, 3(both)] Returns: none Description: This function controls LCD writes to line 1 or 2 of the LCD. *****************************************************************************/ void GotoAddress(char mLine, char mColumn) { BYTE controller=1; // Control at max values: if (mLine > 0x07) mLine = 0x07; if (mColumn > 127) mColumn = 127; x_address = mLine; y_address = mColumn; if (mColumn < 64) controller=1; else controller=2; if (mColumn > 63) mColumn -= 64; LCD_write(CTRL, SET_X_ADDRESS+mLine, controller); WaitForNotBusy(controller); LCD_write(CTRL, SET_Y_ADDRESS+mColumn, controller); WaitForNotBusy(controller); }
/***************************************************************************** Name: InitDisplay Parameters: none Returns: none Description: Intializes the LCD display. *****************************************************************************/ void LCD_display_init( void ) { // initial port directions LCD_Port_Drive(); CS1_PIN = SELECTED; // Preset Values CS2_PIN = SELECTED; EN_PIN = HIGH; RW_PIN = WRITE; DI_PIN = HIGH; BACKLIGHT_PIN = LOW; CS1_PIN_DDR |= DRIVE; // Data Direction Control lines. CS2_PIN_DDR |= DRIVE; EN_PIN_DDR |= DRIVE; RW_PIN_DDR |= DRIVE; DI_PIN_DDR |= DRIVE; RESET_PIN_DDR |= DRIVE; prc2=1; // unprotect as Port 9 is used BACKLIGHT_PIN_DDR = OUTPUT; // RESET LCD EN_PIN = LOW; RESET_PIN = ASSERT; DisplayDelay(4); RESET_PIN = UNASSERTED; DisplayDelay(4); WaitForNotBusy(1); // INITIALIZE REGISTERS: GotoAddress( 0,0 ); // x=0; y=0; LCD_write(CTRL,SET_DISPLAY_START+0x00, BOTH ); WaitForNotBusy(1); LCD_write(CTRL,DISPLAY_ON ,BOTH); BACKLIGHT_PIN = LOW; // BACKLIGHT_PIN = HIGH; }
/***************************************************************************** Name: LCD_write Parameters: value - the value to write data_or_ctrl - To write value as DATA or CONTROL 1 = DATA 0 = CONTROL Returns: none Description: Writes data to display. Sends command to display. *****************************************************************************/ void LCD_write(unsigned char data_or_ctrl, unsigned char value, unsigned char controller) { int shifted = 0; // To correct for hardware wiring error, // data must be shifted right once. if ((data_or_ctrl == DATA) && (controller != BOTH)) { // roll over to controller 2 if necessary: if (y_address > 63) controller = 2; if (y_address == 64) { LCD_write(CTRL, SET_X_ADDRESS+x_address, 2); WaitForNotBusy(2); LCD_write(CTRL, SET_Y_ADDRESS+0, 2); WaitForNotBusy(2); } } // disable Interrupts. We don't want data bus being // a) written. b) DDR changed. c) ctrl lines DISABLE_IRQ LCD_Port_Drive(); EN_PIN = LOW; // Prepare cycle RW_PIN = WRITE; // Setup Read Write DI_PIN = data_or_ctrl; // Data/Instruction SELECT (HIGH=DATA, LOW=CTRL) if (controller == 1) { CS1_PIN = SELECTED; // Chip Select Lines CS2_PIN = UNSELECTED; } else if (controller == 2) { CS1_PIN = UNSELECTED; CS2_PIN = SELECTED; // Chip Select Lines } else if (controller == 3) { CS1_PIN = SELECTED; // Both CS2_PIN = SELECTED; // } LCD_Remap_n_Send_Data(value); DisplayDelay(0); // We only need a very little delay EN_PIN = HIGH; // EN enable chip (HIGH) DisplayDelay(0); // We only need a very little delay EN_PIN = LOW; // Latch data by dropping EN // Re-enable Interrupts ENABLE_IRQ if(data_or_ctrl == DATA) { y_address++; if (y_address > 127) { x_address++; if (x_address > 7) x_address=0; controller = 1; y_address = 0; LCD_SendAddresses(); } } }
//------------------------------------------------------------------------------ SCODE OMAPDDGPE::DMAFill( GPEBltParms* pParms ) { SCODE result = S_OK; RECTL* prclDst = pParms->prclDst; DWORD dwWidth = prclDst->right - prclDst->left; DWORD dwHeight = prclDst->bottom - prclDst->top; DWORD dwStride = pParms->pDst->Stride(); DWORD dwOffset = 0; OMAPDDGPESurface* pOmapSurf = (OMAPDDGPESurface*) pParms->pDst; DmaConfigInfo_t DmaSettings = { 0, // elemSize 1, // srcElemIndex 1, // srcFrameIndex DMA_CCR_SRC_AMODE_CONST, // srcAddrMode 1, // dstElemIndex 1, // dstFrameIndex DMA_CCR_DST_AMODE_DOUBLE, // dstAddrMode FALSE, // dmaPrio DMA_SYNCH_TRIGGER_NONE, // synchTrigger DMA_SYNCH_NONE, // synchMode 0, // interrupts 0 // syncMap }; // Check that a DMA Blt is worth doing if( dwWidth < MIN_DMA_WIDTH || dwHeight < MIN_DMA_HEIGHT ) { if (g_Globals.m_dwEnableNeonBlts) { pParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &OMAPDDGPE::DesignateBlt; return OMAPDDGPE::DesignateBlt(pParms); } else { pParms->pBlt = &GPE::EmulatedBlt; return GPE::EmulatedBlt(pParms); } } // Allocate DMA channel if( g_hDmaChannel1 == NULL ) { g_hDmaChannel1 = DmaAllocateChannel(DMA_TYPE_SYSTEM); InitializeCriticalSection( &g_csDmaLock ); } // Lock access to DMA registers EnterCriticalSection( &g_csDmaLock ); // Wait for any pending operations to complete WaitForNotBusy(); // Configure DMA channel for FILL operation switch( pParms->pDst->BytesPerPixel() ) { case 1: DmaSettings.elemSize = DMA_CSDP_DATATYPE_S8; DmaSettings.dstFrameIndex = 1 + dwStride - dwWidth; dwOffset = prclDst->top * dwStride + prclDst->left; break; case 2: DmaSettings.elemSize = DMA_CSDP_DATATYPE_S16; DmaSettings.dstFrameIndex = 1 + dwStride - 2*dwWidth; dwOffset = prclDst->top * dwStride + 2 * prclDst->left; break; case 4: DmaSettings.elemSize = DMA_CSDP_DATATYPE_S32; DmaSettings.dstFrameIndex = 1 + dwStride - 4*dwWidth; dwOffset = prclDst->top * dwStride + 4 * prclDst->left; break; } // Clear any clipping rect for the operation pOmapSurf->OmapSurface()->SetClipping( NULL ); // Enable bursting for improved memory performance DmaSettings.elemSize |= DMA_CSDP_DST_BURST_64BYTES_16x32_8x64 | DMA_CSDP_DST_PACKED; // Configure the DMA channel DmaConfigure( g_hDmaChannel1, &DmaSettings, 0, &g_tDmaDataInfo1 ); DmaSetColor( &g_tDmaDataInfo1, DMA_CCR_CONST_FILL_ENABLE, (DWORD)pParms->solidColor ); DmaSetSrcBuffer( &g_tDmaDataInfo1, NULL, 0 ); DmaSetDstBuffer( &g_tDmaDataInfo1, NULL, pOmapSurf->OmapSurface()->PhysicalAddr() + dwOffset ); DmaSetElementAndFrameCount( &g_tDmaDataInfo1, dwWidth, (UINT16) dwHeight ); // Start the DMA operation DmaStart( &g_tDmaDataInfo1 ); // Unlock access to DMA registers LeaveCriticalSection( &g_csDmaLock ); return result; }
//------------------------------------------------------------------------------ SCODE OMAPDDGPE::DMASrcCopy( GPEBltParms* pParms ) { SCODE result = S_OK; BOOL bDualDMA = FALSE; RECTL* prclSrc = pParms->prclSrc; RECTL* prclDst = pParms->prclDst; DWORD dwPixelSize = pParms->pDst->BytesPerPixel(); DWORD dwWidth = prclDst->right - prclDst->left; DWORD dwHeight = prclDst->bottom - prclDst->top; DWORD dwSrcStride = pParms->pSrc->Stride(); DWORD dwDstStride = pParms->pDst->Stride(); DWORD dwSrcOffset = 0; DWORD dwDstOffset = 0; DWORD dwSrcMidpoint = 0; DWORD dwDstMidpoint = 0; DWORD dwWidth1 = dwWidth, dwWidth2 = dwWidth; DWORD dwHeight1 = dwHeight, dwHeight2 = dwHeight; OMAPDDGPESurface* pOmapSrcSurf = (OMAPDDGPESurface*) pParms->pSrc; OMAPDDGPESurface* pOmapDstSurf = (OMAPDDGPESurface*) pParms->pDst; DmaConfigInfo_t DmaSettings = { 0, // elemSize 1, // srcElemIndex 1, // srcFrameIndex DMA_CCR_SRC_AMODE_DOUBLE, // srcAddrMode 1, // dstElemIndex 1, // dstFrameIndex DMA_CCR_DST_AMODE_DOUBLE, // dstAddrMode FALSE, // dmaPrio DMA_SYNCH_TRIGGER_NONE, // synchTrigger DMA_SYNCH_NONE, // synchMode 0, // interrupts 0 // syncMap }; // Check that a DMA Blt is worth doing if( dwWidth < MIN_DMA_WIDTH || dwHeight < MIN_DMA_HEIGHT ) { if (g_Globals.m_dwEnableNeonBlts) { pParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &OMAPDDGPE::DesignateBlt; return OMAPDDGPE::DesignateBlt(pParms); } else { pParms->pBlt = &GPE::EmulatedBlt; return GPE::EmulatedBlt(pParms); } } // Allocate DMA channels if( g_hDmaChannel1 == NULL ) { g_hDmaChannel1 = DmaAllocateChannel(DMA_TYPE_SYSTEM); InitializeCriticalSection( &g_csDmaLock ); } if( g_hDmaChannel2 == NULL ) { g_hDmaChannel2 = DmaAllocateChannel(DMA_TYPE_SYSTEM); } // Lock access to DMA registers EnterCriticalSection( &g_csDmaLock ); // Wait for any pending operations to complete WaitForNotBusy(); // Configure DMA channel for SRCCPY operation switch( pParms->pDst->BytesPerPixel() ) { case 1: DmaSettings.elemSize = DMA_CSDP_DATATYPE_S8; break; case 2: DmaSettings.elemSize = DMA_CSDP_DATATYPE_S16; break; case 4: DmaSettings.elemSize = DMA_CSDP_DATATYPE_S32; break; } // Compute element indexing, frame indexing and starting offset for both surfaces // Note that both xPos and yPos will never be both < 0 // Also note that xPos !=1 prevents bursting and actually slows DMA down below memcpy speeds if( pParms->xPositive ) { // Index x axis in positive direction (left to right) DmaSettings.srcElemIndex = 1; DmaSettings.dstElemIndex = 1; // Offset from left side of surface dwSrcOffset = dwPixelSize * prclSrc->left; dwDstOffset = dwPixelSize * prclDst->left; } else { // Index x axis in negative direction (right to left) DmaSettings.srcElemIndex = 1 - 2*dwPixelSize; DmaSettings.dstElemIndex = 1 - 2*dwPixelSize; // Offset from right side of surface dwSrcOffset = dwPixelSize * (prclSrc->right - 1); dwDstOffset = dwPixelSize * (prclDst->right - 1); } if( pParms->yPositive ) { // Index y axis in positive direction (top to bottom) DmaSettings.srcFrameIndex = DmaSettings.srcElemIndex + dwSrcStride; DmaSettings.dstFrameIndex = DmaSettings.dstElemIndex + dwDstStride; if( pParms->xPositive ) { DmaSettings.srcFrameIndex -= dwWidth*dwPixelSize; DmaSettings.dstFrameIndex -= dwWidth*dwPixelSize; } else { DmaSettings.srcFrameIndex += dwWidth*dwPixelSize; DmaSettings.dstFrameIndex += dwWidth*dwPixelSize; } // Offset from top side of surface dwSrcOffset = dwSrcOffset + prclSrc->top * dwSrcStride; dwDstOffset = dwDstOffset + prclDst->top * dwDstStride; } else { // Index y axis in negative direction (bottom to top) DmaSettings.srcFrameIndex = DmaSettings.srcElemIndex - dwSrcStride; DmaSettings.dstFrameIndex = DmaSettings.dstElemIndex - dwDstStride; if( pParms->xPositive ) { DmaSettings.srcFrameIndex -= dwWidth*dwPixelSize; DmaSettings.dstFrameIndex -= dwWidth*dwPixelSize; } else { DmaSettings.srcFrameIndex += dwWidth*dwPixelSize; DmaSettings.dstFrameIndex += dwWidth*dwPixelSize; } // Offset from bottom side of surface dwSrcOffset = dwSrcOffset + (prclSrc->bottom - 1) * dwSrcStride; dwDstOffset = dwDstOffset + (prclDst->bottom - 1) * dwDstStride; } // // Check for fast dual DMA cases // // Different src and dst surfaces can use dual DMA if( pOmapSrcSurf != pOmapDstSurf ) { // Split work in half vertically dwHeight1 = dwHeight/2; dwHeight2 = dwHeight - dwHeight1; dwSrcMidpoint = (pParms->yPositive) ? dwSrcOffset + dwHeight1*dwSrcStride : dwSrcOffset - dwHeight1*dwSrcStride; dwDstMidpoint = (pParms->yPositive) ? dwDstOffset + dwHeight1*dwDstStride : dwDstOffset - dwHeight1*dwDstStride; bDualDMA = TRUE; } // Clear any clipping rect for the operation pOmapSrcSurf->OmapSurface()->SetClipping( NULL ); pOmapDstSurf->OmapSurface()->SetClipping( NULL ); // Enable bursting for improved memory performance DmaSettings.elemSize |= DMA_CSDP_SRC_BURST_64BYTES_16x32_8x64 | DMA_CSDP_SRC_PACKED; DmaSettings.elemSize |= DMA_CSDP_DST_BURST_64BYTES_16x32_8x64 | DMA_CSDP_DST_PACKED; // Configure the DMA channel DmaConfigure( g_hDmaChannel1, &DmaSettings, 0, &g_tDmaDataInfo1 ); DmaSetSrcBuffer( &g_tDmaDataInfo1, NULL, pOmapSrcSurf->OmapSurface()->PhysicalAddr() + dwSrcOffset ); DmaSetDstBuffer( &g_tDmaDataInfo1, NULL, pOmapDstSurf->OmapSurface()->PhysicalAddr() + dwDstOffset ); DmaSetElementAndFrameCount( &g_tDmaDataInfo1, dwWidth1, (UINT16) dwHeight1); if( bDualDMA ) { DmaConfigure( g_hDmaChannel2, &DmaSettings, 0, &g_tDmaDataInfo2 ); DmaSetSrcBuffer( &g_tDmaDataInfo2, NULL, pOmapSrcSurf->OmapSurface()->PhysicalAddr() + dwSrcMidpoint ); DmaSetDstBuffer( &g_tDmaDataInfo2, NULL, pOmapDstSurf->OmapSurface()->PhysicalAddr() + dwDstMidpoint ); DmaSetElementAndFrameCount( &g_tDmaDataInfo2, dwWidth2, (UINT16) dwHeight2 ); } // Configure for transparent copy if requested if( pParms->bltFlags & BLT_TRANSPARENT ) { DmaSetColor( &g_tDmaDataInfo1, DMA_CCR_TRANSPARENT_COPY_ENABLE, (DWORD)pParms->solidColor ); if( bDualDMA ) DmaSetColor( &g_tDmaDataInfo2, DMA_CCR_TRANSPARENT_COPY_ENABLE, (DWORD)pParms->solidColor ); } // Start the DMA operation(s) DmaStart( &g_tDmaDataInfo1 ); if( bDualDMA ) DmaStart( &g_tDmaDataInfo2 ); // Unlock access to DMA registers LeaveCriticalSection( &g_csDmaLock ); return result; }