C and the xMega Pin Control registers

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Been thinking about this for a while, and there has to be a tidy way to do it, but I haven't figured it out yet. 

 

I usually make a file called "Config.h" that describes the board. It has definitions like

 

// TouchScreen
#define TouchPort PORTB
#define TouchYTop 2
#define TouchYBottom 3
#define TouchXTop 0
#define TouchXBottom 1

Which lets me code by name like so:

 

	TouchPort.DIRSET = (1<<TouchXTop) | (1<<TouchXBottom) ;
	TouchPort.DIRCLR = (1<<TouchYTop) | (1<<TouchYBottom) ;
	TouchPort.OUTSET = (1<<TouchXTop) ;
	TouchPort.OUTCLR = (1<<TouchXBottom)  ;

And this is very handy for when I discover I've made a mistake counting pins or wish to use the same code on a different board where the pins may be different.

 

However, the pincontrol registers still trip me up. Inside the code, I have to refer to the pin by number, rather than name:

 

	TouchPort.PIN3CTRL = (3<<3) ;

And this leaves a spot in the code that I have to edit if I need to change something in the Config.h file. Can any of you C mages suggest a way to specify something like:

 

    TouchPort.PIN(TouchYBottom)CTRL = somegibberish

 

 

 

 

The largest known prime number: 282589933-1

In my humble opinion, I'm always right. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wouldn't it be just easier to add them to your config file? eg

#define TouchYBottomCTRL PIN3CTRL

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you can set MPCMASK to the pin mask(s) you want to configure then write to any PORTX.PINnCTRL register (I mean for the correct PORTx but with any pin number n).

Quote:
Bit 7:0 – MPCMASK[7:0]: Multi-pin Configuration Mask
The MPCMASK register enables configuration of several pins of a port at the same time. Writing a one to bit n
makes pin n part of the multi-pin configuration. When one or more bits in the MPCMASK register is set, writing any
of the PINnCTRL registers will update only the PINnCTRL registers matching the mask in the MPCMASK register
for that port. The MPCMASK register is automatically cleared after any PINnCTRL register is written.

Last Edited: Fri. Feb 13, 2015 - 04:19 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bloody-orc wrote:

Wouldn't it be just easier to add them to your config file? eg

#define TouchYBottomCTRL PIN3CTRL

 

 

 

Close, but that's still disconnected from

 

#define TouchYBottom 3

 

The largest known prime number: 282589933-1

In my humble opinion, I'm always right. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

snigelen wrote:

I think you can set MPCMASK to the pin mask(s) you want to configure then write to any PORTX.PINnCTRL register (I mean for the correct PORTx but with any pin number n).

 

Quote:

Bit 7:0 – MPCMASK[7:0]: Multi-pin Configuration Mask
The MPCMASK register enables configuration of several pins of a port at the same time. Writing a one to bit n
makes pin n part of the multi-pin configuration. When one or more bits in the MPCMASK register is set, writing any
of the PINnCTRL registers will update only the PINnCTRL registers matching the mask in the MPCMASK register
for that port. The MPCMASK register is automatically cleared after any PINnCTRL register is written.

 

 

 

But not in bloody E5 or D3 parts.

 

typedef struct PORT_struct
{
    register8_t DIR;  /* I/O Port Data Direction */
    register8_t DIRSET;  /* I/O Port Data Direction Set */
    register8_t DIRCLR;  /* I/O Port Data Direction Clear */
    register8_t DIRTGL;  /* I/O Port Data Direction Toggle */
    register8_t OUT;  /* I/O Port Output */
    register8_t OUTSET;  /* I/O Port Output Set */
    register8_t OUTCLR;  /* I/O Port Output Clear */
    register8_t OUTTGL;  /* I/O Port Output Toggle */
    register8_t IN;  /* I/O port Input */
    register8_t INTCTRL;  /* Interrupt Control Register */
    register8_t INT0MASK;  /* Port Interrupt 0 Mask */
    register8_t INT1MASK;  /* Port Interrupt 1 Mask */
    register8_t INTFLAGS;  /* Interrupt Flag Register */
    register8_t reserved_0x0D;
    register8_t reserved_0x0E;
    register8_t reserved_0x0F;
    register8_t PIN0CTRL;  /* Pin 0 Control Register */
    register8_t PIN1CTRL;  /* Pin 1 Control Register */
    register8_t PIN2CTRL;  /* Pin 2 Control Register */
    register8_t PIN3CTRL;  /* Pin 3 Control Register */
    register8_t PIN4CTRL;  /* Pin 4 Control Register */
    register8_t PIN5CTRL;  /* Pin 5 Control Register */
    register8_t PIN6CTRL;  /* Pin 6 Control Register */
    register8_t PIN7CTRL;  /* Pin 7 Control Register */
} PORT_t;

 

The largest known prime number: 282589933-1

In my humble opinion, I'm always right. 

Last Edited: Fri. Feb 13, 2015 - 04:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MPCMASK isn't in the PORT_t struct, it's in PORTCFG. So it's PORTCFG.MPCMASK or PORTCFG_MPCMASK.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Like this

PORTCFG.MPCMASK = 1<<TouchYBottom;
// Pick any PINxCTRL, only the pin mentioned above is affected
TouchPort.PIN0CTRL = somegibberish;

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The last sentence in this is both a blessing and a curse:

 

Bit 7:0 – MPCMASK[7:0]: Multi-pin Configuration Mask

The MPCMASK register enables configuration of several pins of a port at the same time. Writing a one to bit n

makes pin n part of the multi-pin configuration. When one or more bits in the MPCMASK register is set, writing any

of the PINnCTRL registers will update only the PINnCTRL registers matching the mask in the MPCMASK register

for that port. The MPCMASK register is automatically cleared after any PINnCTRL register is written.

 

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Fri. Feb 13, 2015 - 08:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can only see the blessing. I mean, if you use MPCMASK in one place and some-time/where later do a write to PORTC.PIN5CTRL to configure PC5 it would not be good if there was some bits set in MPCMASK. If it wasn't auto cleared then you had to always set MPCMASK to zero first if you want to configure a single/specific pin.

 

On the other hand, they could have skipped all the PORTx.PINnCTRL and only have one PORTx.PINCTRL for each port and require a write to MPCMASK before every write to PORTx.PINCTRL.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The curse is when you think it will still contain the mask and make an assignment a second time thinking it will do the same as it did the first time. blush  That sentence should be bolded IMO.wink

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Sat. Feb 14, 2015 - 12:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So THAT's where it is. I couldn't believe NEITHER xMega I bought has the feature.

 

And I think it's a blessing. You don't have to worry about mistakenly leaving it set some where and having some unrelated piece of code break.

The largest known prime number: 282589933-1

In my humble opinion, I'm always right.