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
1233void
@@ -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+ }
0 commit comments