void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin); uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin); GPIO_T *gpio_base = NU_PORT_BASE(port_index); switch (event) { case IRQ_RISE: if (enable) { GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_RISING); } else { gpio_base->INTEN &= ~(GPIO_INT_RISING << pin_index); } break; case IRQ_FALL: if (enable) { GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_FALLING); } else { gpio_base->INTEN &= ~(GPIO_INT_FALLING << pin_index); } break; } }
/** * Configure pin pull-up/pull-down */ void pin_mode(PinName pin, PinMode mode) { MBED_ASSERT(pin != (PinName)NC); uint32_t pin_index = NU_PINNAME_TO_PIN(pin); uint32_t port_index = NU_PINNAME_TO_PORT(pin); GPIO_T *gpio_base = NU_PORT_BASE(port_index); uint32_t mode_intern = GPIO_MODE_INPUT; switch (mode) { case PullUp: mode_intern = GPIO_MODE_INPUT; break; case PullDown: case PullNone: // NOTE: Not support return; case PushPull: mode_intern = GPIO_MODE_OUTPUT; break; case OpenDrain: mode_intern = GPIO_MODE_OPEN_DRAIN; break; case Quasi: mode_intern = GPIO_MODE_QUASI; break; } GPIO_SetMode(gpio_base, 1 << pin_index, mode_intern); }
/** * Configure pin multi-function */ void pin_function(PinName pin, int data) { MBED_ASSERT(pin != (PinName)NC); uint32_t pin_index = NU_PINNAME_TO_PIN(pin); uint32_t port_index = NU_PINNAME_TO_PORT(pin); __IO uint32_t *GPx_MFPx = ((__IO uint32_t *) &SYS->GPA_MFPL) + port_index * 2 + (pin_index / 8); uint32_t MFP_Msk = NU_MFP_MSK(pin_index); // E.g.: SYS->GPA_MFPL = (SYS->GPA_MFPL & (~SYS_GPA_MFPL_PA0MFP_Msk) ) | SYS_GPA_MFPL_PA0MFP_SC0_CD ; *GPx_MFPx = (*GPx_MFPx & (~MFP_Msk)) | data; }
void gpio_irq_free(gpio_irq_t *obj) { uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin); uint32_t port_index = NU_PINNAME_TO_PORT(obj->pin); struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index; NVIC_DisableIRQ(var->irq_n); NU_PORT_BASE(port_index)->INTEN = 0; MBED_ASSERT(pin_index < NU_MAX_PIN_PER_PORT); var->obj_arr[pin_index] = NULL; }
/** * Configure pin pull-up/pull-down */ void pin_mode(PinName pin, PinMode mode) { MBED_ASSERT(pin != (PinName)NC); uint32_t pin_index = NU_PINNAME_TO_PIN(pin); uint32_t port_index = NU_PINNAME_TO_PORT(pin); GPIO_T *gpio_base = NU_PORT_BASE(port_index); uint32_t mode_intern = GPIO_MODE_INPUT; switch (mode) { case InputOnly: mode_intern = GPIO_MODE_INPUT; break; case PushPullOutput: mode_intern = GPIO_MODE_OUTPUT; break; case OpenDrain: mode_intern = GPIO_MODE_OPEN_DRAIN; break; case QuasiBidirectional: mode_intern = GPIO_MODE_QUASI; break; default: /* H/W doesn't support separate configuration for input pull mode/direction. * We expect upper layer would have translated input pull mode/direction * to I/O mode */ return; } GPIO_SetMode(gpio_base, 1 << pin_index, mode_intern); /* Invalid combinations of PinMode/PinDirection * * We assume developer would avoid the following combinations of PinMode/PinDirection * which are invalid: * 1. InputOnly/PIN_OUTPUT * 2. PushPullOutput/PIN_INPUT */ }
/** * Configure pin multi-function */ void pin_function(PinName pin, int data) { MBED_ASSERT(pin != (PinName)NC); uint32_t pin_index = NU_PINNAME_TO_PIN(pin); uint32_t port_index = NU_PINNAME_TO_PORT(pin); __IO uint32_t *GPx_MFPx = ((__IO uint32_t *) &SYS->GPA_MFPL) + port_index * 2 + (pin_index / 8); //uint32_t MFP_Pos = NU_MFP_POS(pin_index); uint32_t MFP_Msk = NU_MFP_MSK(pin_index); // E.g.: SYS->GPA_MFPL = (SYS->GPA_MFPL & (~SYS_GPA_MFPL_PA0MFP_Msk) ) | SYS_GPA_MFPL_PA0MFP_SC0_CD ; *GPx_MFPx = (*GPx_MFPx & (~MFP_Msk)) | data; // [TODO] Disconnect JTAG-DP + SW-DP signals. // Warning: Need to reconnect under reset //if ((pin == PA_13) || (pin == PA_14)) { // //} //if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) { // //} }
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { if (pin == NC) { return -1; } uint32_t pin_index = NU_PINNAME_TO_PIN(pin); uint32_t port_index = NU_PINNAME_TO_PORT(pin); if (pin_index >= NU_MAX_PIN_PER_PORT || port_index >= NU_MAX_PORT) { return -1; } obj->pin = pin; obj->irq_handler = (uint32_t) handler; obj->irq_id = id; GPIO_T *gpio_base = NU_PORT_BASE(port_index); //gpio_set(pin); #if NUC472_GPIO_IRQ_DEBOUNCE_ENABLE // Configure de-bounce clock source and sampling cycle time GPIO_SET_DEBOUNCE_TIME(NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); #else GPIO_DISABLE_DEBOUNCE(gpio_base, 1 << pin_index); #endif struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index; var->obj_arr[pin_index] = obj; // NOTE: InterruptIn requires IRQ enabled by default. gpio_irq_enable(obj); return 0; }