This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320C5515: External assembler function for DSP

Part Number: TMS320C5515

Tool/software: Code Composer Studio

I need to create external function on TMS320C5515 Fixed-Point Digital Signal Processor around BFXTR command. I need to write some value directly into memory. I tried something like this:

.def _bfxtr

_bfxtr:
    PSH mmap(ST0_55)
    PSHBOTH XCDP
    MOV T0, AC0
    MOV T1, AC1
    BCC why, AC1 >= #0
why:
    MOV HI(AC0), *(#(metka + 1))
    NOP
    //here comes 512 NOP commands to supress conveyor
    ....
    NOP
    NOP
    B metka

metka:
    BFXTR #0x0, AC1, T2
    MOV T2, T0
    POPBOTH XCDP
    POP mmap(ST0_55)
    RET

But nothing changes memory value. What can I do about it?

  • The team is notified. They will post their feedback directly here.

    BR
    Tsvetolin Shulev
  • Are you sure that AC0 has a different value than *(#(metka+1))? How do you know the value is not changing? Are you looking at it in the CCS variable view?
  • AC0 and *(#(metka+1)) have different values for sure. I'm looking at address at *(#(metka+1)) in "program memory" window (can't remember what it's called exactly, I'll check later) and it's still 00, as it defined in the beginning by BFXTR #0x0.....
  • I wonder if you might be having some trouble with the difference between data and program accesses. You're trying to write to a program memory location; reads and writes are always in terms of 16-bit units, but instructions can be byte-aligned. Is the label metka aligned to a 16-bit address? You may find you need to divide the code label by 2 to convert it to a data address:
    MOV HI(AC0), *(#(metka/2 + 1))
    .align 2
    metka:
  • I don't think, that division of code label is necessary. Address is correct, but, as I can see, ".align 2" did nothing.

    Maybe I missing something here?

  • I'm pretty sure you need the division. What happens if you view label metka in DATA mode instead of PROGRAM mode? I predict the address will change.
  • Yep, it changes, but I need to change it in program, not in data.

    Maybe I wasn't very clear. BFXTR mnemonic has representation like that 0111 0110 kkkk kkkk kkkk kkkk FDDD 00SS. My goal is to change kkkk kkkk kkkk kkkk  values during runtime, not hardcode some value.

    Am I even thinking is right direction?

  • Yes, I get that that's what you're trying to do.
    My claim is that you are successfully modifying memory, but not the location you think you're modifying.

    The first thing you need to make sure of is that the 16-bit field k..k is aligned to a 16-bit address. From the Memory Browser view in the snapshot you posted, it looks like the field is already aligned as you need it, but that's not always going to be the case. You may need to take care to align the text section containing "metka," and to make sure there are an odd number of 8-bit units before the BFXTR instruction. This will force the k..k field to be aligned to a 16-bit address. Note that in the Memory Browser view, the k..k field is at text address 0x231DD, which is not aligned to 16 bits.

    The second thing you need to consider is that although the C55x has unified program and data memory, the program and data buses have different granularity. Program addresses are in terms of 8-bit units, and data addresses are in terms of 16-bit units. Thus, a program address of 0x200 corresponds to a data address of 0x100. It's the same location, but expressed differently. The assembler usually handles this as appropriate. All labels are handled internally as 8-bit-based, but labels defined in data sections are scaled by 2 when their values are used, so that their values are 16-bit-based data addresses. Labels defined in code sections are not scaled.

    You are being a little bit tricky in that you are manipulating a chunk of program memory as if it were data memory, so you've got to be fully aware of the fact that this is being converted for you by the assembler and also by the Code Composer Memory Browser. When you look at a region of memory in "PROGRAM" mode, the text addresses shown are 8-bit-based addresses. For instance, _neqd is at address 0x231E9. However, when you look at the very same region of memory in "DATA" mode, the addresses will be shown as data addresses, which means they will be scaled by two. The label _neqd is at data address 0x118f4 (plus one 8-bit unit; it doesn't divide evenly). So, if you wanted to modify the memory at label _neqd, you'll actually need to write to data address 0x118f4.

    Now the tricky part. Your store target, "metka," is defined in a text section; for this reason, it is NOT scaled when used in a data addressing mode. You must do the scaling yourself by dividing by two.

    MOV HI(AC0), *(#((metka+1)/2))
  • Thank you so much for your help! After some tweaking I ended up with this code:

     .def _bfxtr
    
    _bfxtr:
    	MOV T0, AC0
    	MOV T1, AC1
    	MOV AC0, *(#(metka + 2) / 2)
    	B metka
    metka:
    	NOP
    	BFXTR #0x0, AC1, T2
    	MOV T2, T0
    	RET

    I don't know if it can be further improved, but hey, it finally works. And thanks again.