zoukankan      html  css  js  c++  java
  • dsp28377控制DM9000收发数据——第三版程序,通过外部引脚触发来实现中断接受数据,优化掉帧现象

    //--------------------------------------------------------------------------------------------
    -
    //DSP28377 利用EMIF控制网口DM9000芯片收发数据
    //--------------------------------------------------------------------------------------------
    -
    #include "F28x_Project.h" // Device Headerfile and Examples Include File
    #include "string.h"
    void Emif1Initialize(void);
    //emif 映射地址
    #define ASRAM_CS3_START_ADDR 0x37FFF0
    #define ASRAM_CS3_SIZE 0x8000
    interrupt void xint1_isr(void);
    extern void setup_emif1_pinmux_async_16bit(Uint16);
    #pragma DATA_SECTION(datafrompc , "RAMGS0");
    Uint16 datafrompc[12288];
    //地址指定;通过操作指针实现地址对应数据操作
    Uint16 *ADDR_POINT = (Uint16 *)(ASRAM_CS3_START_ADDR);
    Uint16 *DATA_POINT = (Uint16 *)(ASRAM_CS3_START_ADDR + 1);
    //##########DM9000 SETING ######################
    #define DM_NCR 0X00
    #define DM_NSR 0X01
    #define DM_TCR 0X02
    #define DM_RCR 0X05
    #define DM_BPTR 0X08
    #define DM_FCTR 0X09
    #define DM_RTFCR 0X0A
    #define DM_EPCR 0X0B
    #define DM_EPAR 0X0C
    #define DM_EPDRL 0X0D
    #define DM_EPDRH 0X0E
    #define DM_PAB0 0X10
    #define DM_PAB1 0X11
    #define DM_PAB2 0X12
    #define DM_PAB3 0X13
    #define DM_PAB4 0X14
    #define DM_PAB5 0X15
    #define DM_GPCR 0X1E
    #define DM_GPR 0X1F
    #define DM_SMCR 0X2F
    #define DM_MRCMDX 0XF0
    #define DM_MRCMD 0XF2
    #define DM_MWCMD 0XF8
    #define DM_TXPLH 0XFD
    #define DM_TXPLL 0XFC
    #define DM_ISR 0XFE
    #define DM_IMR 0XFF
    #define PHY_BADDR 0X40
    #define PHY_WCMD 0X0A
    #define PHY_RCMD 0X0C
    Uint16 NODE_ADDR[6] = {0X5A , 0X5A , 0X5A , 0X5A , 0X5A , 0X5A};
    Uint16 PHYIntFlag = 0;
    Uint16 RxReady = 0;
    Uint16 SweepMode = 0;
    Uint16 Index[24] = {0 , 512 , 1024 , 1536 , 2048 , 2560 , 3072 , 3584 , 4096 , 4608 , 5120 ,
    5632 , 6144 , 6656 ,
    7168 , 7680 , 8192 , 8704 , 9216 , 9728 , 10240 , 10752 ,
    11264 ,11776};
    //----------------------------------------------------------------------------------
    //检测到PHY中断信号并触发中断 ---------------------------------------------------------------
    interrupt void xint1_isr(void)
    {
    GpioDataRegs.GPBCLEAR.all = 0x4; // GPIO34 is low
    // Acknowledge this interrupt to get more from group 1
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    PHYIntFlag = 1;
    }
    //---------------------------------------------------------------------
    // 向DM9000内部寄存器写值
    void iow(Uint16 IOADDR , Uint16 REGDARA){
    *ADDR_POINT = IOADDR;
    DELAY_US(20);
    *DATA_POINT = REGDARA;
    DELAY_US(20);
    }
    //---------------------------------------------------------------------
    // 读取DM9000内部寄存器的值
    Uint16 ior(Uint16 IOADDR){
    DELAY_US(20);
    *ADDR_POINT = IOADDR;
    DELAY_US(20);
    return(*DATA_POINT);
    }
    //---------------------------------------------------------------------
    // 往固定地址写值
    void outw(Uint16 REGDATA , Uint16 addr_data_type){
    if(addr_data_type == 1) *DATA_POINT = REGDATA;
    else if(addr_data_type == 2) *ADDR_POINT = REGDATA;
    DELAY_US(50);
    }
    //---------------------------------------------------------------------
    //读取DM9000当前地址值
    Uint16 inw(){
    return *DATA_POINT;
    }
    //---------------------------------------------------------------------
    //写物理接口PHY寄存器的值
    void phy_write(Uint16 offset , Uint16 REGIN){
    iow(DM_EPAR , (offset | PHY_BADDR));
    iow(DM_EPDRH , (REGIN >> 8) & 0x00ff);
    iow(DM_EPDRL , (REGIN & 0x00ff));
    iow(DM_EPCR , PHY_WCMD);
    while((ior(DM_EPCR) & 1));
    DELAY_US(200);
    iow(DM_EPCR , 0x08);
    }
    //---------------------------------------------------------------------
    //读物理接口PHY寄存器的值
    Uint16 phy_reaad(Uint16 offset , Uint16 REGIN){
    Uint16 returndata=0;
    iow(DM_EPAR , (offset | PHY_BADDR));
    iow(DM_EPCR , PHY_RCMD);
    while((ior(DM_EPCR) & 1));
    DELAY_US(200);
    iow(DM_EPCR , 0x08);
    returndata = ior(DM_EPDRH);
    returndata = (returndata << 8) | ior(DM_EPDRL);
    return returndata;
    }
    //---------------------------------------------------------------------
    //DM9000 初始化
    void DM9000_INIT(){
    //开启PHY
    iow(DM_GPR , 0X00);
    //softerware reset and setting as normal mode(TWICE)
    iow(DM_NCR , 0X01);
    DELAY_US(10000);
    iow(DM_NCR , 0X00);
    iow(DM_NCR , 0X01);
    DELAY_US(10000);
    iow(DM_NCR , 0X00);
    //clear the RX/TX flag
    iow(DM_NSR, 0x2C);
    iow(DM_ISR, 0x3F);
    // //write the NODE_ADDR to physical register
    iow(DM_PAB0 , NODE_ADDR[0]);
    iow(DM_PAB1 , NODE_ADDR[1]);
    iow(DM_PAB2 , NODE_ADDR[2]);
    iow(DM_PAB3 , NODE_ADDR[3]);
    iow(DM_PAB4 , NODE_ADDR[4]);
    iow(DM_PAB5 , NODE_ADDR[5]);
    -3-C:UsershaviDesktopDM9000_CTR.c 2016年11月23日 17:10
    //Eenable RX/TX function
    iow(DM_RCR , 0x31);//去掉混杂模式//iow(DM_RCR , 0x31);
    iow(DM_TCR , 0x00);
    //setting phy of dm9000
    phy_write(0x00 , 0x8000);
    DELAY_US(100000);
    phy_write(0x04 , 0x01e1 | 0x0400);
    DELAY_US(100000);
    //set back presure threshold register
    iow(DM_BPTR , 0x3F);
    iow(DM_FCTR , 0x3A);
    iow(DM_RTFCR , 0xFF);
    iow(DM_SMCR , 0x00);
    //clear all flags agin
    iow(DM_NSR, 0x2C);
    iow(DM_ISR, 0x3B);
    //open the rx interrupt
    iow(DM_IMR , 0x81);
    DELAY_US(1000);
    }
    //--------------------------------------------------------------------------------------
    //发送网络包
    void PACKE_SEND(Uint16 *datain , Uint16 datalen){
    Uint16 i = 0;
    Uint16 len=0;
    //关闭RX中断
    iow(DM_IMR , 0x80);
    //write length to internal sram
    //将包的长度写入到寄存器中;
    len = datalen * 2;
    iow(DM_TXPLH , ((len&0xff00)>>8));
    iow(DM_TXPLL , len&0x00ff);
    //DM_MWCMD is pointer to internal TX sdram address
    outw(DM_MWCMD , 2);
    //write data int internal sram
    for(i = 0; i < datalen ; i++) outw(datain[i] , 1);
    //start transmit
    iow(DM_TCR , 0X01);
    // wait transmit complit
    while((ior(DM_NSR) & 0x0c) == 0);
    DELAY_US(20);
    //clear the tx flag
    iow(DM_NSR , 0X2C);
    //oprn rx intterupt
    iow(DM_IMR , 0x81);
    }
    //----------------------------------------------------------------------------------------
    //接受网络包
    //在调试的过程中;通过一片DSP发送1040个数据(8bit);并设置发送长度为1040;但对于接受的网络包
    而言;不仅仅会在接收到的网络包前包含4个
    //信息byte;分别是接受准备;接受状态位;帧长度(2byte);后面跟随1040个数据(byte);后面还会
    跟随4个byte位;作用不知;同时接受到的
    //帧长度为1044个;所以在读取数据是必须读取完成整个1044个数据;rx指针才会自动跳转到SRAM的首地址
    等待下一次触发
    //数据包后面还跟随了2个word的校验位
    void PACKE_RECIVE(Uint16 *datain , Uint16 *data_ready , Uint16 *Type_mode){
    Uint16 i = 0;
    Uint16 rx_length = 0;
    Uint16 state = 0;
    Uint16 ready = 0;
    Uint16 phy_addr[6];
    Uint16 mode_typ = 0;
    Uint16 cnt = 0;
    //获取中断标识
    state = ior(DM_ISR);
    if(state & 0x01){
    //清除中断标志
    iow(DM_ISR , 0x01);
    //将rx指针指向SRAM(此指针的指向方式为读取数据后指针不会自动增加)
    ready = ior(DM_MRCMDX);
    DELAY_US(200);
    //在读取一次状态寄存器
    ready = ior(DM_MRCMDX);
    //取状态寄存器的低8位
    ready = ready & 0X00FF;
    if(ready == 0x01){
    //将rx指针指向SRAM(此指针的指向方式为读取数据后指针会自动增加)
    outw(DM_MRCMD , 2);
    //读取状态信息
    rx_length = inw();
    //读取帧字节数
    rx_length = inw();
    phy_addr[0] = inw();phy_addr[1] = inw();phy_addr[2] = inw();
    phy_addr[3] = inw();phy_addr[4] = inw();phy_addr[5] = inw();
    mode_typ = inw();
    cnt = inw();
    rx_length = (rx_length - 16)/2;
    for(i=0;i<rx_length;i++){
    *(datain + i + Index[cnt]) = inw();
    }
    if(cnt == 23){
    *data_ready = 1;
    *Type_mode = mode_typ;
    }
    }
    else if(ready == 0x00)
    {
    iow(DM_IMR , 0x80);
    iow(DM_ISR , 0x0F);
    iow(DM_RCR , 0x00);
    iow(DM_NCR , 0x01);
    DELAY_US(20);
    iow(DM_NSR, 0x2C);
    iow(DM_ISR, 0x80);
    iow(DM_RCR, 0x39);
    }
    }
    iow(DM_ISR , 0x01);
    iow(DM_IMR , 0x81);
    }
    //--------------------------------------------------------------------------
    //emif 设置
    void emifsetting()
    {
    Emif1Initialize();
    //Configure to run EMIF1 on full Rate (EMIF1CLK = CPU1SYSCLK)
    EALLOW;
    ClkCfgRegs.PERCLKDIVSEL.bit.EMIF1CLKDIV = 0x1;
    EDIS;
    EALLOW;
    //Grab EMIF1 For CPU1
    Emif1ConfigRegs.EMIF1MSEL.all = 0x93A5CE71;
    //Disable Access Protection (CPU_FETCH/CPU_WR/DMA_WR)
    Emif1ConfigRegs.EMIF1ACCPROT0.all = 0x0;
    if (Emif1ConfigRegs.EMIF1ACCPROT0.all != 0x0)
    {
    while(1);
    }
    // Commit the configuration related to protection. Till this bit remains set
    // content of EMIF1ACCPROT0 register can't be changed.
    Emif1ConfigRegs.EMIF1COMMIT.all = 0x1;
    if(Emif1ConfigRegs.EMIF1COMMIT.all != 0x1)
    {
    while(1);
    }
    // Lock the configuration so that EMIF1COMMIT register can't be changed any more.
    Emif1ConfigRegs.EMIF1LOCK.all = 0x1;
    if (Emif1ConfigRegs.EMIF1LOCK.all != 1)
    {
    while(1);
    }
    //
    EDIS;
    //
    // //Configure GPIO pins for EMIF1
    setup_emif1_pinmux_async_16bit(0);
    //
    // //Configure the access timing for CS2 space
    //net
    Emif1Regs.ASYNC_CS3_CR.all = ( EMIF_ASYNC_ASIZE_16 | // 16Bit Memory Interface
    EMIF_ASYNC_TA_3 | // Turn Around time of 2 Emif
    Clock
    EMIF_ASYNC_RHOLD_1 | // Read Hold time of 1 Emif
    Clock
    EMIF_ASYNC_RSTROBE_5 | // Read Strobe time of 4 Emif
    Clock
    EMIF_ASYNC_RSETUP_1 | // Read Setup time of 1 Emif
    Clock
    EMIF_ASYNC_WHOLD_1 | // Write Hold time of 1 Emif
    Clock
    EMIF_ASYNC_WSTROBE_2 | // Write Strobe time of 1 Emif
    Clock
    EMIF_ASYNC_WSETUP_1 | // Write Setup time of 1 Emif
    -6-C:UsershaviDesktopDM9000_CTR.c 2016年11月23日 17:10
    Clock
    EMIF_ASYNC_EW_DISABLE | // Extended Wait Disable.
    EMIF_ASYNC_SS_DISABLE // Strobe Select Mode Disable.
    );
    }
    //--------------------------------------------------------------------------
    //GPIO中断触发设置
    void GPIOINTsetting(){
    //设置中断触发组1
    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.XINT1_INT = &xint1_isr;
    EDIS; // This is needed to disable write to EALLOW protected registers
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
    PieCtrlRegs.PIEIER1.bit.INTx4 = 1; // Enable PIE Group 1 INT4
    PieCtrlRegs.PIEIER1.bit.INTx5 = 1; // Enable PIE Group 1 INT5
    IER |= M_INT1; // Enable CPU INT1
    EINT;
    //出发源为外部引脚GPIO55,此引脚链接至DM9000的中断引脚
    EALLOW;
    GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 0; // GPIO
    GpioCtrlRegs.GPBDIR.bit.GPIO55 = 0; // input
    GpioCtrlRegs.GPBQSEL2.bit.GPIO55 = 0;
    EDIS;
    GPIO_SetupXINT1Gpio(55);
    //设置引脚上升沿出发中断
    XintRegs.XINT1CR.bit.POLARITY = 1; // Falling edge interrupt
    XintRegs.XINT1CR.bit.ENABLE = 1; // Enable XINT1
    }
    //-------------------------------------------------------------------
    // 主函数
    void main(void)
    {
    Uint16 i = 0;
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    EALLOW;
    IER = 0x0000;
    IFR = 0x0000;
    EDIS;
    InitPieVectTable();
    GPIOINTsetting();
    emifsetting();
    DM9000_INIT();
    DELAY_US(500000);
    //********************************************************************
    //接受数据测试段代码
    //******************************************************************
    while(1){
    if(PHYIntFlag == 1){
    PHYIntFlag = 0;
    PACKE_RECIVE(&datafrompc[0] , &RxReady , &SweepMode);
    if(RxReady == 1){
    RxReady = 0;
    //过程处理
    ESTOP0;
    memset(&datafrompc[0] , 0 , 12288);
    }
    }
    }
    //*************************************************************************
    //发送数据测试段代码
    //*************************************************************************
    // databuffer[0] = 0xFFFF; databuffer[1] = 0xFFFF; databuffer[2] = 0xFFFF;
    // databuffer[3] = 0x285B; databuffer[4] = 0xC92D; databuffer[5] = 0x587D;
    // databuffer[6] = 0X00;databuffer[7]=0X00;
    //
    // for(i = 0 ; i< 512 ; i++){
    // databuffer[i+8] = i;
    // }
    //
    // while(1){
    // PACKE_SEND(&databuffer[0] , buffersize);
    //
    // DELAY_US(1000);
    // }
    }
    
  • 相关阅读:
    android测试开发环境搭建
    通过CMD命令行创建和使用Android 模拟器 AVD
    android 内存泄露测试
    NullPointerException检测
    iOS Automated Tests with UIAutomation
    命令方式重新签名apk
    Monkey log分析说明
    jQuery选择器总结[转]
    Java工程带库编译运行
    【转】从零开始学习Gradle之二---如何使用Task
  • 原文地址:https://www.cnblogs.com/havihouston/p/6094538.html
Copyright © 2011-2022 走看看