lpcware

Correct syntax/method for setting IOCON bits

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by deevee on Thu Sep 26 14:55:02 MST 2013
Evening - hoping that someone can shed a little light on something I read in another post (http://www.lpcware.com/content/forum/unable-configure-gpio045-etc-input)

With reference to setting bits in a GPIO's IOCON, NXP_Paul mentions:


Quote:
So the configuration to get this working is minimal:
LPC_IOCON->PIO0_4 &= ~(1<<4); // disable internal pull-up
Make sure you don't set IOCON using:
LPC_IOCON->PIO0_4 = 0;
or else this bit will always read back as a '0' when reading the PIN register (reserved bit 7 must remain 1).



Please can someone explain why the top method is 'better' than the bottom method? Is it actually 'better', is there a convention?

I see that the first version of that line specifically clear bit 4 of that register, where as the second sets its value, in total, to 0. I understand that by clearing a single bit you leave bit 7 alone, as it has to set to one for the stuff that was being discussed there to work.

In the project I am working on, for example, I have an active low input, connected to Port1 Bit0 of my LPCXpresso LPC1114 - which is IOCON_R_PIO1_0

From the data sheet:

This is a 32bit register which initialises as xxxxxxxxxxxxxxxxxxxxx00011010000
bits 11 thru 31 are reserved, so we don't care about them
bits 0 thru 2 set the function, a value of 0x1 here is digital I/O : 001b
bits 3 thru 4 set the mode, this is an active low switch so we need the pull up to be enabled (0x2) : 10b
bit 5 sets the Hysteresis, the opto switch as a Schmitt trigger on it so we don't need it (0) : 0b
bit 7 sets A or D mode, its a switch so let's have D (1) : 1b
bits 8 thru 9 are reserved : 00b
bit 10 sets the open-drain mode, its an input so we don't care, lets leave it as a standard GPIO (0) : 0b
config bits thus are 0001010001 which is 0x0051

From here I seem to have a number of options of setting those bits.

I could:

LPC_IOCON->R_PIO1_0 = 0x51;  //simple enough, right? But will it mess with other things?


or:


LPC_IOCON_R_PIO1_0 &= ~(0xff);   //clear the bits we are about to set, we don't know what they were, best start with zeros. Bitwise AND-equals NOT (~) the bits you want to clear
LPC_IOCON_R_PIO1_0 |= 0x51 & 0xff; //ANDing the value with the mask from above means we don't accidentally set any of the wrong bits
//this seems like the safest way to do this, but its a bit long winded


or:
LPC_IOCON_R_PIO1_0 &= ~(0xff) | (0x51<<8)  //if I've understood the bitmasking thing properly, this should shift 0x51 into the bottom 8bits of the register without touching anything else


So - which method of setting those bits is the 'most correct'/best practice/follows convention? Is my bit mask okay, and, is it actually any more succinct than the two line clear and OR method above?

For reference, I'm extremely new to LPCXpresso/programming for ARM etc. I'm coming from a background of writing ASM for PICs and prototyping with Arduinos (so C 'programming short cuts' will be lost on me a little). Please let me know if you need any further information, to help you help me.

Thanks folks!

Outcomes