⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adc_init.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------
//
//  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 + -