Skip to content

Commit c78b907

Browse files
committed
lpc176x: Add support for GPIO pins
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
1 parent 970831e commit c78b907

File tree

4 files changed

+120
-1
lines changed

4 files changed

+120
-1
lines changed

klippy/pins.py

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ def named_pins(fmt, port_count, bit_count=32):
2525
for port in range(port_count)
2626
for portbit in range(bit_count) }
2727

28+
def lpc_pins():
29+
return { 'P%d.%d' % (port, pin) : port * 32 + pin
30+
for port in range(5) for pin in range(32) }
31+
2832
def beaglebone_pins():
2933
gpios = named_pins("gpio%d_%d", 4)
3034
gpios.update({"AIN%d" % i: i+4*32 for i in range(8)})
@@ -37,6 +41,7 @@ def beaglebone_pins():
3741
"atmega1280": port_pins(12), "atmega2560": port_pins(12),
3842
"sam3x8e": port_pins(4, 32),
3943
"stm32f103": port_pins(5, 16),
44+
"lpc176x": lpc_pins(),
4045
"pru": beaglebone_pins(),
4146
"linux": {"analog%d" % i: i for i in range(8)}, # XXX
4247
}

src/lpc176x/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ if MACH_LPC176X
55
config LPC_SELECT
66
bool
77
default y
8+
select HAVE_GPIO
89

910
config BOARD_DIRECTORY
1011
string

src/lpc176x/gpio.c

+92-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,29 @@
55
// This file may be distributed under the terms of the GNU GPLv3 license.
66

77
#include "LPC17xx.h" // LPC_PINCON
8-
#include "internal.h" // gpio_peripheral
98
#include "board/irq.h" // irq_save
9+
#include "command.h" // shutdown
10+
#include "gpio.h" // gpio_out_setup
11+
#include "internal.h" // gpio_peripheral
12+
#include "sched.h" // sched_shutdown
13+
14+
15+
/****************************************************************
16+
* Pin mappings
17+
****************************************************************/
18+
19+
#define GPIO(PORT, NUM) ((PORT) * 32 + (NUM))
20+
#define GPIO2PORT(PIN) ((PIN) / 32)
21+
#define GPIO2BIT(PIN) (1<<((PIN) % 32))
22+
23+
static LPC_GPIO_TypeDef * const digital_regs[] = {
24+
LPC_GPIO0, LPC_GPIO1, LPC_GPIO2, LPC_GPIO3, LPC_GPIO4
25+
};
26+
27+
28+
/****************************************************************
29+
* General Purpose Input Output (GPIO) pins
30+
****************************************************************/
1031

1132
// Set the mode and extended function of a pin
1233
void
@@ -26,3 +47,73 @@ gpio_peripheral(int bank, int pin, int func, int pullup)
2647
pinmode[bank_pos] = (pinmode[bank_pos] & mask) | mode_bits;
2748
irq_restore(flag);
2849
}
50+
51+
52+
struct gpio_out
53+
gpio_out_setup(uint8_t pin, uint8_t val)
54+
{
55+
if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs))
56+
goto fail;
57+
LPC_GPIO_TypeDef *regs = digital_regs[GPIO2PORT(pin)];
58+
uint32_t bit = GPIO2BIT(pin);
59+
irqstatus_t flag = irq_save();
60+
if (val)
61+
regs->FIOSET = bit;
62+
else
63+
regs->FIOCLR = bit;
64+
regs->FIODIR |= bit;
65+
irq_restore(flag);
66+
return (struct gpio_out){ .regs=regs, .bit=bit };
67+
fail:
68+
shutdown("Not an output pin");
69+
}
70+
71+
void
72+
gpio_out_toggle_noirq(struct gpio_out g)
73+
{
74+
LPC_GPIO_TypeDef *regs = g.regs;
75+
regs->FIOPIN = regs->FIOSET ^ g.bit;
76+
}
77+
78+
void
79+
gpio_out_toggle(struct gpio_out g)
80+
{
81+
irqstatus_t flag = irq_save();
82+
gpio_out_toggle_noirq(g);
83+
irq_restore(flag);
84+
}
85+
86+
void
87+
gpio_out_write(struct gpio_out g, uint8_t val)
88+
{
89+
LPC_GPIO_TypeDef *regs = g.regs;
90+
if (val)
91+
regs->FIOSET = g.bit;
92+
else
93+
regs->FIOCLR = g.bit;
94+
}
95+
96+
97+
struct gpio_in
98+
gpio_in_setup(uint8_t pin, int8_t pull_up)
99+
{
100+
if (GPIO2PORT(pin) >= ARRAY_SIZE(digital_regs))
101+
goto fail;
102+
uint32_t port = GPIO2PORT(pin);
103+
LPC_GPIO_TypeDef *regs = digital_regs[port];
104+
uint32_t bit = GPIO2BIT(pin);
105+
irqstatus_t flag = irq_save();
106+
gpio_peripheral(port, pin % 32, 0, pull_up);
107+
regs->FIODIR &= ~bit;
108+
irq_restore(flag);
109+
return (struct gpio_in){ .regs=regs, .bit=bit };
110+
fail:
111+
shutdown("Not an input pin");
112+
}
113+
114+
uint8_t
115+
gpio_in_read(struct gpio_in g)
116+
{
117+
LPC_GPIO_TypeDef *regs = g.regs;
118+
return !!(regs->FIOPIN & g.bit);
119+
}

src/lpc176x/gpio.h

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef __LPC176X_GPIO_H
2+
#define __LPC176X_GPIO_H
3+
4+
#include <stdint.h>
5+
6+
struct gpio_out {
7+
void *regs;
8+
uint32_t bit;
9+
};
10+
struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val);
11+
void gpio_out_toggle_noirq(struct gpio_out g);
12+
void gpio_out_toggle(struct gpio_out g);
13+
void gpio_out_write(struct gpio_out g, uint8_t val);
14+
15+
struct gpio_in {
16+
void *regs;
17+
uint32_t bit;
18+
};
19+
struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up);
20+
uint8_t gpio_in_read(struct gpio_in g);
21+
22+
#endif // gpio.h

0 commit comments

Comments
 (0)