Lines Matching +full:interrupt +full:- +full:map +full:- +full:mask
4 * SPDX-License-Identifier: Apache-2.0
27 * @brief GPIO Emulator interrupt capabilities
30 * model GPIO interrupt controllers with varying interrupt trigger support.
91 /** Interrupt status for each pin */
95 /** Is interrupt enabled for each pin */
97 /** Singly-linked list of callbacks associated with the controller */
102 * @brief Obtain a mask of pins that match all of the provided @p flags
109 * @param mask A mask of flags to match
112 * @return a mask of the pins with matching @p flags
115 get_pins_with_flags(const struct device *port, gpio_port_pins_t mask, in get_pins_with_flags() argument
121 (struct gpio_emul_data *)port->data; in get_pins_with_flags()
123 (const struct gpio_emul_config *)port->config; in get_pins_with_flags()
125 for (i = 0; i < config->num_pins; ++i) { in get_pins_with_flags()
126 if ((drv_data->flags[i] & mask) == flags) { in get_pins_with_flags()
135 * @brief Obtain a mask of pins that are configured as @ref GPIO_INPUT
141 * @return a mask of pins that are configured as @ref GPIO_INPUT
149 * @brief Obtain a mask of pins that are configured as @ref GPIO_OUTPUT
155 * @return a mask of pins that are configured as @ref GPIO_OUTPUT
174 (const struct gpio_emul_config *)port->config; in gpio_emul_config_has_caps()
176 return (caps & config->interrupt_caps) == caps; in gpio_emul_config_has_caps()
183 gpio_port_pins_t mask, in gpio_emul_gen_interrupt_bits() argument
193 (struct gpio_emul_data *)port->data; in gpio_emul_gen_interrupt_bits()
195 (const struct gpio_emul_config *)port->config; in gpio_emul_gen_interrupt_bits()
197 for (i = 0, *interrupts = 0; mask && i < config->num_pins; in gpio_emul_gen_interrupt_bits()
198 ++i, mask >>= 1, prev_values >>= 1, values >>= 1) { in gpio_emul_gen_interrupt_bits()
199 if ((mask & 1) == 0) { in gpio_emul_gen_interrupt_bits()
206 switch (drv_data->flags[i] & GPIO_EMUL_INT_BITMASK) { in gpio_emul_gen_interrupt_bits()
210 drv_data->interrupts |= BIT(i); in gpio_emul_gen_interrupt_bits()
211 *interrupts |= (BIT(i) & drv_data->enabled_interrupts); in gpio_emul_gen_interrupt_bits()
218 drv_data->interrupts |= BIT(i); in gpio_emul_gen_interrupt_bits()
219 *interrupts |= (BIT(i) & drv_data->enabled_interrupts); in gpio_emul_gen_interrupt_bits()
227 drv_data->interrupts |= BIT(i); in gpio_emul_gen_interrupt_bits()
228 *interrupts |= (BIT(i) & drv_data->enabled_interrupts); in gpio_emul_gen_interrupt_bits()
235 drv_data->interrupts |= BIT(i); in gpio_emul_gen_interrupt_bits()
236 *interrupts |= (BIT(i) & drv_data->enabled_interrupts); in gpio_emul_gen_interrupt_bits()
243 drv_data->interrupts |= BIT(i); in gpio_emul_gen_interrupt_bits()
244 *interrupts |= (BIT(i) & drv_data->enabled_interrupts); in gpio_emul_gen_interrupt_bits()
253 drv_data->flags[i] & GPIO_EMUL_INT_BITMASK); in gpio_emul_gen_interrupt_bits()
260 * @brief Trigger possible interrupt events after an input pin has changed
267 * @param mask The mask of pins that have changed
271 static void gpio_emul_pend_interrupt(const struct device *port, gpio_port_pins_t mask, in gpio_emul_pend_interrupt() argument
277 (struct gpio_emul_data *)port->data; in gpio_emul_pend_interrupt()
280 key = k_spin_lock(&drv_data->lock); in gpio_emul_pend_interrupt()
281 gpio_emul_gen_interrupt_bits(port, mask, prev_values, values, in gpio_emul_pend_interrupt()
284 k_spin_unlock(&drv_data->lock, key); in gpio_emul_pend_interrupt()
285 gpio_fire_callbacks(&drv_data->callbacks, port, interrupts); in gpio_emul_pend_interrupt()
286 key = k_spin_lock(&drv_data->lock); in gpio_emul_pend_interrupt()
288 drv_data->interrupts &= ~interrupts; in gpio_emul_pend_interrupt()
289 gpio_emul_gen_interrupt_bits(port, mask, prev_values, values, in gpio_emul_pend_interrupt()
293 k_spin_unlock(&drv_data->lock, key); in gpio_emul_pend_interrupt()
297 gpio_port_pins_t mask, in gpio_emul_input_set_masked_int() argument
303 (struct gpio_emul_data *)port->data; in gpio_emul_input_set_masked_int()
305 (const struct gpio_emul_config *)port->config; in gpio_emul_input_set_masked_int()
307 if (mask == 0) { in gpio_emul_input_set_masked_int()
311 if (~config->common.port_pin_mask & mask) { in gpio_emul_input_set_masked_int()
312 LOG_ERR("Pin not supported port_pin_mask=%x mask=%x", in gpio_emul_input_set_masked_int()
313 config->common.port_pin_mask, mask); in gpio_emul_input_set_masked_int()
314 return -EINVAL; in gpio_emul_input_set_masked_int()
318 if (~input_mask & mask) { in gpio_emul_input_set_masked_int()
319 LOG_ERR("Not input pin input_mask=%x mask=%x", input_mask, in gpio_emul_input_set_masked_int()
320 mask); in gpio_emul_input_set_masked_int()
321 return -EINVAL; in gpio_emul_input_set_masked_int()
324 prev_values = drv_data->input_vals; in gpio_emul_input_set_masked_int()
325 drv_data->input_vals &= ~mask; in gpio_emul_input_set_masked_int()
326 drv_data->input_vals |= values & mask; in gpio_emul_input_set_masked_int()
332 int gpio_emul_input_set_masked(const struct device *port, gpio_port_pins_t mask, in gpio_emul_input_set_masked() argument
335 struct gpio_emul_data *drv_data = (struct gpio_emul_data *)port->data; in gpio_emul_input_set_masked()
341 key = k_spin_lock(&drv_data->lock); in gpio_emul_input_set_masked()
342 prev_input_values = drv_data->input_vals; in gpio_emul_input_set_masked()
343 rv = gpio_emul_input_set_masked_int(port, mask, values); in gpio_emul_input_set_masked()
344 input_values = drv_data->input_vals; in gpio_emul_input_set_masked()
345 k_spin_unlock(&drv_data->lock, key); in gpio_emul_input_set_masked()
350 gpio_emul_pend_interrupt(port, mask, prev_input_values, input_values); in gpio_emul_input_set_masked()
355 int gpio_emul_output_get_masked(const struct device *port, gpio_port_pins_t mask, in gpio_emul_output_get_masked() argument
359 (struct gpio_emul_data *)port->data; in gpio_emul_output_get_masked()
361 (const struct gpio_emul_config *)port->config; in gpio_emul_output_get_masked()
364 if (mask == 0) { in gpio_emul_output_get_masked()
368 if (~config->common.port_pin_mask & mask) { in gpio_emul_output_get_masked()
369 return -EINVAL; in gpio_emul_output_get_masked()
372 key = k_spin_lock(&drv_data->lock); in gpio_emul_output_get_masked()
373 *values = drv_data->output_vals & get_output_pins(port); in gpio_emul_output_get_masked()
374 k_spin_unlock(&drv_data->lock, key); in gpio_emul_output_get_masked()
383 (struct gpio_emul_data *)port->data; in gpio_emul_flags_get()
385 (const struct gpio_emul_config *)port->config; in gpio_emul_flags_get()
389 return -EINVAL; in gpio_emul_flags_get()
392 if ((config->common.port_pin_mask & BIT(pin)) == 0) { in gpio_emul_flags_get()
393 return -EINVAL; in gpio_emul_flags_get()
396 key = k_spin_lock(&drv_data->lock); in gpio_emul_flags_get()
397 *flags = drv_data->flags[pin]; in gpio_emul_flags_get()
398 k_spin_unlock(&drv_data->lock, key); in gpio_emul_flags_get()
413 (struct gpio_emul_data *)port->data; in gpio_emul_pin_configure()
415 (const struct gpio_emul_config *)port->config; in gpio_emul_pin_configure()
420 return -ENOTSUP; in gpio_emul_pin_configure()
424 return -ENOTSUP; in gpio_emul_pin_configure()
427 if ((config->common.port_pin_mask & BIT(pin)) == 0) { in gpio_emul_pin_configure()
428 return -EINVAL; in gpio_emul_pin_configure()
431 key = k_spin_lock(&drv_data->lock); in gpio_emul_pin_configure()
432 drv_data->flags[pin] = flags; in gpio_emul_pin_configure()
435 drv_data->output_vals &= ~BIT(pin); in gpio_emul_pin_configure()
437 /* for push-pull mode to generate interrupts */ in gpio_emul_pin_configure()
439 port, BIT(pin), drv_data->output_vals); in gpio_emul_pin_configure()
443 drv_data->output_vals |= BIT(pin); in gpio_emul_pin_configure()
445 /* for push-pull mode to generate interrupts */ in gpio_emul_pin_configure()
447 port, BIT(pin), drv_data->output_vals); in gpio_emul_pin_configure()
462 k_spin_unlock(&drv_data->lock, key); in gpio_emul_pin_configure()
463 gpio_fire_callbacks(&drv_data->callbacks, port, BIT(pin)); in gpio_emul_pin_configure()
464 /* GPIO pin configuration changed so clear the pending interrupt. */ in gpio_emul_pin_configure()
465 drv_data->interrupts &= ~((gpio_port_pins_t)BIT(pin)); in gpio_emul_pin_configure()
475 (struct gpio_emul_data *)port->data; in gpio_emul_pin_get_config()
478 key = k_spin_lock(&drv_data->lock); in gpio_emul_pin_get_config()
480 *out_flags = drv_data->flags[pin] & in gpio_emul_pin_get_config()
483 if (drv_data->flags[pin] & GPIO_OUTPUT) { in gpio_emul_pin_get_config()
484 if (drv_data->output_vals & BIT(pin)) { in gpio_emul_pin_get_config()
491 k_spin_unlock(&drv_data->lock, key); in gpio_emul_pin_get_config()
500 (struct gpio_emul_data *)port->data; in gpio_emul_port_get_raw()
504 return -EINVAL; in gpio_emul_port_get_raw()
507 key = k_spin_lock(&drv_data->lock); in gpio_emul_port_get_raw()
508 *values = drv_data->input_vals & get_input_pins(port); in gpio_emul_port_get_raw()
509 k_spin_unlock(&drv_data->lock, key); in gpio_emul_port_get_raw()
515 gpio_port_pins_t mask, in gpio_emul_port_set_masked_raw() argument
524 (struct gpio_emul_data *)port->data; in gpio_emul_port_set_masked_raw()
528 key = k_spin_lock(&drv_data->lock); in gpio_emul_port_set_masked_raw()
530 mask &= output_mask; in gpio_emul_port_set_masked_raw()
531 prev_values = drv_data->output_vals; in gpio_emul_port_set_masked_raw()
533 values &= mask; in gpio_emul_port_set_masked_raw()
534 drv_data->output_vals &= ~mask; in gpio_emul_port_set_masked_raw()
535 drv_data->output_vals |= values; in gpio_emul_port_set_masked_raw()
536 /* in push-pull, set input values & fire interrupts */ in gpio_emul_port_set_masked_raw()
537 prev_input_values = drv_data->input_vals; in gpio_emul_port_set_masked_raw()
538 input_mask = mask & get_input_pins(port); in gpio_emul_port_set_masked_raw()
540 drv_data->output_vals); in gpio_emul_port_set_masked_raw()
541 input_values = drv_data->input_vals; in gpio_emul_port_set_masked_raw()
542 k_spin_unlock(&drv_data->lock, key); in gpio_emul_port_set_masked_raw()
546 /* for output-wiring, so the user can take action based on output */ in gpio_emul_port_set_masked_raw()
548 gpio_fire_callbacks(&drv_data->callbacks, port, mask & ~get_input_pins(port)); in gpio_emul_port_set_masked_raw()
558 (struct gpio_emul_data *)port->data; in gpio_emul_port_set_bits_raw()
565 key = k_spin_lock(&drv_data->lock); in gpio_emul_port_set_bits_raw()
567 drv_data->output_vals |= pins; in gpio_emul_port_set_bits_raw()
568 prev_input_values = drv_data->input_vals; in gpio_emul_port_set_bits_raw()
571 drv_data->output_vals); in gpio_emul_port_set_bits_raw()
572 input_values = drv_data->input_vals; in gpio_emul_port_set_bits_raw()
573 k_spin_unlock(&drv_data->lock, key); in gpio_emul_port_set_bits_raw()
576 /* for output-wiring, so the user can take action based on output */ in gpio_emul_port_set_bits_raw()
577 gpio_fire_callbacks(&drv_data->callbacks, port, pins & ~get_input_pins(port)); in gpio_emul_port_set_bits_raw()
586 (struct gpio_emul_data *)port->data; in gpio_emul_port_clear_bits_raw()
593 key = k_spin_lock(&drv_data->lock); in gpio_emul_port_clear_bits_raw()
595 drv_data->output_vals &= ~pins; in gpio_emul_port_clear_bits_raw()
596 prev_input_values = drv_data->input_vals; in gpio_emul_port_clear_bits_raw()
598 rv = gpio_emul_input_set_masked_int(port, input_mask, drv_data->output_vals); in gpio_emul_port_clear_bits_raw()
599 input_values = drv_data->input_vals; in gpio_emul_port_clear_bits_raw()
600 k_spin_unlock(&drv_data->lock, key); in gpio_emul_port_clear_bits_raw()
603 /* for output-wiring, so the user can take action based on output */ in gpio_emul_port_clear_bits_raw()
604 gpio_fire_callbacks(&drv_data->callbacks, port, pins & ~get_input_pins(port)); in gpio_emul_port_clear_bits_raw()
612 (struct gpio_emul_data *)port->data; in gpio_emul_port_toggle_bits()
616 key = k_spin_lock(&drv_data->lock); in gpio_emul_port_toggle_bits()
617 drv_data->output_vals ^= (pins & get_output_pins(port)); in gpio_emul_port_toggle_bits()
618 /* in push-pull, set input values but do not fire interrupts (yet) */ in gpio_emul_port_toggle_bits()
620 drv_data->output_vals); in gpio_emul_port_toggle_bits()
621 k_spin_unlock(&drv_data->lock, key); in gpio_emul_port_toggle_bits()
623 /* for output-wiring, so the user can take action based on output */ in gpio_emul_port_toggle_bits()
624 gpio_fire_callbacks(&drv_data->callbacks, port, pins); in gpio_emul_port_toggle_bits()
667 (struct gpio_emul_data *)port->data;
669 (const struct gpio_emul_config *)port->config;
672 if ((BIT(pin) & config->common.port_pin_mask) == 0) {
673 return -EINVAL;
687 return -EINVAL;
693 return -ENOTSUP;
699 return -ENOTSUP;
703 key = k_spin_lock(&drv_data->lock);
706 /* According to the GPIO interrupt configuration flag documentation,
707 * changes to the interrupt trigger properties should clear pending
711 drv_data->interrupts &= ~((gpio_port_pins_t)BIT(pin));
714 drv_data->interrupts &= ~((gpio_port_pins_t)BIT(pin));
719 drv_data->flags[pin] &= ~GPIO_EMUL_INT_BITMASK;
720 drv_data->flags[pin] |= GPIO_INT_DISABLE;
725 drv_data->enabled_interrupts &= ~((gpio_port_pins_t)BIT(pin));
729 drv_data->flags[pin] &= ~GPIO_EMUL_INT_BITMASK;
730 drv_data->flags[pin] |= (mode | trig);
735 drv_data->enabled_interrupts |= BIT(pin);
738 ret = -EINVAL;
745 k_spin_unlock(&drv_data->lock, key);
747 /* Trigger callback if this pin has pending interrupt */
748 if (BIT(pin) & (drv_data->interrupts & drv_data->enabled_interrupts)) {
749 gpio_fire_callbacks(&drv_data->callbacks, port, BIT(pin));
750 drv_data->interrupts &= ~((gpio_port_pins_t)BIT(pin));
760 (struct gpio_emul_data *)port->data;
762 return gpio_manage_callback(&drv_data->callbacks, cb, set);
768 (struct gpio_emul_data *)dev->data;
770 return drv_data->interrupts;
774 static int gpio_emul_port_get_direction(const struct device *port, gpio_port_pins_t map, argument
780 struct gpio_emul_data *const drv_data = (struct gpio_emul_data *)port->data;
781 const struct gpio_emul_config *config = (const struct gpio_emul_config *)port->config;
783 map &= config->common.port_pin_mask;
786 for (i = find_lsb_set(map) - 1; map;
787 map &= ~BIT(i), i = find_lsb_set(map) - 1) {
788 ip |= !!(drv_data->flags[i] & GPIO_INPUT) * BIT(i);
795 for (i = find_lsb_set(map) - 1; map;
796 map &= ~BIT(i), i = find_lsb_set(map) - 1) {
797 op |= !!(drv_data->flags[i] & GPIO_OUTPUT) * BIT(i);
828 (struct gpio_emul_data *)dev->data;
830 sys_slist_init(&drv_data->callbacks);