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.

Compiler/TMS320F28075: Byte peripheral accesses and associated types

Part Number: TMS320F28075
Other Parts Discussed in Thread: CONTROLSUITE, C2000WARE

Tool/software: TI C/C++ Compiler

Hello everyone,

I am working with an F28075 and trying to understand how byte peripherals work. My goal is to make the DCAN peripheral work.

1. The only example code I have is in the controlSuite/device_support/F2807x directory. I have seen users on the forum mention C2000Ware. Which of these libraries should I use as a starting point and is one of them better maintained than the other?

2. I have the TMS320F2807x Technical Reference Manual which only offers the following information at chapter 21.3.1:

NOTE: The CAN module uses a special addressing scheme to support byte accesses. This is the same addressing that is used on the USB module. For ease of use, it is recommended to only make 32-bit accesses to the CAN registers. However, at higher optimization levels, the compiler may split a 32-bit access into two sequential 16-bit accesses, which will corrupt the register value. A compiler fix is in development. In the meantime, 16-bit accesses can be used as a workaround. The lower 16 bits should be written to the register's address, and the upper 16 bits should be written to the register's address plus 2.

I'm working with all optimization disabled therefore I think I can enforce 32-bit accesses (MOVL instructions) but I don't mind using the workaround with 16-bits accesses if necessary. However I wonder what the impact is on the debugger and the Expressions window. Is the debugger able to show me correct values of the DCAN registers?

3. I also have the TMS320C28x Optimizing C/C++ Compiler v18.1.0LTS User's Guide and I am trying to understand chapter 6.14.6, "Using the Byte Peripheral Type Attribute" but I have trouble understanding it. Is there a more detailed explanation available somewhere?

What does this sentence mean:  "The byte peripherals bridge translates addresses between the CPU and byte peripherals by treating an address as a byte address."? Does it mean that when you make a 16-bit write to an address in a byte peripheral the value is truncated at 8 bits?

Cheers,

Pierre

  • Pierre

    1. C2000Ware is the new package, please use that one. For CAN specifically, make sure to use the library and examples under the root ~/driverlib directory
    2. The driverlib will take care using the __byte_peripheral_32 intrinsic which is the optimal way to access such peripherals. Yes, you should see the correct values in the debugger windows.
    3. That guide has the most information on it. The instrintric essentially prevents the code from translating 32-bits into two 16-bit accesses which messes up with the byte bridge. CAN uses byte addressing so two address accesses will split the data where the second access will go to the wrong address.
    e2e.ti.com/.../1586639
    processors.wiki.ti.com/.../MCU_Compiler_v15

    Best regards
    Chris
  • Christopher,

    1. I would like to understand better what the byte bridge does and how it works, is this information available somewhere?

    2. You wrote: "CAN uses byte addressing so two address accesses will split the data where the second access will go to the wrong address." I don't understand how "two address accesses will split the data where the second access will go to the wrong address" is a consequence of "CAN uses byte addressing". Could you explain?

    Cheers,

    Pierre

  • Pierre

    1. The high level is that is makes these byte addressing peripherals compatible with the C28 word addressing architecture. I am not aware that we have any further information on this.
    2. When a 32-bit write was being split into two 16-bit writes (before the fixes I mentioned), The first 16-bit word was being written to let's say address 0x0 which from a byte addressing view populated addresses 0x0 and 0x1. Then the next upper 16-bit word gets written at byte address 0x1 (instead of populating 0x2 and 0x3 as expected) which messes up the data. The fixes adjust the translation between the word and byte addresses so that they get written into their respective locations.

    Best regards
    Chris
  • Christopher,

    After thinking a bit about this I believe I'm starting to understand better how it works. If a 16-bit write is performed with the MOV instruction on an odd address of the byte peripheral (such as 0x1 from your example) is the data messed up in a deterministic way or is it completely undefined behavior?

    Does the CPU support writes to byte peripherals with the MOVB instruction? At first I thought the __byte() intrinsic would work but the argument type does not match and if I try to cast a type with the byte_peripheral attribute to the expected int * the compiler gives the warning "Illegal use of intrinsic: __byte_peripheral_32".

    Cheers,

    Pierre

  • Pierre

    Yes, it is deterministic.

    The byte intrinsic is supported. It is used in the CAN_writeDataReg and CAN_readDataReg driver APIs (see can.h). I recommend looking at the driver source to see how these intrinsics are used. the HWREG_BP makes use of the byte_peripheral_32 intrinsic and the macro is defined in hw_types.h

    Best regards
    Chris
  • Christopher,

    The HWREGB macro relies neither on the __byte_peripheral_32 nor the byte_peripheral attribute since it accesses the register via its raw address. Now that TI has gone through the trouble of adding these features so that we can have bitfields mapped to the CAN registers by the compiler it feels hacky that the only way to do certain things is to alias them with hundreds of preprocessor macros.

    Anyway I'm not going to use the macros since it works fine without them - I'm very grateful for the can_loopback_bitfield example in C2000Ware.

    Best Regards,

    Pierre