Beispiel #1
0
void timer_select_internal_clock(openlab_timer_t timer, uint16_t prescaler)
{
    const _openlab_timer_t *_timer = timer;

    // Disable slave mode
    *timer_get_SMCR(_timer) &= ~TIMER_SMCR__SMS_MASK;

    // Set the prescaler
    *timer_get_PSC(_timer) = prescaler;

    // Compute and save the timer frequency
    uint32_t freq;

    // Get internal frequency
    if (_timer->apb_bus == 1)
    {
        freq = rcc_sysclk_get_clock_frequency(RCC_SYSCLK_CLOCK_PCLK1_TIM);
    }
    else
    {
        freq = rcc_sysclk_get_clock_frequency(RCC_SYSCLK_CLOCK_PCLK2_TIM);
    }

    // Divide by prescaler
    freq /= (prescaler + 1);

    // Store
    _timer->data->frequency = freq;
}
Beispiel #2
0
uint32_t timer_get_frequency(openlab_timer_t timer)
{
    const _openlab_timer_t *_timer = timer;

    if (_timer->data->frequency != 0)
    {
        // Return the estimated frequency
        return _timer->data->frequency;
    }
    else
    {
        // Assume internal clock
        uint32_t freq;

        // Get internal frequency
        if (_timer->apb_bus == 1)
        {
            freq = rcc_sysclk_get_clock_frequency(RCC_SYSCLK_CLOCK_PCLK1_TIM);
        }
        else
        {
            freq = rcc_sysclk_get_clock_frequency(RCC_SYSCLK_CLOCK_PCLK2_TIM);
        }

        return freq;
    }
}
Beispiel #3
0
static void timer_drivers_setup()
{
    // Enable Motor timer
    timer_enable(TIM_1);
    timer_enable(TIM_8);

    // Enable Soft timer
    timer_enable(TIM_2);


    // Setting Motor timer to about 2MHz (2^21) = 2097152
    timer_select_internal_clock(TIM_1,
            (rcc_sysclk_get_clock_frequency(RCC_SYSCLK_CLOCK_PCLK1_TIM) / 2097152)
                    - 1);

   boot_success("Starting TIM_1 at about 2MHz\n");

    // Setting servo timer to about 30Hz (2^5) = 32
    // Setting Motor timer to about 2MHz (2^21) = 2097152
    timer_select_internal_clock(TIM_8,
            (rcc_sysclk_get_clock_frequency(RCC_SYSCLK_CLOCK_PCLK1_TIM) / 2097152)
                    - 1);

   boot_success("Starting TIM_8 at about 30Hz\n");

    // Setting Soft timer to about 32kHz
    timer_select_internal_clock(TIM_2,
            (rcc_sysclk_get_clock_frequency(RCC_SYSCLK_CLOCK_PCLK1_TIM) / 2097152)//32768)
                    - 1);
   boot_success("Starting TIM_2 at about 32kHz\n");

    // Start ALL timers
    timer_start(TIM_1, 0xFFFF, NULL, NULL, TIMER_MODE_CLOCK);
    timer_start(TIM_2, 0xFFFF, NULL, NULL, TIMER_MODE_CLOCK);
    timer_start(TIM_8, 0xFFFF, NULL, NULL, TIMER_MODE_CLOCK);


    timer_set_channel_compare(TIM_1, TIMER_CHANNEL_1, 0x00FF, NULL, NULL);
    timer_set_channel_compare(TIM_8, TIMER_CHANNEL_1, 0x00FF, NULL, NULL);
}
Beispiel #4
0
void platform_drivers_setup()
{
    // Set base address and AHB bit for all GPIO ports
    gpio_enable(GPIO_A);
    gpio_enable(GPIO_B);
    gpio_enable(GPIO_C);
    gpio_enable(GPIO_D);

    // Enable the AFIO
    rcc_apb_enable(RCC_APB_BUS_AFIO, RCC_APB_BIT_AFIO);

    // Start the TIM3 at ~32kHz
    timer_enable(TIM_3);
    timer_select_internal_clock(TIM_3, (rcc_sysclk_get_clock_frequency(
                                           RCC_SYSCLK_CLOCK_PCLK1_TIM) / 32768) - 1);
    timer_start(TIM_3, 0xFFFF, NULL, NULL);

    // Enable the print uart
    gpio_set_uart_tx(GPIO_A, GPIO_PIN_9);
    gpio_set_uart_rx(GPIO_A, GPIO_PIN_10);
    uart_enable(UART_1, PLATFORM_UART_PRINT_BAUDRATE);

    // Configure the DMA for the SPIs
    dma_enable(DMA_1_CH4);
    dma_enable(DMA_1_CH5);

    // Configure the SPI 2
    gpio_set_spi_clk(GPIO_B, GPIO_PIN_13);
    gpio_set_spi_miso(GPIO_B, GPIO_PIN_14);
    gpio_set_spi_mosi(GPIO_B, GPIO_PIN_15);
    spi_set_dma(SPI_2, DMA_1_CH4, DMA_1_CH5);
    spi_enable(SPI_2, 4000000, SPI_CLOCK_MODE_IDLE_LOW_RISING);

    // Configure the I2C 1
    gpio_set_i2c_scl(GPIO_B, GPIO_PIN_6);
    gpio_set_i2c_sda(GPIO_B, GPIO_PIN_7);
    i2c_enable(I2C_1, I2C_CLOCK_MODE_FAST);

    // Force inclusion of EXTI
    exti_set_handler(EXTI_LINE_Px0, NULL, NULL);
}
Beispiel #5
0
void ethmac_init(ethmac_mode_t mode, int always_on)
{
    // Initialize the descriptors
    ethmac_descriptors_init();

    // Configure the desired mode
    if (mode == ETHMAC_MODE_MII)
    {
        // MII mode
        syscfg_pmc_config(SYSCFG_PMC__MII_RMII_SEL, 0);
    }
    else
    {
        // RMII mode
        syscfg_pmc_config(SYSCFG_PMC__MII_RMII_SEL, 1);
    }

    // Set default PHY address
    mac.phy_addr = 0;

    // Set the always_on value
    mac.always_on = always_on;

    // Compute MII divider
    switch (rcc_sysclk_get_clock_frequency(RCC_SYSCLK_CLOCK_HCLK))
    {
        case 20000000 ... 35000000:
            mac.mii_cr = ETHMAC_MACMIIAR__CR_Div16;
            break;
        case 35000001 ... 60000000:
            mac.mii_cr = ETHMAC_MACMIIAR__CR_Div26;
            break;
        case 60000001 ... 100000000:
            mac.mii_cr = ETHMAC_MACMIIAR__CR_Div42;
            break;
        case 100000001 ... 168000000:
            mac.mii_cr = ETHMAC_MACMIIAR__CR_Div42;
            break;
    }
}
Beispiel #6
0
void i2c_enable(i2c_t i2c, i2c_clock_mode_t mode)
{
    uint32_t pclk, freq;
    const _i2c_t *_i2c = i2c;

    // Disable the I2C EV and ERR interrupt lines in the NVIC
    nvic_disable_interrupt_line(_i2c->irq_line_ev);
    nvic_disable_interrupt_line(_i2c->irq_line_er);

    // Enable the clock for this peripheral
    rcc_apb_enable(_i2c->apb_bus, _i2c->apb_bit);

    // Reset the peripheral
    *i2c_get_CR1(_i2c) = I2C_CR1__SWRST;

    // Clear all registers
    *i2c_get_CR2(_i2c) = 0;
    *i2c_get_CCR(_i2c) = 0;
    *i2c_get_TRISE(_i2c) = 0;
    *i2c_get_SR1(_i2c) = 0;
    *i2c_get_SR2(_i2c) = 0;
    *i2c_get_OAR1(_i2c) = 0;
    *i2c_get_OAR2(_i2c) = 0;

    // Release SWRST
    *i2c_get_CR1(_i2c) = 0;

    /* Step 1: program the peripheral input clock in CR2 */

    // Compute clock frequency
    pclk = rcc_sysclk_get_clock_frequency(
               _i2c->apb_bus == 1 ? RCC_SYSCLK_CLOCK_PCLK1
               : RCC_SYSCLK_CLOCK_PCLK2);
    freq = pclk / 1000000;

    *i2c_get_CR2(_i2c) = freq & I2C_CR2__FREQ_MASK;

    /* Step 2: configure the clock control registers */

    if (mode == I2C_CLOCK_MODE_FAST)
    {
        // Set Fast Speed mode and bitrate: ~400kHz
        uint32_t ccr = freq * 10;
        ccr = ccr / 12 + (ccr % 12 ? 1 : 0);
        *i2c_get_CCR(_i2c) = I2C_CCR__FS | ccr;
    }
    else
    {
        // Set Standard Speed mode and bitrate: 100kHz
        *i2c_get_CCR(_i2c) = (freq * 5) & I2C_CCR__CCR_MASK;
    }

    /* Step 3: configure the rise time registers */

    if (mode == I2C_CLOCK_MODE_FAST)
    {
        // Configure maximum rise time
        *i2c_get_TRISE(_i2c) = (freq * 3 / 10 + 1) & I2C_TRISE__TRISE_MASK;
    }
    else
    {
        // Configure maximum rise time
        *i2c_get_TRISE(_i2c) = (freq + 1) & I2C_TRISE__TRISE_MASK;
    }

    /* Step 4: program the CR1 register to enable the peripheral */

    // Enable I2C
    *i2c_get_CR1(_i2c) = I2C_CR1__PE;

    // Enable EVT and ERR interrupt
    // Note: do not enable BUF to avoid stm32f problem
    *i2c_get_CR2(_i2c) |= I2C_CR2__ITEVTEN | I2C_CR2__ITERREN;

    // Initialize I2C state
    _i2c->data->state = I2C_IDLE;
    _i2c->data->len_send = 0;
    _i2c->data->len_recv = 0;
    _i2c->data->cpt_send = 0;
    _i2c->data->cpt_recv = 0;
    _i2c->data->transfer_handler = NULL;

    // Enable I2C EV and ERR interrupt line in the NVIC
    nvic_enable_interrupt_line(_i2c->irq_line_ev);
    nvic_enable_interrupt_line(_i2c->irq_line_er);
}
Beispiel #7
0
void i2c_enable(i2c_t i2c, i2c_clock_mode_t mode)
{
    uint32_t pclk, freq;
    _i2c_t *_i2c = i2c;

    // Disable the I2C EV and ERR interrupt lines in the NVIC
    nvic_disable_interrupt_line(_i2c->irq_line_ev);
    nvic_disable_interrupt_line(_i2c->irq_line_er);

    // Enable the clock for this peripheral
    rcc_apb_enable(_i2c->apb_bus, _i2c->apb_bit);

    // Reset the peripheral
    *i2c_get_CR1(_i2c) = I2C_CR1__SWRST;

    // Clear all registers
    *i2c_get_CR1(_i2c) = 0;
    *i2c_get_CR2(_i2c) = 0;
    *i2c_get_CCR(_i2c) = 0;
    *i2c_get_TRISE(_i2c) = 0;
    *i2c_get_SR1(_i2c) = 0;
    *i2c_get_SR2(_i2c) = 0;

    /* Step 1: program the peripheral input clock in CR2 */

    // Compute clock frequency
    pclk = rcc_sysclk_get_clock_frequency(
               _i2c->apb_bus == 1 ? RCC_SYSCLK_CLOCK_PCLK1
               : RCC_SYSCLK_CLOCK_PCLK2);
    freq = pclk / 1000000;

    *i2c_get_CR2(_i2c) = freq & I2C_CR2__FREQ_MASK;

    /* Step 2: configure the clock control registers */

    if (mode == I2C_CLOCK_MODE_FAST)
    {
        // Set Fast Speed mode and bitrate: 400kHz with duty t_low/t_high = 16/9
        *i2c_get_CCR(_i2c) = I2C_CCR__FS | I2C_CCR__DUTY | (freq / 10 * 25);
    }
    else
    {
        // Set Standard Speed mode and bitrate: 100kHz
        *i2c_get_CCR(_i2c) = (freq * 5) & I2C_CCR__CCR_MASK;
    }

    /* Step 3: configure the rise time registers */

    if (mode == I2C_CLOCK_MODE_FAST)
    {
        // Configure maximum rise time
        *i2c_get_TRISE(_i2c) = (freq * 3 / 10 + 1) & I2C_TRISE__TRISE_MASK;
    }
    else
    {
        // Configure maximum rise time
        *i2c_get_TRISE(_i2c) = (freq + 1) & I2C_TRISE__TRISE_MASK;
    }

    /* Step 4: program the CR1 register to enable the peripheral */

    // Set I2C mode, enable ACK and enable I2C
    *i2c_get_CR1(_i2c) = I2C_CR1__ACK | I2C_CR1__PE;

    // Enable EV and BUF interrupt
    *i2c_get_CR2(_i2c) |= I2C_CR2__ITEVTEN | I2C_CR2__ITBUFEN
                          | I2C_CR2__ITERREN;

    // Initialize I2C state
    state = I2C_IDLE;

    // Enable I2C EV and ERR interrupt line in the NVIC
    nvic_enable_interrupt_line(_i2c->irq_line_ev);
    nvic_enable_interrupt_line(_i2c->irq_line_er);
}
Beispiel #8
0
void platform_init()
{
    // Enable watchdog if requested
    if (platform_should_start_watchdog && platform_should_start_watchdog())
    {
        watchdog_enable(WATCHDOG_DIVIDER_256, 0xFFF);
    }

    // Enable floating point
    *cm3_scb_get_CPACR() |= 0xF << 20;  /* set CP10 and CP11 Full Access */

    // Enable syscfg
    rcc_apb_enable(RCC_APB_BUS_SYSCFG, RCC_APB_BIT_SYSCFG);

    // At reset, HCLK is 16MHz, set flash latency to 5 wait state to handle 168MHz
    flash_set_latency(5);

    // Configure PLL to have 336MHz VCO, then 48MHz for USB and 168 MHz for sysclk
    rcc_pll_enable(RCC_PLL_SOURCE_HSI, 8, 168, RCC_PLL_MAIN_DIV_2, 7);

    // Now SYSCLK is at 168MHz, set AHB divider to 1, APB1 to 4 and APB2 to 4
    /*
     *  The frequency of the AHB domain is 168 MHz.
     *  The frequency of the APBx domain is 42 MHz.
     */
    rcc_sysclk_set_prescalers(RCC_SYSCLK_AHB_PRE_1, RCC_SYSCLK_APB_PRE_4,
            RCC_SYSCLK_APB_PRE_4);

    // Select PLL as SYSCLK source clock
    rcc_sysclk_select_source(RCC_SYSCLK_SOURCE_PLL);

    // Setup the drivers
    platform_drivers_setup();

    // Setup the LEDs
    platform_leds_setup();

    // Setup the libraries
    platform_lib_setup();

    // Setup the peripherals
    platform_periph_setup();

    // Setup the net stack
    platform_net_setup();

    // Feed the random number generator
    random_init(uid->uid32[2]);

    log_printf(
            "HCLK @%uMHz, SYSTICK @%uMHz", rcc_sysclk_get_clock_frequency(RCC_SYSCLK_CLOCK_HCLK) / 1000000,
            rcc_sysclk_get_clock_frequency(RCC_SYSCLK_CLOCK_SYSTICK_CLK) / 1000000);

    log_printf("\n\nPlatform starting in ");
    uint32_t i;

    for (i = 1; i > 0; i--)
    {
        log_printf("%u... ", i);
        soft_timer_delay_s(1);
    }
    log_printf("\nGO!\n");
}