📄 dsp.c
字号:
/*******************************************************************
*******************************************************************/
#include "..\system.h"
//#ifdef ARM_XSCALE_CPU
// #include <string.h>
//#endif
#ifdef INTEL_X86_CPU
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#endif
#include "..\utility.h"
#include "..\syscst.h"
#include "..\dbstru.h"
#include "..\address.h"
#include "..\hardware.h"
#include "..\dbs\dbs.h"
#include "dsp.h"
/**************************** 常量定义 *************************************/
#define MS_SWITCH 8 /* Task2Parameter[MS_SWITCH] : dp master state flag */
#define WAITDATARIGHTTIMEOUT 10 /* 等待数据权限超时时间100ms */
#define WAITMAILRIGHTTIMEOUT 10 /* 等待邮箱权限超时时间100ms */
/*************************** 调试变量和函数 ********************************/
#if defined(INTEL_X86_CPU) && defined(DEBUG)
static FILE *pFLog = NULL; /* dp parameter log file */
#endif
/***************************** 全局变量定义 ********************************/
INT8U bDspWTO = 0; /* 是否启动Dsp超时计数器 */
INT16U dspTimeout = 0; /* 等待Dsp超时计数器 */
/***************************** 局部变量定义 ********************************/
static INT8U SetMask[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
/**************************** 函数声明 *************************************/
static void ResetDsp(void); /* 复位Dsp */
static INT16U DownloadBusParm(void); /* 下装总线参数 */
static INT16U DownloadSlavePrm(void); /* 下装从站参数 */
static void FillIOPrm(IOSTRUCT *); /* 填写从站参数 */
static BOOL IsHaveMailRight(void); /* 判断是否拥有邮箱区权限 */
static BOOL IsHaveDataRight(void); /* 判断是否拥有数据区权限 */
static BOOL IsDspReady(void); /* 判断Dsp是否准备好 */
static INT8U ReadMail(void); /* 读dsp发送的邮件 */
static INT16U WaitMailRight(void); /* 等待得到邮箱区权限(dsp交回) */
static INT16U WaitDataRight(void); /* 等待得到数据区权限(dsp交回) */
/**************************** 全局函数定义 *********************************/
/* DP主站初始化 */
INT16U DPInit(void)
{
#if defined(INTEL_X86_CPU) && defined(DEBUG)
pFLog = fopen("dp_log.txt", "wt");
#endif
ResetDsp();
/* 等待Dsp初始化完成 */
while (FALSE == IsDspReady()) ;
/* 设置DP主站为侦听状态 */
SetDPState(DPLISTEN);
pDPRAM->Others[0] = 0x00;
pDPRAM->Others[1] = 0x00;
pDPRAM->Others[2] = 0x00;
/* 下装从站参数 */
if ( DownloadSlavePrm() != SYS_NOERR )
{
return(DPMError(DP_SLAVEPRM_ERROR));
}
/* 下装总线参数 */
if ( DownloadBusParm() != SYS_NOERR )
{
return(DPMError(DP_BUSPRM_ERROR));
}
/* 等待数据区权限 */
if ( WaitDataRight() != SYS_NOERR )
{
return(DPMError(DP_WAIT_DATA_TIMEOUT));
}
#if defined(INTEL_X86_CPU) && defined(DEBUG)
if (pFLog != NULL)
{
fclose(pFLog);
}
#endif
return(SYS_NOERR);
}
INT16U DPClose(void)
{
SetDPState(DPLISTEN);
return(SYS_NOERR);
}
/* 设置DP主站的状态 */
void SetDPState(BOOL bstate)
{
pDPRAM->Task2Parameter[MS_SWITCH] = (INT8U)bstate;
}
/* 与Dsp交换数据 */
void ExchangeData(void)
{
INT16U i = 0;
RunDEVSTRUCT *pRunDev;
WaitDataRight();
flashLed((INT8U)DP_LED);
/* 处理所有从站 */
pRunDev = (RunDEVSTRUCT *)(DBS_ADDRESS);
if (NULL == pRunDev)
{
failureExit();
}
for (i = 0; i < dpPrmCfg[0].nTotal; i++)
{
if (pRunDev->RcvDataLen > 0)
{ /* 复制输入数据 */
memcpy((void*)(pRunDev->pInData),
(void*)(pRunDev->IOM.pDPRIn), pRunDev->RcvDataLen);
}
if (pRunDev->SndDataLen > 0)
{ /* 复制输出数据 */
memcpy((void*)(pRunDev->IOM.pDPROut), (void*)(pRunDev->pOutData),
(unsigned short)(pRunDev->SndDataLen));
}
if ((pDPRAM->Sl_state[pRunDev->IOM.Addr /8] &
SetMask[pRunDev->IOM.Addr %8]) != 0)
{
pRunDev->IOM.OnLine = 1; /* 在线 */
}
else
{
pRunDev->IOM.OnLine = 0; /* 离线 */
}
pRunDev++; /* 指向下一个设备 */
}
} /* End of ExchangeData */
/* 发送全局控制报文(不使用同步和冻结功能) */
void DpBroadCast(void)
{
static INT8U y = 0;
pDPRAM->SMsg.Rx = 3;
pDPRAM->SMsg.Tx = 16;
pDPRAM->SMsg.Ln = 3;
pDPRAM->SMsg.Nr = 'J';
pDPRAM->SMsg.A = 0;
pDPRAM->SMsg.F = 0;
pDPRAM->SMsg.B = 70;
pDPRAM->SMsg.E = 'K';
pDPRAM->SMsg.D[0] = 127;
/* D[1]字节必须每周期发生变化,才能保证SPC3产生中断*/
if ( (y++) % 2 == 0)
{
pDPRAM->SMsg.D[1] = 0x10;
}
else
{
pDPRAM->SMsg.D[1] = 0x00;
}
/* D[2]字节表示组号,0x00表示不分组,0x04表示OCM组 */
pDPRAM->SMsg.D[2] = 0x04;
pDPRAM->DevFlags ^= 0x02;
} /* End of DpBroadCast */
/*
功能: 轮询IO模块
参数: polltype IO模块类型
0xAA ICM从站
0x55 OCM从站
0xFF 所有从站
0x00 不轮询任何从站
返回值: 无
*/
void PollIO(INT8U polltype)
{
pDPRAM->Others[0] = polltype;
if (IsHaveDataRight())
{
pDPRAM->DevFlags ^= 0x04;
}
/* WaitDataRight(); */
}
/* DP是否出于活动状态 */
BOOL IsDpActive(void)
{
return(DPACTIVE == pDPRAM->Task2Parameter[MS_SWITCH]);
}
/**************************** 局部函数定义 *********************************/
/* 复位Dsp */
static void ResetDsp(void)
{
pDPRAM->DevFlags |= 0xC0; /* restart dsp */
while (pDPRAM->DevFlags != 0x00) /* wait dsp reset finish */
{
#if defined(INTEL_X86_CPU) && defined(DEBUG)
wprintf(0, 60, "%02X %02X", pDPRAM->DevFlags, pDPRAM->HostFlags);
#endif
}
}
/* 下装总线参数 */
static INT16U DownloadBusParm(void)
{
INT16U wPrmLen = 0;
WaitMailRight();
/* 消息头 */
pDPRAM->SMsg.Rx = 3;
pDPRAM->SMsg.Tx = 16;
pDPRAM->SMsg.Ln = 30;
pDPRAM->SMsg.Nr = 'J';
pDPRAM->SMsg.A = 0;
pDPRAM->SMsg.F = 0;
pDPRAM->SMsg.B = 68;
pDPRAM->SMsg.E = 'K';
/* 报文头 */
pDPRAM->SMsg.D[0] = 0;
pDPRAM->SMsg.D[1] = 127;
pDPRAM->SMsg.D[2] = 0;
pDPRAM->SMsg.D[3] = 0;
/* 总线参数 */
if (dpPrmCfg[0].pdpprm != NULL)
{
/* 读入参数长度 */
wPrmLen = MAKEWORD(*(INT8U*)(dpPrmCfg[0].pdpprm),
*(INT8U*)(dpPrmCfg[0].pdpprm + 1));
/* 拷贝参数 */
memcpy((void*)&pDPRAM->SMsg.D[4],
(void*)(dpPrmCfg[0].pdpprm), wPrmLen);
}
pDPRAM->DevFlags ^= 0x02;
#if defined(INTEL_X86_CPU) && defined(DEBUG)
{
INT8U j = 0;
if (pFLog != NULL) {
fprintf(pFLog, "\n----Bus parameter----\n");
for (j = 0; j < pDPRAM->SMsg.Ln; j++) {
if ((j % 20 == 0) && (j != 0)) {
fprintf(pFLog, "\n");
}
fprintf(pFLog, "%02X ", pDPRAM->SMsg.D[j]);
}
}
}
#endif
WaitMailRight();
return(ReadMail());
} /* End of DownloadBusParm */
/* 下装从站参数 */
static INT16U DownloadSlavePrm(void)
{
INT16U i = 0;
RunDEVSTRUCT *pRunDev; /* 设备运行结构指针 */
#if defined(INTEL_X86_CPU) && defined(DEBUG)
if (pFLog != NULL) {
fprintf(pFLog, "----Slave parameter----\n");
}
#endif
pRunDev = (RunDEVSTRUCT *)(DBS_ADDRESS);
if (NULL == pRunDev)
{
failureExit();
}
for (i = 0; i < dpPrmCfg[0].nTotal ; i++)
{
WaitMailRight();
FillIOPrm((IOSTRUCT*)&(pRunDev->IOM));
pDPRAM->DevFlags ^= 0x02;
WaitMailRight();
if (ReadMail())
{
return(1);
}
pRunDev++; /* 指向下一个设备 */
}
return(0);
} /* End of DownloadSlavePrm */
/* 填写从站参数 */
static void FillIOPrm(IOSTRUCT *pIO)
{
INT16U wPrmLen = 0;
INT8U i = 0;
/* 消息头 */
pDPRAM->SMsg.Rx = 3;
pDPRAM->SMsg.Tx = 16;
pDPRAM->SMsg.Nr = 'J';
pDPRAM->SMsg.A = 0;
pDPRAM->SMsg.F = 0;
pDPRAM->SMsg.B = 68;
pDPRAM->SMsg.E = 'K';
/* 报文头 */
pDPRAM->SMsg.D[0] = 0;
pDPRAM->SMsg.D[1] = pIO->Addr; /* slave address */
pDPRAM->SMsg.D[2] = 0;
pDPRAM->SMsg.D[3] = 0;
/* 从站参数 */
if (pIO->pSlavePrm != NULL)
{
/* 读入参数长度 */
wPrmLen = MAKEWORD(*(INT8U*)(pIO->pSlavePrm),
*(INT8U*)(pIO->pSlavePrm + 1));
/* 拷贝参数 */
memcpy((void*)&pDPRAM->SMsg.D[4],
(void*)(pIO->pSlavePrm), wPrmLen);
i = (INT8U)(wPrmLen - 8 + 4);
pDPRAM->SMsg.D[i] = 1; /* Input Count */
pDPRAM->SMsg.D[i + 1] = 1; /* Output Count */
/* Input Offset */
pDPRAM->SMsg.D[i + 2] = LOBYTE(pIO->OffsetIn);
pDPRAM->SMsg.D[i + 3] = (INT8U)(HIBYTE(pIO->OffsetIn) | 0x80);
/* Output Offset */
if (pIO->OffsetOut != 0x0000)
{
pDPRAM->SMsg.D[i + 4] = LOBYTE(pIO->OffsetOut);
pDPRAM->SMsg.D[i + 5] = (INT8U)(HIBYTE(pIO->OffsetOut) | 0x80);
}
else
{
/* Output Offset */
pDPRAM->SMsg.D[i + 4] = (INT8U)0x00;
pDPRAM->SMsg.D[i + 5] = 0x80;
}
}
/* 计算实际消息长度 */
pDPRAM->SMsg.Ln = (INT8U)(MAKEWORD(pDPRAM->SMsg.D[4],
pDPRAM->SMsg.D[5]) + 4);
#if defined(INTEL_X86_CPU) && defined(DEBUG)
{
INT16U j = 0;
if (pFLog != NULL)
{
fprintf(pFLog, "\nstation:%d\n", pIO->Addr);
for (j = 0; j < pDPRAM->SMsg.Ln; j++)
{
if ((j % 20 == 0) && (j != 0))
{
fprintf(pFLog, "\n");
}
fprintf(pFLog, "%02X ", pDPRAM->SMsg.D[j]);
}
}
}
#endif
} /* End of FillIOPrm */
static BOOL IsHaveMailRight(void)
{
if (((pDPRAM->HostFlags ^ pDPRAM->DevFlags) & 0x03) != 0x02)
{
return(TRUE);
}
else
{
return(FALSE);
}
}
static BOOL IsHaveDataRight(void)
{
if (((pDPRAM->HostFlags ^ pDPRAM->DevFlags) & 0x04) != 0 )
{
return(TRUE);
}
else
{
return(FALSE);
}
}
static BOOL IsDspReady(void)
{
return((pDPRAM->HostFlags & 0x80) == 0x80);
}
static INT8U ReadMail(void)
{
if (((pDPRAM->HostFlags ^ pDPRAM->DevFlags) & 0x01) == 0x01)
{
if (pDPRAM->RMsg.F != 0)
{
return(1);
}
pDPRAM->DevFlags ^= 0x01;
}
return(0);
}
/* 等待邮箱权限 */
static INT16U WaitMailRight(void)
{
bDspWTO = 0xAA;
dspTimeout = 0;
while (FALSE == IsHaveMailRight())
{
if (dspTimeout > WAITMAILRIGHTTIMEOUT)
{
bDspWTO = 0x00;
dspTimeout = 0;
return(DPMError(DP_WAIT_MAIL_TIMEOUT));
}
}
bDspWTO = 0x00;
dspTimeout = 0;
return(SYS_NOERR);
} /* End of WaitMailRight */
/* 等待数据权限 */
static INT16U WaitDataRight(void)
{
bDspWTO = 0xAA;
dspTimeout = 0;
while (FALSE == IsHaveDataRight())
{
if (dspTimeout > WAITDATARIGHTTIMEOUT)
{
bDspWTO = 0x00;
dspTimeout = 0;
return(DPMError(DP_WAIT_DATA_TIMEOUT));
}
}
bDspWTO = 0x00;
dspTimeout = 0;
return(SYS_NOERR);
} /* End of WaitDataRight */
#if defined(INTEL_X86_CPU) && defined(DEBUG)
/* 调试函数 */
void dump_DPRam(void)
{
static INT16U ngood = 0, nbad = 0, nwrong = 0;
RunDEVSTRUCT *ptmp = NULL;
INT8U i = 0;
wprintf(2, 55, "%02x %02x", pDPRAM->bGlobalBits, pDPRAM->DPM_state);
wprintf(3, 55, "%02x %02x", pDPRAM->HostFlags, pDPRAM->DevFlags);
if (IsHaveDataRight())
{
wprintf(2, 0, "stat:");
for (i = 0; i < 16; i++)
{
wprintf(2, (INT8U)(i*3+5), "%02X ", pDPRAM->Sl_state[i]);
}
wprintf(3, 0, "cfg :");
for (i = 0; i < 16; i++)
{
wprintf(3, (INT8U)(i*3+5), "%02X ", pDPRAM->Sl_cfg[i]);
}
wprintf(4, 0, "diag:");
for (i = 0; i < 16; i++)
{
wprintf(4, (INT8U)(i*3+5), "%02X ", pDPRAM->Sl_diag[i]);
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -