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

📄 i2c.c

📁 WINCE5.0下的I2C总线的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    			{
					IICError = I2C_ERROR_NO_ERR;
					SetEvent(gI2CEvent);
    			}
    			else
    			{
    				v_pIICPregs->rIICSTAT = (3 << 6) | (0 << 5) | (1 << 4);
    				
					IICCON_DACK(v_pIICPregs->rIICCON);	
					Sleep(1);												// 等待结束信号产生完毕   		
    				
					IICError = I2C_ERROR_SEND;
					SetEvent(gI2CEvent);
				}
     		break;
    			
    		// Receive Bytes
    		case I2C_STATUS_RECEIVE:
    			if((v_pIICPregs->rIICSTAT & 0x08) == 0)
    			{
					
					IICError = I2C_ERROR_NO_ERR;	
					SetEvent(gI2CEvent); 
    			}
    			else
    			{
		   			// 发送结束信号	
					v_pIICPregs->rIICSTAT = (2 << 6) | (0 << 5) | (1 << 4);	
					IICCON_DACK(v_pIICPregs->rIICCON);
					Sleep(1);											// 等待结束信号产生完毕
				
					IICError = I2C_ERROR_RECEIVE;
					SetEvent(gI2CEvent);
    			}
    		break;
    
			default:
  			break;	
		}
	
		InterruptDone(g_I2CSysIntr);
	}      
  	
}


/*******************************************************************************************
函数名称: IIC_Init
描    述: 驱动程序初始化函数
输入参数: DWORD dwContext: 设备管理器传递给本驱动的参数, 通常为流接口驱动在注册表内的位置 	
输出参数: 无
返    回: 驱动程序句柄
*******************************************************************************************/
DWORD
IIC_Init(DWORD dwContext)
{
	DWORD   IDThread;
      RETAILMSG(1, (TEXT("IIC_Init\r\n")));
	// 取得 GPIO 及 IIC 相关寄存器的虚拟地址空间
	I2C_InitializeAddresses();		

	// 使能 IIC 引脚为中断引脚, 并初始化相关寄存器
	I2C_InitHareware();

    // 从 OAL 请求一个 SYSINTR 值
   /*if (!KernelIoControl(IOCTL_HAL_TRANSLATE_IRQ, &g_I2CIrq, sizeof(UINT32), &g_I2CSysIntr, sizeof(UINT32), NULL))
    {
        RETAILMSG(1, (TEXT("ERROR: I2C Bus: Failed to request sysintr value for I2C Bus interrupt.\r\n")));
        return(0);
    }
    
    */
    g_I2CSysIntr=0x10+20;
    RETAILMSG(1,(TEXT("INFO: I2C Bus: Mapped Irq 0x%x to SysIntr 0x%x.\r\n"), g_I2CIrq, g_I2CSysIntr));

	gI2CIntrThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) I2C_IntrThread, 0, 0, &IDThread);
	if (gI2CIntrThread == 0) 
	{
		RETAILMSG(1, (TEXT("::: CreateThread() Fail\r\n")));
		return 0;
	}
	SetThreadPriority(gI2CIntrThread, THREAD_PRIORITY_ABOVE_NORMAL);

	gI2CEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
 
	return (DWORD)gI2CIntrThread;
}


/*******************************************************************************************
函数名称: DllEntry
描    述: 驱动程序动态库入口
输入参数: 	
输出参数:
返    回: 
*******************************************************************************************/
PUBLIC BOOL WINAPI
DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
    switch ( dwReason ) 
	{
		case DLL_PROCESS_ATTACH:
			RETAILMSG(1, (TEXT("IIC: DLL_PROCESS_ATTACH\r\n")));
			DisableThreadLibraryCalls((HMODULE) hInstDll);
			break;

		case DLL_PROCESS_DETACH:
			RETAILMSG(1, (TEXT("IIC: DLL_PROCESS_DETACH\r\n")));
			break;
    }
    
    return (TRUE);
}


/*******************************************************************************************
函数名称: IIC_Close
描    述: 驱动程序关闭函数
输入参数: DWORD Handle:驱动程序句柄
输出参数: 无
返    回: FALSE: 失败    TRUE: 成功 
*******************************************************************************************/
BOOL IIC_Close(DWORD Handle)
{
	g_OpenCount = 0;

    return TRUE;
}   // IIC_Close


/*******************************************************************************************
函数名称: IIC_Deinit
描    述: 驱动程序卸载函数
输入参数: DWORD dwContext: 驱动程序句柄
输出参数: 无
返    回: FALSE: 失败    TRUE: 成功
*******************************************************************************************/
BOOL IIC_Deinit(DWORD dwContext)
{
	RETAILMSG(1, (TEXT(":::IIC: IIC Driver deinit.\r\n")));

	// 通知中断服务线程退出
	g_bKillIST = TRUE;
	PulseEvent(gI2CIntrEvent);		
	Sleep(200);												/* 等待.... */

	// 释放中断资源
	InterruptDone(g_I2CSysIntr);
	InterruptDisable(g_I2CSysIntr);
	KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &g_I2CSysIntr, sizeof(UINT32), NULL, 0, NULL);

	// 恢复 I2C 引脚为输入引脚
	I2C_ConfigPinDefault();

	/* 释放申请的虚拟内存 */
	if (v_pIOPregs)
		VirtualFree((PVOID)v_pIOPregs, 0, MEM_RELEASE);

	if (v_pIICPregs)
		VirtualFree((PVOID)v_pIICPregs, 0, MEM_RELEASE);

	// 关闭 I2C 事件句柄
	CloseHandle(gI2CEvent);
	g_OpenCount = 0;

    return TRUE;
}   // IIC_Deinit


/*******************************************************************************************
函数名称: IIC_Open
描    述: 打开驱动程序
输入参数: DWORD dwData     : 设备驱动程序句柄
          DWORD dwAccess   : 访问请求代码,是读和写的组合
          DWORD dwShareMode: 共享模式  
输出参数:
返    回: 驱动程序引用事例句柄
*******************************************************************************************/
DWORD
IIC_Open(
    DWORD dwData,
    DWORD dwAccess,
    DWORD dwShareMode
    )
{
	if(g_OpenCount > 0)
		return 0;

	g_OpenCount++;
    return g_OpenCount;
}   // IIC_Open


/*******************************************************************************************
函数名称: IIC_IOControl
描    述: 驱动程序 I/O 请求
输入参数: 
输出参数:
返    回: TRUE: 成功   FALSE: 失败
*******************************************************************************************/
BOOL
IIC_IOControl(
    DWORD Handle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{
	BOOL bErr = FALSE;  
		
	switch (dwIoControlCode)
	{
		case IOCTL_SET_I2C_SLAVE:					   /* 设置从机地址 */
			if (nInBufSize > 0)
			{
				I2cSla = pInBuf[0];
				bErr = TRUE;	
			}
		break;
		
		case IOCTL_SET_SPEED_DIV:	
			if ((nInBufSize > 0)  && 
			    (pInBuf[0] <= 15) && 				   /* I2C的分频值为: 0 ~ 15 */
			    (nOutBufSize >= 0))                    /* pOutBuf 为 DWORD */
			{
				/* 写入分频值 */	
				v_pIICPregs->rIICCON = IICCON_DEFAULT | pInBuf[0];
				
                *(DWORD *)pOutBuf = I2C_GetSpeed();	   /* 取得I2C传输速度(HZ) */
				*pBytesReturned = 1;
				bErr = TRUE;
			}
		break;
		
		case IOCTL_GET_SPEED:                          /* pOutBuf 为 DWORD */
			if (nOutBufSize > 0)
			{
                *(DWORD *)pOutBuf = I2C_GetSpeed();	   /* 取得I2C传输速度(HZ) */
				*pBytesReturned = 1;				
				bErr = TRUE;
			}
		break;
					
		default:
		break;
	}
	
    return bErr;
}   // IIC_IOControl



/*******************************************************************************************
函数名称: IIC_Read
描    述: 从 IIC 从机读取数据
输入参数: DWORD Handle    : 驱动程序引用事例句柄
          LPVOID pBuffer  : 接收缓冲区
          DWORD dwNumBytes: 要读的字节数
输出参数: 无
返    回: 实际读到字节数
*******************************************************************************************/
DWORD IIC_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)
{
	UINT32 count, ret;
	uchar *pReadBuffer;

	if ((pBuffer == NULL) || (dwNumBytes <= 0))
		return 0;

	pReadBuffer = MapPtrToProcess(pBuffer, GetCallerProcess());

	// 设置从机地址及当前状态
	I2cCurSla = I2cSla | 0x01;
	I2cStatus = I2C_STATUS_SETADDR;
	StartI2C(I2cCurSla);

	ret = WaitForSingleObject(gI2CEvent, I2C_RW_TIMEOUT);		/* 挂起当前线程,直到IIC中断的产生 */   
	ResetEvent(gI2CEvent);	
	if ((IICError != I2C_ERROR_NO_ERR) || (ret != WAIT_OBJECT_0))
	{
		RETAILMSG(1, (TEXT("ERROR: IIC_Read: Send Slave Address fail! \r\n")));
		return 0;	
	}
	
	I2cStatus = I2C_STATUS_RECEIVE;						// 进入接收状态
	for (count = 0; count < dwNumBytes; count++)
	{
		if (count == (dwNumBytes - 1))
			IIC_StartRecByteNA();
		else
			IIC_StartRecByteA();	
		
		/* 挂起当前线程,直到IIC中断的产生 */ 
		ret = WaitForSingleObject(gI2CEvent, I2C_RW_TIMEOUT);
		ResetEvent(gI2CEvent);
		if (ret != WAIT_OBJECT_0)
		{
			if (ret == WAIT_TIMEOUT)
				RETAILMSG(1, (TEXT("ERROR: IIC read data time out! \r\n")));
			else
				RETAILMSG(1, (TEXT("ERROR: IIC read data fail! \r\n")));
			
			return count;
		}
	
		*pReadBuffer = IIC_RecByte();	
		pReadBuffer++;

		if (IICError != I2C_ERROR_NO_ERR)
		{
			RETAILMSG(1, (TEXT("ERROR: IIC_Read: Receive data fail! \r\n")));
			break;	
		}
	}
	
	StopI2C(0);

	return count;
}


/*******************************************************************************************
函数名称: IIC_Write
描    述: 向 IIC 从机发送数据
输入参数: 
输出参数:
返    回: 成功发送的字节数
*******************************************************************************************/
DWORD IIC_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)
{
	UINT32 count, ret;
	uchar *pWriteBuffer;

	if ((pBuffer == NULL) || (dwNumBytes <= 0))
		return 0;

	pWriteBuffer = MapPtrToProcess((LPVOID)pBuffer, GetCallerProcess());

	// 设置从机地址及当前状态
	I2cCurSla = I2cSla;
	I2cStatus = I2C_STATUS_SETADDR;
	StartI2C(I2cCurSla);

	ret = WaitForSingleObject(gI2CEvent, I2C_RW_TIMEOUT);		/* 挂起当前线程,直到IIC中断的产生 */   
	ResetEvent(gI2CEvent);	
	if ((IICError != I2C_ERROR_NO_ERR) || (ret != WAIT_OBJECT_0))
	{
		RETAILMSG(1, (TEXT("ERROR: IIC_Write: send slave address fail! \r\n")));
		return 0;	
	}
	
	I2cStatus = I2C_STATUS_SEND;						// 进入发送状态
	for (count = 0; count < dwNumBytes; count ++)
	{
		IIC_SendByte(*pWriteBuffer);					/* 启动I2C总线,发送在中断中进行 */
		pWriteBuffer++;

		/* 挂起当前线程,直到IIC中断的产生 */
		ret = WaitForSingleObject(gI2CEvent, I2C_RW_TIMEOUT);
		ResetEvent(gI2CEvent);	
		if (ret != WAIT_OBJECT_0)
		{
			RETAILMSG(1, (TEXT("ERROR: IIC write data fail! \r\n")));
			return count;
		}		

		if (IICError != I2C_ERROR_NO_ERR)
		{
			RETAILMSG(1, (TEXT("ERROR: IIC_Write: send data fail! \r\n")));
			break;	
		}
	}
	
	StopI2C(1);

	return count;
}


/*******************************************************************************************
函数名称: IIC_Seek
描    述: 对设备的数据指针进行操作,本驱动不支持该函数
输入参数: 
输出参数:
返    回:
*******************************************************************************************/
DWORD IIC_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod)
{
	return 0;
}


/*******************************************************************************************
函数名称: IIC_PowerUp
描    述: 电源上电驱动处理函数
输入参数: 
输出参数:
返    回: 无
*******************************************************************************************/
void IIC_PowerUp(void)
{
	return 1;
}


/*******************************************************************************************
函数名称: IIC_PowerDown
描    述: 电源下电驱动处理函数
输入参数: 
输出参数:
返    回: 无
*******************************************************************************************/
void IIC_PowerDown(void)
{
	return 1;
}

⌨️ 快捷键说明

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