📄 hpi.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 + -