/*****************************************************************************
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();
		}
	}
}
Пример #4
0
//------------------------------------------------------------------------------
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;    
}
Пример #5
0
//------------------------------------------------------------------------------
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;    
}