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.

strange problem about the TMS 570 N2HET

Other Parts Discussed in Thread: TMS5703137

My customer use TMS5703137  N2HET to produce a 2ms cycle square wave(they use the pin 4,10,11,14,16,17,19,22,27,29,30) ,but they find a very strange problem :

when they operate the other N2HET pins (23,24,26),they found that the square wave output cycle is changed to an uncertainty value.

the code they operate the N2HET is   " hetREG1-> DOUT | = (uint32)(0x1U << 23U)" ,and when they comment this code,the problem no longer appear.

Does anyone have encountered similar problems?

  • Shaui,

    So this is a very good issue to bring up and it is why we don't just include 'DOUT' but we also have the DSET and DCLR registers.

    The HET is a little different than other peripherals because there isn't a register that selects between HET and GIO functions.
    Both HET and GIO are simultaneously available.

    That means when the HET is running a program, the DOUT register is updated by HET as the PWMs change. When the HET sets a pin high it changes DOUT for that pin to '1' and when it clears a PWM pin it changes the DOUT bit for the pin to '0'.
    You can see this behavior by updating the HET registers while the HET is running (but CPU is halted) in CCS.

    So your customer's problem is most likely the hazard associated with the use of |= and read-modify-write not being atomic.
    There are 2 separate 'threads' modifying the same register in parallel - one running on the CPU and one running on the HET ...

    So now what happens is:

    1. CPU reads the DOUT register as the first part of |=
    2. HET updates DOUT register
    3. CPU performs the | but based on the *old* value of DOUT read in step 1, prior to the HET update in step 2.
    4. CPU writes back the result in step 3. This 'undoes' the work that the HET did in step 2; so it messes up the PWW

    This will occur even if the CPU is modifying a different pin than the HET, because the CPU cannot perform bit-wide acceses to the HET registers, the minimum access is a byte and the normal access is a word.

    This issue can occur as well on any peripheral where two different threads from the CPU are sharing an IO port.

    So that is why you see that almost all the peripherals include a DSET and DCLR alias register to DOUT.

    These registers (DSET, DCLR) allow you to either SET (to 1) or CLEAR (to 0) bits that are written with a value '1' while *not changing* any bits written with a 0.

    So let's change this around...

    1. CPU writes DSET with a '1' in each bit that it wants to set.
    2. HET clears a particular pin...

    Or..

    1. HET clears a particular pin...
    2. CPU writes DSET with a '1' in each bit that it wants to set.

    It won't matter which occurs, by using DSET the read-modify-write hazard is gone, The HET PWM will clear it's pin and the CPU write to DSET will set the pin that the CPU wants to be '1' and the two operations will not interfere.

    As a side effect I should note that the DSET and DCLR registers only require a write, not a read-modify-write. So they will also speed up by 2x the toggling of pins by the CPU if they are used instead of DOUT.

    -Anthony
  • Thank you very much for your professional reply.  But the problems still exist, the following is a screenshot of the code, can you help to check it ?

  • Hi,

    So think about  DOUT, DSET, DCLR as three different interfaces to the same set of digital output register.

    All three interfaces return the same value on a read - which is the current value of DOUT.

    The difference between them is how they behave when written

    DOUT ->  writes of '0' and '1' go directly into the digital output register

    DSET -> writes of '1' set the same bit in the digital output register, writes of '0' do not change the bit.

    DCLR -> writes of '1' clear the same bit in the digital output register, writes of '0' do not change the bit.

    Now when you do:


    DSET |= 1U<<23;

    The problem is that you are still performing the read-modify-write sequence and so are changing more than the single bit 23.


    What you need to do is simply:

    DSET = 1U<<23;

    In other words,  ONLY WRITE to DSET.   The write creates one action which is to set bit 23 and leave all of the other bits unchanged.

    If you do a read-modify-write ( DSET |= 1U<<23)  then any pins that the HET changes to '0' between the read and the write will be put back to '1'

    by the software in the main loop - which causes the interference problem you are seeing.

    -Anthony