Bitfield Example 3

The PIC32 library include files contain numerous examples of definitions of bit fields for the manipulation of the control bits in various special function registers (SFRs).

Below is an example from the PIC32, where the Timer1 module control register T1CON is defined and each individual control bit is exposed:

extern volatile unsigned int        T1CON __attribute__((section("sfrs")));
typedef union {
  struct {
    unsigned :1;
    unsigned TCS:1;
    unsigned TSYNC:1;
    unsigned :1;
    unsigned TCKPS0:1;
    unsigned TCKPS1:1;
    unsigned :1;
    unsigned TGATE:1;
    unsigned :3;
    unsigned TWIP:1;
    unsigned TWDIS:1;
    unsigned SIDL:1;
    unsigned FRZ:1;
    unsigned ON:1;
  };
  struct {
    unsigned :4;
    unsigned TCKPS:2;
    unsigned :7;
    unsigned TSIDL:1;
    unsigned :1;
    unsigned TON:1;
  };
  struct {
    unsigned w:32;
  };
} __T1CONbits_t;
extern volatile __T1CONbits_t T1CONbits asm ("T1CON") __attribute__((section("sfrs")));

The example program, modified from timer3, uses Timer1 to schedule changes to an LED. The example uses bit fields to control the timer and LED.

Of particuliar interest, we observe the disassembly of line 39:

39:	T1CONbits.TCKPS = 3; // Set prescaller to 1:256
   lui         a0,0xbf80      a0 <= base address (0xbf800000)
   lw          v0,1536(a0)    v0 <= T1CONbits (a0+1536)note 1
   addiu       v1,zero,3      v1 <= 3
   ins         v0,v1,4,2      v0 <= insert_bitfield(v1,4,2)
   sw          v0,1536(a0)    T1CONbits <= v0
where the ins instruction (insert bitfield) is used. This is the companion instruction to ext (extract bitfield).

Note 1: T1CON address = 0xBF800600 and 0x600 = 153610

Contents

C Source
Disassembly Listing

C Source

C Source: bitfields.zip


01: /* bitfield3.c
02:  *
03: */
04: 
05: #include <plib.h>
06: 
07: void wait();
08: 
09: typedef union {
10:         struct {
11:                 unsigned int LED1: 1;
12:                 unsigned int LED2: 1;
13:                 unsigned int LED3: 1;
14:         };
15:         unsigned int w;
16: } leds_t;
17: 
18: 
19: 
20: int main()
21: {
22:         int i;
23:         leds_t leds;
24:         leds.w = 0;
25:         leds.LED2 = 1;
26:         mPORTDSetPinsDigitalOut(leds.w);   /* Make selected leds output */
27:         mPORTDClearBits(leds.w);      /* Turn off selected leds on startup */
28:         while (1) {
29:                 mPORTDToggleBits(leds.w);     /* Toggle selected leds */
30:                 wait();
31:         }
32:         return 0;
33: }
34: 
35: void wait()
36: {
37:         const int DLY = 5000;
38:         T1CON = 0; // turn timer off and clear all bits
39:         T1CONbits.TCKPS = 3; // Set prescaller to 1:256
40:         TMR1 = 0;
41:         PR1 = 0xFFFF;
42:         T1CONbits.TON = 1; // start timer
43:         while (TMR1 < DLY) {
44:                 // just wait
45:         }
46:         T1CONbits.TON = 0; // stop timer
47: }


Disassembly Listing

---  C:\pic32\test\bitfield3.c  ------------------------------------------------------------------
1:                   /* bitfield3.c
2:                    *
3:                   */
4:                   
5:                   #include 
6:                   
7:                   void wait();
8:                   
9:                   typedef union {
10:                  	struct {
11:                  		unsigned int LED1: 1;
12:                  		unsigned int LED2: 1;
13:                  		unsigned int LED3: 1;
14:                  	};
15:                  	unsigned int w;
16:                  } leds_t;
17:                  
18:                  
19:                  
20:                  int main()
21:                  {
9D000018  27BDFFE0   addiu       sp,sp,-32
9D00001C  AFBF001C   sw          ra,28(sp)
9D000020  AFBE0018   sw          s8,24(sp)
9D000024  03A0F021   addu        s8,sp,zero
22:                  	int i;
23:                  	leds_t leds;
24:                  	leds.w = 0;
9D000028  AFC00014   sw          zero,20(s8)
25:                  	leds.LED2 = 1;
9D00002C  8FC20014   lw          v0,20(s8)
9D000030  34420002   ori         v0,v0,0x2
9D000034  AFC20014   sw          v0,20(s8)
26:                  	mPORTDSetPinsDigitalOut(leds.w);   /* Make selected leds output */
9D000038  3C03BF88   lui         v1,0xbf88
9D00003C  8FC20014   lw          v0,20(s8)
9D000040  AC6260C4   sw          v0,24772(v1)
27:                  	mPORTDClearBits(leds.w);      /* Turn off selected leds on startup */
9D000044  3C03BF88   lui         v1,0xbf88
9D000048  8FC20014   lw          v0,20(s8)
9D00004C  AC6260E4   sw          v0,24804(v1)
28:                  	while (1) {
29:                  		mPORTDToggleBits(leds.w);     /* Toggle selected leds */
9D000050  3C03BF88   lui         v1,0xbf88
9D000054  8FC20014   lw          v0,20(s8)
9D000058  AC6260EC   sw          v0,24812(v1)
30:                  		wait();
9D00005C  0F40001B   jal         0x9d00006c
9D000060  00000000   nop         
9D000064  1000FFFA   beq         zero,zero,0x9d000050
9D000068  00000000   nop         
31:                  	}
32:                  	return 0;
33:                  }
34:                  
35:                  void wait()
36:                  {
9D00006C  27BDFFF0   addiu       sp,sp,-16
9D000070  AFBE0008   sw          s8,8(sp)
9D000074  03A0F021   addu        s8,sp,zero
37:                  	const int DLY = 5000;
9D000078  24021388   addiu       v0,zero,5000
9D00007C  AFC20000   sw          v0,0(s8)
38:                  	T1CON = 0; // turn timer off and clear all bits
9D000080  3C02BF80   lui         v0,0xbf80
9D000084  AC400600   sw          zero,1536(v0)
39:                  	T1CONbits.TCKPS = 3; // Set prescaller to 1:256
9D000088  3C04BF80   lui         a0,0xbf80
9D00008C  8C820600   lw          v0,1536(a0)
9D000090  24030003   addiu       v1,zero,3
9D000094  7C622904   ins         v0,v1,4,2
9D000098  AC820600   sw          v0,1536(a0)
40:                  	TMR1 = 0;
9D00009C  3C02BF80   lui         v0,0xbf80
9D0000A0  AC400610   sw          zero,1552(v0)
41:                  	PR1 = 0xFFFF;
9D0000A4  3C03BF80   lui         v1,0xbf80
9D0000A8  3402FFFF   ori         v0,zero,0xffff
9D0000AC  AC620620   sw          v0,1568(v1)
42:                  	T1CONbits.TON = 1; // start timer
9D0000B0  3C04BF80   lui         a0,0xbf80
9D0000B4  90830601   lbu         v1,1537(a0)
9D0000B8  2402FF80   addiu       v0,zero,-128
9D0000BC  00621025   or          v0,v1,v0
9D0000C0  A0820601   sb          v0,1537(a0)
43:                  	while (TMR1 < DLY) {
9D0000C4  3C02BF80   lui         v0,0xbf80
9D0000C8  8FC30000   lw          v1,0(s8)
9D0000CC  8C420610   lw          v0,1552(v0)
9D0000D0  0043102B   sltu        v0,v0,v1
9D0000D4  10400003   beq         v0,zero,0x9d0000e4
9D0000D8  00000000   nop         
9D0000DC  1000FFF9   beq         zero,zero,0x9d0000c4
9D0000E0  00000000   nop         
44:                  		// just wait
45:                  	}
46:                  	T1CONbits.TON = 0; // stop timer
9D0000E4  3C02BF80   lui         v0,0xbf80
9D0000E8  90430601   lbu         v1,1537(v0)
9D0000EC  3063007F   andi        v1,v1,0x7f
9D0000F0  A0430601   sb          v1,1537(v0)
47:                  }
9D0000F4  03C0E821   addu        sp,s8,zero
9D0000F8  8FBE0008   lw          s8,8(sp)
9D0000FC  27BD0010   addiu       sp,sp,16
9D000100  03E00008   jr          ra
9D000104  00000000   nop         


Maintained by John Loomis, updated Fri Aug 08 15:39:44 2008