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; }
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; } }
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); }
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); }
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; } }
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); }
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); }
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"); }