Intel® Quark™ Microcontroller Software Interface 1.4.0 Intel® Quark™ Microcontroller BSP

- Main Page
- Modules
- Data Structures
- Files

- File List

qm_gpio.c
1 /*
2 * {% copyright %}
3 */
4
5 #include "qm_gpio.h"
6
7 #if (HAS_SOC_CONTEXT_RETENTION)
8 #include "power_states.h"
9 #endif /* HAS_SOC_CONTEXT_RETENTION */
10
11 #define ENABLE_PCLK (0x1)
12
13 #ifndef UNIT_TEST
14 qm_gpio_reg_t *qm_gpio[QM_GPIO_NUM] = {(qm_gpio_reg_t *)QM_GPIO_BASE,
15 #if (HAS_AON_GPIO)
16 (qm_gpio_reg_t *)QM_AON_GPIO_BASE
17 #endif /* HAS_AON_GPIO */
18 };
19 #endif /* UNIT_TEST */
20
21 static void (*callback[QM_GPIO_NUM])(void *, uint32_t);
22 static void *callback_data[QM_GPIO_NUM];
23
24 static void gpio_isr(const qm_gpio_t gpio)
25 {
26 const uint32_t int_status = QM_GPIO[gpio]->gpio_intstatus;
27
28 #if (HAS_SOC_CONTEXT_RETENTION)
29 if (QM_SCSS_GP->gps0 & QM_GPS0_POWER_STATES_MASK) {
30 qm_power_soc_restore();
31 }
32 #endif
33
34 if (callback[gpio]) {
35 (*callback[gpio])(callback_data[gpio], int_status);
36 }
37
38 /* This will clear all pending interrupts flags in status */
39 QM_GPIO[gpio]->gpio_porta_eoi = int_status;
40 /* Read back EOI register to avoid a spurious interrupt due to EOI
41 * propagation delay */
42 QM_GPIO[gpio]->gpio_porta_eoi;
43 }
44
45 QM_ISR_DECLARE(qm_gpio_0_isr)
46 {
47 gpio_isr(QM_GPIO_0);
48 QM_ISR_EOI(QM_IRQ_GPIO_0_INT_VECTOR);
49 }
50
51 #if (HAS_AON_GPIO)
52 QM_ISR_DECLARE(qm_aon_gpio_0_isr)
53 {
54 gpio_isr(QM_AON_GPIO_0);
55 QM_ISR_EOI(QM_IRQ_AON_GPIO_0_INT_VECTOR);
56 }
57 #endif
58
59 int qm_gpio_set_config(const qm_gpio_t gpio,
60 const qm_gpio_port_config_t *const cfg)
61 {
62 QM_CHECK(gpio < QM_GPIO_NUM, -EINVAL);
63 QM_CHECK(cfg != NULL, -EINVAL);
64
65 qm_gpio_reg_t *const controller = QM_GPIO[gpio];
66
67 uint32_t mask = controller->gpio_intmask;
68 controller->gpio_intmask = 0xffffffff;
69
70 controller->gpio_swporta_ddr = cfg->direction;
71 controller->gpio_inten = cfg->int_en;
72 controller->gpio_inttype_level = cfg->int_type;
73 controller->gpio_int_polarity = cfg->int_polarity;
74 controller->gpio_debounce = cfg->int_debounce;
75 controller->gpio_int_bothedge = cfg->int_bothedge;
76 controller->gpio_ls_sync |= ENABLE_PCLK;
77 callback[gpio] = cfg->callback;
78 callback_data[gpio] = cfg->callback_data;
79
80 controller->gpio_intmask = mask;
81
82 return 0;
83 }
84
85 int qm_gpio_read_pin(const qm_gpio_t gpio, const uint8_t pin,
86 qm_gpio_state_t *const state)
87 {
88 QM_CHECK(gpio < QM_GPIO_NUM, -EINVAL);
89 QM_CHECK(pin <= QM_NUM_GPIO_PINS, -EINVAL);
90 QM_CHECK(state != NULL, -EINVAL);
91
92 *state = ((QM_GPIO[gpio]->gpio_ext_porta) >> pin) & 1;
93
94 return 0;
95 }
96
97 int qm_gpio_set_pin(const qm_gpio_t gpio, const uint8_t pin)
98 {
99 QM_CHECK(gpio < QM_GPIO_NUM, -EINVAL);
100 QM_CHECK(pin <= QM_NUM_GPIO_PINS, -EINVAL);
101
102 QM_GPIO[gpio]->gpio_swporta_dr |= (1 << pin);
103
104 return 0;
105 }
106
107 int qm_gpio_clear_pin(const qm_gpio_t gpio, const uint8_t pin)
108 {
109 QM_CHECK(gpio < QM_GPIO_NUM, -EINVAL);
110 QM_CHECK(pin <= QM_NUM_GPIO_PINS, -EINVAL);
111
112 QM_GPIO[gpio]->gpio_swporta_dr &= ~(1 << pin);
113
114 return 0;
115 }
116
117 int qm_gpio_set_pin_state(const qm_gpio_t gpio, const uint8_t pin,
118 const qm_gpio_state_t state)
119 {
120 QM_CHECK(gpio < QM_GPIO_NUM, -EINVAL);
121 QM_CHECK(pin <= QM_NUM_GPIO_PINS, -EINVAL);
122 QM_CHECK(state < QM_GPIO_STATE_NUM, -EINVAL);
123
124 uint32_t reg = QM_GPIO[gpio]->gpio_swporta_dr;
125 reg ^= (-state ^ reg) & (1 << pin);
126 QM_GPIO[gpio]->gpio_swporta_dr = reg;
127
128 return 0;
129 }
130
131 int qm_gpio_read_port(const qm_gpio_t gpio, uint32_t *const port)
132 {
133 QM_CHECK(gpio < QM_GPIO_NUM, -EINVAL);
134 QM_CHECK(port != NULL, -EINVAL);
135
136 *port = QM_GPIO[gpio]->gpio_ext_porta;
137
138 return 0;
139 }
140
141 int qm_gpio_write_port(const qm_gpio_t gpio, const uint32_t val)
142 {
143 QM_CHECK(gpio < QM_GPIO_NUM, -EINVAL);
144
145 QM_GPIO[gpio]->gpio_swporta_dr = val;
146
147 return 0;
148 }
149
150 #if (ENABLE_RESTORE_CONTEXT)
151 int qm_gpio_save_context(const qm_gpio_t gpio, qm_gpio_context_t *const ctx)
152 {
153 QM_CHECK(gpio < QM_GPIO_NUM, -EINVAL);
154 QM_CHECK(ctx != NULL, -EINVAL);
155
156 qm_gpio_reg_t *const controller = QM_GPIO[gpio];
157
158 if (gpio == QM_GPIO_0) {
159 ctx->gpio_swporta_dr = controller->gpio_swporta_dr;
160 ctx->gpio_swporta_ddr = controller->gpio_swporta_ddr;
161 ctx->gpio_swporta_ctl = controller->gpio_swporta_ctl;
162 ctx->gpio_inten = controller->gpio_inten;
163 ctx->gpio_intmask = controller->gpio_intmask;
164 ctx->gpio_inttype_level = controller->gpio_inttype_level;
165 ctx->gpio_int_polarity = controller->gpio_int_polarity;
166 ctx->gpio_debounce = controller->gpio_debounce;
167 ctx->gpio_ls_sync = controller->gpio_ls_sync;
168 ctx->gpio_int_bothedge = controller->gpio_int_bothedge;
169 }
170
171 return 0;
172 }
173
174 int qm_gpio_restore_context(const qm_gpio_t gpio,
175 const qm_gpio_context_t *const ctx)
176 {
177 QM_CHECK(gpio < QM_GPIO_NUM, -EINVAL);
178 QM_CHECK(ctx != NULL, -EINVAL);
179
180 qm_gpio_reg_t *const controller = QM_GPIO[gpio];
181
182 if (gpio == QM_GPIO_0) {
183 controller->gpio_intmask = 0xffffffff;
184 controller->gpio_swporta_dr = ctx->gpio_swporta_dr;
185 controller->gpio_swporta_ddr = ctx->gpio_swporta_ddr;
186 controller->gpio_swporta_ctl = ctx->gpio_swporta_ctl;
187 controller->gpio_inten = ctx->gpio_inten;
188 controller->gpio_inttype_level = ctx->gpio_inttype_level;
189 controller->gpio_int_polarity = ctx->gpio_int_polarity;
190 controller->gpio_debounce = ctx->gpio_debounce;
191 controller->gpio_ls_sync = ctx->gpio_ls_sync;
192 controller->gpio_int_bothedge = ctx->gpio_int_bothedge;
193 controller->gpio_intmask = ctx->gpio_intmask;
194 }
195
196 return 0;
197 }
198 #else
199 int qm_gpio_save_context(const qm_gpio_t gpio, qm_gpio_context_t *const ctx)
200 {
201 (void)gpio;
202 (void)ctx;
203
204 return 0;
205 }
206
207 int qm_gpio_restore_context(const qm_gpio_t gpio,
208 const qm_gpio_context_t *const ctx)
209 {
210 (void)gpio;
211 (void)ctx;
212
213 return 0;
214 }
215 #endif /* ENABLE_RESTORE_CONTEXT */
qm_gpio_reg_t::gpio_inten
QM_RW uint32_t gpio_inten
Interrupt Enable.
Definition: qm_soc_regs.h:1021
QM_ISR_DECLARE
QM_ISR_DECLARE(qm_gpio_0_isr)
ISR for GPIO 0 interrupt.
Definition: qm_gpio.c:45
qm_gpio_clear_pin
int qm_gpio_clear_pin(const qm_gpio_t gpio, const uint8_t pin)
Clear a single pin on a given GPIO port.
Definition: qm_gpio.c:107
qm_power_soc_restore
void qm_power_soc_restore(void)
Restore system state after sleep or deep sleep.
Definition: power_states.c:402
qm_gpio_port_config_t::int_polarity
uint32_t int_polarity
Interrupt polarity, 0b: low, 1b: high.
Definition: qm_gpio.h:36
qm_gpio_context_t::gpio_swporta_ddr
uint32_t gpio_swporta_ddr
Port A Data Direction.
Definition: qm_soc_regs.h:1401
qm_gpio_port_config_t::direction
uint32_t direction
GPIO direction, 0b: input, 1b: output.
Definition: qm_gpio.h:33
qm_gpio_context_t::gpio_inttype_level
uint32_t gpio_inttype_level
Interrupt Type.
Definition: qm_soc_regs.h:1405
qm_gpio_read_pin
int qm_gpio_read_pin(const qm_gpio_t gpio, const uint8_t pin, qm_gpio_state_t *const state)
Read the current state of a single pin on a given GPIO port.
Definition: qm_gpio.c:85
qm_gpio_set_pin
int qm_gpio_set_pin(const qm_gpio_t gpio, const uint8_t pin)
Set a single pin on a given GPIO port.
Definition: qm_gpio.c:97
qm_gpio_write_port
int qm_gpio_write_port(const qm_gpio_t gpio, const uint32_t val)
Write a value to every pin on a GPIO port.
Definition: qm_gpio.c:141
qm_gpio
qm_gpio_reg_t * qm_gpio[QM_GPIO_NUM]
GPIO register block.
Definition: qm_gpio.c:14
qm_gpio_context_t::gpio_ls_sync
uint32_t gpio_ls_sync
Synchronization Level.
Definition: qm_soc_regs.h:1408
qm_gpio_context_t::gpio_intmask
uint32_t gpio_intmask
Interrupt Mask.
Definition: qm_soc_regs.h:1404
qm_gpio_reg_t::gpio_swporta_ddr
QM_RW uint32_t gpio_swporta_ddr
Port A Data Direction.
Definition: qm_soc_regs.h:1019
qm_gpio_port_config_t::int_debounce
uint32_t int_debounce
Interrupt debounce on/off.
Definition: qm_gpio.h:37
qm_gpio_reg_t::gpio_debounce
QM_RW uint32_t gpio_debounce
Debounce Enable.
Definition: qm_soc_regs.h:1027
qm_gpio_port_config_t::callback
void(* callback)(void *data, uint32_t int_status)
Transfer callback.
Definition: qm_gpio.h:46
qm_gpio_context_t::gpio_int_polarity
uint32_t gpio_int_polarity
Interrupt Polarity.
Definition: qm_soc_regs.h:1406
qm_gpio_reg_t::gpio_swporta_dr
QM_RW uint32_t gpio_swporta_dr
Port A Data.
Definition: qm_soc_regs.h:1018
qm_gpio_port_config_t::int_type
uint32_t int_type
Interrupt type, 0b: level; 1b: edge.
Definition: qm_gpio.h:35
qm_gpio_port_config_t::int_bothedge
uint32_t int_bothedge
Interrupt on rising and falling edges.
Definition: qm_gpio.h:38
qm_gpio_context_t::gpio_int_bothedge
uint32_t gpio_int_bothedge
Interrupt both edge type.
Definition: qm_soc_regs.h:1409
qm_gpio_save_context
int qm_gpio_save_context(const qm_gpio_t gpio, qm_gpio_context_t *const ctx)
Save GPIO context.
Definition: qm_gpio.c:151
qm_gpio_reg_t::gpio_swporta_ctl
QM_RW uint32_t gpio_swporta_ctl
Port A Data Source.
Definition: qm_soc_regs.h:1372
qm_gpio_reg_t
GPIO register map.
Definition: qm_soc_regs.h:1017
qm_gpio_reg_t::gpio_intmask
QM_RW uint32_t gpio_intmask
Interrupt Mask.
Definition: qm_soc_regs.h:1022
QM_GPIO_STATE_NUM
Number of GPIO states.
Definition: qm_gpio.h:24
qm_gpio_set_pin_state
int qm_gpio_set_pin_state(const qm_gpio_t gpio, const uint8_t pin, const qm_gpio_state_t state)
Set or clear a single GPIO pin using a state variable.
Definition: qm_gpio.c:117
qm_gpio_reg_t::gpio_int_polarity
QM_RW uint32_t gpio_int_polarity
Interrupt Polarity.
Definition: qm_soc_regs.h:1024
qm_gpio_context_t::gpio_inten
uint32_t gpio_inten
Interrupt Enable.
Definition: qm_soc_regs.h:1403
qm_gpio_port_config_t::int_en
uint32_t int_en
Interrupt enable.
Definition: qm_gpio.h:34
qm_gpio_state_t
qm_gpio_state_t
GPIO pin states.
Definition: qm_gpio.h:21
qm_gpio_context_t::gpio_swporta_dr
uint32_t gpio_swporta_dr
Port A Data.
Definition: qm_soc_regs.h:1400
qm_gpio_context_t
GPIO context type.
Definition: qm_soc_regs.h:1399
qm_gpio_t
qm_gpio_t
Number of GPIO controllers.
Definition: qm_soc_regs.h:1014
qm_gpio_reg_t::gpio_ls_sync
QM_RW uint32_t gpio_ls_sync
Synchronization Level.
Definition: qm_soc_regs.h:1031
qm_gpio_context_t::gpio_debounce
uint32_t gpio_debounce
Debounce Enable.
Definition: qm_soc_regs.h:1407
qm_gpio_read_port
int qm_gpio_read_port(const qm_gpio_t gpio, uint32_t *const port)
Read the value of every pin on a GPIO port.
Definition: qm_gpio.c:131
qm_gpio_reg_t::gpio_inttype_level
QM_RW uint32_t gpio_inttype_level
Interrupt Type.
Definition: qm_soc_regs.h:1023
qm_gpio_restore_context
int qm_gpio_restore_context(const qm_gpio_t gpio, const qm_gpio_context_t *const ctx)
Restore GPIO context.
Definition: qm_gpio.c:174
qm_gpio_port_config_t::callback_data
void * callback_data
Callback user data.
Definition: qm_gpio.h:47
qm_gpio_port_config_t
GPIO port configuration type.
Definition: qm_gpio.h:32
qm_gpio_context_t::gpio_swporta_ctl
uint32_t gpio_swporta_ctl
Port A Data Source.
Definition: qm_soc_regs.h:1402
qm_gpio_set_config
int qm_gpio_set_config(const qm_gpio_t gpio, const qm_gpio_port_config_t *const cfg)
Set GPIO port configuration.
Definition: qm_gpio.c:59
qm_gpio_reg_t::gpio_int_bothedge
QM_RW uint32_t gpio_int_bothedge
Interrupt both edge type.
Definition: qm_soc_regs.h:1033