📄 adc_init.c
字号:
//------------------------------------------------------------------------------
//
// Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//
// File: adc_init.c
//
// Init IPU for ADC operations
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <ceddk.h>
#include "bsp.h"
#include "adc_init.h"
#include "di_init.h"
//------------------------------------------------------------------------------
// External Functions
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
// Defines
#define ADC_ERROR DEBUGZONE(0)
#define MUTEX_WAITING_TIME 10000
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// Global Variables
PCSP_IPU_REGS g_pIPU;
//------------------------------------------------------------------------------
// Local Variables
static HANDLE ipu_mutex;
static BOOL need_map = TRUE;
//------------------------------------------------------------------------------
// Local Functions
static void _create_template(TEMPLATE_CMD_REG *pCmd,
unsigned int SPage,
unsigned int EPage,
unsigned int SCol,
unsigned int ECol,
unsigned int Format,
BOOL Write);
static void _program_template(TEMPLATE_CMD_REG * pCmd,
unsigned int Display,
BOOL Write);
static void _setup_channel(BOOL Enabled, unsigned int Display,
unsigned int StartAddr, unsigned int Ch,
unsigned int Mode, BOOL Write, BOOL b24Bit);
static void _setup_display(unsigned int display, unsigned int sl,
unsigned int disp_type, unsigned int data_width,
unsigned int data_map);
static void _init_adc_dma(int width, int height, int bpp);
//------------------------------------------------------------------------------
//
// Function: InitializeADC
//
// This function initializes ADC related bits in IPU common registers, the
// IPU ADC registers and IDMAC registers for ADC operation.
//
// Parameters:
// none
//
// Returns:
// TRUE if successful.
//------------------------------------------------------------------------------
UINT32 InitializeADC(int width, int height, int bpp)
{
UINT32 ret = FALSE;
PHYSICAL_ADDRESS phyAddr;
TEMPLATE_CMD_REG Cmd[TEMPLATE_BUF_SIZE];
if (need_map == TRUE)
{
phyAddr.QuadPart = CSP_BASE_REG_PA_IPU;
// Map peripheral physical address to virtual address
g_pIPU = (PCSP_IPU_REGS)MmMapIoSpace(phyAddr,
sizeof(CSP_IPU_REGS),
FALSE);
// Check if virtual mapping failed
if (g_pIPU == NULL)
{
DEBUGMSG(ADC_ERROR,
(TEXT("%s(): MmMapIoSpace failed!\r\n"), __WFUNCTION__));
return ret;
}
ipu_mutex = CreateMutex(NULL, FALSE, IPU_COMMON_MUTEX);
if (ipu_mutex == NULL)
{
DEBUGMSG(ADC_ERROR,
(TEXT("%s(): Failed to create nutex!\r\n"),
__WFUNCTION__));
return ret;
}
// Turn on clock for IPU
DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_IPU,
DDK_CLOCK_GATE_MODE_ENABLED_ALL);
need_map = FALSE;
}
if (WaitForSingleObject(ipu_mutex, MUTEX_WAITING_TIME) == WAIT_TIMEOUT)
{
DEBUGMSG(ADC_ERROR,
(TEXT("%s(): Waiting for mutex time out!\r\n"),
__WFUNCTION__));
return ret;
}
// IPU Common Registers
// Set little endian
INSREG32BF(&g_pIPU->IPU_CONF, IPU_IPU_CONF_PXL_ENDIAN, IPU_LITTLE_ENDIAN);
// Set no double-buffer, use buf0
INSREG32BF(&g_pIPU->IPU_CHA_DB_MODE_SEL, IPU_DMA_CHA_DMAADC_2, IPU_SIG_BUF);
// Set buffer 0 as current buffer (non double buffered)
INSREG32BF(&g_pIPU->IPU_CHA_CUR_BUF, IPU_DMA_CHA_DMAADC_2, 0);
ReleaseMutex(ipu_mutex);
// Setup DI
if (bpp == 16)
{
DIRGB565(IPU_ADC_DISPLAY_0);
}
else
{
DIRGB888To666(IPU_ADC_DISPLAY_0);
}
DICommandMapping(IPU_ADC_DISPLAY_0);
INSREG32BF(&g_pIPU->DI_DISP_IF_CONF,
IPU_DI_DISP_IF_CONF_DISP0_EN, IPU_ENABLE);
INSREG32BF(&g_pIPU->DI_DISP_IF_CONF,
IPU_DI_DISP_IF_CONF_DISP0_IF_MODE, 2);
INSREG32BF(&g_pIPU->DI_DISP_IF_CONF,
IPU_DI_DISP_IF_CONF_DISP0_PAR_BURST_MODE, 2);
INSREG32BF(&g_pIPU->DI_HSP_CLK_PER,
IPU_DI_HSP_CLK_PER_HSP_CLK_PERIOD_1,
0x10);
INSREG32BF(&g_pIPU->DI_HSP_CLK_PER,
IPU_DI_HSP_CLK_PER_HSP_CLK_PERIOD_2,
0x10);
INSREG32BF(&g_pIPU->DI_DISP0_TIME_CONF_1,
IPU_DISP0_TIME_CONF_1_DISP0_IF_CLK_PER_WR,
32);
INSREG32BF(&g_pIPU->DI_DISP0_TIME_CONF_1,
IPU_DISP0_TIME_CONF_1_DISP0_IF_CLK_UP_WR,
1);
INSREG32BF(&g_pIPU->DI_DISP0_TIME_CONF_1,
IPU_DISP0_TIME_CONF_1_DISP0_IF_CLK_DOWN_WR,
3);
INSREG32BF(&g_pIPU->DI_DISP0_TIME_CONF_2,
IPU_DISP0_TIME_CONF_2_DISP0_IF_CLK_PER_RD,
0);
INSREG32BF(&g_pIPU->DI_DISP0_TIME_CONF_2,
IPU_DISP0_TIME_CONF_2_DISP0_IF_CLK_UP_RD,
0);
INSREG32BF(&g_pIPU->DI_DISP0_TIME_CONF_2,
IPU_DISP0_TIME_CONF_2_DISP0_IF_CLK_DOWN_RD,
0);
INSREG32BF(&g_pIPU->DI_DISP0_TIME_CONF_3,
IPU_DISP0_TIME_CONF_3_DISP0_PIX_CLK_PER,
0x80);
INSREG32BF(&g_pIPU->DI_DISP0_TIME_CONF_3,
IPU_DISP0_TIME_CONF_3_DISP0_READ_EN,
0);
INSREG32BF(&g_pIPU->DI_DISP0_TIME_CONF_3,
IPU_DISP0_TIME_CONF_3_DISP0_RD_WAIT_ST,
0);
INSREG32BF(&g_pIPU->DI_HSP_CLK_PER, IPU_DI_HSP_CLK_PER_HSP_CLK_PERIOD_1, 8);
// Setup ADC template parameters
if (bpp == 16)
{
_create_template(Cmd, 0, height - 1, 2, width + 1, RGB_565_FORMAT, 1);
}
else
{
_create_template(Cmd, 0, height - 1, 2, width + 1, RGB_666_FORMAT, 1);
}
_program_template(Cmd, IPU_ADC_DISPLAY_0, 1);
// Setup ADC channel parameters
_setup_channel(1, 0, 0x0, CHANNEL_SYS1, 1, 1, 1);
// Configure the display parameters for DISPLAY 0
_setup_display(IPU_ADC_DISPLAY_0, width, 1, 1, 0);
INSREG32BF(&g_pIPU->ADC_DISP_VSYNC, IPU_ADC_DISP_VSYNC_DISP0_VSYNC_MODE, 1);
// IDMAC channel parameters
_init_adc_dma(width, height, bpp);
ret = TRUE;
return ret;
}
//------------------------------------------------------------------------------
//
// Function: EnableADC
//
// This function enables ADC for normal opertion
//
// Parameters:
// none
//
// Returns:
// none.
//------------------------------------------------------------------------------
void EnableADC(void)
{
if (WaitForSingleObject(ipu_mutex, MUTEX_WAITING_TIME) == WAIT_TIMEOUT)
{
DEBUGMSG(ADC_ERROR,
(TEXT("%s(): Waiting for mutex time out!\r\n"),
__WFUNCTION__));
return;
}
// Enable ADC in IPU_CONF
INSREG32BF(&g_pIPU->IPU_CONF, IPU_IPU_CONF_ADC_EN, IPU_ENABLE);
// Enable DMA ADC Channel 2
INSREG32BF(&g_pIPU->IDMAC_CHA_EN, IPU_DMA_CHA_DMAADC_2, IPU_ENABLE);
// Set DMA ADC Channel 2 as ready
INSREG32BF(&g_pIPU->IPU_CHA_BUF0_RDY,
IPU_DMA_CHA_DMAADC_2,
IPU_DMA_CHA_READY);
// Turn on the LCD via low level access
// SLPOUT
OUTREG32(&g_pIPU->DI_DISP_LLA_CONF,
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_RS, WR_CMND) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_DISP_NUM, IPU_ADC_DISPLAY_0) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_LOCK, 0) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_MAP_DC, 1) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_BE_MODE, 0));
OUTREG32(&g_pIPU->DI_DISP_LLA_DATA, CMD_SLPOUT);
// DISON
OUTREG32(&g_pIPU->DI_DISP_LLA_CONF,
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_RS, WR_CMND) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_DISP_NUM, IPU_ADC_DISPLAY_0) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_LOCK, 0) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_MAP_DC, 1) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_BE_MODE, 0));
OUTREG32(&g_pIPU->DI_DISP_LLA_DATA, CMD_DISON);
ReleaseMutex(ipu_mutex);
// Sleep(100);
DEBUGMSG(ADC_ERROR, (TEXT("-%s()\r\n"), __WFUNCTION__));
}
//------------------------------------------------------------------------------
//
// Function: DisableADC
//
// This function disables ADC
//
// Parameters:
// none
//
// Returns:
// none.
//------------------------------------------------------------------------------
void DisableADC(void)
{
if (WaitForSingleObject(ipu_mutex, MUTEX_WAITING_TIME) == WAIT_TIMEOUT)
{
DEBUGMSG(ADC_ERROR,
(TEXT("%s(): Waiting for mutex time out!\r\n"), __WFUNCTION__));
return;
}
// Disable ADC
INSREG32BF(&g_pIPU->IPU_CONF, IPU_IPU_CONF_ADC_EN, IPU_DISABLE);
// Disable DMA ADC Channel 2
INSREG32BF(&g_pIPU->IDMAC_CHA_EN, IPU_DMA_CHA_DMAADC_2, IPU_DISABLE);
// Set DMA ADC Channel 2 as not ready
INSREG32BF(&g_pIPU->IPU_CHA_BUF0_RDY,
IPU_DMA_CHA_DMAADC_2,
IPU_DMA_CHA_NOT_READY);
// Turn off the LCD via low level access
// DISOFF
OUTREG32(&g_pIPU->DI_DISP_LLA_CONF,
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_RS, WR_CMND) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_DISP_NUM, IPU_ADC_DISPLAY_0) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_LOCK, 0) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_MAP_DC, 1) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_BE_MODE, 0));
OUTREG32(&g_pIPU->DI_DISP_LLA_DATA, CMD_DISOFF);
// SLPIN
OUTREG32(&g_pIPU->DI_DISP_LLA_CONF,
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_RS, WR_CMND) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_DISP_NUM, IPU_ADC_DISPLAY_0) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_LOCK, 0) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_MAP_DC, 1) |
CSP_BITFVAL(IPU_DI_DISP_LLA_CONF_DRCT_BE_MODE, 0));
OUTREG32(&g_pIPU->DI_DISP_LLA_DATA, CMD_SLPIN);
ReleaseMutex(ipu_mutex);
}
//------------------------------------------------------------------------------
//
// Function: _create_template
//
// This function creates a template
//
// Parameters:
// none
//
// Returns:
// none.
//------------------------------------------------------------------------------
void _create_template(TEMPLATE_CMD_REG *pCmd,
unsigned int SPage,
unsigned int EPage,
unsigned int SCol,
unsigned int ECol,
unsigned int Format,
BOOL Write)
{
unsigned int i = 0;
unsigned char StartPage[2];
unsigned char EndPage[2];
unsigned char StartCol[2];
unsigned char EndCol[2];
unsigned int ColorMode = 0;
switch(Format)
{
case RGB_666_FORMAT:
ColorMode = 0x08;
break;
case RGB_565_FORMAT:
ColorMode = 0x28;
break;
case RGB_444_FORMAT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -