summaryrefslogtreecommitdiff
path: root/tests/adc-power/main-stm32f3-disco.c
blob: fd155faddff1b1bc39b0118d6debe503cc9b8014 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * Oct 2015 Karl Palsson <karlp@tweak.net.au>
 */

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/adc.h>
#include <libopencm3/stm32/dac.h>
#include <libopencm3/stm32/flash.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/usart.h>

#include "trace.h"
#include "adc-power.h"

/* f3 pll setup, based on l1/f4*/

typedef struct {
	uint8_t pll_mul;
	uint8_t pll_div;
	uint8_t pll_source;
	uint32_t flash_config;
	uint8_t hpre;
	uint8_t ppre1;
	uint8_t ppre2;
	uint32_t apb1_frequency;
	uint32_t apb2_frequency;
	uint32_t ahb_frequency;
} rcc_clock_scale_t;

static void rcc_clock_setup_pll_f3_special(const rcc_clock_scale_t *clock)
{
	/* Turn on the appropriate source for the PLL */
	// TODO, some f3's have extra bits here
	enum rcc_osc my_osc;
	if (clock->pll_source == RCC_CFGR_PLLSRC_HSE_PREDIV) {
		my_osc = RCC_HSE;
	} else {
		my_osc = RCC_HSI;
	}
	rcc_osc_on(my_osc);
	while (!rcc_is_osc_ready(my_osc));

	/* Configure flash settings. */
	flash_set_ws(clock->flash_config);

	/*
	 * Set prescalers for AHB, ADC, ABP1, ABP2.
	 * Do this before touching the PLL (TODO: why?).
	 */
	rcc_set_hpre(clock->hpre);
	rcc_set_ppre1(clock->ppre1);
	rcc_set_ppre2(clock->ppre2);

	rcc_osc_off(RCC_PLL);
	while (rcc_is_osc_ready(RCC_PLL));
	rcc_set_pll_source(clock->pll_source);
	rcc_set_pll_multiplier(clock->pll_mul);
	// TODO - iff pll_div != 0, then maybe we're on a target that 
	// has the dividers?

	/* Enable PLL oscillator and wait for it to stabilize. */
	rcc_osc_on(RCC_PLL);
	while (!rcc_is_osc_ready(RCC_PLL));

	/* Select PLL as SYSCLK source. */
	rcc_set_sysclk_source(RCC_CFGR_SW_PLL);
	rcc_wait_for_sysclk_status(RCC_PLL);

	/* Set the peripheral clock frequencies used. */
	rcc_ahb_frequency = clock->ahb_frequency;
	rcc_apb1_frequency = clock->apb1_frequency;
	rcc_apb2_frequency = clock->apb2_frequency;
}

static void setup_clocks(void)
{
	rcc_clock_scale_t clock_full_hse8mhz ={
		.pll_mul = RCC_CFGR_PLLMUL_PLL_IN_CLK_X9,
		.pll_source = RCC_CFGR_PLLSRC_HSE_PREDIV,
		.hpre = RCC_CFGR_HPRE_DIV_NONE,
		.ppre1 = RCC_CFGR_PPRE1_DIV_2,
		.ppre2 = RCC_CFGR_PPRE2_DIV_NONE,
		.flash_config = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_2WS,
		.apb1_frequency = 36000000,
		.apb2_frequency = 72000000,
		.ahb_frequency = 72000000,
	};

	rcc_clock_setup_pll_f3_special(&clock_full_hse8mhz);
}

int main(void)
{
	int i;
	int j = 0;
	setup_clocks();
	/* Board led */
	rcc_periph_clock_enable(RCC_GPIOE);
	gpio_mode_setup(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8);
	gpio_set(GPIOE, GPIO8);
	printf("hi guys!\n");

	// ADC seems to take these no matter what?
//	rcc_periph_clock_enable(RCC_GPIOA);
//	rcc_periph_clock_enable(RCC_GPIOF);
//	gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO0);
//	gpio_mode_setup(GPIOF, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO4);

	adc_power_init();
	for (i = 0; i < 0x1000; i++) { /* need as much as 10 usecs for vreg */
		__asm__("NOP");
	}
	while (1) {
		adc_power_task_up();
		gpio_toggle(GPIOE, GPIO8);

		for (i = 0; i < 0x100000; i++) { /* Wait a bit. */
			__asm__("NOP");
		}
		printf("tick...\n");
		adc_power_task_down();
		gpio_toggle(GPIOE, GPIO8);
		for (i = 0; i < 0x100000; i++) { /* Wait a bit. */
			__asm__("NOP");
		}
	}

	return 0;
}