Skip to content

Commit 94a7fbc

Browse files
author
Jamie Smith
authored
LPC1768: Support static pinmaps (ARMmbed#276)
* LPC1768: Fix I2C pins not being open drain, fix destroying and recreating I2C making transactions fail * bus -> peripheral * LPC1768: Support static pinmaps * Update ARCH_PRO pin names header to pass muster
1 parent 6ae571d commit 94a7fbc

File tree

14 files changed

+430
-245
lines changed

14 files changed

+430
-245
lines changed

hal/include/hal/serial_api.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,12 @@ void serial_pinout_tx(PinName tx);
324324

325325
#if DEVICE_SERIAL_FC
326326
/** Configure the serial for the flow control. It sets flow control in the hardware
327-
* if a serial peripheral supports it, otherwise software emulation is used.
327+
* if a serial peripheral supports it, otherwise software emulation shall be used.
328328
*
329329
* @param obj The serial object
330330
* @param type The type of the flow control. Look at the available FlowControl types.
331-
* @param rxflow The TX pin name
332-
* @param txflow The RX pin name
331+
* @param rxflow The TX (RTS) pin name
332+
* @param txflow The RX (CTS) pin name
333333
*/
334334
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow);
335335

hal/include/hal/static_pinmap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ MSTD_CONSTEXPR_FN_14 serial_fc_pinmap_t get_uart_fc_pinmap(const PinName rxflow,
165165
#endif // DEVICE_SERIAL
166166

167167
#if defined(DEVICE_SPI) && defined(PINMAP_SPI_MOSI) && defined(PINMAP_SPI_MISO) && defined(PINMAP_SPI_SCLK) && defined(PINMAP_SPI_SSEL)
168-
MSTD_CONSTEXPR_FN_14 spi_pinmap_t get_spi_pinmap(const PinName mosi, const PinName miso, const PinName sclk, const PinName ssel)
168+
MSTD_CONSTEXPR_FN_14 spi_pinmap_t get_spi_pinmap(const PinName mosi, const PinName miso, const PinName sclk, const PinName ssel = NC)
169169
{
170170
const PinMap *mosi_map = nullptr;
171171
for (const PinMap &pinmap : PINMAP_SPI_MOSI) {

targets/TARGET_NXP/TARGET_LPC176X/PeripheralNames.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ typedef enum {
4646
DAC_0 = 0
4747
} DACName;
4848

49+
// Note: We only use the two SSP peripherals in Mbed, not SPI0. This is because
50+
// SPI0 is a legacy version of the SSP peripheral and cannot be used at the same time as SSP0.
4951
typedef enum {
5052
SPI_0 = (int)LPC_SSP0_BASE,
5153
SPI_1 = (int)LPC_SSP1_BASE
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2024 ARM Limited
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef PERIPHERAL_PINMAPS_H
19+
#define PERIPHERAL_PINMAPS_H
20+
21+
#include <mstd_cstddef>
22+
23+
#include "pinmap.h"
24+
25+
#include "PeripheralNames.h"
26+
27+
// For LPC1768, PinMap entries are in the form
28+
// (pin name, peripheral name, function number)
29+
// where the function number is the 2-bit value that will be written into the PINSELn
30+
// bitfield for this pin.
31+
// See section 8.5 in the LPC1768 user manual for the source of these pinmappings.
32+
33+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_UART_TX[] = {
34+
{P0_0, UART_3, 2},
35+
{P0_2, UART_0, 1},
36+
{P0_10, UART_2, 1},
37+
{P0_15, UART_1, 1},
38+
{P0_25, UART_3, 3},
39+
{P2_0 , UART_1, 2},
40+
{P2_8 , UART_2, 2},
41+
{P4_28, UART_3, 3},
42+
{NC , NC , 0}
43+
};
44+
45+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_UART_RX[] = {
46+
{P0_1 , UART_3, 2},
47+
{P0_3 , UART_0, 1},
48+
{P0_11, UART_2, 1},
49+
{P0_16, UART_1, 1},
50+
{P0_26, UART_3, 3},
51+
{P2_1 , UART_1, 2},
52+
{P2_9 , UART_2, 2},
53+
{P4_29, UART_3, 3},
54+
{NC , NC , 0}
55+
};
56+
57+
// Only UART1 has hardware flow control on LPC176x
58+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_UART_RTS[] = {
59+
{P0_22, UART_1, 1},
60+
{P2_7, UART_1, 2},
61+
{NC, NC, 0}
62+
};
63+
64+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_UART_CTS[] = {
65+
{P0_17, UART_1, 1},
66+
{P2_2, UART_1, 2},
67+
{NC, NC, 0}
68+
};
69+
70+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_SPI_SCLK[] = {
71+
{P0_7 , SPI_1, 2},
72+
{P0_15, SPI_0, 2},
73+
{P1_20, SPI_0, 3},
74+
{P1_31, SPI_1, 2},
75+
{NC , NC , 0}
76+
};
77+
78+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_SPI_MOSI[] = {
79+
{P0_9 , SPI_1, 2},
80+
{P0_13, SPI_1, 2},
81+
{P0_18, SPI_0, 2},
82+
{P1_24, SPI_0, 3},
83+
{NC , NC , 0}
84+
};
85+
86+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_SPI_MISO[] = {
87+
{P0_8 , SPI_1, 2},
88+
{P0_12, SPI_1, 2},
89+
{P0_17, SPI_0, 2},
90+
{P1_23, SPI_0, 3},
91+
{NC , NC , 0}
92+
};
93+
94+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_SPI_SSEL[] = {
95+
{P0_6 , SPI_1, 2},
96+
{P0_11, SPI_1, 2},
97+
{P0_16, SPI_0, 2},
98+
{P1_21, SPI_0, 3},
99+
{NC , NC , 0}
100+
};
101+
102+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_ADC[] = {
103+
{P0_23, ADC0_0, 1},
104+
{P0_24, ADC0_1, 1},
105+
{P0_25, ADC0_2, 1},
106+
{P0_26, ADC0_3, 1},
107+
{P1_30, ADC0_4, 3},
108+
{P1_31, ADC0_5, 3},
109+
{P0_2, ADC0_7, 2},
110+
{P0_3, ADC0_6, 2},
111+
{NC, NC, 0}
112+
};
113+
114+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_DAC[] = {
115+
{P0_26, DAC_0, 2},
116+
{NC , NC , 0}
117+
};
118+
119+
// NOTE: For I2C, only the P0_27/P0_28 pinmapping is fully electrically compliant to the I2C standard.
120+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_I2C_SDA[] = {
121+
{P0_27, I2C_0, 1},
122+
{P0_0 , I2C_1, 3},
123+
{P0_19, I2C_1, 3},
124+
{P0_10, I2C_2, 2},
125+
{NC , NC , 0}
126+
};
127+
128+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_I2C_SCL[] = {
129+
{P0_28, I2C_0, 1},
130+
{P0_1 , I2C_1, 3},
131+
{P0_20, I2C_1, 3},
132+
{P0_11, I2C_2, 2},
133+
{NC , NC, 0}
134+
};
135+
136+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_PWM[] = {
137+
{P1_18, PWM_1, 2},
138+
{P1_20, PWM_2, 2},
139+
{P1_21, PWM_3, 2},
140+
{P1_23, PWM_4, 2},
141+
{P1_24, PWM_5, 2},
142+
{P1_26, PWM_6, 2},
143+
{P2_0, PWM_1, 1},
144+
{P2_1, PWM_2, 1},
145+
{P2_2, PWM_3, 1},
146+
{P2_3, PWM_4, 1},
147+
{P2_4, PWM_5, 1},
148+
{P2_5, PWM_6, 1},
149+
{P3_25, PWM_2, 3},
150+
{P3_26, PWM_3, 3},
151+
{NC, NC, 0}
152+
};
153+
154+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_CAN_RD[] = {
155+
{P0_0 , CAN_1, 1},
156+
{P0_4 , CAN_2, 2},
157+
{P0_21, CAN_1, 3},
158+
{P2_7 , CAN_2, 1},
159+
{NC , NC , 0}
160+
};
161+
162+
static MSTD_CONSTEXPR_OBJ_11 PinMap PinMap_CAN_TD[] = {
163+
{P0_1 , CAN_1, 1},
164+
{P0_5 , CAN_2, 2},
165+
{P0_22, CAN_1, 3},
166+
{P2_8 , CAN_2, 1},
167+
{NC , NC , 0}
168+
};
169+
170+
// Pinmap name macros
171+
#define PINMAP_UART_TX PinMap_UART_TX
172+
#define PINMAP_UART_RX PinMap_UART_RX
173+
#define PINMAP_UART_RTS PinMap_UART_RTS
174+
#define PINMAP_UART_CTS PinMap_UART_CTS
175+
#define PINMAP_SPI_SCLK PinMap_SPI_SCLK
176+
#define PINMAP_SPI_MOSI PinMap_SPI_MOSI
177+
#define PINMAP_SPI_MISO PinMap_SPI_MISO
178+
#define PINMAP_SPI_SSEL PinMap_SPI_SSEL
179+
#define PINMAP_ANALOGIN PinMap_ADC
180+
#define PINMAP_ANALOGOUT PinMap_DAC
181+
#define PINMAP_I2C_SDA PinMap_I2C_SDA
182+
#define PINMAP_I2C_SCL PinMap_I2C_SCL
183+
#define PINMAP_PWM PinMap_PWM
184+
#define PINMAP_CAN_RD PinMap_CAN_RD
185+
#define PINMAP_CAN_TD PinMap_CAN_TD
186+
#endif

targets/TARGET_NXP/TARGET_LPC176X/TARGET_ARCH_PRO/PinNames.h

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ typedef enum {
3131
PIN_OUTPUT
3232
} PinDirection;
3333

34+
/* If this macro is defined, you can use constexpr utility functions for pin map search. */
35+
#define STATIC_PINMAP_READY 1
36+
3437
#define PORT_SHIFT 5
3538

3639
typedef enum {
@@ -70,18 +73,6 @@ typedef enum {
7073
p29 = P0_5,
7174
p30 = P0_4,
7275

73-
// Other mbed Pin Names
74-
#ifdef MCB1700
75-
LED1 = P1_28,
76-
LED2 = P1_29,
77-
LED3 = P1_31,
78-
LED4 = P2_2,
79-
#else
80-
LED1 = P1_18,
81-
LED2 = P1_20,
82-
LED3 = P1_21,
83-
LED4 = P1_23,
84-
#endif
8576
CONSOLE_TX = P0_2,
8677
CONSOLE_RX = P0_3,
8778

@@ -110,19 +101,25 @@ typedef enum {
110101
A4 = P1_30,
111102
A5 = P1_31,
112103

113-
I2C_SCL = D15,
114-
I2C_SDA = D14,
115-
116-
//SPI Pins configuration
117-
SPI_MOSI = P0_9,
118-
SPI_MISO = P0_8,
119-
SPI_SCK = P0_7,
120-
SPI_CS = P0_6,
121-
122104
// Not connected
123105
NC = (int)0xFFFFFFFF
124106
} PinName;
125107

108+
// Standard buttons and LEDs
109+
#define LED1 P1_18
110+
#define LED2 P1_20
111+
#define LED3 P1_21
112+
#define LED4 P1_23
113+
114+
// I2C and SPI pin names
115+
#define I2C_SCL D15
116+
#define I2C_SDA D14
117+
118+
#define SPI_MOSI P0_9
119+
#define SPI_MISO P0_8
120+
#define SPI_SCK P0_7
121+
#define SPI_CS P0_6
122+
126123
typedef enum {
127124
PullUp = 0,
128125
PullDown = 3,

targets/TARGET_NXP/TARGET_LPC176X/TARGET_MBED_LPC1768/PinNames.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ typedef enum {
3131
PIN_OUTPUT
3232
} PinDirection;
3333

34+
/* If this macro is defined, you can use constexpr utility functions for pin map search. */
35+
#define STATIC_PINMAP_READY 1
36+
3437
#define PORT_SHIFT 5
3538

3639
typedef enum {

targets/TARGET_NXP/TARGET_LPC176X/analogin_api.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include "analogin_api.h"
1919

2020
#include "cmsis.h"
21-
#include "pinmap.h"
21+
#include "PeripheralPinMaps.h"
2222

2323
#define ANALOGIN_MEDIAN_FILTER 1
2424

@@ -29,23 +29,10 @@ static inline int div_round_up(int x, int y) {
2929
return (x + (y - 1)) / y;
3030
}
3131

32-
static const PinMap PinMap_ADC[] = {
33-
{P0_23, ADC0_0, 1},
34-
{P0_24, ADC0_1, 1},
35-
{P0_25, ADC0_2, 1},
36-
{P0_26, ADC0_3, 1},
37-
{P1_30, ADC0_4, 3},
38-
{P1_31, ADC0_5, 3},
39-
{P0_2, ADC0_7, 2},
40-
{P0_3, ADC0_6, 2},
41-
{NC, NC, 0}
42-
};
43-
4432
#define ADC_RANGE ADC_12BIT_RANGE
4533

46-
void analogin_init(analogin_t *obj, PinName pin) {
47-
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
48-
MBED_ASSERT(obj->adc != (ADCName)NC);
34+
void analogin_init_direct(analogin_t *obj, const PinMap *pinmap) {
35+
obj->adc = pinmap->peripheral;
4936

5037
// ensure power is turned on
5138
LPC_SC->PCONP |= (1 << 12);
@@ -69,7 +56,19 @@ void analogin_init(analogin_t *obj, PinName pin) {
6956
| (0 << 24) // START: 0 = no start
7057
| (0 << 27); // EDGE: not applicable
7158

72-
pinmap_pinout(pin, PinMap_ADC);
59+
// Map pin
60+
pin_function(pinmap->pin, pinmap->function);
61+
pin_mode(pinmap->pin, PullNone);
62+
}
63+
64+
void analogin_init(analogin_t *obj, PinName pin) {
65+
PinMap pinmap;
66+
pinmap.pin = pin;
67+
pinmap.function = pinmap_find_function(pin, PinMap_ADC);
68+
pinmap.peripheral = pinmap_peripheral(pin, PinMap_ADC);
69+
MBED_ASSERT(pinmap.peripheral != NC);
70+
71+
analogin_init_direct(obj, &pinmap);
7372
}
7473

7574
static inline uint32_t adc_read(analogin_t *obj) {

targets/TARGET_NXP/TARGET_LPC176X/analogout_api.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,31 @@
1818
#include "analogout_api.h"
1919

2020
#include "cmsis.h"
21-
#include "pinmap.h"
21+
#include "PeripheralPinMaps.h"
2222

23-
static const PinMap PinMap_DAC[] = {
24-
{P0_26, DAC_0, 2},
25-
{NC , NC , 0}
26-
};
27-
28-
void analogout_init(dac_t *obj, PinName pin) {
29-
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
30-
MBED_ASSERT(obj->dac != (DACName)NC);
23+
void analogout_init_direct(dac_t *obj, const PinMap *pinmap) {
24+
obj->dac = (DACName)pinmap->peripheral;
3125

3226
// power is on by default, set DAC clk divider is /4
3327
LPC_SC->PCLKSEL0 &= ~(0x3 << 22);
3428

3529
// map out (must be done before accessing registers)
36-
pinmap_pinout(pin, PinMap_DAC);
30+
pin_function(pinmap->pin, pinmap->function);
31+
pin_mode(pinmap->pin, PullNone);
3732

3833
analogout_write_u16(obj, 0);
3934
}
4035

36+
void analogout_init(dac_t *obj, PinName pin) {
37+
PinMap pinmap;
38+
pinmap.pin = pin;
39+
pinmap.function = pinmap_find_function(pin, PinMap_DAC);
40+
pinmap.peripheral = pinmap_peripheral(pin, PinMap_DAC);
41+
MBED_ASSERT(pinmap.peripheral != NC);
42+
43+
analogout_init_direct(obj, &pinmap);
44+
}
45+
4146
void analogout_free(dac_t *obj) {}
4247

4348
static inline void dac_write(int value) {

0 commit comments

Comments
 (0)