/** * gpio init in * * Initializes the specified pin as an input * * @param pin Pin number to set as input * @param pull pull type * * @return int 0: no error; -1 otherwise. */ int hal_gpio_init_in(int pin, hal_gpio_pull_t pull) { int rc; GPIO_InitTypeDef init_cfg; init_cfg.Mode = GPIO_MODE_INPUT; init_cfg.Pull = pull; rc = hal_gpio_init_stm(pin, &init_cfg); return rc; }
/** * gpio init af * * Configure the specified pin for AF. */ int hal_gpio_init_af(int pin, uint8_t af_type, enum hal_gpio_pull pull, uint8_t od) { GPIO_InitTypeDef cfg; cfg.Mode = od ? GPIO_MODE_AF_OD : GPIO_MODE_AF_PP; cfg.Speed = GPIO_SPEED_FREQ_HIGH; cfg.Pull = hal_gpio_pull_to_stm_pull(pull); cfg.Alternate = af_type; return hal_gpio_init_stm(pin, &cfg); }
/** * Configure an ADC channel on the STM32F4 ADC. * * @param dev The ADC device to configure * @param cnum The channel on the ADC device to configure * @param cfgdata An opaque pointer to channel config, expected to be * a ADC_ChannelConfTypeDef * * @return 0 on success, non-zero on failure. */ static int stm32f4_adc_configure_channel(struct adc_dev *dev, uint8_t cnum, void *cfgdata) { int rc; ADC_HandleTypeDef *hadc; struct stm32f4_adc_dev_cfg *cfg; struct adc_chan_config *chan_cfg; GPIO_InitTypeDef gpio_td; rc = OS_EINVAL; if (dev == NULL && !IS_ADC_CHANNEL(cnum)) { goto err; } cfg = (struct stm32f4_adc_dev_cfg *)dev->ad_dev.od_init_arg; hadc = cfg->sac_adc_handle; chan_cfg = &((struct adc_chan_config *)cfg->sac_chans)[cnum]; cfgdata = (ADC_ChannelConfTypeDef *)cfgdata; if ((HAL_ADC_ConfigChannel(hadc, cfgdata)) != HAL_OK) { goto err; } dev->ad_chans[cnum].c_res = chan_cfg->c_res; dev->ad_chans[cnum].c_refmv = chan_cfg->c_refmv; dev->ad_chans[cnum].c_configured = 1; dev->ad_chans[cnum].c_cnum = cnum; if (stm32f4_resolve_adc_gpio(hadc, cnum, &gpio_td)) { goto err; } hal_gpio_init_stm(gpio_td.Pin, &gpio_td); return (OS_OK); err: return (rc); }
int hal_spi_config(int spi_num, struct hal_spi_settings *settings) { struct stm32_hal_spi *spi; struct stm32_hal_spi_cfg *cfg; SPI_InitTypeDef *init; GPIO_InitTypeDef gpio; uint32_t gpio_speed; IRQn_Type irq; uint32_t prescaler; int rc; int sr; __HAL_DISABLE_INTERRUPTS(sr); STM32_HAL_SPI_RESOLVE(spi_num, spi); init = &spi->handle.Init; cfg = spi->cfg; if (!spi->slave) { spi->handle.Init.NSS = SPI_NSS_HARD_OUTPUT; spi->handle.Init.Mode = SPI_MODE_MASTER; } else { spi->handle.Init.NSS = SPI_NSS_SOFT; spi->handle.Init.Mode = SPI_MODE_SLAVE; } gpio.Mode = GPIO_MODE_AF_PP; gpio.Pull = GPIO_NOPULL; /* TODO: also VERY_HIGH for STM32L1x */ if (settings->baudrate <= 2000) { gpio_speed = GPIO_SPEED_FREQ_LOW; } else if (settings->baudrate <= 12500) { gpio_speed = GPIO_SPEED_FREQ_MEDIUM; } else { gpio_speed = GPIO_SPEED_FREQ_HIGH; } /* Enable the clocks for this SPI */ switch (spi_num) { #if SPI_0_ENABLED case 0: __HAL_RCC_SPI1_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF5_SPI1; #endif spi->handle.Instance = SPI1; break; #endif #if SPI_1_ENABLED case 1: __HAL_RCC_SPI2_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF5_SPI2; #endif spi->handle.Instance = SPI2; break; #endif #if SPI_2_ENABLED case 2: __HAL_RCC_SPI3_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF6_SPI3; #endif spi->handle.Instance = SPI3; break; #endif #if SPI_3_ENABLED case 3: __HAL_RCC_SPI4_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF5_SPI4; #endif spi->handle.Instance = SPI4; break; #endif #if SPI_4_ENABLED case 4: __HAL_RCC_SPI5_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF5_SPI5; #endif spi->handle.Instance = SPI5; break; #endif #if SPI_5_ENABLED case 5: __HAL_RCC_SPI6_CLK_ENABLE(); #if !defined(STM32F1) gpio.Alternate = GPIO_AF5_SPI6; #endif spi->handle.Instance = SPI6; break; #endif default: assert(0); rc = -1; goto err; } if (!spi->slave) { if (settings->data_mode == HAL_SPI_MODE2 || settings->data_mode == HAL_SPI_MODE3) { gpio.Pull = GPIO_PULLUP; } else { gpio.Pull = GPIO_PULLDOWN; } } /* NOTE: Errata ES0125: STM32L100x6/8/B, STM32L151x6/8/B and * STM32L152x6/8/B ultra-low-power device limitations. * * 2.6.6 - Corrupted last bit of data and or CRC, received in Master * mode with delayed SCK feedback * * This driver is always using very high speed for SCK on STM32L1x */ #if defined(STM32L152xC) if (!spi->slave) { gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; } else { gpio.Speed = gpio_speed; } #else gpio.Speed = gpio_speed; #endif rc = hal_gpio_init_stm(cfg->sck_pin, &gpio); if (rc != 0) { goto err; } #if defined(STM32L152xC) if (!spi->slave) { gpio.Speed = gpio_speed; } #endif if (!spi->slave) { gpio.Pull = GPIO_NOPULL; } else { gpio.Mode = GPIO_MODE_AF_OD; } rc = hal_gpio_init_stm(cfg->mosi_pin, &gpio); if (rc != 0) { goto err; } if (!spi->slave) { gpio.Mode = GPIO_MODE_AF_OD; } else { gpio.Mode = GPIO_MODE_AF_PP; } rc = hal_gpio_init_stm(cfg->miso_pin, &gpio); if (rc != 0) { goto err; } switch (settings->data_mode) { case HAL_SPI_MODE0: init->CLKPolarity = SPI_POLARITY_LOW; init->CLKPhase = SPI_PHASE_1EDGE; break; case HAL_SPI_MODE1: init->CLKPolarity = SPI_POLARITY_LOW; init->CLKPhase = SPI_PHASE_2EDGE; break; case HAL_SPI_MODE2: init->CLKPolarity = SPI_POLARITY_HIGH; init->CLKPhase = SPI_PHASE_1EDGE; break; case HAL_SPI_MODE3: init->CLKPolarity = SPI_POLARITY_HIGH; init->CLKPhase = SPI_PHASE_2EDGE; break; default: rc = -1; goto err; } switch (settings->data_order) { case HAL_SPI_MSB_FIRST: init->FirstBit = SPI_FIRSTBIT_MSB; break; case HAL_SPI_LSB_FIRST: init->FirstBit = SPI_FIRSTBIT_LSB; break; default: rc = -1; goto err; } switch (settings->word_size) { case HAL_SPI_WORD_SIZE_8BIT: init->DataSize = SPI_DATASIZE_8BIT; break; case HAL_SPI_WORD_SIZE_9BIT: init->DataSize = SPI_DATASIZE_16BIT; break; default: rc = -1; goto err; } rc = stm32_spi_resolve_prescaler(spi_num, settings->baudrate * 1000, &prescaler); if (rc != 0) { goto err; } init->BaudRatePrescaler = prescaler; /* Add default values */ init->Direction = SPI_DIRECTION_2LINES; init->TIMode = SPI_TIMODE_DISABLE; init->CRCCalculation = SPI_CRCCALCULATION_DISABLE; init->CRCPolynomial = 1; #ifdef SPI_NSS_PULSE_DISABLE init->NSSPMode = SPI_NSS_PULSE_DISABLE; #endif irq = stm32_resolve_spi_irq(&spi->handle); NVIC_SetPriority(irq, cfg->irq_prio); NVIC_SetVector(irq, stm32_resolve_spi_irq_handler(&spi->handle)); NVIC_EnableIRQ(irq); /* Init, Enable */ rc = HAL_SPI_Init(&spi->handle); if (rc != 0) { goto err; } if (spi->slave) { hal_spi_slave_set_def_tx_val(spi_num, 0); rc = hal_gpio_irq_init(cfg->ss_pin, spi_ss_isr, spi, HAL_GPIO_TRIG_BOTH, HAL_GPIO_PULL_UP); spi_ss_isr(spi); } __HAL_ENABLE_INTERRUPTS(sr); return (0); err: __HAL_ENABLE_INTERRUPTS(sr); return (rc); }
/** * gpio irq init * * Initialize an external interrupt on a gpio pin * * @param pin Pin number to enable gpio. * @param handler Interrupt handler * @param arg Argument to pass to interrupt handler * @param trig Trigger mode of interrupt * @param pull Push/pull mode of input. * * @return int */ int hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull) { int rc; int irqn; int index; uint32_t pin_mask; uint32_t mode; GPIO_InitTypeDef cfg; /* Configure the gpio for an external interrupt */ rc = 0; switch (trig) { case HAL_GPIO_TRIG_NONE: rc = -1; break; case HAL_GPIO_TRIG_RISING: mode = GPIO_MODE_IT_RISING; break; case HAL_GPIO_TRIG_FALLING: mode = GPIO_MODE_IT_FALLING; break; case HAL_GPIO_TRIG_BOTH: mode = GPIO_MODE_IT_RISING_FALLING; break; case HAL_GPIO_TRIG_LOW: rc = -1; break; case HAL_GPIO_TRIG_HIGH: rc = -1; break; default: rc = -1; break; } /* Check to make sure no error has occurred */ if (!rc) { /* Disable interrupt and clear any pending */ hal_gpio_irq_disable(pin); pin_mask = HAL_GPIO_PIN(pin); __HAL_GPIO_EXTI_CLEAR_FLAG(pin_mask); /* Set the gpio irq handler */ index = HAL_GPIO_PIN_NUM(pin); hal_gpio_irq[index].isr = handler; hal_gpio_irq[index].arg = arg; hal_gpio_irq[index].invoked = 0; /* Configure the GPIO */ cfg.Mode = mode; cfg.Pull = pull; rc = hal_gpio_init_stm(pin, &cfg); if (!rc) { /* Enable interrupt vector in NVIC */ irqn = hal_gpio_pin_to_irq(pin); hal_gpio_set_nvic(irqn); } } return rc; }