This repository has been archived by the owner on Oct 15, 2021. It is now read-only.
forked from dev26th/electronic_load
-
Notifications
You must be signed in to change notification settings - Fork 0
/
adc.c
61 lines (51 loc) · 1.37 KB
/
adc.c
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
#include "adc.h"
#include "stm8.h"
static ADC_onResult_t _onResult;
static uint8_t _counts[ADC_COUNTS_SIZE];
static uint8_t _ch;
static uint8_t _n;
static uint8_t _countMax;
static uint16_t _countValue;
void ADC_init(void) {
ADC1->CR1 |= ADC1_CR1_SPSEL_6;
ADC1->CR1 |= ADC1_CR1_ADON; // wake up
ADC1->CR2 |= ADC1_CR2_ALIGN; // right-align
}
void ADC_start(uint8_t ch, uint8_t n, ADC_onResult_t onResult) {
_onResult = onResult;
_ch = ch;
_n = n;
_countMax = 0;
_countValue = 0;
// the same as:
// for(i = 0; i < ADC_COUNTS_SIZE; ++i) _counts[i] = 0; // 1108 us
// but 515 us
__asm
LDW x, #__counts
00001$:
CLR (x)
INCW x
CPW x, #__counts+ADC_COUNTS_SIZE
JRULT 00001$
__endasm;
ADC1->CR3 &= ~ADC1_CR3_OVR;
ADC1->CSR = ADC1_CSR_EOCIE | _ch;
ADC1->CR1 |= ADC1_CR1_CONT;
ADC1->CR3 |= ADC1_CR3_DBUF;
ADC1->CR1 |= ADC1_CR1_ADON;
}
// ~7 us for non-last one
void ADC_ADC1_eoc(void) __interrupt(IRQN_ADC1_EOC) {
uint16_t v, c;
ADC1->CSR = ADC1_CSR_EOCIE | _ch;
v = ADC1->DRL | ((uint16_t)ADC1->DRH << 8);
c = _counts[v] + 1;
_counts[v] = c;
if(c > _countMax) {
_countMax = c;
_countValue = v;
}
--_n;
if(_n == 1) ADC1->CR1 &= ~ADC1_CR1_CONT;
if(_n == 0) _onResult(_counts, _countMax, _countValue);
}