📄 s3c6410_iic_lib.cpp
字号:
//
// 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 + -