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

📄 i2c_hal.c

📁 BlackFin处理器视频演示代码
💻 C
字号:
/**
 *@file i2c_hal.c
 *@author Zlatan Stanojevic
 */


#ifdef __ADSPBF537__
#include <services/services.h>
#include <cdefBF537.h>
#include "i2c_framing_layer.h"
//#define CLKIN 25000000
//#include "../../misc/clock_query.h"


/**
 * Controls the IVG for TWI interrupts.
 */
//#define INT_LEVEL 14		// use default


static enum
{
	I2C_UNCONFIGURED,
	I2C_IDLE,
	I2C_SCANBUS,
	I2C_READ,
	I2C_WRITE,
	I2C_GET,
	I2C_SET,
} state = I2C_UNCONFIGURED;


u16 fast_flag;


static I2CScanCallback scan_callback;
static I2CCallback msg_callback;
static unsigned char *msg_start;
static unsigned char *msg_buffer;
static unsigned char msg_size;
unsigned char xmt_counter = 0;
unsigned char rcv_counter = 0;


static void load( void );


static ADI_INT_HANDLER( TWI_HANDLER )
{
	u16 irq = *pTWI_INT_STAT;
	if( irq )
	{
		u16 stat = *pTWI_MASTER_STAT;
		u16 addr = *pTWI_MASTER_ADDR;

		switch( state )
		{
			case I2C_SCANBUS:
			{
				
				if( ! addr )
				{
					*pTWI_INT_MASK = 0;
					state = I2C_IDLE;
					*pTWI_MASTER_STAT = 0x003f;
					*pTWI_INT_STAT = 0x00ff;
				}
				else
				{
					*pTWI_MASTER_STAT = 0x003f;
					( *pTWI_MASTER_ADDR )--;
					*pTWI_MASTER_CTL = MEN | fast_flag;
					*pTWI_INT_STAT = 0x00ff;
				}
				
				if( ( ! ( stat & ANAK ) ) && scan_callback )
					scan_callback( (u8)addr );
				
				break;
			}
			
			case I2C_WRITE:
			case I2C_SET:
			{
				if( irq & XMTSERV )
				{
					*pTWI_XMT_DATA8 = *(msg_buffer++);
					xmt_counter++;
				}
				if( irq & MCOMP )
				{
					if( msg_callback )
						msg_callback( xmt_counter, msg_start );
					*pTWI_FIFO_CTL = 0x0001; //flush fifo
					asm( "ssync;" );
					*pTWI_FIFO_CTL = 0;
					*pTWI_INT_MASK = 0;
					state = I2C_IDLE;
				}
				*pTWI_INT_STAT = 0x00ff;
				break;
			}
			
			case I2C_GET:
			{
				if( irq & MCOMP )
				{
					*pTWI_INT_MASK = RCVSERV | MCOMP;
					*pTWI_MASTER_CTL = msg_size << 6 | MDIR | MEN | fast_flag;
					state = I2C_READ;
				}
				*pTWI_INT_STAT = 0x00ff;
				break;
			}
			
			case I2C_READ:
			{
				if( irq & RCVSERV )
				{
					*(msg_buffer++) = *pTWI_RCV_DATA8;
					rcv_counter++;
				}
				else if( irq & MCOMP )
				{
					if( msg_callback )
						msg_callback( rcv_counter, msg_start );
					*pTWI_INT_MASK = 0;
					state = I2C_IDLE;
				}
				*pTWI_INT_STAT = 0x00ff;
				break;
			}
				
			case I2C_IDLE:
				*pTWI_INT_STAT = 0x00ff;
				*pTWI_INT_MASK = 0;
				break;
		}
		
		return ADI_INT_RESULT_PROCESSED;
	}
	return ADI_INT_RESULT_NOT_PROCESSED;
}


void I2CInitHAL( unsigned long pa_lFrequency, unsigned long pa_lSystemClk)
{
	unsigned long nIVG;
	adi_int_SICGetIVG(ADI_INT_TWI, &nIVG);
//	adi_int_SICSetIVG( ADI_INT_TWI, INT_LEVEL );
	adi_int_CECHook( nIVG/*INT_LEVEL*/, TWI_HANDLER, 0, FALSE );
	adi_int_SICEnable( ADI_INT_TWI );
	
	*pTWI_CLKDIV = 5000000 / pa_lFrequency; //set SCL freq
	*pTWI_CLKDIV |= *pTWI_CLKDIV << 8;
	*pTWI_CONTROL = 1 << 7 | (u16)( pa_lSystemClk / 10000000. ); //enable twi and set clk ref.
	
	fast_flag = 0;
	state = I2C_IDLE;
	if( pa_lFrequency > 100000 )
		fast_flag = FAST;
}


void I2CScanbus( I2CScanCallback callback )
{
	state = I2C_SCANBUS;
	scan_callback = callback;
	
	*pTWI_FIFO_CTL = 0;
	*pTWI_MASTER_ADDR = 128;
	*pTWI_INT_STAT = 0x00ff;
	*pTWI_INT_MASK = MCOMP;
	*pTWI_MASTER_CTL = MEN;
	while( state != I2C_IDLE );
}


void _I2CRead_non_blocking( unsigned char hwid, unsigned char *message,
		    unsigned char msg_length, I2CCallback callback )
{
	while( state != I2C_IDLE );
	state = I2C_READ;
	msg_callback = callback;
	msg_start = message;
	msg_buffer = message;
	msg_size = msg_length;
	
	*pTWI_MASTER_ADDR = hwid;
	*pTWI_FIFO_CTL = 0;
	*pTWI_INT_STAT = 0x00ff;
	*pTWI_INT_MASK = RCVSERV | MCOMP;
	*pTWI_MASTER_CTL = ( msg_length ) << 6 | MDIR | MEN | fast_flag;
}

void _I2CWrite_non_blocking( unsigned char hwid, unsigned char *message,
			unsigned char msg_length, I2CCallback callback )
{
	while( state != I2C_IDLE );
	state = I2C_WRITE;
	msg_callback = callback;
	msg_start = message;
	msg_buffer = message + 1;
	msg_size = msg_length;
	
	*pTWI_MASTER_ADDR = hwid;
	*pTWI_XMT_DATA8 = *message;
	*pTWI_FIFO_CTL = 0;
	*pTWI_INT_STAT = 0x00ff;
	*pTWI_INT_MASK = XMTSERV | MCOMP;
	*pTWI_MASTER_CTL = ( msg_length ) << 6 | MEN | fast_flag;
}

void _I2CSet_non_blocking( unsigned char hwid, unsigned char start_addr, 
		   unsigned char *values, unsigned char vals_length, I2CCallback callback )
{
	while( state != I2C_IDLE );
	state = I2C_SET;
	msg_callback = callback;
	msg_buffer = msg_start = values;
	msg_size = vals_length;
	
	*pTWI_MASTER_ADDR = hwid;
	*pTWI_XMT_DATA8 = start_addr;
	*pTWI_FIFO_CTL = 0;
	*pTWI_INT_STAT = 0x00ff;
	*pTWI_INT_MASK = XMTSERV | MCOMP;
	*pTWI_MASTER_CTL = ( vals_length + 1 ) << 6 | MEN | fast_flag;
}

void _I2CGet_non_blocking( unsigned char hwid, unsigned char start_addr, 
		   unsigned char *values, unsigned char vals_length, I2CCallback callback )
{
	while( state != I2C_IDLE );
	state = I2C_GET;
	msg_callback = callback;
	msg_buffer = values;
	msg_size = vals_length;
	
	*pTWI_MASTER_ADDR = hwid;
	*pTWI_XMT_DATA8 = start_addr;
	*pTWI_FIFO_CTL = 0;
	*pTWI_INT_STAT = 0x00ff;
	*pTWI_INT_MASK = MCOMP;
	*pTWI_MASTER_CTL = 1 << 6 | RSTART | MEN | fast_flag;
}


void _I2CRead_blocking( unsigned char hwid, unsigned char *message,
		    unsigned char msg_length )
{
	_I2CRead_non_blocking( hwid, message, msg_length, 0 );
	while( state != I2C_IDLE );
}


void _I2CWrite_blocking( unsigned char hwid, unsigned char *message,
			unsigned char msg_length )
{
	_I2CWrite_non_blocking( hwid, message, msg_length, 0 );
	while( state != I2C_IDLE );
}

void _I2CSet_blocking( unsigned char hwid, unsigned char start_addr, 
		   unsigned char *values, unsigned char vals_length )
{
	_I2CSet_non_blocking( hwid, start_addr, values, vals_length, 0 );
	while( state != I2C_IDLE );
}

void _I2CGet_blocking( unsigned char hwid, unsigned char start_addr, 
		   unsigned char *values, unsigned char vals_length )
{
	_I2CGet_non_blocking( hwid, start_addr, values, vals_length, 0 );
	while( state != I2C_IDLE );
}


#else //__ADSPBF537__
//#warning i2c_hal.c: No BF537 target specified. Compilation of i2c_hal.c omitted.
#endif //__ADSPBF537__

⌨️ 快捷键说明

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