Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Tips for using atomic functions when changing PIC32 registers
14-01-2014, 08:23 PM, (This post was last modified: 14-01-2014, 11:38 PM by agolac.)
#1
Tips for using atomic functions when changing PIC32 registers
Microchip has atomic functions for all register manipulation and they can be viewed in processor header file and processor.o These are xSET, xCLR and xINV.

xSET works in a way that it sets to 1 all bits that are 1 in mask
Example:
Code:
Register        0 0 0 0 0 0 0 0
Mask            1 0 0 0 1 1 1 1
-------------------------------
Register result 1 0 0 0 1 1 1 1

xCLR works in a way that it sets to 0 all bits that are 1 in mask
Example:
Code:
Register        1 1 1 1 1 1 1 1
Mask            1 0 0 0 1 1 1 1
-------------------------------
Register result 0 1 1 1 0 0 0 0

xINV works in a way that it inverts all bits that are 1 in mask
Example:
Code:
Register        1 1 1 1 1 1 1 1
Mask            1 0 1 0 1 0 1 0
-------------------------------
Register result 0 1 0 1 0 1 0 1

If you do objdump of processor.o you will see adressess of all SFR's
These addresess are used in the application disassembly code below this list.
Code:
bf885250 g     O *ABS*    00000000 U1CON
bf885254 g     O *ABS*    00000000 U1CONCLR
bf885258 g     O *ABS*    00000000 U1CONSET
bf88525c g     O *ABS*    00000000 U1CONINV

Functions marked "C Code" do the same thing, and that is, set USBEN bit of register U1CON to 1, or enabled.
Application disassembly code:
Code:
U1CONSET = _U1CON_USBEN_MASK;                    // C code atomic fuction
9d0000d0:    3c02bf88     lui   v0,0xbf88        // Load first part of SFR address
9d0000d4:    24030001     li    v1,1             // Load _U1CON_USBEN_MASK
9d0000d8:    ac435258     sw    v1,21080(v0)     // Save to 21080 (0x5258h,second part of address)
U1CONbits.USBEN = 1;                             // C code XXXbits function
9d0000dc:    3c03bf88     lui    v1,0xbf88       // Load first part of SFR address
9d0000e0:    8c625250     lw    v0,21072(v1)     // Read word from 21072 (0x5250h, U1CON)
9d0000e4:    24040001     li    a0,1             // Load _U1CON_USBEN_MASK
9d0000e8:    7c820004     ins    v0,a0,0x0,0x1   // Modify and apply mask
9d0000ec:    ac625250     sw    v0,21072(v1)     // Write to U1CON

You will notice that using atomic functions, only three instructions are necessary, and by using XXXbits, five instructions. Atomic functions are done in hardware and cannot be interrupted so they are safer.

When using XXXbits value, SFR is first read, then its value is modified and then written back to SFR. This can cause potential problems if in the mean time interrupt occurs, and value written by interrupt will be overwritten when interrupt returns by continuing XXXbits code.

So, tip is, always use use atomic instead of XXXbits. Your code will be smaller, potential bugs and problems will be less
Dreaming in Code...
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)