void init_adc_sensor(){ // we will use ADC1 channel 0 for IR sensor & ADC1 channel 1 for laser's photoresistor uint8_t adc_channel_array[ADC_CHANNEL_NUMBER] = {0,1,6}; // Make sure the ADC doesn't run during config adc_off(ADC1); // enable ADC & PA0/PA1 clocking rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN | RCC_APB2ENR_IOPAEN); rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV4); gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0 | GPIO1); rcc_periph_clock_enable(RCC_DMA1); // enable DMA for ADC values storing // Configure ADC as continuous scan mode with DMA ADC1_CR1 = ADC_CR1_SCAN; // enable scan mode // set sample time on channels 1&2: 239.5 cycles for better results ADC1_SMPR2 = 0x3f; dma_channel_reset(DMA1, DMA_CHANNEL1); DMA1_CPAR1 = (uint32_t) &(ADC_DR(ADC1)); DMA1_CMAR1 = (uint32_t) ADC_value; DMA1_CNDTR1 = ADC_CHANNEL_NUMBER; DMA1_CCR1 = DMA_CCR_MINC | DMA_CCR_PSIZE_16BIT | DMA_CCR_MSIZE_16BIT | DMA_CCR_CIRC | DMA_CCR_PL_HIGH | DMA_CCR_EN; // continuous conv, enable ADC & DMA ADC1_CR2 = ADC_CR2_CONT | ADC_CR2_ADON | ADC_CR2_DMA; // set channels adc_set_regular_sequence(ADC1, ADC_CHANNEL_NUMBER, adc_channel_array); // reset calibration registers & start calibration ADC1_CR2 |= ADC_CR2_RSTCAL; while(ADC1_CR2 & ADC_CR2_RSTCAL); // wait for registers reset ADC1_CR2 |= ADC_CR2_CAL; while(ADC1_CR2 & ADC_CR2_CAL); // wait for calibration ends nvic_enable_irq(NVIC_ADC1_2_IRQ); ADC1_CR2 |= ADC_CR2_SWSTART; // turn on ADC - to do it we need set ADC_CR2_ADON again! ADC1_CR2 |= ADC_CR2_ADON; }
void rcc_clock_setup_in_hse_8mhz_out_72mhz(void) { /* Enable internal high-speed oscillator. */ rcc_osc_on(RCC_HSI); rcc_wait_for_osc_ready(RCC_HSI); /* Select HSI as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); /* Enable external high-speed oscillator 8MHz. */ rcc_osc_on(RCC_HSE); rcc_wait_for_osc_ready(RCC_HSE); rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); /* * Set prescalers for AHB, ADC, ABP1, ABP2. * Do this before touching the PLL (TODO: why?). */ rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 9MHz Max. 14MHz */ rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ /* * Sysclk runs with 72MHz -> 2 waitstates. * 0WS from 0-24MHz * 1WS from 24-48MHz * 2WS from 48-72MHz */ flash_set_ws(FLASH_ACR_LATENCY_2WS); /* * Set the PLL multiplication factor to 9. * 8MHz (external) * 9 (multiplier) = 72MHz */ rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9); /* Select HSE as PLL source. */ rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); /* * External frequency undivided before entering PLL * (only valid/needed for HSE). */ rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); /* Enable PLL oscillator and wait for it to stabilize. */ rcc_osc_on(RCC_PLL); rcc_wait_for_osc_ready(RCC_PLL); /* Select PLL as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); /* Set the peripheral clock frequencies used */ rcc_ahb_frequency = 72000000; rcc_apb1_frequency = 36000000; rcc_apb2_frequency = 72000000; }
void rcc_clock_setup_in_hse_25mhz_out_72mhz(void) { /* Enable external high-speed oscillator 25MHz. */ rcc_osc_on(RCC_HSE); rcc_wait_for_osc_ready(RCC_HSE); rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); /* * Sysclk runs with 72MHz -> 2 waitstates. * 0WS from 0-24MHz * 1WS from 24-48MHz * 2WS from 48-72MHz */ flash_set_ws(FLASH_ACR_LATENCY_2WS); /* * Set prescalers for AHB, ADC, ABP1, ABP2. * Do this before touching the PLL (TODO: why?). */ rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */ rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ /* Set pll2 prediv and multiplier */ rcc_set_prediv2(RCC_CFGR2_PREDIV2_DIV5); rcc_set_pll2_multiplication_factor(RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL8); /* Enable PLL2 oscillator and wait for it to stabilize */ rcc_osc_on(RCC_PLL2); rcc_wait_for_osc_ready(RCC_PLL2); /* Set pll1 prediv/multiplier, prediv1 src, and usb predivider */ rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); rcc_set_prediv1_source(RCC_CFGR2_PREDIV1SRC_PLL2_CLK); rcc_set_prediv1(RCC_CFGR2_PREDIV_DIV5); rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9); rcc_set_pll_source(RCC_CFGR_PLLSRC_PREDIV1_CLK); rcc_set_usbpre(RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV3); /* enable PLL1 and wait for it to stabilize */ rcc_osc_on(RCC_PLL); rcc_wait_for_osc_ready(RCC_PLL); /* Select PLL as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); /* Set the peripheral clock frequencies used */ rcc_ahb_frequency = 72000000; rcc_apb1_frequency = 36000000; rcc_apb2_frequency = 72000000; }
static void rcc_clock_setup_in_hse_12mhz_out_96mhz(void) { /* Enable internal high-speed oscillator. */ rcc_osc_on(RCC_HSI); rcc_wait_for_osc_ready(RCC_HSI); /* Select HSI as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); /* Enable external high-speed oscillator 12MHz. */ rcc_osc_on(RCC_HSE); rcc_wait_for_osc_ready(RCC_HSE); rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); /* * Set prescalers for AHB, ADC, ABP1, ABP2. * Do this before touching the PLL */ rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 96MHz Max. 108MHz */ rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 12MHz Max. 14MHz */ rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 48MHz Max. 54MHz */ rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 96MHz Max. 108MHz */ RCC_CFGR |= RCC_GCFGR_USBPS_Div2; /* USB Set. 48MHz Max. 48MHz */ /* GD32 has 0-wait-state flash, do not touch anything! */ /* * Set the PLL multiplication factor to 10. * 12MHz (external) * 8 (multiplier) = 96MHz */ rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL8); /* Select HSE as PLL source. */ rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); /* * External frequency undivided before entering PLL * (only valid/needed for HSE). */ rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); /* Enable PLL oscillator and wait for it to stabilize. */ rcc_osc_on(RCC_PLL); rcc_wait_for_osc_ready(RCC_PLL); /* Select PLL as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); /* Set the peripheral clock frequencies used */ rcc_ahb_frequency = 96000000; rcc_apb1_frequency = 48000000; rcc_apb2_frequency = 96000000; }
void rcc_clock_setup_in_hsi_out_48mhz(void) { /* Enable internal high-speed oscillator. */ rcc_osc_on(RCC_HSI); rcc_wait_for_osc_ready(RCC_HSI); /* Select HSI as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); /* * Set prescalers for AHB, ADC, ABP1, ABP2. * Do this before touching the PLL (TODO: why?). */ rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /*Set.48MHz Max.72MHz */ rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /*Set. 6MHz Max.14MHz */ rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /*Set.24MHz Max.36MHz */ rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /*Set.48MHz Max.72MHz */ rcc_set_usbpre(RCC_CFGR_USBPRE_PLL_CLK_NODIV); /*Set.48MHz Max.48MHz */ /* * Sysclk runs with 48MHz -> 1 waitstates. * 0WS from 0-24MHz * 1WS from 24-48MHz * 2WS from 48-72MHz */ flash_set_ws(FLASH_ACR_LATENCY_1WS); /* * Set the PLL multiplication factor to 12. * 8MHz (internal) * 12 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 48MHz */ rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL12); /* Select HSI/2 as PLL source. */ rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); /* Enable PLL oscillator and wait for it to stabilize. */ rcc_osc_on(RCC_PLL); rcc_wait_for_osc_ready(RCC_PLL); /* Select PLL as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); /* Set the peripheral clock frequencies used */ rcc_ahb_frequency = 48000000; rcc_apb1_frequency = 24000000; rcc_apb2_frequency = 48000000; }
int main(void) { int32_t i; rcc_periph_clock_enable(RCC_GPIOA); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO5); flash_set_ws(FLASH_ACR_LATENCY_2WS); rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV4); /* 14MHz */ rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* 56MHz */ rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* 28MHz */ rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* 56MHz */ rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL14); /* 8MHz/2 x14 = 56MHz */ rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); rcc_osc_on(PLL); rcc_wait_for_osc_ready(PLL); rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); rcc_periph_clock_enable(RCC_USART2); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX); gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_USART2_RX); uint32_t baud = 57600; uint32_t clock = 28000000; USART2_BRR = ((2 * clock) + baud) / (2 * baud); usart_set_databits(USART2, 8); usart_set_stopbits(USART2, USART_STOPBITS_1); usart_set_mode(USART2, USART_MODE_TX_RX); usart_set_parity(USART2, USART_PARITY_NONE); usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE); usart_enable(USART2); usart_puts(USART2, "ready to receive.\r\n"); gpio_set(GPIOA, GPIO5); while(1) { uint16_t c; c = usart_recv_blocking(USART2); usart_send_blocking(USART2, toupper(c)); gpio_toggle(GPIOA, GPIO5); } }
/* * These functions are setting up the whole clock system for the most common * input clock and output clock configurations. */ void rcc_clock_setup_in_hsi_out_64mhz(void) { /* Enable internal high-speed oscillator. */ rcc_osc_on(HSI); rcc_wait_for_osc_ready(HSI); /* Select HSI as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSICLK); /* * Set prescalers for AHB, ADC, ABP1, ABP2. * Do this before touching the PLL (TODO: why?). */ rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Max. 72MHz */ rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Max. 14MHz */ rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Max. 36MHz */ rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Max. 72MHz */ /* * Sysclk is running with 64MHz -> 2 waitstates. * 0WS from 0-24MHz * 1WS from 24-48MHz * 2WS from 48-72MHz */ flash_set_ws(FLASH_LATENCY_2WS); /* * Set the PLL multiplication factor to 16. * 8MHz (internal) * 16 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 64MHz */ rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL16); /* Select HSI/2 as PLL source. */ rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); /* Enable PLL oscillator and wait for it to stabilize. */ rcc_osc_on(PLL); rcc_wait_for_osc_ready(PLL); /* Select PLL as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); }