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

📄 s3c6410_iic_lib.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Samsung Electronics. Co. LTD.  All rights reserved.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
*/
/**************************************************************************************
*
*    Project Name : IIC Driver
*
*    Project Description :
*        This software is PDD layer for IIC Samsung driver.
*
*--------------------------------------------------------------------------------------
*
*    File Name : s3c6410_iic_lib.cpp
*
*    File Description : This file implements PDD layer functions
*
**************************************************************************************/

#include <bsp.h>
#include <types.h>
#include <linklist.h>
#include <devload.h>
#include <pm.h>

#include <iic_mdd.h>
#include <iic_pdd.h>

#if DEBUG
#define ZONE_ERROR          DEBUGZONE(0)
#define ZONE_WARN           DEBUGZONE(1)
#define ZONE_FUNCTION       DEBUGZONE(2)
#define ZONE_INIT           DEBUGZONE(3)
#define ZONE_INFO           DEBUGZONE(4)
#define ZONE_IST            DEBUGZONE(5)

extern DBGPARAM dpCurSettings;
#endif

#define DEFAULT_FILTER_ENABLE        1
#define DEFAULT_DELAY                Clk_15
#define DEFAULT_CLOCK                3000
#define DEFAULT_MODE                Master_transmit

#define TIMEOUT_MS_TX                    3000
#define TIMEOUT_MS_RX                3000

#define IIC_POWER_ON   (1<<17)    // PCLK_GATE bit 17

#define UnusedParameter(x)  x = x

static volatile S3C6410_GPIO_REG     *g_pGPIOReg     = NULL;
static volatile S3C6410_SYSCON_REG     *g_pSYSCONReg     = NULL;
static volatile S3C6410_IIC_REG     *g_pIICReg        = NULL;

static HANDLE                g_hTransferDone;        // transmit event done, both rx and tx
static HANDLE                g_hTransferEvent;        // IIC event, both rx and tx
static HANDLE                g_hTransferThread;        // transmit thread, both rx and tx

static DWORD                 g_IntrIIC         = SYSINTR_NOP;

static PHW_OPEN_INFO        g_OwnerContext = NULL;

static PUCHAR                 g_pcIIC_BUFFER;
static UINT32                 g_uIIC_PT;
static UINT32                 g_uIIC_DATALEN;

static BOOL    MapVirtualAddress(void);
static void    InitializeGPIOPort(void);
static void    CalculateClockSet(PHW_OPEN_INFO pOpenContext);
static BOOL    WaitForReg(PVOID pRegAddress, UINT32 tMask, UINT32 tWaitForEqual, DWORD dwTimeout);
static DWORD    IIC_IST(LPVOID Context);

//////////
// Function Name : HW_Init
// Function Description : IIC device H/W initialization.
// Input :     PHW_INIT_INFO    pInitContext
// Output :The return is a BOOL, representing success (TRUE) or failure (FALSE).
// Version : v0.1
BOOL         HW_Init (PHW_INIT_INFO pInitContext)
{
    BOOL    RetVal           = TRUE;        // Initialize to success
    UINT32     Irq;

    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+HW_Init(0x%X)\r\n"),
               pInitContext));

    if(!MapVirtualAddress())
    {
        RetVal = FALSE;
        goto CleanUp;
    }

    InitializeGPIOPort();

    /* Create tx and rx events. Check return.
     */
    g_hTransferEvent = CreateEvent(0,FALSE,FALSE,NULL);
    if ( !g_hTransferEvent ) {
        DEBUGMSG(ZONE_ERROR,
                 (TEXT("Error creating event, HW_Init failed\n\r")));
        RetVal = FALSE;
        goto CleanUp;
    }

    g_hTransferDone = CreateEvent(0,FALSE,FALSE,NULL);
    if ( !g_hTransferDone ) {
        DEBUGMSG(ZONE_ERROR,
                 (TEXT("Error creating done event, HW_Init failed\n\r")));
        RetVal = FALSE;
        goto CleanUp;
    }

    // Obtain sysintr values from the OAL for the IIC interrupt.
    //
    Irq = IRQ_I2C;
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(UINT32), &g_IntrIIC, sizeof(UINT32), NULL))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: Failed to request the IIC sysintr.\r\n")));
        g_IntrIIC = SYSINTR_UNDEFINED;
        RetVal = FALSE;
        goto CleanUp;
    }

    DEBUGMSG(ZONE_INFO, (TEXT("IIC IRQ mapping: [IRQ:%d->sysIRQ:%d].\r\n"), Irq, g_IntrIIC));

    // initialize the interrupt
    if( !InterruptInitialize(g_IntrIIC, g_hTransferEvent, NULL, 0) )
    {
        DEBUGMSG(ZONE_ERROR,(TEXT("HW_Init ERROR: Unable to initialize interrupt: %u\r\n"), GetLastError()));
        RetVal = FALSE;
        goto CleanUp;
    }


    // create the IST
    if ( (g_hTransferThread = CreateThread(NULL, 0, IIC_IST, (LPVOID)pInitContext, 0, NULL)) == NULL)
    {
        DEBUGMSG(ZONE_ERROR,(TEXT("HW_Init ERROR: Unable to create IST: %u\r\n"), GetLastError()));
        RetVal = FALSE;
        goto CleanUp;
    }

    if ( !CeSetThreadPriority(g_hTransferThread, pInitContext->Priority256)) {

        DEBUGMSG(ZONE_ERROR,(TEXT("HW_Init ERROR: CeSetThreadPriority ERROR:%d\n"), GetLastError()));
        RetVal = FALSE;
        goto CleanUp;
    }

CleanUp:
    DEBUGMSG (ZONE_FUNCTION|(RetVal == FALSE?ZONE_ERROR:0),
              (TEXT("-HW_Init %s Ecode=%d\r\n"),
               (RetVal == TRUE) ? TEXT("Success") : TEXT("Error"),
               GetLastError()));
    return (RetVal);
}


//////////
// Function Name : HW_Deinit
// Function Description : IIC device H/W de-initialization.
// Input :     PHW_INIT_INFO    pInitContext
// Output :   VOID
// Version : v0.1
VOID         HW_Deinit (PHW_INIT_INFO pInitContext)
{
    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+HW_Deinit(0x%X)\r\n"),
               pInitContext));

    if (g_hTransferDone)
    {
        CloseHandle(g_hTransferDone);
        g_hTransferDone = NULL;
    }

    if (g_IntrIIC != SYSINTR_UNDEFINED)
    {
        InterruptDisable(g_IntrIIC);        
    }
    if (g_hTransferEvent)
    {
        CloseHandle(g_hTransferEvent);
        g_hTransferEvent = NULL;
    }
    if (g_IntrIIC != SYSINTR_UNDEFINED)
    {
        KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &g_IntrIIC, sizeof(DWORD), NULL, 0, NULL);
    }
    g_IntrIIC = SYSINTR_UNDEFINED;

    if (g_hTransferThread)
    {
        CloseHandle(g_hTransferThread);
        g_hTransferThread = NULL;
    }

    if (g_pGPIOReg)
    {
        MmUnmapIoSpace((PVOID)g_pGPIOReg, sizeof(S3C6410_GPIO_REG));
        g_pGPIOReg = NULL;
    }

    if (g_pSYSCONReg)
    {
        MmUnmapIoSpace((PVOID)g_pSYSCONReg, sizeof(S3C6410_SYSCON_REG));
        g_pSYSCONReg = NULL;
    }

    if (g_pIICReg)
    {
        MmUnmapIoSpace((PVOID)g_pIICReg, sizeof(S3C6410_IIC_REG));
        g_pIICReg = NULL;
    }

    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("-HW_Deinit\r\n")));

}


//////////
// Function Name : MapVirtualAddress
// Function Description : Mapping Virtual address of Registers.
// Input :
// Output :The return is a BOOL, representing success (TRUE) or failure (FALSE).
// Version : v0.1
BOOL         MapVirtualAddress(void)
{
    BOOL            RetVal           = TRUE;        // Initialize to success
    PHYSICAL_ADDRESS    ioPhysicalBase = {0,0};

    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("++%s\r\n"), __FUNCTION__));

    // GPIO SFR
    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_GPIO;
    g_pGPIOReg = (S3C6410_GPIO_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_GPIO_REG), FALSE);
    if (g_pGPIOReg == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (_T("%s : g_pGPIOReg MmMapIoSpace() Failed \n\r"), __FUNCTION__));
        return FALSE;
    }

    // SYSCON SFR
    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_SYSCON;    
    g_pSYSCONReg = (S3C6410_SYSCON_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_SYSCON_REG), FALSE);
    if (g_pSYSCONReg == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (_T("%s : g_pSYSCONReg MmMapIoSpace() Failed \n\r"), __FUNCTION__));
        return FALSE;
    }

    // IIC SFR
    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_IICBUS;    
    g_pIICReg = (S3C6410_IIC_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_IIC_REG), FALSE);
    if (g_pIICReg == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (_T("%s : g_pIICReg MmMapIoSpace() Failed \n\r"), __FUNCTION__));
        return FALSE;
    }

    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("--%s\r\n"),__FUNCTION__));
    return (RetVal);
}


//////////
// Function Name : InitializeGPIOPort
// Function Description : Initializing GPIO port for IIC.
// Input :
// Output :
// Version : v0.9
void     InitializeGPIOPort(void)
{
    // set SCL
    g_pGPIOReg->GPBCON = (g_pGPIOReg->GPBCON & ~(0xf<<20)) | (0x2<<20);

    // set SDA
    g_pGPIOReg->GPBCON = (g_pGPIOReg->GPBCON & ~(0xf<<24)) | (0x2<<24);

    // set SCL pull-up
    g_pGPIOReg->GPBPUD = (g_pGPIOReg->GPBPUD & ~(0x3<<10)) | (0x0<<10);

    // set SDA pull-up
    g_pGPIOReg->GPBPUD = (g_pGPIOReg->GPBPUD & ~(0x3<<12)) | (0x0<<12);
}

//////////
// Function Name : HW_PowerUp
// Function Description : Power control for IIC.
// Input :     PHW_INIT_INFO pInitContext
// Output : The return is a BOOL, representing success (TRUE) or failure (FALSE).
// Version : v0.9
BOOL
HW_PowerUp(
    PHW_INIT_INFO pInitContext    /* value from I2C_Init */
   )
{
    UnusedParameter(pInitContext);
    DEBUGMSG(ZONE_FUNCTION,(TEXT("+[IIC]HW_PowerUp\r\n")));
    g_pSYSCONReg->PCLK_GATE |= IIC_POWER_ON;
    DEBUGMSG(ZONE_FUNCTION,(TEXT("-[IIC]HW_PowerUp\r\n")));
    return TRUE;
}

//////////
// Function Name : HW_PowerDown
// Function Description : Power control for IIC.
// Input :     PHW_INIT_INFO pInitContext
// Output : The return is a BOOL, representing success (TRUE) or failure (FALSE).
// Version : v0.9
BOOL
HW_PowerDown(
    PHW_INIT_INFO pInitContext    /* value from I2C_Init */
   )
{
    UnusedParameter(pInitContext);
    DEBUGMSG(ZONE_FUNCTION,(TEXT("+[IIC]HW_PowerDown\r\n")));
    g_pSYSCONReg->PCLK_GATE &= ~IIC_POWER_ON;

    g_OwnerContext = NULL; // This is for Power Management. When Power up, IIC set register again.
    DEBUGMSG(ZONE_FUNCTION,(TEXT("-[IIC]HW_PowerDown\r\n")));
    return TRUE;
}

//////////
// Function Name : HW_OpenFirst
// Function Description : IIC device dirver is opened first.
// Input :     PHW_OPEN_INFO    pOpenContext
// Output :The return is a BOOL, representing success (TRUE) or failure (FALSE).
// Version : v0.1
BOOL         HW_OpenFirst (PHW_OPEN_INFO pOpenContext)
{
    BOOL            RetVal          =     TRUE;        // Initialize to success
    PHW_INIT_INFO    pInitContext    =    pOpenContext->pInitContext;

    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+HW_OpenFirst(0x%X)\r\n"),
               pOpenContext));

    // slave address setting
    pInitContext->PDDCommonVal.SlaveAddress = DEFAULT_SLAVE_ADDRESS;
    pInitContext->PDDCommonVal.InterruptEnable = DEFAULT_INTERRUPT_ENABLE;

    DEBUGMSG (ZONE_FUNCTION|(RetVal == FALSE?ZONE_ERROR:0),
              (TEXT("-HW_OpenFirst %s Ecode=%d\r\n"),
               (RetVal == TRUE) ? TEXT("Success") : TEXT("Error"),
               GetLastError()));
    return (RetVal);
}

//////////
// Function Name : HW_CloseLast
// Function Description : IIC device dirver is closed last.
// Input :     PHW_OPEN_INFO    pOpenContext
// Output :The return is a BOOL, representing success (TRUE) or failure (FALSE).
// Version : v0.1
BOOL         HW_CloseLast (PHW_OPEN_INFO pOpenContext)
{
    BOOL    RetVal           = TRUE;        // Initialize to success

    DEBUGMSG (ZONE_FUNCTION,
              (TEXT("+HW_CloseLast(0x%X)\r\n"),
               pOpenContext));



    DEBUGMSG (ZONE_FUNCTION|(RetVal == FALSE?ZONE_ERROR:0),
              (TEXT("-HW_CloseLast %s Ecode=%d\r\n"),
               (RetVal == TRUE) ? TEXT("Success") : TEXT("Error"),
               GetLastError()));
    return (RetVal);
}

//////////
// Function Name : HW_Open

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -