1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: #include <sys/machine.h>
15: #ifdef CPU_STM32L4
16:
17: #include <tk/tkernel.h>
18: #include "../../adc.h"
19: #include "../../../include/dev_def.h"
20: #if DEV_ADC_ENABLE
21: 22: 23: 24: 25:
26:
27: 28: 29:
30: const LOCAL UW ba[DEV_ADC_UNITNM] = { ADC1_BASE, ADC2_BASE, ADC3_BASE };
31:
32: #define ADC_ISR(x) (ba[x] + ADCx_ISR)
33: #define ADC_IER(x) (ba[x] + ADCx_IER)
34: #define ADC_CR(x) (ba[x] + ADCx_CR)
35: #define ADC_SMPR1(x) (ba[x] + ADCx_SMPR1)
36: #define ADC_SMPR2(x) (ba[x] + ADCx_SMPR2)
37: #define ADC_SQR1(x) (ba[x] + ADCx_SQR1)
38: #define ADC_DR(x) (ba[x] + ADCx_DR)
39:
40:
41: 42: 43:
44: LOCAL struct {
45: ID wait_tskid;
46: UW smpr1, smpr2;
47: } ll_devcb[DEV_ADC_UNITNM] = {
48:
49: {0, DEVCONF_ADC1_SMPR1, DEVCONF_ADC1_SMPR2},
50: {0, DEVCONF_ADC2_SMPR1, DEVCONF_ADC2_SMPR2},
51: {0, DEVCONF_ADC3_SMPR1, DEVCONF_ADC3_SMPR2}
52: };
53:
54:
55: 56: 57:
58: void adc_inthdr( UINT intno)
59: {
60: UW unit;
61:
62: if(intno == INTNO_INTADC3) {
63: unit = DEV_ADC_3;
64: } else if( in_w(ADC_ISR(DEV_ADC_1))) {
65: unit = DEV_ADC_1;
66: } else if( in_w(ADC_ISR(DEV_ADC_2))) {
67: unit = DEV_ADC_2;
68: } else {
69: return;
70: }
71:
72: if(ll_devcb[unit].wait_tskid) {
73: tk_wup_tsk(ll_devcb[unit].wait_tskid);
74: }
75:
76: out_w(ADC_ISR(unit), 0x000007FF);
77: ClearInt((unit == DEV_ADC_3)?INTNO_INTADC3:INTNO_INTADC1_2);
78: }
79:
80: 81: 82:
83: LOCAL UW adc_convert( UINT unit, INT ch, INT size, UW *buf )
84: {
85: _UW *sqr;
86: UINT sqsz, sqch, sqpos;
87: UW rtn;
88: ER err;
89:
90: if((ch >= ADC_CH_NUM) || (size > ADC_MAX_SQ) || ((ch+size) > ADC_CH_NUM)) return (UW)E_PAR;
91:
92: out_w(ADC_SQR1(unit), size-1);
93:
94:
95: sqr = (UW*)ADC_SQR1(unit);
96: sqsz = size; sqch = ch; sqpos = 6;
97: while(sqsz--) {
98: *sqr |= (sqch++)<<sqpos;
99: if((sqpos += 6) >= 32) {
100: sqpos = 0;
101: *(++sqr) = 0;
102: }
103: }
104:
105: ll_devcb[unit].wait_tskid = tk_get_tid();
106: tk_can_wup(TSK_SELF);
107: out_w(ADC_CR(unit), ADC_CR_ADSTART | ADC_CR_ADVREGEN);
108: for( rtn = 0; rtn < size; rtn++) {
109: err = tk_slp_tsk(DEVCNF_ADC_TMOSCAN);
110: if(err < E_OK) {
111: rtn = err;
112: break;
113: }
114: *buf++ = in_w(ADC_DR(unit));
115: }
116: ll_devcb[unit].wait_tskid = 0;
117:
118: return rtn;
119: }
120:
121:
122: 123: 124:
125: LOCAL ER adc_open(UW unit)
126: {
127: ER err = E_OK;
128:
129:
130: out_w(ADC_SMPR1(unit), ll_devcb[unit].smpr1);
131: out_w(ADC_SMPR2(unit), ll_devcb[unit].smpr2);
132:
133:
134: out_w(ADC_ISR(unit), 0x000007FF);
135: out_w(ADC_IER(unit), ADC_IER_ADRDYIE | ADC_IER_EOCIE);
136: if(unit != DEV_ADC_3) {
137: EnableInt(INTNO_INTADC1_2, DEVCNF_ADC12_INTPRI);
138: } else {
139: EnableInt(INTNO_INTADC3, DEVCNF_ADC3_INTPRI);
140: }
141:
142:
143: ll_devcb[unit].wait_tskid = tk_get_tid();
144: out_w(ADC_CR(unit), ADC_CR_ADEN | ADC_CR_ADVREGEN);
145:
146: err = tk_slp_tsk(DEVCNF_ADC_TMOSCAN);
147: if(err < E_OK) err = E_TMOUT;
148: ll_devcb[unit].wait_tskid = 0;
149:
150: return err;
151: }
152:
153: 154: 155:
156: LOCAL void adc_close(UW unit)
157: {
158: DisableInt((unit==DEV_ADC_3)?INTNO_INTADC3:INTNO_INTADC1_2);
159:
160:
161: out_w(ADC_CR(unit), ADC_CR_ADDIS);
162: while(in_w(ADC_ISR(unit)) & ADC_ISR_ADRDY);
163: }
164:
165: 166: 167:
168: EXPORT W dev_adc_llctl( UW unit, INT cmd, UW p1, UW p2, UW *pp)
169: {
170: W rtn = (W)E_OK;
171:
172: switch(cmd) {
173: case LLD_ADC_OPEN:
174: rtn = (W)adc_open(unit);
175: break;
176:
177: case LLD_ADC_CLOSE:
178: adc_close(unit);
179: break;
180:
181: case LLD_ADC_READ:
182: rtn = adc_convert(unit, p1, p2, pp);
183: break;
184:
185: case LLD_ADC_RSIZE:
186: rtn = ADC_CH_NUM - p1;
187: if(rtn < 0 ) rtn = 0;
188: break;
189: }
190:
191: return rtn;
192: }
193:
194: 195: 196:
197: EXPORT ER dev_adc_llinit( T_ADC_DCB *p_dcb)
198: {
199: static BOOL uninit = TRUE;
200:
201: const T_DINT dint = {
202: .intatr = TA_HLNG,
203: .inthdr = adc_inthdr
204: };
205: UW unit;
206: ER err;
207:
208: #if DEVCONF_ADC_INIT_MCLK
209: UW ccipr;
210:
211: if(uninit) {
212: switch(DEVCNF_ADCSEL) {
213: case 1:
214: *(_UW*)RCC_CR |= RCC_CR_PLLSAI1ON;
215: *(_UW*)RCC_PLLSAI1CFGR |= 1<<24;
216: break;
217: case 2:
218: *(_UW*)RCC_CR |= RCC_CR_PLLSAI2ON;
219: *(_UW*)RCC_PLLSAI2CFGR |= 1<<24;
220: break;
221: default:
222: if(DEVCNF_ADCSEL > 3) return E_IO;
223: }
224: ccipr = in_w(RCC_CCIPR) & ~RCC_CCIPR_ADCSEL;
225: out_w(RCC_CCIPR, ccipr | (DEVCNF_ADCSEL << 28));
226:
227: *(_UW*)RCC_AHB2ENR |= RCC_AHB2ENR_ADCEN;
228: }
229: #endif
230:
231: unit = p_dcb->unit;
232:
233:
234: out_w(ADC_CR(unit), 0);
235: out_w(ADC_CR(unit), ADC_CR_ADVREGEN);
236:
237:
238: if(uninit) {
239: out_w(ADC_CCR,
240: ((DEVCNF_ADC_CKMODE & 0x03)<< 16)
241: |((DEVCNF_ADC_PRESC & 0x0F)<< 18)
242: );
243: }
244:
245:
246: out_w(ADC_CR(unit), ADC_CR_ADVREGEN | ADC_CR_ADCAL);
247: while( in_w(ADC_CR(unit)) & ADC_CR_ADCAL);
248:
249:
250: err = tk_def_int((unit == DEV_ADC_3)?INTNO_INTADC3:INTNO_INTADC1_2, &dint);
251:
252: uninit = FALSE;
253: return err;
254: }
255:
256: #endif
257: #endif