Example #1
0
/**
 * 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;
}
Example #2
0
/**
 * 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);
}
Example #4
0
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);
}
Example #5
0
/**
 * 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;
}