summaryrefslogtreecommitdiff
path: root/tests/adc-power/adc-power.c
blob: 817671c0ff570586552d52d3d677933e64e71f19 (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
/**
 * Testing ADC power up and power down, for timing and actual on/off
 * Uses TIM6, because DWT_CYCCNT not available on cm0(+) :(
 * (And with no DWT, no ITM timestamping either, get a real mcu!)
 */

#include <stdio.h>
#include <stdint.h>
#include <libopencm3/stm32/adc.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>

#include "adc-power.h"

/* Everyone has tim6 right? */
#define TIMER TIM6
#define TIMER_RCC RCC_TIM6

// TODO - stick this in libopencm3?
#define	ARRAY_SIZE(a)	(sizeof((a)) / sizeof((a)[0]))


void adc_power_init(void)
{
	/* Some basic ADC config, that we won't touch again */
	rcc_periph_clock_enable(RCC_ADC1);
	adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28CYC);
#if 0
	// DANGER DANGER! doing this without DMA is dum.
	// but... we're busy polling, we should be right... right?
	// (dma across platforms is teh suck)
	adc_enable_scan_mode(ADC1);
	ADC_CR2 |= ADC_CR2_EOCS; // FIXME
#else
	adc_disable_scan_mode(ADC1);
#endif
	
	/*
	 * We're going to setup a timer to run at top speed, so... "fast" 
	 * but we don't actually care about the rate itself.  We just 
	 * want to collect how many ticks it takes to enable and disable
	 * the adc.
	 */
	rcc_periph_clock_enable(TIMER_RCC);
	timer_reset(TIMER);
	timer_set_prescaler(TIMER, 0);
	timer_enable_counter(TIMER);
}

static uint16_t read_adc_naiive(uint8_t channel)
{
	uint8_t channel_array[16];
	channel_array[0] = channel;
	adc_set_regular_sequence(ADC1, 1, channel_array);
	adc_start_conversion_regular(ADC1);
	while (!adc_eoc(ADC1));
	return adc_read_regular(ADC1);
}

void adc_power_task_up(void) {
	TIM_CNT(TIMER) = 0;
	adc_power_on(ADC1);
	unsigned int td = TIM_CNT(TIMER);
	
	/* just for kicks, let's time some sequences too....
	 * I mean, we're going to do some conversions right? */
	adc_set_single_conversion_mode(ADC1);
#if 0
	uint8_t channels[2] = { 0, 1 };
	adc_set_regular_sequence(ADC1, ARRAY_SIZE(channels), channels);
	TIM_CNT(TIMER) = 0;
	adc_start_conversion_regular(ADC1);
	while (!adc_eoc(ADC1));
	unsigned int v1 = adc_read_regular(ADC1);
	while (!adc_eoc(ADC1));
	unsigned int v2 = adc_read_regular(ADC1);
	unsigned int tconv = TIM_CNT(TIMER);
#else
	TIM_CNT(TIMER) = 0;
	unsigned int v1 = read_adc_naiive(0);
	unsigned int v2 = read_adc_naiive(1);
	unsigned int tconv = TIM_CNT(TIMER);
#endif
	
	printf("ton: %u, tconv: %u, v1: %u, v2: %u\n", td, tconv, v1, v2);
}

void adc_power_task_down()
{
	TIM_CNT(TIMER) = 0;
	adc_power_off(ADC1);
	unsigned int td = TIM_CNT(TIMER);
	printf("toff in: %u\n", td);
}