void pin_dir_mode(PinName name, PinDirection direction, PinMode mode) { MBED_ASSERT(name != (PinName)NC); unsigned int port = PINNAME_TO_PORT(name); unsigned int pin = PINNAME_TO_PIN(name); /* Set function; Firmware Control (GPIO mode) */ MXC_GPIO->func_sel[port] &= ~(0xF << (4 * pin)); /* Normal input is always enabled */ MXC_GPIO->in_mode[port] &= ~(0xF << (4 * pin)); uint32_t new_mode; if (direction == PIN_OUTPUT) { // PullUp = not valid, // PullDown = not valid, // OpenDrain = MXC_V_GPIO_OUT_MODE_OD, // PullNone = MXC_V_GPIO_OUT_MODE_NORMAL, if (mode == OpenDrain) { new_mode = MXC_V_GPIO_OUT_MODE_OPEN_DRAIN; } else { new_mode = MXC_V_GPIO_OUT_MODE_NORMAL; } } else { // PullUp = MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLUP // PullDown = MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLDOWN // OpenDrain = MXC_V_GPIO_OUT_MODE_OD // PullNone = MXC_V_GPIO_OUT_MODE_NORMAL_HIGH_Z if (mode == PullUp) { new_mode = MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLUP; MXC_GPIO->out_val[port] |= 1 << pin; } else if (mode == PullDown) { new_mode = MXC_V_GPIO_OUT_MODE_HIGH_Z_WEAK_PULLDOWN; MXC_GPIO->out_val[port] &= ~(1 << pin); } else if (mode == OpenDrain) { new_mode = MXC_V_GPIO_OUT_MODE_OPEN_DRAIN; MXC_GPIO->out_val[port] |= 1 << pin; } else { new_mode = MXC_V_GPIO_OUT_MODE_NORMAL_HIGH_Z; MXC_GPIO->out_val[port] &= ~(1 << pin); } } /* Set new mode */ uint32_t out_mode = MXC_GPIO->out_mode[port]; out_mode &= ~(0xF << (pin * 4)); out_mode |= (new_mode << (pin * 4)); MXC_GPIO->out_mode[port] = out_mode; }
gpio_irq_t *gpio_irq_get_obj(PinName name) { if (name == NC) { return NULL; } unsigned int port = PINNAME_TO_PORT(name); unsigned int pin = PINNAME_TO_PIN(name); if ((port > MXC_GPIO_NUM_PORTS) || (pin > MXC_GPIO_MAX_PINS_PER_PORT)) { return NULL; } return objs[port][pin]; }
int gpio_irq_init(gpio_irq_t *obj, PinName name, gpio_irq_handler handler, uint32_t id) { if (name == NC) { return -1; } uint8_t port = PINNAME_TO_PORT(name); uint8_t pin = PINNAME_TO_PIN(name); if ((port > MXC_GPIO_NUM_PORTS) || (pin > MXC_GPIO_MAX_PINS_PER_PORT)) { return 1; } obj->port = port; obj->pin = pin; obj->id = id; objs[port][pin] = obj; /* register handlers */ irq_handler = handler; NVIC_SetVector(GPIO_P0_IRQn, (uint32_t)gpio_irq_0); NVIC_SetVector(GPIO_P1_IRQn, (uint32_t)gpio_irq_1); NVIC_SetVector(GPIO_P2_IRQn, (uint32_t)gpio_irq_2); NVIC_SetVector(GPIO_P3_IRQn, (uint32_t)gpio_irq_3); NVIC_SetVector(GPIO_P4_IRQn, (uint32_t)gpio_irq_4); NVIC_SetVector(GPIO_P5_IRQn, (uint32_t)gpio_irq_5); NVIC_SetVector(GPIO_P6_IRQn, (uint32_t)gpio_irq_6); /* request WUD in case the application is going to sleep */ gpio_irq_wud_req(obj); /* disable the interrupt locally */ MXC_GPIO->int_mode[port] &= ~(0xF << (pin*4)); /* clear a pending request */ MXC_GPIO->intfl[port] = 1 << pin; /* enable the requested interrupt */ MXC_GPIO->inten[port] |= (1 << pin); NVIC_EnableIRQ((IRQn_Type)((uint32_t)GPIO_P0_IRQn + port)); return 0; }
void gpio_init(gpio_t *obj, PinName name) { obj->name = name; if (name == (PinName)NC) { return; } unsigned int port = PINNAME_TO_PORT(name); unsigned int pin = PINNAME_TO_PIN(name); obj->reg_out = (uint32_t*)BITBAND(&MXC_GPIO->out_val[port], pin); obj->reg_in = (uint32_t*)BITBAND(&MXC_GPIO->in_val[port], pin); obj->mode = PullDefault; /* Ensure that the GPIO clock is enabled */ MXC_CLKMAN->clk_gate_ctrl1 |= MXC_F_CLKMAN_CLK_GATE_CTRL1_GPIO_CLK_GATER; /* Ensure that the GPIO clock is enabled */ MXC_CLKMAN->sys_clk_ctrl_6_gpio = MXC_S_CLKMAN_CLK_SCALE_DIV_1; }
//****************************************************************************** uint16_t analogin_read_u16(analogin_t *obj) { // Set the pin to take readings from uint32_t adc_input = PINNAME_TO_PIN(obj->adc_pin); // Select the channel obj->adc->ctrl &= ~MXC_F_ADC_CTRL_ADC_CHSEL; obj->adc->ctrl |= (adc_input << MXC_F_ADC_CTRL_ADC_CHSEL_POS) & MXC_F_ADC_CTRL_ADC_CHSEL; // We want unity gain, to get full 0-Vref range // So, both ref and adc input scale should be enabled obj->adc->ctrl |= MXC_F_ADC_CTRL_ADC_SCALE | MXC_F_ADC_CTRL_ADC_REFSCL; // Not using internal buffer, disable anyway obj->adc->ctrl &= ~MXC_F_ADC_CTRL_BUF_PU; obj->adc->ctrl |= MXC_F_ADC_CTRL_BUF_BYPASS; // Normal LSB justified data alignment // Not using limits // Clear ADC done flag (wite 1 to clr) obj->adc->intr = (obj->adc->intr & 0xFFFF) | MXC_F_ADC_INTR_ADC_DONE_IF; // Start the conversion obj->adc->ctrl |= MXC_F_ADC_CTRL_CPU_ADC_START; // Wait for ADC done while (!(obj->adc->intr & MXC_F_ADC_INTR_ADC_DONE_IF)); // Get sample from the fifo uint16_t sample = obj->adc->data; // Check for overflow, hardware will report overflow as 0 if (obj->adc->status & MXC_F_ADC_STATUS_ADC_OVERFLOW) { sample = (uint16_t)ADC_FULL_SCALE; } return sample; }
uint32_t gpio_set(PinName name) { MBED_ASSERT(name != (PinName)NC); pin_function(name, 0); return 1 << PINNAME_TO_PIN(name); }