Peripheral usage endianness observation

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Peripheral usage endianness observation

771 Views
davidsherman
Senior Contributor I

Just made an observation on the Kinetis that might save some frustration, I just went through this and discovered a nasty little surprise.  If you're writing to registers that have high bytes and low bytes associated with them (example:  Watchdog registers), the memory maps provided by Freescale do provide a accessors for the whole word, but DON'T USE THEM!  The Kinetis ARM is little-endian.  The peripheral registers, however, are not arranged that way.  I was trying to figure out why the watchdog timeout was much longer than expected, but found out the example given in the user's manual doesn't work.

In the example given in the Kinetis KE06 user's manual (page 220), it shows:

WDOG_TOVAL = 1000

This is supposed to to load the timeout value with 1000 for a 1-second timeout using the 1kHz clock.

Although there is a 16 bit accessor provided with that name, you should not use this, it won't work correctly.  In the example above, what happens is it writes 0xE8 to WDOG_TOVALH and 0x03 to WDOG_TOVALL, so instead of a count of 1000 (decimal), you have a count of 59,395.  This happens because WDOG_TOVALH is at 0x40052004, and WDOG_TOVALL is at 0x40052005.

So, when writing to peripheral registers, you must do byte reads/writes to the individual registers.  Another example is the UART baud rate registers, these will have the same problem.

1 Reply

540 Views
mjbcswitzerland
Specialist V

Hi David

In the case of the watchdog, the user's manual points out the implementation details with:

pastedImage_0.png

However, in the case of the KE manuals, all do have an error in their example of the usage of

WDOG_TOVAL = 1000;

When accessing such non-native registers the method to use is something like

WDOG_TOVAL = BIG_SHORT_WORD(1000);

where

#define BIG_SHORT_WORD(x) (unsigned short)((x << 8) | (x >> 8))

Essentially one needs to always check the peripheral implementation details (some are native and some may not be - others even have a control bit to select whether they are little - or big endian [eg. ENET's buffer descriptors])

Regards

Mark

Kinetis: µTasker Kinetis support

KE: µTasker FRDM-KE02Z support / µTasker FRDM-KE02Z40M support / µTasker FRDM-KE06Z support

For the complete "out-of-the-box" Kinetis experience and faster time to market