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

📄 i2c.c

📁 FreeScale imx21开发板Nand flash烧写程序
💻 C
字号:
// ***************************************************************************
//
//  Filename:       i2c.c
//
//  Created:        Louis Lai (7/20/2003)
//
//  Modified:       $Author: $ $Date: $
//
// ***************************************************************************


// ***************************************************************************
//  pragmas
// ***************************************************************************


// ***************************************************************************
//  includes
// ***************************************************************************
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "tht_memory_map_defines.h"
#include "common.h"


// ***************************************************************************
//  macros
// ***************************************************************************
// Status
#define		I2C_ICF			0x00000080						// I2C Data Transfer
#define		I2C_IAAS		0x00000040						// I2C Address As a slave 
#define		I2C_IBB			0x00000020						// I2C Bus Busy Bit
#define 	I2C_IAL			0x00000010						// I2C Arbitration Lost
#define		I2C_SRW			0x00000004						// I2C Slave read/write
#define		I2C_RXAK		0x00000001						// I2C Receive Acknowledge
#define		I2C_IIF			0x00000002						// I2C Interrupt

// Control
#define		I2C_MS			0x00000020						// I2C Master Mode
#define		I2C_SL			0x00000000						// I2C Slave Mode
#define		I2C_TX			0x00000010
#define		I2C_RX			0x00000000						// I2C Receive Mode
#define		I2C_IC			0xFFFFFFFD						// I2C Interrupt Clear
#define		I2C_IEN			0x00000080;						// I2C module enable
#define		I2C_TXAK		0X00000008;						




// ***************************************************************************
//  definitions
// ***************************************************************************


	
// ***************************************************************************
//  types
// ***************************************************************************


// ***************************************************************************
//  structures
// ***************************************************************************


// ***************************************************************************
//  data
// ***************************************************************************


// ***************************************************************************
//  function implementations
// ***************************************************************************

// *******************************************************************
// 
//	Function:		I2c_Init
//					Initialize the I2C module
//					Set SCL to HCLK/2/320
//						Slave Address = 0001000					
//
//	Parameters:		void
//		
//
//	Return:			void		
// *******************************************************************
void I2c_Init (void)
{
		
		*(volatile U32*)CRM_PCCR0 	|= 0x1000;				// Enable the ipg_clk to I2C
		*(volatile U32*)GPIOD_GIUS	&= 0xFFFCFFFF;	
		*(volatile U32*)GPIOD_GPR	&= 0xFFFCFFFF;		
				
		*(volatile U32*)I2C_IFDR 	=	(0 << 5) | 
										(1 << 4) | 
										(0 << 3) | 
										(1 << 2) | 
										(1 << 1) | 
										(1 << 0);			// SCL = HCLK/2/320
															//	   = 103kHz @ 66MHz	 
		*(volatile U32*)I2C_IADR 	= 	(0 << 7) | 
										(0 << 6) | 
										(0 << 5) | 
										(1 << 4) | 
										(0 << 3) | 
										(0 << 2) | 
										(0 << 1);			// I2C ADDRESS = 0001000
										
		*(volatile U32*)I2C_I2CR 	=		0X0;
		*(volatile U32*)I2C_I2CR 	|= 	I2C_IEN;			// ENABLE I2C MODULE
		*(volatile U32*)I2C_I2CR 	|=	I2C_TXAK;			// send ack. after receive  
															// one byte of data
} 


// *******************************************************************
// 
//	Function:		i2c_sltx
//					This function set the I2C module to slave 
//					transmit mode. 
//
//	Parameters:		U8*			data			data to store
//					U32			dlength			number of byte to receive
//					U32			s_address		address of slave
//
//	Return:			void		
// *******************************************************************

//U8 i2c_slrx (void)
//{
//		
//}

// *******************************************************************
// 
//	Function:		i2c_slrx
//					This function set the I2C module to slave 
//					receive mode. 
//
//	Parameters:		U8*			data			data to store
//					U32			dlength			number of byte to receive
//					U32			s_address		address of slave
//
//	Return:			void		
// *******************************************************************
//void i2c_sltx (U8)
//{
//	BOOL	selected = FALSE;
//
//	if (*(volatile U32*)I2C_I2SR & I2C_IIF)
//	{
//		*(volatile U32*)I2C_I2SR = (0 << 1);
//	}
//	
	// ***********************************************************
	// Address Cycle
	// send out slave address and wait for acknowledgement
	// After receive acknowledgement from slave, switch to receive 
	// mode.
	// ***********************************************************
		
//	I2CR =	(0 << 5);				// Slave 
//				
//	while (selected)
//	{
//		if (*(volatile U32*)I2C_ISDR & IAAS)
//		{
//			selected = TRUE;
//		}
//		
//	}
//	
//	if (*(volatile U32*)I2C_ISDR & I2C_SRW)
//	{
//		*(volatile U32*)I2C_I2CR = (1 << 4);			// transmit mode
//		i2c_transmit(
//	{
//	else 
//	{
//		*(volatile U32*)I2C_I2CR = (0 << 4);			// receive mode
//	}
//	
//	
//	
//	
//	
//}

// *******************************************************************
// 
//	Function:		i2c_msrx
//					This function set the I2C module to master 
//					receive mode. 
//
//	Parameters:		U8*			data			data to store
//					U32			dlength			number of byte to receive
//					U32			s_address		address of slave
//
//	Return:			void		
// *******************************************************************


void i2c_msrx (U8* data, U32 dlength, U32 s_address)
{
		
		BOOL	add_sent = FALSE;
		BOOL	data_receive;
		BOOL 	busfree = FALSE;
		BOOL	ack = FALSE;
		U8		dummy;
		U32		dWalk;
		
		
		if (*(volatile U32*)I2C_I2SR & I2C_IIF)						// Check any interrupt pending
		{
			*(volatile U32*)I2C_I2SR &= I2C_IC;
		}
		
		while (busfree)							// to ensure that the bus is free
		{											// before sending out the start signal
			if (*(volatile U32*)I2C_I2SR & I2C_IBB)
			{
				busfree = TRUE;
			}
										
		}
		
		// ***********************************************************
		// Address Cycle
		// send out slave address and wait for acknowledgement
		// After receive acknowlt tedgement from slave, switch to receive 
		// mode.
		// ***********************************************************
		
		*(volatile U32*)I2C_I2CR =	(1 << 5) |				// Master 
									(1 << 4);				// Tramit
				
		*(volatile U32*)I2C_I2DR = s_address;
		
		while (ack)						
		{
			while (add_sent)
			{
				if ((*(volatile U32*)I2C_I2SR & I2C_ICF) && (*(volatile U32*)I2C_I2SR & I2C_IIF))
				{
					add_sent = TRUE;
					*(volatile U32*)I2C_I2SR &= I2C_IC;
				}
			}
			if (*(volatile U32*)I2C_I2SR & I2C_RXAK)
			{
				ack = TRUE;
			}
		}
		
		*(volatile U32*)I2C_I2CR =	(1 << 5) |				// Master 
				(0 << 4);				// Receive
		
		dummy = *(volatile U32*)I2C_I2DR;					// dummy read;
		
		// ***********************************************************
		// Data Cycle
		// receive data byte by byte
		// ***********************************************************
		for (dWalk = 1; dWalk <= dlength; dWalk++) 
		{
			data_receive = FALSE;
			
			while (data_receive)	
			{
				if ((*(volatile U32*)I2C_I2SR & I2C_ICF) && (*(volatile U32*)I2C_I2SR & I2C_IIF))
				{
					data_receive = TRUE;
					*(volatile U32*)I2C_I2SR &= I2C_IC;
				}
			}
			
			if (dWalk == dlength - 1)						// second last byte
			{												// do not acknowledge							
				*(volatile U32*)I2C_I2CR = (1 <<3);
			}
			
			*data = *(volatile U32*)I2C_I2DR;
			data++;
		}
		*(volatile U32*)I2C_I2CR = (0 << 5);				// reset to slave and 
															// generate STOP
}
		 
/*
// *******************************************************************
// 
//	Function:		i2c_mstx
//					This function set the I2C module to master 
//					transmit mode. 
//
//	Parameters:		U32*		data			data to send
//					U32			dlength			number of byte to send
//					U32			s_address		address of slave
//
//	Return:			void		
// *******************************************************************
void i2c_mstx (U32* data, U32 dlength, U32 s_address)
{
		U32 	dWalk;
		BOOL	busfree = FALSE;
		BOOL	datasent = FALSE;
		BOOL	ack =FALSE;

		
		if (*(volatile U32*)I2C_I2SR & I2C_IIF)					// Check any interrupt pending
		{
			*(volatile U32*)I2C_I2SR &= I2C_IC;
		}
		
		while (!busfree)					// to ensure that the bus is free
		{									// before sending out the start signal
			if (!(*(volatile U32*)I2C_I2SR & I2C_IBB))
			{
				busfree = TRUE;
			}
										
		}
		
		
	
		
		// ***********************************************************
		// Address Cycle
		// send out slave address and wait for acknowledgement
		// ***********************************************************
		
		*(volatile U32*)I2C_I2CR |=	I2C_MS;				// Master 
		
		*(volatile U32*)I2C_I2CR |= I2C_TX;				// Transmit
				
		*(volatile U32*)I2C_I2DR = s_address;
		
		while (!ack)						
		{
			while (!datasent)
			{
				if (*(volatile U32*)I2C_I2SR & I2C_IIF)
				{
					datasent = TRUE;
					*(volatile U32*)I2C_I2SR &= I2C_IC;
				}
			}
			if (*(volatile U32*)I2C_I2SR & I2C_RXAK)
			{
				ack = TRUE;
			}
		}
		
		// ***********************************************************
		// Data Cycle
		// send data byte by byte
		// ***********************************************************
		
		for (dWalk = 1; dWalk <= dlength; dWalk++)
		{
			datasent = FALSE;
			ack = FALSE;
			
			*(volatile U32*)I2C_I2DR = *data;
			while (!ack)						
			{
				while (!datasent)
				{
					if (*(volatile U32*)I2C_I2SR & I2C_IIF)
					{
						datasent = TRUE;
						*(volatile U32*)I2C_I2SR &= I2C_IC;
					}
				}
				if (*(volatile U32*)I2C_I2SR & I2C_RXAK)
				{
					ack = TRUE;
				}
			}
			
			data++;
		}
		*(volatile U32*)I2C_I2CR = (0 << 4);			// Return to Slave mode and
														// generate Stop signal 
}
*/
// *******************************************************************
// 
//	Function:		I2c_Mode
//					This function config. the I2C module as Master/Slave
//					and Transmit/Receive 
//
//	Parameters:		BOOL		master			master/slave mode?
//					BOOL		transmit		transmit/receive ??
//
//	Return:			void		
// *******************************************************************
void I2c_Mode(BOOL master, BOOL transmit)
{
		BOOL	busfree = FALSE;
		
		if (master)
		{
		
			if (*(volatile U32*)I2C_I2SR & I2C_IIF)			// Check any interrupt pending
			{
				*(volatile U32*)I2C_I2SR &= I2C_IC;
			}
		
			while (!busfree)								// to ensure that the bus is free
			{												// before sending out the start signal
				if (!(*(volatile U32*)I2C_I2SR & I2C_IBB))
				{
					busfree = TRUE;
				}
										
			}
			*(volatile U32*)I2C_I2CR |=	I2C_MS;				// Config. as Master 
		}
		else
		{
			*(volatile U32*)I2C_I2CR &= !I2C_MS;
		}
		
		if (transmit)
		{
			*(volatile U32*)I2C_I2CR |= I2C_TX;				// Config. as Transmit
		}
		else 
		{
			*(volatile U32*)I2C_I2CR &= !I2C_TX;			// Config. as Receive 
		}
}
			
		
// *******************************************************************
// 
//	Function:		i2c_tx
//					This function send a byte of data to SDA
//
//	Parameters:		U32			data			data to send
//
//	Return:			void		
// *******************************************************************		
void I2c_Tx(U32 data)
{
		BOOL	ack = FALSE;
		BOOL	datasent = FALSE;
		
		
		*(volatile U32*)I2C_I2DR = data;
		while (!ack)						
		{
			while (!datasent)
			{
				if (*(volatile U32*)I2C_I2SR & I2C_IIF)
				{
					datasent = TRUE;
					*(volatile U32*)I2C_I2SR &= I2C_IC;
				}
			}
			if (*(volatile U32*)I2C_I2SR & I2C_RXAK)
			{
				ack = TRUE;
			}
		}				
}


⌨️ 快捷键说明

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