This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

MDU unit

hello ,
i am having some problems with the multiplication division unit of the xc878 infineon microcontroller.
i am trying to do a shift operation. the number to be shifted is a 32 bit. lets say i want to do this: 0x00FB00FF >> 16. i would require the MD0,MD1,MD2,MD3 registers. now my problem. i can load the MD0 and MD1 registers but i dont know how to load the MD2 and MD3 registers. please kindly help out.
stephen

  • This is how you can do it in assembly language:

    #include <xc878.h>
    
    ULSHR:          MOV     A,R0
                    JZ      RETURN
                    ANL     A,#1FH
                    ORL     A,#20H
                    MOV     MDU_MD0,R7
                    MOV     MDU_MD1,R6
                    MOV     MDU_MD2,R5
                    MOV     MDU_MD3,R4
                    MOV     MDU_MDUCON,A
                    LCALL   ?C?WAIT18       ;WAIT 18 CYCLES
                    MOV     R7,MDU_MD0
                    MOV     R6,MDU_MD1
                    MOV     R5,MDU_MD2
                    MOV     R4,MDU_MD3
    RETURN:         RET
    

    Note that this code is not tested, you should verify (using the datasheet) that it is working with the MDU of the XC878.

  • hello everyone,

    thanks for your quick reply. i was wondering if it is possible to do that in C too. i am not familiar with Assembler.
    here is what i did i C. The function Shift_MDU gets two Parameters. param_5 is a 32bit
    number and param_6 is the number of shift to be performed. MDU_MD01 and MDU_MD23 are 16bit
    Registers. when i assign the 32 bit varaible(param_5) to the MDU_MD01, it automatically reads the 16 lower bits. now
    i cant seem to be able to read the other 16 high bits into the MDU_MD23 Register.

    int Shift_MDU(long int param_5, int param_6)

    {

    SYSCON0 |= 0x01;

    MDU_MD01 = param_5; MDU_MD23 = param_5; // dont know how to load this. MDU_MDUCON = 0x13; MDU_MD4 = 0x20 | param_6;
    // MDU_MD23=(param_5 & 0xFFFF0000)>> 16; // this is what should be loaded in the MD23 register while(MDU_BSY==1); erg_shift = (MDU_MR01); SYSCON0 &= ~(ubyte)0x01;

    return erg_shift;

    }

  • You would normally do:

    MDU_MD01 = param_5;
    MDU_MD23 = param_5 >> 16;
    

    and often even show the compiler that you know about the difference in size between left-hand and right-hand side of the assign:

    MDU_MD01 = (uint16_t)param_5;
    MDU_MD23 = (uint16_t)(param_5 >> 16);
    

    The compiler should be smart enough to figure out that a shift right with 16 steps for the second assign is the same as picking up the two most significant bytes - so no real shifting performed.

    Personally, I would prefer a function that accesses 32-bit physical registers to use int32_t or uint32_t as argument type instead of using long int or unsigned long - but it isn't too important since the full function is most definitely not portable anyway. Note that uint16_t etc require that you #include <stdint.h>

  • Hello,

    thanks for that tip. but unfortunately the C51 Compiler still does the shifting. actually i am using the MDU to make shifting faster but
    if i end up shifting again then it doesnt make much sense. any other idea how this Problem can be solved? actually the datasheet says the MDU can handle 32 bit shift, so i cant seem to understand why it doesnt recognise 32 bit variable.

  • Another solution, if the compiler performs 16-bit shifts as actual shifts, is to use a pointer to a struct of two uint16_t integers and assign (with type cast) this pointer the address of the 32-bit integer. Then individually do

    p = (u32_to_u16_struct*)&my_32_bit_val;
    MDU_MD01 = p->low16;
    MDU_MD23 = p->high16;
    

  • I recommend to use an assembly module.

    I believe that the Infineon XC800 is compatible with this
    http://www.keil.com/support/man/docs/c51/c51_mdu_r515.htm

    Using the MDU_R515 directive should therefore automatically use the MDU.