📄 s3c6400_iic_lib.cpp
字号:
/**************************************************************************************
*
* Project Name : IIC Driver
*
* Copyright 2006 by Samsung Electronics, Inc.
* All rights reserved.
*
* Project Description :
* This software is PDD layer for IIC Samsung driver.
*
*--------------------------------------------------------------------------------------
*
* File Name : s3c6400_iic_lib.cpp
*
* File Description : This file implements PDD layer functions
*
* Author : JeGeon.Jung
* Dept. : AP Development Team
* Created Date : 2007/06/12
* Version : 0.1
*
* History
* - Created(JeGeon.Jung 2007/06/12)
* - Add Power Management (JeGeon.Jung 2007/06/25)
* Todo
*
*
* Note
*
**************************************************************************************/
#include <windows.h>
#include <types.h>
#include <linklist.h>
#include <nkintr.h>
#include <devload.h>
#include <pm.h>
#include <iic_mdd.h>
#include <iic_pdd.h>
#include <bsp_cfg.h> // for reference S3C6400_PCLK
#include <s3c6400.h>
#include <DrvLib.h>
#include <oal_intr.h>
#define MSG_ERROR 1
#define MSG_FUNCTION 0
#define MSG_INFO 0
#define MSG_WARN 0
#define MSG_THREAD_INFO 0
#define DEFAULT_FILTER_ENABLE 1
#define DEFAULT_DELAY Clk_15
#define DEFAULT_CLOCK 3000
#define DEFAULT_MODE Master_transmit
#define TIMEOUT_MS 3000
#define TIMEOUT_MS_RX 3000
#define IIC_POWER_ON (1<<17) // PCLK_GATE bit 17
static volatile S3C6400_GPIO_REG *g_pGPIOReg = NULL;
static volatile S3C6400_SYSCON_REG *g_pSYSCONReg = NULL;
static volatile S3C6400_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;
BOOL MapVirtualAddress(void);
void InitializeGPIOPort(void);
void CalculateClockSet(PHW_OPEN_INFO pOpenContext);
static DWORD IIC_IST(LPVOID Context);
BOOL WaitForReg(PVOID pRegAddress, UINT32 tMask, UINT32 tWaitForEqual, DWORD dwTimeout);
//////////
// 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;
RETAILMSG (MSG_FUNCTION,
(TEXT("+HW_Init(0x%X)\r\n"),
pInitContext));
if(!MapVirtualAddress())
{
return FALSE;
}
InitializeGPIOPort();
/* Create tx and rx events. Check return.
*/
g_hTransferEvent = CreateEvent(0,FALSE,FALSE,NULL);
if ( !g_hTransferEvent ) {
RETAILMSG(MSG_ERROR,
(TEXT("Error creating event, HW_Init failed\n\r")));
return(FALSE);
}
g_hTransferDone = CreateEvent(0,FALSE,FALSE,NULL);
if ( !g_hTransferDone ) {
RETAILMSG(MSG_ERROR,
(TEXT("Error creating done event, HW_Init failed\n\r")));
return(FALSE);
}
// 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))
{
RETAILMSG(MSG_ERROR, (TEXT("ERROR: Failed to request the IIC sysintr.\r\n")));
g_IntrIIC = SYSINTR_UNDEFINED;
return(FALSE);
}
RETAILMSG(MSG_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) )
{
RETAILMSG(MSG_ERROR,(TEXT("HW_Init ERROR: Unable to initialize interrupt: %u\r\n"), GetLastError()));
return(FALSE);
}
// create the IST
if ( (g_hTransferThread = CreateThread(NULL, 0, IIC_IST, (LPVOID)pInitContext, 0, NULL)) == NULL)
{
RETAILMSG(MSG_ERROR,(TEXT("HW_Init ERROR: Unable to create IST: %u\r\n"), GetLastError()));
return(FALSE);
}
// TODO: registry override
if ( !CeSetThreadPriority(g_hTransferThread, pInitContext->Priority256)) {
RETAILMSG(MSG_ERROR,(TEXT("HW_Init ERROR: CeSetThreadPriority ERROR:%d\n"), GetLastError()));
return(FALSE);
}
RETAILMSG (MSG_FUNCTION|(RetVal == FALSE?MSG_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 :The return is a BOOL, representing success (TRUE) or failure (FALSE).
// Version : v0.1
BOOL HW_Deinit (PHW_INIT_INFO pInitContext)
{
BOOL RetVal = TRUE; // Initialize to success
RETAILMSG (MSG_FUNCTION,
(TEXT("+HW_Deinit(0x%X)\r\n"),
pInitContext));
if (g_hTransferDone) {
CloseHandle(g_hTransferDone);
g_hTransferDone = NULL;
}
if (g_hTransferEvent) {
CloseHandle(g_hTransferEvent);
g_hTransferEvent = NULL;
}
if (g_hTransferThread) {
CloseHandle(g_hTransferThread);
g_hTransferThread = NULL;
}
if (g_pGPIOReg)
{
DrvLib_UnmapIoSpace((PVOID)g_pGPIOReg);
g_pGPIOReg = NULL;
}
if (g_pSYSCONReg)
{
DrvLib_UnmapIoSpace((PVOID)g_pSYSCONReg);
g_pSYSCONReg = NULL;
}
if (g_pIICReg)
{
DrvLib_UnmapIoSpace((PVOID)g_pIICReg);
g_pIICReg = NULL;
}
RETAILMSG (MSG_FUNCTION,
(TEXT("-HW_Deinit\r\n")));
return (RetVal);
}
//////////
// 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
RETAILMSG (MSG_FUNCTION,
(TEXT("+MapVirtualAddress\r\n")));
// GPIO SFR
g_pGPIOReg = (S3C6400_GPIO_REG *)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_GPIO, sizeof(S3C6400_GPIO_REG), FALSE);
if (g_pGPIOReg == NULL)
{
RETAILMSG(MSG_ERROR, (_T("MapVirtualAddress() : g_pGPIOReg DrvLib_MapIoSpace() Failed \n\r")));
return FALSE;;
}
// SYSCON SFR
g_pSYSCONReg = (S3C6400_SYSCON_REG *)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_SYSCON, sizeof(S3C6400_SYSCON_REG), FALSE);
if (g_pSYSCONReg == NULL)
{
RETAILMSG(MSG_ERROR, (_T("MapVirtualAddress() : g_pSYSCONReg DrvLib_MapIoSpace() Failed \n\r")));
return FALSE;;
}
// IIC SFR
g_pIICReg = (S3C6400_IIC_REG *)DrvLib_MapIoSpace(S3C6400_BASE_REG_PA_IICBUS, sizeof(S3C6400_IIC_REG), FALSE);
if (g_pIICReg == NULL)
{
RETAILMSG(MSG_ERROR, (_T("MapVirtualAddress() : g_pIICReg DrvLib_MapIoSpace() Failed \n\r")));
return FALSE;;
}
RETAILMSG (MSG_FUNCTION,
(TEXT("-MapVirtualAddress\r\n")));
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 */
)
{
RETAILMSG(MSG_FUNCTION,(TEXT("+[IIC]HW_PowerUp\r\n")));
g_pSYSCONReg->PCLK_GATE |= IIC_POWER_ON;
RETAILMSG(MSG_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 */
)
{
RETAILMSG(MSG_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.
RETAILMSG(MSG_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;
RETAILMSG (MSG_FUNCTION,
(TEXT("+HW_OpenFirst(0x%X)\r\n"),
pOpenContext));
// slave address setting
pInitContext->PDDCommonVal.SlaveAddress = DEFAULT_SLAVE_ADDRESS;
pInitContext->PDDCommonVal.InterruptEnable = DEFAULT_INTERRUPT_ENABLE;
RETAILMSG (MSG_FUNCTION|(RetVal == FALSE?MSG_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
RETAILMSG (MSG_FUNCTION,
(TEXT("+HW_CloseLast(0x%X)\r\n"),
pOpenContext));
RETAILMSG (MSG_FUNCTION|(RetVal == FALSE?MSG_ERROR:0),
(TEXT("-HW_CloseLast %s Ecode=%d\r\n"),
(RetVal == TRUE) ? TEXT("Success") : TEXT("Error"),
GetLastError()));
return (RetVal);
}
//////////
// Function Name : HW_Open
// Function Description : IIC device dirver is opened.
// Input : PHW_OPEN_INFO pOpenContext
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -