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

📄 hpi.c

📁 lpc2290通过HPI访问DSP5402的子程序
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                              深圳振华重大新电气有限公司
**                                      技术开发部
**
**-----------------------------------------------------------------------------------------------------
** 文件名:			HPI.c
** 最后修改日期:    2005-08-25
** 最后版本:		1.0
** 描述:		    使用并口对DSP的HPI口(内部80H-4000H)进行访问。
**                  DSP的HPI映象到ARM的0x83000000(NCS3)。
**                  使用此程序时要求DSP配合,DSP不能处于复位状态,否则不能写入到DSP中去。
**
**------------------------------------------------------------------------------------------------------
** 创建者:			CXP
** 创建日期:		2005-08-25
** 版本:			1.0
** 描述:		    原始版本
**
**------------------------------------------------------------------------------------------------------
** 修改者:          LSJ
** 修改日期:        2005-09-15
** 版本:
** 描述:
**
********************************************************************************************************/
#define  HPI_GLOBALS

#include  "Main.h"
#include  "HPI.h"

#if  _MY_DEBUG_COUNTER > 0
	uint32  LSJ20_IRQ_EINT2 = 0;
	uint32  LSJ21 = 0;
#endif

/********************************************************************************************************
**                                       HPI初始化
**           bob must be initialized before the first data or address register access
**
********************************************************************************************************/
void HPIInit(void)
{
 	HPIC_W_F = 0x01;              // bob = 1 (第一字节为低位,第二字节为高位)
  	HPIC_W_S = 0x01;
}

/********************************************************************************************************
**                                     写地址到HPIA中
********************************************************************************************************/
void HPISetAddr(uint16 addr)
{  
 	HPIA_W_F=(uint8)(addr & 0xff);
  	HPIA_W_S=(uint8)((addr >> 8) & 0xff);
}

/********************************************************************************************************
**                                     从DSP中读出一个数据
********************************************************************************************************/
uint16 HPIReadOneData(uint16 addr)
{
	uint16 i, j;
	
	HPISetAddr(addr);  /* 设置起始地址                                                                 */
                       /* 当从DSP中读取数据时,地址在读之后自动增长,因此必须设置为addr才能正确访问.   */
	i=HPID_R_A_F;      /* 读出第一字节                                                                 */
	j=HPID_R_A_S;      /* 读出第二字节                                                                 */

	i=(j<<8)|(i &0xff);
	
	return i;
}

/********************************************************************************************************
**                                     从DSP中读出指定数据到指定地址
********************************************************************************************************/
uint8 HPIReadLenData(uint16 addr, uint16 len, uint8 *data1)
{
	uint16  i;
 
	HPISetAddr(addr);

	for(i=0;i<len;i++)
	{ 
		*data1 ++ = HPID_R_A_F;   //HPI已经设置传输的第1字节为低字节;ARM为小端模式,低字节放在低地址      
		*data1 ++ = HPID_R_A_S;  
	}
	return 1;
}

/********************************************************************************************************
**                           从DSP中读出指定数据到指定地址,每2个字节都用信号量保护
********************************************************************************************************/
uint8 HPIReadLenDataSem(uint16 addr, uint16 len, uint8 *data1)
{
	uint8   err;
	uint16  i;

	for(i=0;i<len;i++)
	{ 
		OSSemPend(SemHPI, 0, &err);
		HPISetAddr(addr ++);
		*data1 ++ = HPID_R_A_F;
		*data1 ++ = HPID_R_A_S;
		OSSemPost(SemHPI);		  

	}	
	return 1;
}

/********************************************************************************************************
**                                     写数据到DSP中去
********************************************************************************************************/
void HPIWriteOneData(uint16 addr,uint16 data)
{
	
	HPISetAddr(addr-1);  /* 设置起始地址                                                               */
                         /* 当写数据到DSP中时,地址在写之前自动增长,因此必须设置为addr-1才能正确访问. */
	HPID_W_A_F = (uint8)(data&0xff);   /* 写入第一字节                                            */
	HPID_W_A_S = (uint8)((data>>8)&0xff);        /* 写入第二字节                                            */
	
}

/********************************************************************************************************
**                                     写指定长度的16位数据到指定地址
********************************************************************************************************/
uint8 HPIWriteLenData(uint16 addr,uint16 len,uint16 *data1)
{
 uint16 *p;
 uint16 i;

 p=data1;
 HPISetAddr(addr-1);
 for(i=0;i<len;i++)
 {
 	HPID_W_A_F =(uint8)((*p)&0xff);  //写入第一字节
 	HPID_W_A_S =(uint8)(((*p)>>8)&0xff);       //写入第二字节
 	
 	p++;
 }
 return 1;
}


/********************************************************************************************************
**                         写指定长度的8位单字节数据到指定地址,源数据的高、低字节放在两个地方
********************************************************************************************************/
uint8 HPIWriteLenCharData2(uint16 addr,uint16 len,uint8 *bufh,uint8 *bufl)
{
	uint8 *ph;
	uint8 *pl;
	uint16 i;

	ph=bufh;
	pl=bufl;
	HPISetAddr(addr-1);
	for(i=0;i<len;i++)
	{
		HPID_W_A_F = *pl;  /* 写入第一字节 */
		HPID_W_A_S = *ph;  /* 写入第二字节 */

		pl++;
		ph++;
	}
	return 1;

}

/********************************************************************************************************
**                                     ARM中断DSP
********************************************************************************************************/
void HPIInterruptDSP(void)
{
	HPIC_W_F = 0x5;  //dspint=1, 保持BOB==1
	HPIC_W_S = 0x5;
}

/********************************************************************************************************
**                                    ARM清除来自DSP的中断
********************************************************************************************************/
void HPIInterruptClear(void)
{
	HPIC_W_F = 0x9;  //HINT=0, 保持BOB==1
	HPIC_W_S = 0x9;
}

/********************************************************************************************************
**                                ARM的外部中断2入口,即DSP产生的HPI中断
********************************************************************************************************/
#if  _MY_DEBUG_HPIINT > 0
	extern  uint16  LSJ_DSPToARMCmd[100];
	extern  uint16  LSJ_DSPToARMCmdCnt;
#endif

void  IRQ_EINT2(void)
{
	
	HPIInterruptClear();                                  /* 清除HPI中断标记位                         */
	EXTINT  |=4;                                          /* 清除外部中断标记位,否则一直产生中断      */
	VICVectAddr = 0x00;                                   /* 通知VIC中断处理结束                       */

#if  _MY_DEBUG_COUNTER > 0
	LSJ20_IRQ_EINT2 ++;                                   /* 测试ARM进入HPI中断的次数                  */
#endif

	if(ARMProgState == ARM_STATE_DOWNLOADING)
	{

#if  _MY_DEBUG_HPIINT > 0
		if(LSJ_DSPToARMCmdCnt < 100)
		{			
			LSJ_DSPToARMCmd[LSJ_DSPToARMCmdCnt ++] = HPIReadOneData(DSP_TO_ARM_CMD_ADDR);
		}
#endif

		FlagDSPIntARM = TRUE;                    /* 设置DSP中断ARM的标记,此标志只在下载DSP程序时使用  */
	}

	else if(ARMProgState == ARM_STATE_RUNNING)
	{
		OSSemPost(SemHPIInterrupt);
	}
}


/********************************************************************************************************
**                                初始化ARM的外部中断2入口,即DSP产生的HPI中断
********************************************************************************************************/
void Init_ARM_HPI_INT(void)
{
	PINSEL0   &= 0X3FFFFFFF;
	PINSEL0   |= 0X80000000;
	EXTMODE   |= 0X4;               // 0XF
	EXTPOLAR  &= ~0X4;              // EXTPOLAR = 0;

	HPIInterruptClear();            // 清除HPI中断标记位
	EXTINT  |=4;                    // 初始化时要清除外部中断标记位,以免一开始就产生中断
	 
	VICIntEnable |= 1 << 16;        // 使能外部中断2,即使能HPI中断

}


/********************************************************************************************************
**                                         初始化复位DSP所用到的引脚
********************************************************************************************************/
void BootInitReset(void)
{
	PINSEL0 &=ResetDspFootIO;
	IO0DIR  |=ResetDspFootDir;

}


/********************************************************************************************************
**                                           使DSP复位一次
********************************************************************************************************/
void ResetDsp(void) 
{
	uint16 i;

	IO0CLR |=ResetDspFootLow;
	for(i=0;i<1000;i++);
	IO0SET |=ResetDspFootHigh;

}


/********************************************************************************************************
**                                           文件结束
********************************************************************************************************/



⌨️ 快捷键说明

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