/*----------------------------------------------------------------------------*/ static void commonPinInit(struct Pin pin) { pinSetFunction(pin, PIN_DEFAULT); pinSetPull(pin, PIN_NOPULL); pinSetSlewRate(pin, PIN_SLEW_NORMAL); pinSetType(pin, PIN_PUSHPULL); }
/*----------------------------------------------------------------------------*/ static enum Result pinInterruptInit(void *object, const void *configBase) { const struct PinInterruptConfig * const config = configBase; assert(config); const struct Pin input = pinInit(config->pin); assert(pinValid(input)); /* Try to allocate a new channel */ struct PinInterrupt * const interrupt = object; const int channel = setInstance(interrupt); if (channel == -1) return E_BUSY; /* Configure the pin */ pinInput(input); pinSetPull(input, config->pull); interrupt->callback = 0; interrupt->channel = channel; interrupt->enabled = false; interrupt->event = config->event; interrupt->pin = input.data; const uint8_t index = interrupt->channel >> 2; const uint32_t mask = 1UL << interrupt->channel; /* Enable peripheral */ if (!sysClockStatus(CLK_PINT)) sysClockEnable(CLK_PINT); /* Select pin and port */ LPC_SYSCON->PINTSEL[index] = (LPC_SYSCON->PINTSEL[index] & ~PINTSEL_CHANNEL_MASK(channel)) | PINTSEL_CHANNEL(channel, input.data.port, input.data.offset); /* Configure interrupt as edge sensitive */ LPC_GPIO_INT->ISEL &= ~mask; /* Configure edge sensitivity options */ if (config->event == PIN_RISING || config->event == PIN_TOGGLE) LPC_GPIO_INT->SIENR = mask; if (config->event == PIN_FALLING || config->event == PIN_TOGGLE) LPC_GPIO_INT->SIENF = mask; #ifdef CONFIG_PM /* Interrupt will wake the controller from low-power modes */ LPC_SYSCON->STARTERP0 |= STARTERP0_PINT(interrupt->channel); #endif /* Configure interrupt priority, interrupt is disabled by default */ irqSetPriority(calcVector(interrupt->channel), config->priority); return E_OK; }