Skip to content

Commit 4a331c7

Browse files
LPC1768: Add open drain pull up / pull down / etc modes (#484)
1 parent 4ba0016 commit 4a331c7

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

targets/TARGET_NXP/TARGET_LPC17XX/TARGET_MBED_LPC1768/PinNames.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,18 @@ typedef enum {
122122
#define I2C_SDA I2C_SDA2
123123

124124
typedef enum {
125-
PullUp = 0,
126-
PullDown = 3,
127-
PullNone = 2,
128-
Repeater = 1,
129-
OpenDrain = 4,
130-
PullDefault = PullDown
125+
PullUp = 0, ///< Pull up to VDD with internal resistor of between 59kOhm and 333kOhm. This is the default mode.
126+
PullDown = 3, ///< Pull down to GND with internal resistor of between 33kOhm and 500kOhm.
127+
PullNone = 2, ///< High impedance, no pull up or pull down
128+
Repeater = 1, ///< AKA "keeper" mode. This keeps the pin in the current logic level state (high or low) to prevent it from floating
129+
130+
OpenDrain = 4,///< Open drain mode with pull-up (default)
131+
OpenDrainPullUp = OpenDrain,
132+
OpenDrainPullDown = OpenDrain | PullDown, ///< Open-drain mode with pull down
133+
OpenDrainNoPull = OpenDrain | PullNone, ///< Open-drain mode with no pullup/pulldown
134+
OpenDrainRepeater = OpenDrain | PullNone, ///< Open-drain mode with repeater/keeper
135+
136+
PullDefault = PullUp
131137
} PinMode;
132138

133139
// version of PINCON_TypeDef using register arrays

targets/TARGET_NXP/TARGET_LPC17XX/pinmap.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,23 @@ void pin_mode(PinName pin, PinMode mode) {
3535
uint32_t pin_number = (uint32_t)pin - (uint32_t)P0_0;
3636
int index = pin_number >> 5;
3737
int offset = pin_number & 0x1F;
38-
uint32_t drain = ((uint32_t) mode & (uint32_t) OpenDrain) >> 2;
38+
bool open_drain = (uint32_t) mode & (uint32_t) OpenDrain;
3939

40-
PINCONARRAY->PINMODE_OD[index] &= ~(drain << offset);
41-
PINCONARRAY->PINMODE_OD[index] |= drain << offset;
42-
43-
if (!drain) {
44-
index = pin_number >> 4;
45-
offset = (pin_number & 0xF) << 1;
46-
47-
PINCONARRAY->PINMODE[index] &= ~(0x3 << offset);
48-
PINCONARRAY->PINMODE[index] |= (uint32_t)mode << offset;
40+
if(open_drain) {
41+
PINCONARRAY->PINMODE_OD[index] |= 1 << offset;
42+
}
43+
else {
44+
PINCONARRAY->PINMODE_OD[index] &= ~(1 << offset);
4945
}
46+
47+
// Even if open drain mode is active, the normal pinmode is still used when the open drain pin is outputting a 1.
48+
// So, always set the PINMODE register.
49+
const uint8_t pinmode_sel_msk = 0x3;
50+
uint8_t mode_no_drain = mode & pinmode_sel_msk;
51+
52+
index = pin_number >> 4;
53+
offset = (pin_number & 0xF) << 1;
54+
55+
PINCONARRAY->PINMODE[index] &= ~(pinmode_sel_msk << offset);
56+
PINCONARRAY->PINMODE[index] |= mode_no_drain << offset;
5057
}

0 commit comments

Comments
 (0)