hw_acces.c

来自「使用ISP1362芯片的USB_OTG参考设计源代码比较新的版本」· C语言 代码 · 共 491 行

C
491
字号
/*
**  WASABI-Hot! version 1.2c   
**
**
**      -- copyright (c) 2001-2004 by Philips Japan, Ltd. -- All rights reserved --
**
**
**      ** This code has been made to check/learn                          ** 
**      **                             the ISP1362/ISP1363 functionalities **
**      ** Release 06-Aug-2004                                             **
**
**      OKANO, Akifumi
**      
**		Application Laboratory, Mobile and Connectivity
**      Semiconductors Div, Philips Japan Ltd.
**      akifumi.okano@philips.com
**      +81-3-3740-4668 
**
*/


/****************************************************************************/
/*	includes																*/
/****************************************************************************/

#include		<stdio.h>
#include		<dos.h>
#include		<conio.h>

#include		"general.h"
#include		"ui.h"

#include		"_hc_hw/hc_comm.h"
#include		"_hc_hw/hw_acces.h"
#include		"_hc_hw/pci.h"

#include		"_dc/dc_hal.h"
#include		"_dc/dc_isr.h"

/****************************************************************************/
/*	constants																*/
/****************************************************************************/

#define			DISABLE		0
#define			ENABLE		1


/****************************************************************************/
/*	global vars																*/
/****************************************************************************/

unsigned int	gp_ISA_base_address;
unsigned int	gp_1362_Hc_command_address;
unsigned int	gp_1362_Hc_data_address;

unsigned char	gp_Hc_IRQ_num;

unsigned char	gp_is_PCI					= 0;
unsigned char	gp_is_PCMCIA					= 0;
unsigned char	gp_charge_pump_external		= False;

unsigned char	gp_force_to_use_ISA			= Disabled;

unsigned char	gp_shared_IRQ;
funcPtr			gp_shared_IRQ_Dc_vector		= NULL;

unsigned char	gp_old_PCI					= False;

unsigned short	PCI_interrupt_enable[ 2 ][ 2 ]	= 	{
														{ 0x08, 0x0A },	//	for NEW  disable/enable
														{ 0x0E, 0x10 }	//	for OLD  disable/enable
													};
													


/****************************************************************************/
/*	function definitions													*/
/****************************************************************************/



/* ********** ********** ********** ********** ********** ********** **********
	IO port access functions.
   ********** ********** ********** ********** ********** ********** ********** */
   

void read_direct_access( unsigned short address, unsigned char *data, unsigned short length )	//	RAM access, read
{
	disable_INT();

	write_register32( Com32_HcDirectAddressLength, (unsigned long)length << 16 | address & 0x7FFF );
	read_register_burst_char( Com16_HcDirectAddressData, data, length );

	enable_INT();
}


void write_direct_access( unsigned short address, unsigned char *data, unsigned short length )	//	RAM access, write
{
	disable_INT();

	write_register32( Com32_HcDirectAddressLength, (unsigned long)length << 16 | address & 0x7FFF );
	write_register_burst_char( Com16_HcDirectAddressData, data, length );

	enable_INT();
}


void read_register_burst_char( unsigned short register_address, unsigned char *data, unsigned short length  )
{
	unsigned short	tmp;
	unsigned short	i;
	unsigned short	odd;
	
	odd		= length & 0x0001;
	
	if ( odd )
		length	&= ~0x1;		
	
	disable_INT();

	outport( gp_1362_Hc_command_address, register_address );

	for ( i = 0; i < length; i += 2 )
	{
		tmp		= inport( gp_1362_Hc_data_address );
		
		*(data + i + 1)		= tmp >> 8;
		*(data + i + 0)		= tmp & 0x00FF;
	}
	
	
	if ( odd )
	{
		tmp		= inport( gp_1362_Hc_data_address );
		
		*(data + i + 0)		= tmp & 0x00FF;
	}

	enable_INT();
}


void write_register_burst_char( unsigned short register_address, unsigned char *data, unsigned short length  )
{
	unsigned short	tmp;
	unsigned short	i;

	register_address	|= 0x80;

	disable_INT();

	outport( gp_1362_Hc_command_address, register_address );

	for ( i = 0; i < length; i += 2 )
	{

		tmp		= (*(data + i + 1) << 8) | *(data + i);		/*  swap bytes  */
		outport( gp_1362_Hc_data_address, tmp );		
	}
	
	enable_INT();
}


void read_register_burst_int( unsigned short register_address, unsigned char *data, unsigned short length  )
{
	unsigned short		i;

	disable_INT();

	outport( gp_1362_Hc_command_address, register_address );

	for ( i = 0; i < length; i++ )
		*data++		= inport( gp_1362_Hc_data_address );

	enable_INT();
}


void write_register_burst_int( unsigned short register_address, unsigned short *data, unsigned short length  )
{
	unsigned short		i;

	register_address	|= 0x80;

	disable_INT();

	outport( gp_1362_Hc_command_address, register_address );

	for ( i = 0; i < length; i++ )
		outport( gp_1362_Hc_data_address, *data++ );

	enable_INT();
}


unsigned long read_register32( unsigned short register_address )
{
	unsigned long		tmp;
	
	disable_INT();

	outport( gp_1362_Hc_command_address, register_address );
	tmp		 = inport( gp_1362_Hc_data_address );
	tmp		|= (unsigned long)inport( gp_1362_Hc_data_address ) << 16;

	enable_INT();

	return ( tmp );
}


void write_register32( unsigned short register_address, unsigned long value )
{
	register_address	|= 0x80;

	disable_INT();

	outport( gp_1362_Hc_command_address, register_address );	
	outport( gp_1362_Hc_data_address, (unsigned short)(value & 0x0000FFFF) );
	outport( gp_1362_Hc_data_address, (unsigned short)(value >> 16)        );

	enable_INT();
}


unsigned short read_register16( unsigned short register_address )
{
	unsigned short	tmp;

	disable_INT();

	outport( gp_1362_Hc_command_address, register_address );
	tmp	= inport( gp_1362_Hc_data_address );
	
	enable_INT();

	return ( tmp );
}


void write_register16( unsigned short register_address, unsigned short value )
{
	register_address	|= 0x80;
	
	disable_INT();

	outport( gp_1362_Hc_command_address, register_address );
	outport( gp_1362_Hc_data_address,    value            );

	enable_INT();
}


void hwacces_erase_all( void )
{
	unsigned short	i;

	write_register32( Com32_HcDirectAddressLength, 4096L << 16 | 0 );
	
	outport( gp_1362_Hc_command_address, Com16_HcDirectAddressData | 0x80 );
	
	for ( i = 0; i < 4096; i++ )
		outport( gp_1362_Hc_data_address, 0 );
}


void hwacces_memory_test( void )
{
	unsigned char	a[ 256 ];
	unsigned short	i;

	write_register32( Com32_HcDirectAddressLength, 4096L << 16 | 0 );
	
	outport( gp_1362_Hc_command_address, Com16_HcDirectAddressData | 0x80 );
	
	for ( i = 0; i < 4096; i++ )
		outport( gp_1362_Hc_data_address, i );
	
	write_register16( Com16_HcTransferCounter, 256 );
	read_register_burst_char( Com16_HcISTL0BufferPort, a, 256 );
	
	for ( i = 0; i < 256; i++ )
		mprintf( YELLOW, CONTINUE, "  %02X", a[ i ] );

	mprintf( YELLOW, CONTINUE, "\r\n" );
}


unsigned short hwacces_get_ISA_base_address( void )		//	return IO base address
{
	return ( gp_ISA_base_address );
}





/* ********** ********** ********** ********** ********** ********** **********
	IO port access initialization
   ********** ********** ********** ********** ********** ********** ********** */
   

void hwacces_io_port_access_initialize( void )
{
	 unsigned long	dummy;

	if ( !(gp_force_to_use_ISA == Enabled) )
	{
		if ( 0 != (gp_is_PCI	= pci_find_PCI_dev( 0x00068000, (ULONG *)(&gp_ISA_base_address), (ULONG *)(&gp_Hc_IRQ_num) )) )
		{
			pci_set_pci_bridge();
		}
		else if ( 0 != (gp_is_PCMCIA	= pci_find_PCI_dev( 0x00060700, &dummy, &dummy )) )
		{
			mprintf( YELLOW, CONTINUE, "\r\nit's PCMCIA\r\n" );
		}
	}
	
	if ( gp_is_PCI | gp_is_PCMCIA )
		gp_shared_IRQ	= True;
	else
		gp_shared_IRQ	= False;

	if ( gp_Dc_IRQ_num == gp_Hc_IRQ_num )
		gp_shared_IRQ	= True;
		
	if ( gp_shared_IRQ )
		gp_Dc_IRQ_num			= gp_Hc_IRQ_num;
	
	
	if ( gp_is_PCMCIA )
	{
		gp_1362_Hc_data_address			= gp_ISA_base_address;
		gp_1362_Hc_command_address		= gp_ISA_base_address + 4;
		gp_1362_Dc_data_address			= gp_ISA_base_address + 8;
		gp_1362_Dc_command_address		= gp_ISA_base_address + 12;
	}
	else
	{
		gp_1362_Hc_data_address			= gp_ISA_base_address;
		gp_1362_Hc_command_address		= gp_ISA_base_address + 2;
		gp_1362_Dc_data_address			= gp_ISA_base_address + 4;
		gp_1362_Dc_command_address		= gp_ISA_base_address + 6;
	}
	
	hwacces_isr_hw_enable();
}




unsigned long	disabled		= 0;
unsigned long	m_disabled		= 0;

void hwacces_isr_hw_disable( void )
{
	if ( disabled )
		m_disabled++;
		
	disabled++;

#ifdef	PURE_DOS
	disable_INT();
#else
	inport( gp_ISA_base_address + PCI_interrupt_enable[ gp_old_PCI ][ DISABLE ] );
#endif
}


void hwacces_isr_hw_enable( void )
{
	if ( disabled )
		disabled--;

	if ( !disabled )
#ifdef PURE_DOS
		enable_INT();
#else
		inport( gp_ISA_base_address + PCI_interrupt_enable[ gp_old_PCI ][ ENABLE ] );
#endif
}




/* ********** ********** ********** ********** ********** ********** **********
	ISR install/restore functions
   ********** ********** ********** ********** ********** ********** ********** */
   

int		get_int_num( int irq_num );
void	get_PIC_masks( int *m_lower , int *m_higher, int irq_num );


/*
**	Reference : 
**	
**		http://www.jkmicro.com/c.html	(English)
**		http://www.asahi-net.or.jp/~WR7S-NKMR/BeOS/Documents/IRQ.html
*/


isrPtr hwacces_install_isr( int irq_num, isrPtr new_vector )	//	Install ISR function to geven number IRQ
{
	int			int_num;
	int			PIC_mask1,
				PIC_mask2;
	isrPtr		old_vector;

	outportb(0xA0, 0x20);
	outportb(0x20, 0x20);

	int_num		= get_int_num( irq_num );
	get_PIC_masks( &PIC_mask1, &PIC_mask2, irq_num );


	old_vector	= getvect( int_num );
	setvect( int_num, new_vector );

	outportb( 0x21, inportb( 0x21 ) & ~PIC_mask1 );
	outportb( 0xA1, inportb( 0xA1 ) & ~PIC_mask2 );

	return ( old_vector );
}


void hwacces_restore_isr( int irq_num, isrPtr old_vector )
{
	int		int_num;
	int		PIC_mask1,
			PIC_mask2;

	int_num		= get_int_num( irq_num );
	get_PIC_masks( &PIC_mask1, &PIC_mask2, irq_num );

	setvect( int_num, old_vector );

	outportb( 0x21, inportb( 0x21 ) | PIC_mask1 );
	outportb( 0xA1, inportb( 0xA1 ) | PIC_mask2 );
}



void hwacces_clear_interrupt_controller( void )
{
	outportb( 0xA0, 0x20 );		//	Clear interrupt controller on PC
	outportb( 0x20, 0x20 );		//	Clear interrupt controller on PC	
}


static int get_int_num( int irq_num )
{

#define		LowerINTOffset		0x08
#define		HigherINTOffset		0x68

	return ( ( irq_num < 8 ) ? irq_num + LowerINTOffset : irq_num + HigherINTOffset );
}


static void get_PIC_masks( int *m_lower , int *m_higher, int irq_num )
{
	if ( irq_num < 8 )
	{
		*m_lower	= 0x01 << irq_num;
		*m_higher	= 0x00;
	}
	else
	{
		*m_lower	= 0x04;		/*	for cascaded IRQ(IRQ2)  */
		*m_higher	= 0x01 << (irq_num - 8);
	}
}















⌨️ 快捷键说明

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