PROFIBUS DP从站开发 VPC3源程序分析---vpc3_get_doutbufptr (UBYTE PTR_ATTR state_ptr)

//
/// 以下程序注释由成都地质学院霸王猫添加,引用时请尊重作者劳动成果,标明引用者来自成都地质学院霸王猫。
//

UBYTE PTR_ATTR vpc3_get_doutbufptr (UBYTE PTR_ATTR state_ptr)


    入口参数:

         无

    出口参数:
        UBYTE PTR_ATTR state_ptr

    返回值:
            输出缓冲区的指针

    调用格式:
        UBYTE                PTR_ATTR *output_buf_ptr;     // pointer to output buffer
        UBYTE   PTR_ATTR  outp_state;         // state of output data
        output_buf_ptr = vpc3_get_doutbufptr (&outp_state)


    函数功能:
        获取输出缓冲区的指针
    


    源程序:

/*---------------------------------------------------------------------------*/
/*  D e s c r i p t i o n : vpc3_get_doutbufptr                              */
/*                                                                           */
/* This function fetches the pointer to the actual output buffer.            */
/*---------------------------------------------------------------------------*/
UBYTE PTR_ATTR* vpc3_get_doutbufptr (UBYTE PTR_ATTR *state_ptr)
{
    UBYTE PTR_ATTR* p_doutbuf; // pointer to output buffer ( DP-Master -> VPC3+ )


    *state_ptr = (vpc3->ctrl_reg.rd.next_dout_buf_cmd & (VPC3_NEW_DOUT_BUF | VPC3_DOUT_BUF_CLEARED));

    switch (vpc3->ctrl_reg.rd.dout_buffer_sm & 0x30)    // locate user Dout Buffer
    {
        case 0x10:
            p_doutbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->dout_buf_ptr[0] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
            break;
            
        case 0x20:
            p_doutbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->dout_buf_ptr[1] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
            break;
            
        case 0x30:
            p_doutbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->dout_buf_ptr[2] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
            break;
            
        default:
            p_doutbuf = NULL_PTR;
            break;
    }

    return (p_doutbuf);
}

//-------------------------------------------------------------------------------------
1. 执行下面语句 
//-------------------------------------------------------------------------------------
 *state_ptr = (vpc3->ctrl_reg.rd.next_dout_buf_cmd & (VPC3_NEW_DOUT_BUF | VPC3_DOUT_BUF_CLEARED));

已知:
    (1)、#define VPC3_NEW_DOUT_BUF               ((UBYTE)0x04)
    (2)、#define VPC3_DOUT_BUF_CLEARED           ((UBYTE)0x08)
    (3)、vpc3->ctrl_reg.rd.next_dout_buf_cmd = 寄存器地址(0BH)
           当读取next_dout_buf_cmd指令时,用户获得了在数据交换后哪个缓冲器(‘U’ buffer)属于用户(即获得User-Buffer的地址指针),
           或是否发生过数据交换的信息。

        (3.1) bit3 = 用户缓冲器User-Buffer是否清除的标志位
                0 = U缓冲器中有数据
                1 = U缓冲器被清空
        (3.2) bit2 = 用户缓冲器User-Buffer的状态 
                0 = 没有新的U缓冲器
                1 = 有新的U缓冲器

        (3.3) bit1,bit0 = 指明了User-Buffer使用哪个缓冲器,即获得User-Buffer的地址指针
            01 = Dout_Buf_Ptr1
            10 = Dout_Buf_Ptr2
            11 = Dout_Buf_Ptr3    


目的:
    当用户读取 next_dout_buf_cmd 后,可得到用户缓冲器的信息,判断缓冲器是否发生变化或发生变化后哪一个缓冲器属于用户。

结果:
    (1)、0
    (2)、4
    


//-------------------------------------------------------------------------------------
2. 执行下面语句 
//-------------------------------------------------------------------------------------
    switch (vpc3->ctrl_reg.rd.dout_buffer_sm & 0x30)    // locate user Dout Buffer

已知:
    (1)、vpc3->ctrl_reg.rd.dout_buffer_sm = 寄存器地址(0AH)= 数据输出状态机的缓冲器
                             bit5   bit4             --->  U:  用户缓冲器的分配
                             0       0                NULL
                             0       1                Dout_Buf_Ptr1
                             1       0                Dout_Buf_Ptr2
                             1       1                Dout_Buf_Ptr3
目的:
    通过状态机得到数据输出缓冲区的指针。

结果:
    随机得到如下3个值。
    (1)、0x10(16)
    (2)、0x20(32)
    (3)、0x30(48)


//-------------------------------------------------------------------------------------
3. 执行下面语句 
//-------------------------------------------------------------------------------------
        case 0x10:
            p_doutbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->dout_buf_ptr[0] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
            break;
已知:
    (1)、vpc3->dout_buf_ptr[0] = 10
    (2)、SEG_MULDIV = 0x03
    (3)、VPC3_ASIC_ADDRESS = 0x2000


目的:
    获取Dout_Buf_Ptr1的物理地址。
    vpc3->ctrl_reg.rd.dout_buffer_sm = 0x10 ,表示用户缓冲器的分配使用Dout_Buf_Ptr1。

结果:
    p_doutbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->dout_buf_ptr[0] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
                  = 10 << 3  + 0x2000  = 80 + 8192 = 8272 = 0x2050

//-------------------------------------------------------------------------------------
4. 执行语句
//-------------------------------------------------------------------------------------
        case 0x20:
            p_doutbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->dout_buf_ptr[1] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS); 
            break;
已知:
    (1)、vpc3->dout_buf_ptr[1] = 41
    (2)、SEG_MULDIV = 0x03
    (3)、VPC3_ASIC_ADDRESS = 0x2000


目的:
    获取Dout_Buf_Ptr2的物理地址。
    vpc3->ctrl_reg.rd.dout_buffer_sm = 0x20 ,表示用户缓冲器的分配使用Dout_Buf_Ptr2。

结果:
    p_doutbuf = UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->dout_buf_ptr[1] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
                  = 41 << 3  + 0x2000  = 328 + 8192 = 8520 = 0x2148

//-------------------------------------------------------------------------------------
5. 执行语句
//-------------------------------------------------------------------------------------
        case 0x30:
            p_doutbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->dout_buf_ptr[2] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
            break;
已知:
    (1)、vpc3->dout_buf_ptr[2] = 72
    (2)、SEG_MULDIV = 0x03
    (3)、VPC3_ASIC_ADDRESS = 0x2000


目的:
    获取Dout_Buf_Ptr3的物理地址。
    vpc3->ctrl_reg.rd.dout_buffer_sm = 0x30 ,表示用户缓冲器的分配使用Dout_Buf_Ptr3。

结果:
     p_doutbuf = (UBYTE PTR_ATTR *)((VPC3_ADR)(vpc3->dout_buf_ptr[2] << SEG_MULDIV)+(VPC3_ADR)VPC3_ASIC_ADDRESS);
                  = 72 << 3  + 0x2000  = 576 + 8192 = 8768 = 0x2240


//-------------------------------------------------------------------------------------
6. 执行语句
//-------------------------------------------------------------------------------------      
  default:
            p_doutbuf = NULL_PTR;
            break;


目的:
    判断数据输入状态机是否进入不可用的状态

结果:
    上述语句不执行。


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值