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

📄 dsp.c

📁 ARM得编程实例。很经典。在win ce5.0环境下的编程实例
💻 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 + -