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

📄 drv_i2c.c

📁 基于Freescale的MX21处理器的bootloader程序
💻 C
字号:
/*-------------------------------------------------------------------
FILE NAME:
	drv_i2c.c
DESCRIPTION:
	this file includes i2c bus driver. 
AUTHOR:
	WYF
VERSION:
	2005.1122.00
COMPANY:
	DATANG MICROELECTRONICS TECHNOLOGY CO,.LTD
HISTORY:
	2005.1122 Creat this file
	...
--------------------------------------------------------------------*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "nucleus.h"
#include "ADSmx21_defs.h"
#include "drv_defs.h"
#include "drv_extr.h"

#define I2C_I2CR_IEN  7
#define I2C_I2CR_IIEN 6
#define I2C_I2CR_MSTA 5
#define I2C_I2CR_MTX  4
#define I2C_I2CR_TXAK 3
#define I2C_I2CR_RSTA 2
#define I2C_I2SR_ICF  7
#define I2C_I2SR_IAAS 6
#define I2C_I2SR_IBB  5
#define I2C_I2SR_IAL  4
#define I2C_I2SR_SRW  2
#define I2C_I2SR_IIF  1
#define I2C_I2SR_RXAK 0

#define I2C_STOP()				{I2CR &= ~(1<<5); }
#define I2C_PUT_BYTE(byData)	{while(!(I2SR&(1<<7)));I2DR = byData;}
#define SET_TRANSMIT_MODE()		{I2CR |= (1<<4);}
#define SET_MASTER_MODE()		{while(I2SR&(1<<5));I2CR |= (1<<5);}
#define CLR_BITS(reg, bit)      do{reg &= ~(1<<bit);}while(0)
#define SET_BITS(reg, bit)      do{reg |=  (1<<bit);}while(0)

static TDRV_I2C i2c;

void __DoTransfer(void)
{
	TDRV_I2C *pI2C = &i2c;
	int dwData;
	
	while (pI2C->FbProgress) {
		while (!(I2SR&(1<<I2C_I2SR_IIF))); 
		I2SR &= ~(1<<I2C_I2SR_IIF);

		if (pI2C->FbProcessTxMode) {
			// Processing Tx Mode
			if (I2SR & (1<<I2C_I2SR_RXAK)) {
				// No Acknowledge receive
				I2C_STOP();
				pI2C->FbProgress = FALSE;
			}
			else {
				// Acknowledge Received
				if (pI2C->FiTxProgressIndex == pI2C->FiTxBufferSize) {
					// Last Byte Transmitted
					if (pI2C->FbTxMode) {
						// In Tx Mode and Last Byte Transmitted
						// Every thing is OK, Bye bye
						I2C_STOP();
						pI2C->FbProgress = FALSE;
					}
					else {
						// Switch to Rx Mode
						pI2C->FbProcessTxMode = FALSE;
						CLR_BITS(I2CR, I2C_I2CR_MTX);
						if (pI2C->FiRxBufferSize == 1) {
							// Disable Acknowledge
							SET_BITS(I2CR, I2C_I2CR_TXAK);
						}
						else {
							// Enable Acknowledge
							CLR_BITS(I2CR, I2C_I2CR_TXAK);
						}
						// Dummy Read from I2DR
						dwData = I2DR;
					}
				}
				else {
					// Still other Byte
					dwData = pI2C->FpbyTxBuffer[pI2C->FiTxProgressIndex++];
					I2DR = (char)dwData;
				}
			}
		}
		else {
			// Processing Rx Mode
			if (pI2C->FiRxProgressIndex == (pI2C->FiRxBufferSize - 1)) {
				// Last Byte to be Read
				I2C_STOP();
				pI2C->FbProgress = FALSE;
			}
			else if (pI2C->FiRxProgressIndex == (pI2C->FiRxBufferSize - 2)) {
				// 2nd Last Byte to be Read
				// Disable Acknowledge
				SET_BITS(I2CR, I2C_I2CR_TXAK);
			}
			dwData = I2DR;
			pI2C->FpbyRxBuffer[pI2C->FiRxProgressIndex++] = (char)dwData;
		}
	}
}


static void __WriteMasterData(char byAddress, char* pbyDataBuffer, int iDataSize)
{
	SET_MASTER_MODE();
	SET_TRANSMIT_MODE();
	/* indicate to the DoTransfer function that I2C is in transmiting mode */
	i2c.FbTxMode = TRUE;
	i2c.FbProcessTxMode = TRUE;
	i2c.FbProgress = TRUE;
	i2c.FpbyTxBuffer = pbyDataBuffer;
	i2c.FiTxBufferSize = iDataSize;
	i2c.FiTxProgressIndex = 0;

	byAddress &= ~0x01;
	I2C_PUT_BYTE(byAddress);
	__DoTransfer();
}

static void __ReadMasterData(char byAddress, char* pbyRxDataBuffer, int iRxDataSize)
{
	SET_MASTER_MODE();
	SET_TRANSMIT_MODE();
	/* indicate to the DoTransfer function that I2C is in receiving mode */
	i2c.FbTxMode = FALSE;
	i2c.FbProcessTxMode = TRUE;
	i2c.FbProgress = TRUE;
	i2c.FiTxBufferSize = 0;
	i2c.FiTxProgressIndex = 0;
	i2c.FpbyRxBuffer = pbyRxDataBuffer;
	i2c.FiRxBufferSize = iRxDataSize;
	i2c.FiRxProgressIndex = 0;
	byAddress |= 0x01;
	I2C_PUT_BYTE(byAddress);
	__DoTransfer();
}

void I2C_init(void)
{
	STATUS s;
	
	PTD_GIUS &= ~0x60000;
	PCCR0 |= 0x1000;

//	IFDR = 0x3F; /* Clk: 66.5MHz/2048 */
	IFDR = 0x38; /* Clk: 66.5MHz/640 */
	I2CR |= 0x80; /* Enable I2C */
	I2CR |= 0x08; /* Disable Ack */

	s = NU_Create_Semaphore(&(i2c.lock), "i2c", 1, NU_PRIORITY);
	assert(s == NU_SUCCESS);
}

void I2C_write(char I2CAddress, char* DataBuffer, int DataSize)
{
	STATUS s;
	s = NU_Obtain_Semaphore(&(i2c.lock), NU_NO_SUSPEND);
	assert(s == NU_SUCCESS);

	__WriteMasterData(I2CAddress, DataBuffer, DataSize);

	s = NU_Release_Semaphore(&(i2c.lock));
	assert(s == NU_SUCCESS);
}

void I2C_read(char I2CAddress, char* DataBuffer, int DataSize)
{
	STATUS s;
	s = NU_Obtain_Semaphore(&(i2c.lock), NU_NO_SUSPEND);
	assert(s == NU_SUCCESS);

	__ReadMasterData(I2CAddress, DataBuffer, DataSize);

	s = NU_Release_Semaphore(&(i2c.lock));
	assert(s == NU_SUCCESS);
}

⌨️ 快捷键说明

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