I have a project that uses LPC2387 and makes extensive use of the timer match
outputs.
A problem I have is that the timer match control is stored in the same register
as the status of the bits.
This is the TxEMR register.
Bits 3 through 0 contain the states of the output pins, readable and
writable.
Bits 11 through 4 contain the control bits that tell the comparators what to do
on a match.
Problem with this design is that making alterations to the control bits is
liable to conflict with
changes that happen on the state bits, done by the comparators.
Effectively, with instructions like this:
- ldr into register address of T3EMR
- bic or orr to change the states of the control bits
- str from register back to T3EMR
You're going to have a problem if the comparator matches during the
non-atomic operation where a copy is made of the EMR
and that copy stored back on the EMR overriding the change that the comparator
did.
I think it's extremely silly to store state and control bits on the same
register, where the state bits are writable and can be overwritten by attempts
to alter the control bits.
Now, I have a question, is there a way to atomically change the bits on those
registers without making a copy first?
Is there a way to lock access to the register while the change is being made?
Baldur Gislason
Posted by: Baldur Gislason

Timer external match design silliness
Started by ●August 24, 2015
Reply by ●December 23, 20152015-12-23
I had a similar issue. My code now has more convoluted logic than it should need
with this at the end:
union{
__emr_bits EMR;
Int32U image;
};
image &= 0xfffffff0;
if (writeEMR)
{
T0TCR = 0;
image |= (0xf & T0EMR);
T0EMR = image;
T0TCR = 1;
}
Playing with T0TCR wasn't desirable, but there didn't seem to be any other way to keep output compares from changing T0EMR between read and write of T0EMR.
union{
__emr_bits EMR;
Int32U image;
};
image &= 0xfffffff0;
if (writeEMR)
{
T0TCR = 0;
image |= (0xf & T0EMR);
T0EMR = image;
T0TCR = 1;
}
Playing with T0TCR wasn't desirable, but there didn't seem to be any other way to keep output compares from changing T0EMR between read and write of T0EMR.
