-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathports.c
95 lines (86 loc) · 2.49 KB
/
ports.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "ccu.h"
#include "ports.h"
#include "util.h"
void gpio_init()
{
#ifdef AWBM_PLATFORM_h3
BUS_CLK_GATING2 |= (1 << 5);
APB0_CLK_GATING |= (1 << 0);
#elif defined(AWBM_PLATFORM_h616)
// Neither APB1 nor the ports seem to have any gates.
#else
#error unknown platform
#endif
}
void set_pin_mode(uint32_t port_addr, uint32_t pin, uint32_t mode)
{
volatile struct port_registers *port = (volatile struct port_registers *)port_addr;
if (pin < 8) {
port->cfg0 &= ~(7 << ((pin - 0) * 4));
port->cfg0 |= (mode << ((pin - 0) * 4));
} else if (pin < 16) {
port->cfg1 &= ~(7 << ((pin - 8) * 4));
port->cfg1 |= (mode << ((pin - 8) * 4));
} else if (pin < 24) {
port->cfg2 &= ~(7 << ((pin - 16) * 4));
port->cfg2 |= (mode << ((pin - 16) * 4));
} else {
port->cfg3 &= ~(7 << ((pin - 24) * 4));
port->cfg3 |= (mode << ((pin - 24) * 4));
}
}
void set_pin_data(uint32_t port_addr, uint32_t pin, uint32_t data)
{
volatile struct port_registers *port = (volatile struct port_registers *)port_addr;
if (data) {
port->data |= (1 << pin);
} else {
port->data &= ~(1 << pin);
}
}
int get_pin_data(uint32_t port_addr, uint32_t pin)
{
volatile struct port_registers *port = (volatile struct port_registers *)port_addr;
return !!(port->data & (1 << pin));
}
void set_pin_drive(uint32_t port_addr, uint32_t pin, uint32_t strength)
{
volatile struct port_registers *port = (struct port_registers *)port_addr;
if (pin < 16) {
port->drv0 &= ~(3 << pin * 2);
port->drv0 |= strength << pin * 2;
} else {
pin -= 16;
port->drv1 &= ~(3 << pin * 2);
port->drv1 |= strength << pin * 2;
}
}
void set_pin_pull(uint32_t port_addr, uint32_t pin, uint32_t pull)
{
volatile struct port_registers *port = (struct port_registers *)port_addr;
if (pin < 16) {
port->pul0 &= ~(3 << pin * 2);
port->pul0 |= pull << pin * 2;
} else {
pin -= 16;
port->pul1 &= ~(3 << pin * 2);
port->pul1 |= pull << pin * 2;
}
}
void gpio_irq_set_trigger(uint32_t port_addr, int pin, uint8_t mode)
{
set_pin_mode(port_addr + 0x200, pin, mode);
}
void gpio_irq_enable(uint32_t port_addr, int pin, int enable)
{
volatile struct port_irq_registers *port = (volatile struct port_irq_registers *)(port_addr + 0x200);
if (enable)
port->ctl |= BIT(pin);
else
port->ctl &= ~BIT(pin);
}
void gpio_irq_ack(uint32_t port_addr)
{
volatile struct port_irq_registers *port = (volatile struct port_irq_registers *)(port_addr + 0x200);
port->status = port->status;
}