OSStatus platform_gpio_irq_disable( const platform_gpio_t* gpio ) { OSStatus err = kNoErr; ioport_port_mask_t mask = ioport_pin_to_mask ( gpio->pin ); ioport_port_t port = ioport_pin_to_port_id( gpio->pin ); volatile Pio* port_register = arch_ioport_port_to_base( port ); platform_mcu_powersave_disable(); require_action_quiet( gpio != NULL, exit, err = kParamErr); /* Disable interrupt on pin */ port_register->PIO_IDR = mask; /* Disable Cortex-M interrupt vector as well if no pin interrupt is enabled */ if ( port_register->PIO_IMR == 0 ) { NVIC_DisableIRQ( irq_vectors[port] ); } gpio_irq_data[port][mask].wakeup_pin = false; gpio_irq_data[port][mask].arg = 0; gpio_irq_data[port][mask].callback = NULL; exit: platform_mcu_powersave_enable(); return err; }
OSStatus gpio_irq_disable( gpio_port_t gpio_port, gpio_pin_number_t gpio_pin_number ) { Pio *p_pio = arch_ioport_port_to_base(gpio_port); ioport_port_mask_t ul_mask = ioport_pin_to_mask(CREATE_IOPORT_PIN(gpio_port, gpio_pin_number)); pio_disable_interrupt(p_pio, ul_mask); return kGeneralErr; }
OSStatus gpio_irq_enable( gpio_port_t gpio_port, gpio_pin_number_t gpio_pin_number, gpio_irq_trigger_t trigger, gpio_irq_handler_t handler, void* arg ) { //gpio_irq_data_t *pSource; uint32_t ul_attr; if (gs_ul_nb_sources >= MAX_INTERRUPT_SOURCES) return 1; //Pio *p_pio = (Pio *)ioport_port_to_base(gpio_port); Pio *p_pio = arch_ioport_port_to_base(gpio_port); //ioport_pin_t pin = CREATE_IOPORT_PIN(gpio_port, gpio_pin_number); ioport_port_mask_t ul_mask = ioport_pin_to_mask(CREATE_IOPORT_PIN(gpio_port, gpio_pin_number)); if ( gpio_irq_management_initted == 0 ) { memset( (void*)gpio_irq_data, 0, sizeof( gpio_irq_data ) ); gpio_irq_management_initted = 1; } if (trigger == IRQ_TRIGGER_RISING_EDGE ) { ul_attr = PIO_IT_RISE_EDGE; } else if (trigger == IRQ_TRIGGER_FALLING_EDGE ) { ul_attr = PIO_IT_FALL_EDGE; } else if (trigger == IRQ_TRIGGER_BOTH_EDGES ) { ul_attr = PIO_IT_EDGE; } //pSource = &(gpio_irq_data[gs_ul_nb_sources]); gpio_irq_data[gs_ul_nb_sources].owner_port = gpio_port; if ( gpio_port == PORTA) { gpio_irq_data[gs_ul_nb_sources].id = ID_PIOA; // pmc_enable_periph_clk(ID_PIOA); } else if (gpio_port == PORTB) { gpio_irq_data[gs_ul_nb_sources].id = ID_PIOB; // pmc_enable_periph_clk(ID_PIOB); } gpio_irq_data[gs_ul_nb_sources].mask = ul_mask; gpio_irq_data[gs_ul_nb_sources].handler = handler; gpio_irq_data[gs_ul_nb_sources].arg = arg; gs_ul_nb_sources++; /* Configure interrupt mode */ pio_configure_interrupt(p_pio, ul_mask, ul_attr); if ( gpio_port == PORTA){ NVIC_EnableIRQ( PIOA_IRQn ); pio_handler_set_priority(PIOA, PIOA_IRQn, IRQ_PRIORITY_PIO); } else if (gpio_port == PORTB) { NVIC_EnableIRQ( PIOB_IRQn); pio_handler_set_priority(PIOB, PIOB_IRQn, IRQ_PRIORITY_PIO); } pio_enable_interrupt(p_pio, ul_mask); return kGeneralErr; }
void gpio_irq( ioport_port_t port ) { volatile Pio* port_register = arch_ioport_port_to_base( port ); uint32_t status = port_register->PIO_ISR; /* Get interrupt status. Read clears the interrupt */ uint32_t mask = port_register->PIO_IMR; uint32_t iter = 0; if ( ( status != 0 ) && ( mask != 0 ) ) { /* Call the respective GPIO interrupt handler/callback */ for ( iter = 0; iter < PINS_PER_PORT; iter++, status >>= 1, mask >>= 1 ) { if ( ( ( mask & 0x1 ) != 0 ) && ( ( status & 0x1 ) != 0 ) && ( gpio_irq_data[port][iter].callback != NULL ) ) { if ( gpio_irq_data[port][iter].wakeup_pin == true ) { platform_mcu_powersave_exit_notify(); } gpio_irq_data[port][iter].callback( gpio_irq_data[port][iter].arg ); } } } }
OSStatus platform_gpio_irq_enable( const platform_gpio_t* gpio, platform_gpio_irq_trigger_t trigger, platform_gpio_irq_callback_t handler, void* arg ) { ioport_port_mask_t mask = ioport_pin_to_mask( gpio->pin ); ioport_port_t port = ioport_pin_to_port_id( gpio->pin ); volatile Pio* port_register = arch_ioport_port_to_base( port ); uint8_t pin_number = (gpio->pin) & 0x1F; uint32_t temp; uint8_t samg5x_irq_trigger; OSStatus err = kNoErr; platform_mcu_powersave_disable(); require_action_quiet( gpio != NULL, exit, err = kParamErr); NVIC_DisableIRQ( irq_vectors[port] ); NVIC_ClearPendingIRQ( irq_vectors[port] ); gpio_irq_data[port][pin_number].wakeup_pin = gpio->is_wakeup_pin; gpio_irq_data[port][pin_number].arg = arg; gpio_irq_data[port][pin_number].callback = handler; switch ( trigger ) { case IRQ_TRIGGER_RISING_EDGE: samg5x_irq_trigger = IOPORT_SENSE_RISING; break; case IRQ_TRIGGER_FALLING_EDGE: samg5x_irq_trigger = IOPORT_SENSE_FALLING; break; case IRQ_TRIGGER_BOTH_EDGES: samg5x_irq_trigger = IOPORT_SENSE_BOTHEDGES; break; default: err = kParamErr; goto exit; } if( gpio->is_wakeup_pin == true ) { platform_powersave_enable_wakeup_pin( gpio ); } if ( samg5x_irq_trigger == IOPORT_SENSE_RISING || samg5x_irq_trigger == IOPORT_SENSE_BOTHEDGES ) { port_register->PIO_AIMER |= mask; port_register->PIO_ESR |= mask; port_register->PIO_REHLSR |= mask; } if ( samg5x_irq_trigger == IOPORT_SENSE_FALLING || samg5x_irq_trigger == IOPORT_SENSE_BOTHEDGES ) { port_register->PIO_AIMER |= mask; port_register->PIO_ESR |= mask; port_register->PIO_FELLSR |= mask; } /* Read ISR to clear residual interrupt status */ temp = port_register->PIO_ISR; UNUSED_PARAMETER( temp ); /* Enable interrupt source */ port_register->PIO_IER |= mask; NVIC_EnableIRQ( irq_vectors[port] ); exit: platform_mcu_powersave_enable(); return err; }