source: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/adc.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 20.7 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 * Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
9 *
10 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
11 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
13 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15 * スコード中に含まれていること.
16 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
18 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
19 * の無保証規定を掲載すること.
20 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
21 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
22 * と.
23 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
24 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
25 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
26 * 報告すること.
27 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
28 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
29 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
30 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
31 * 免責すること.
32 *
33 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
34 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
35 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
36 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
37 * の責任を負わない.
38 *
39 * @(#) $Id$
40 */
41/*
42 *
43 * ADCドライバ関数群
44 *
45 */
46#include <kernel.h>
47#include <t_syslog.h>
48#include <t_stdlib.h>
49#include <stdio.h>
50#include <string.h>
51#include "syssvc/serial.h"
52#include "syssvc/syslog.h"
53#include <target_syssvc.h>
54#include "device.h"
55#include "adc.h"
56
57/*
58 * SIL関数のマクロ定義
59 */
60#define sil_orw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) | (b))
61#define sil_andw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
62#define sil_modw_mem(a, b, c) sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
63
64/*
65 * I2CポートIDから管理ブロックを取り出すためのマクロ
66 */
67#define INDEX_ADC(adcid) ((uint_t)((adcid) - 1))
68
69#define ADC_CHANNEL_TEMPSENSOR ((uint32_t)ADC_CHANNEL_16)
70
71/*
72 * ADC実行待ち時間(μsec)
73 */
74#define ADC_STAB_DELAY_US 3
75/*
76 * ADC温度センサー実行待ち時間(μsec)
77 */
78#define ADC_TEMPSENSOR_DELAY_US 10
79
80/*
81 * ADCポート設定テーブル
82 */
83static const ADC_PortControlBlock adc_pcb[NUM_ADCPORT] = {
84 { TADR_ADC1_BASE,
85 (TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_ADC1EN,
86 (TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2EN,
87 TADR_DMA2_STM0_BASE, DMA_CHANNEL_0 },
88 { TADR_ADC2_BASE,
89 (TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_ADC2EN,
90 (TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2EN,
91 TADR_DMA2_STM2_BASE, DMA_CHANNEL_1 },
92 { TADR_ADC3_BASE,
93 (TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_ADC3EN,
94 (TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_DMA2EN,
95 TADR_DMA2_STM0_BASE, DMA_CHANNEL_2 }
96};
97
98static ADC_Handle_t AdcHandle[NUM_ADCPORT];
99
100/*
101 * ADC DMA転送終了コールバック関数
102 */
103static void
104adc_dmatrans_func(DMA_Handle_t *hdma)
105{
106 ADC_Handle_t* hadc = ( ADC_Handle_t* )((DMA_Handle_t* )hdma)->localdata;
107
108 if(hadc->Init.ContinuousConvMode == ADC_CONTINUOUS_DISABLE)
109 hadc->status = ADC_STATUS_EOC;
110 else
111 hadc->status = ADC_STATUS_BUSY_EOC;
112 if(hadc->xfercallback != NULL)
113 hadc->xfercallback(hadc);
114}
115
116/*
117 * ADC DMAハーフ転送コールバック関数
118 */
119static void
120adc_dmahalftrans_func(DMA_Handle_t *hdma)
121{
122 ADC_Handle_t* hadc = ( ADC_Handle_t* )((DMA_Handle_t* )hdma)->localdata;
123
124 if(hadc->xferhalfcallback != NULL)
125 hadc->xferhalfcallback(hadc);
126}
127
128/*
129 * ADC DMAエラーコールバック関数
130 */
131static void
132adc_dmaerror_func(DMA_Handle_t *hdma)
133{
134 ADC_Handle_t* hadc = ( ADC_Handle_t* )((DMA_Handle_t* )hdma)->localdata;
135
136 hadc->status = ADC_STATUS_READY;
137 hadc->ErrorCode |= ADC_ERROR_DMA;
138 if(hadc->errorcallback != NULL)
139 hadc->errorcallback(hadc);
140}
141
142/*
143 * ADC初期設定
144 * parameter1 port: ADCポート番号
145 * parameter2 pini: ADC初期設定構造体へのポインタ
146 * return ADCハンドラへのポインタ、NULLでエラー
147 */
148ADC_Handle_t *
149adc_init(ID portid, ADC_Init_t* pini)
150{
151 static DMA_Handle_t hdma_adc;
152 ADC_Handle_t *hadc;
153 const ADC_PortControlBlock *apcb;
154
155 /*
156 * 設定パラメータチェック
157 */
158 if(portid < 1 || portid > NUM_ADCPORT)
159 return NULL;
160
161 hadc = &AdcHandle[INDEX_ADC(portid)];
162 memcpy(&hadc->Init, pini, sizeof(ADC_Init_t));
163
164 apcb = &adc_pcb[INDEX_ADC(portid)];
165 hadc->base = apcb->base;
166
167 /*
168 * ADCクロック設定
169 */
170 sil_orw_mem((uint32_t *)(apcb->adcclockbase), apcb->adcclockbit);
171 sil_rew_mem((uint32_t *)(apcb->adcclockbase));
172
173 /*
174 * DMA対応があれば、DMA設定を行う
175 */
176 if(apcb->dmaclockbase != 0 && pini->DMAContinuousRequests != ADC_DMACONTINUOUS_DISABLE){
177 sil_orw_mem((uint32_t *)(apcb->dmaclockbase), apcb->dmaclockbit);
178 sil_rew_mem((uint32_t *)(apcb->dmaclockbase));
179
180 hdma_adc.base = apcb->dmarxbase;
181 hdma_adc.Init.Channel = apcb->dmarxchannel;
182 hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
183 hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
184 hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
185 hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
186 hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
187 if((pini->DMAContinuousRequests & ADC_DMANONECIRCULAR) != 0)
188 hdma_adc.Init.Mode = DMA_NORMAL;
189 else
190 hdma_adc.Init.Mode = DMA_CIRCULAR;
191 hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
192 hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
193 hdma_adc.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
194 hdma_adc.Init.MemBurst = DMA_MBURST_SINGLE;
195 hdma_adc.Init.PeriphBurst = DMA_PBURST_SINGLE;
196
197 dma_init(&hdma_adc);
198
199 hadc->hdmarx = &hdma_adc;
200 hdma_adc.localdata = hadc;
201 }
202 else{
203 hadc->hdmarx = NULL;
204 }
205
206 /*
207 * ADCのプリスケーラ設定(コモン設定)
208 */
209 sil_modw_mem((uint32_t *)(TADR_ADC_BASE+TOFF_ADC_CCR), ADC_CCR_ADCPRE, hadc->Init.ClockPrescaler);
210
211 /*
212 * ADC初期設定
213 */
214 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_SCAN, hadc->Init.ScanConvMode);
215 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_RES, hadc->Init.Resolution);
216 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_ALIGN, hadc->Init.DataAlign);
217
218 /*
219 * ADC外部トリガ設定
220 */
221 if(hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START){
222 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_EXTSEL, hadc->Init.ExternalTrigConv);
223 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_EXTEN, hadc->Init.ExternalTrigConvEdge);
224 }
225 else{
226 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), (ADC_CR2_EXTSEL | ADC_CR2_EXTEN));
227 }
228
229 /*
230 * ADC継続モード設定
231 */
232 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_CONT, hadc->Init.ContinuousConvMode);
233 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_DISCEN, hadc->Init.DiscontinuousConvMode);
234 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_DISCNUM, hadc->Init.NumDiscConversion << 13);
235
236 /*
237 * コンバージョン数設定
238 */
239 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SQR1), ADC_SQR1_L, (hadc->Init.NumConversion - 1) << 20);
240
241 /*
242 * ADC-DMAモード設定
243 */
244 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_DDS, hadc->Init.DMAContinuousRequests);
245
246 /*
247 * ADC EOC設定
248 */
249 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_EOCS, hadc->Init.EOCSelection);
250
251 /*
252 * ADCを初期状態に
253 */
254 hadc->ErrorCode = ADC_ERROR_NONE;
255 hadc->status = ADC_STATUS_READY;
256 return hadc;
257}
258
259/*
260 * ADC終了設定
261 * parameter1 hadc: ADCハンドラへのポインタ
262 * return ERコード
263 */
264ER
265adc_deinit(ADC_Handle_t* hadc)
266{
267 if(hadc == NULL)
268 return E_PAR;
269
270 /*
271 * ADCリセット(コモン設定)
272 */
273 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_ADCRST);
274 sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2RSTR), RCC_APB2RSTR_ADCRST);
275
276 /*
277 * DMA停止
278 */
279 if(hadc->hdmarx != NULL)
280 dma_deinit(hadc->hdmarx);
281
282 /*
283 * ADCの状態初期化
284 */
285 hadc->ErrorCode = ADC_ERROR_NONE;
286 hadc->status = ADC_STATUS_RESET;
287 return E_OK;
288}
289
290/*
291 * ADC-割込みモード開始処理
292 * parameter1 hadc: ADCハンドラへのポインタ
293 * return ERコード
294 */
295ER
296adc_start_int(ADC_Handle_t* hadc)
297{
298 if(hadc == NULL)
299 return E_PAR;
300
301 /*
302 * 実行状態に移行
303 */
304 hadc->status = ADC_STATUS_BUSY;
305 hadc->ErrorCode = ADC_ERROR_NONE;
306
307 /*
308 * ADCが有効でなければ、ADCを設定し実行待ちを行う
309 */
310 if((sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2)) & ADC_CR2_ADON) == 0){
311 sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_ADON);
312 sil_dly_nse(ADC_STAB_DELAY_US*1000);
313 }
314
315 /*
316 * エラー転送割込み設定
317 */
318 sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), (ADC_CR1_OVRIE | ADC_CR1_EOCIE));
319
320 /*
321 * マルチモード判定
322 */
323 if((sil_rew_mem((uint32_t *)(TADR_ADC_BASE+TOFF_ADC_CCR)) & ADC_CCR_MULTI) == 0){
324 /*
325 * 非マルチモード:外部トリガでなければソフトスタート
326 */
327 if((sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2)) & ADC_CR2_EXTEN) == 0){
328 sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_SWSTART);
329 }
330 }
331 else{
332 /*
333 * マルチモード:ADC1で外部トリガでなければソフトスタート
334 */
335 if((hadc->base == TADR_ADC1_BASE) && ((sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2)) & ADC_CR2_EXTEN) == 0)){
336 sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_SWSTART);
337 }
338 }
339 return E_OK;
340}
341
342/*
343 * ADC-割込みモード停止処理
344 * parameter1 hadc: ADCハンドラへのポインタ
345 * return ERコード
346 */
347ER
348adc_end_int(ADC_Handle_t* hadc)
349{
350 if(hadc == NULL)
351 return E_PAR;
352
353 /*
354 * 転送、エラー割込み停止
355 */
356 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), (ADC_CR1_EOCIE | ADC_CR1_JEOCIE | ADC_CR1_OVRIE));
357
358 /*
359 * ADCモジュール停止
360 */
361 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_ADON);
362
363 hadc->status = ADC_STATUS_READY;
364 return E_OK;
365}
366
367/*
368 * ADC-DMAモード開始処理
369 * parameter1 hadc: ADCハンドラへのポインタ
370 * parameter2 pdata: 受信領域のポインタ
371 * parameter3 length: 受信データ長
372 * return ERコード
373 */
374ER
375adc_start_dma(ADC_Handle_t* hadc, uint32_t* pdata, uint32_t length)
376{
377 if(hadc == NULL)
378 return E_PAR;
379
380 /*
381 * ADC DMA設定
382 */
383 sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_DMA);
384
385 /*
386 * ADCオーバーラン割込み設定
387 */
388 sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_OVRIE);
389
390 /*
391 * DMAコールバック関数設定
392 */
393 hadc->hdmarx->xfercallback = adc_dmatrans_func;
394 hadc->hdmarx->xferhalfcallback = adc_dmahalftrans_func;
395 hadc->hdmarx->errorcallback = adc_dmaerror_func;
396
397 /*
398 * 実行状態に移行
399 */
400 hadc->status = ADC_STATUS_BUSY;
401 hadc->ErrorCode = ADC_ERROR_NONE;
402 hadc->NumCurrentConversionRank = hadc->Init.NumConversion;
403
404 /*
405 * DMAスタート
406 */
407 dma_start(hadc->hdmarx, hadc->base+TOFF_ADC_DR, (uint32_t)pdata, length);
408
409 /*
410 * ADCが有効でなければ、ADCを設定し実行待ちを行う
411 */
412 if((sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2)) & ADC_CR2_ADON) == 0){
413 sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_ADON);
414 sil_dly_nse(ADC_STAB_DELAY_US*1000);
415 }
416
417 /*
418 * 外部トリガ設定がなければ、ソフトウェアコンバージョンスタート設定を行う
419 */
420 if((sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2)) & ADC_CR2_EXTEN) == 0){
421 sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_SWSTART);
422 }
423 return E_OK;
424}
425
426/*
427 * ADC-DMAモード停止処理
428 * parameter1 hadc: ADCハンドラへのポインタ
429 * return ERコード
430 */
431ER
432adc_end_dma(ADC_Handle_t* hadc)
433{
434 if(hadc == NULL)
435 return E_PAR;
436
437 /*
438 * ADCモジュール停止
439 */
440 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_ADON);
441
442 /*
443 * オーバーラン割込みを停止
444 */
445 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_OVRIE);
446
447 /*
448 * ADCのDMAモードをオフ
449 */
450 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2), ADC_CR2_DMA);
451
452 /*
453 * DMAを停止
454 */
455 if(hadc->hdmarx != NULL)
456 dma_end(hadc->hdmarx);
457
458 hadc->status = ADC_STATUS_READY;
459 return E_OK;
460}
461
462/*
463 * ADC 割込みハンドラ実行関数
464 */
465void
466adc_handler(ADC_Handle_t* hadc)
467{
468 uint32_t sr = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_SR));
469 uint32_t cr1 = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1));
470 uint32_t cr2 = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_CR2));
471
472 /*
473 * レギュラーレジスタの終了判定
474 */
475 if((sr & ADC_SR_EOC) != 0 && (cr1 & ADC_CR1_EOCIE) != 0){
476 if((cr2 & ADC_CR2_CONT) == 0) /* ステータスの変更 */
477 hadc->status = ADC_STATUS_EOC;
478 else
479 hadc->status = ADC_STATUS_BUSY_EOC;
480
481 if((hadc->Init.ContinuousConvMode == ADC_CONTINUOUS_DISABLE) && ((cr2 & ADC_CR2_EXTEN) == 0)){
482 if(hadc->Init.EOCSelection == ADC_EOC_SEQ_DISABLE){
483 /*
484 * 転送とエラー割込みを停止
485 */
486 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_EOCIE);
487 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_OVRIE);
488 }
489 else{
490 if (hadc->NumCurrentConversionRank != 0){
491 hadc->NumCurrentConversionRank--;
492 }
493
494 /*
495 * RANK終了判定
496 */
497 if(hadc->NumCurrentConversionRank == 0){
498 /*
499 * 転送とエラー割込みを停止
500 */
501 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_EOCIE);
502 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_OVRIE);
503 }
504 }
505 }
506
507 /*
508 * 終了コールバック関数の読み出し
509 */
510 if(hadc->xfercallback != NULL)
511 hadc->xfercallback(hadc);
512
513 /*
514 * レギュラー転送の割込みクリア
515 */
516 sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_SR), ~ADC_SR_EOC);
517 }
518
519 /*
520 * インジェクテェットチャネルの終了判定
521 */
522 sr = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_SR));
523 if((sr & ADC_SR_JEOC) != 0 && (cr1 & ADC_CR1_JEOCIE) != 0){
524 if((cr2 & ADC_CR2_CONT) == 0) /* ステータスの変更 */
525 hadc->status = ADC_STATUS_EOC;
526 else
527 hadc->status = ADC_STATUS_BUSY_EOC;
528
529 if(((hadc->Init.ContinuousConvMode == ADC_CONTINUOUS_DISABLE) || (cr1 & ADC_CR1_JAUTO) == 0) && (cr2 & ADC_CR2_JEXTEN) == 0){
530 /*
531 * インジェクテェットチャネル転送を停止
532 */
533 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_JEOCIE);
534 }
535
536 /*
537 * インジェクテェットチャネル割込みクリア
538 */
539 sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_SR), ~ADC_SR_JEOC);
540 }
541
542 /*
543 * アナログウォッチドック判定
544 */
545 sr = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_SR));
546 if((sr & ADC_SR_AWD) != 0 && (cr1 & ADC_CR1_AWDIE) != 0){
547 /*
548 * ウォッチドック発生状態に変更
549 */
550 hadc->status = ADC_STATUS_AWD;
551
552 /*
553 * ウォッチドック割込みクリア
554 */
555 sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_SR), ~ADC_SR_AWD);
556
557 /*
558 * ウィンドウ領域アウトのコールバック関数読み出し
559 */
560 if(hadc->outofwincallback != NULL)
561 hadc->outofwincallback(hadc);
562 }
563
564 /*
565 * オーバーランエラー判定
566 */
567 sr = sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_SR));
568 if((sr & ADC_SR_OVR) != 0 && (cr1 & ADC_CR1_OVRIE) != 0){
569 /*
570 * オーバーラン発生状態に変更
571 */
572 hadc->status = ADC_STATUS_READY;
573 hadc->ErrorCode |= ADC_ERROR_OVR;
574
575 /*
576 * オーバーラン割込みクリア
577 */
578 sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_SR), ~ADC_SR_OVR);
579
580 /*
581 * エラーコールバック関数を読み出し
582 */
583 if(hadc->errorcallback != NULL)
584 hadc->errorcallback(hadc);
585 }
586}
587
588/*
589 * ADC割込みハンドラ
590 */
591void
592adc_int_handler(void)
593{
594 uint32_t i;
595 ADC_Handle_t* hadc = &AdcHandle[0];
596
597 for(i = 0 ; i < NUM_ADCPORT ; i++, hadc++){
598 if(hadc->status > ADC_STATUS_READY)
599 adc_handler(hadc);
600 }
601}
602
603
604/*
605 * レギュラーレジスタの取り出し
606 * parameter1 hadc: ADCハンドラへのポインタ
607 * return レギュラーレジスタ値
608 */
609uint32_t
610adc_getvalue(ADC_Handle_t* hadc)
611{
612 return sil_rew_mem((uint32_t *)(hadc->base+TOFF_ADC_DR));
613}
614
615/*
616 * ADCチャネル設定
617 * parameter1 hadc: ADCハンドラへのポインタ
618 * parameter2 sConfig: チャネル設定構造体へのポインタ
619 * return ERコード
620 */
621ER
622adc_setupchannel(ADC_Handle_t* hadc, ADC_ChannelConf_t* sConfig)
623{
624 GPIO_Init_t GPIO_InitStruct;
625 uint32_t shift, clkpin;
626
627 if(hadc == NULL || sConfig == NULL)
628 return E_PAR;
629
630 clkpin = (sConfig->GpioBase - TADR_GPIOA_BASE) / 0x400;
631 if(clkpin >= 12 || sConfig->GpioPin >= 16)
632 return E_PAR;
633
634 /*
635 * チャネル有効設定
636 */
637 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), 1<<clkpin);
638 sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
639
640 GPIO_InitStruct.mode = GPIO_MODE_ANALOG;
641 GPIO_InitStruct.pull = GPIO_NOPULL;
642 gpio_setup(sConfig->GpioBase, &GPIO_InitStruct, sConfig->GpioPin);
643
644 /*
645 * サンプリング時間設定
646 */
647 if (sConfig->Channel > ADC_CHANNEL_9){ /* チャネル10から18 */
648 shift = 3 * (sConfig->Channel - 10);
649 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SMPR1), (ADC_SMPR1_SMP10 << shift), (sConfig->SamplingTime << shift));
650 }
651 else{ /* チャネル0から9 */
652 shift = 3 * sConfig->Channel;
653 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SMPR2), (ADC_SMPR2_SMP0 << shift), (sConfig->SamplingTime << shift));
654 }
655
656 /*
657 * ランク設定
658 */
659 if (sConfig->Rank < 7){ /* ランク1から6 */
660 shift = 5 * (sConfig->Rank - 1);
661 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SQR3), (ADC_SQR3_SQ1 << shift), (sConfig->Channel << shift));
662 }
663 else if (sConfig->Rank < 13){ /* ランク7から12 */
664 shift = 5 * (sConfig->Rank - 7);
665 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SQR2), (ADC_SQR2_SQ7 << shift), (sConfig->Channel << shift));
666 }
667 else{ /* ランク13から16 */
668 shift = 5 * (sConfig->Rank - 13);
669 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_SQR1), (ADC_SQR1_SQ13 << shift), (sConfig->Channel << shift));
670 }
671
672 /*
673 * 電圧管理用チャネル設定
674 */
675 if ((hadc->base == TADR_ADC1_BASE) && (sConfig->Channel == ADC_CHANNEL_VBAT)){
676 sil_orw_mem((uint32_t *)(TADR_ADC_BASE+TOFF_ADC_CCR), ADC_CCR_VBATE);
677 }
678
679 /*
680 * 温度センサー専用チャネル設定
681 */
682 if ((hadc->base == TADR_ADC1_BASE) && ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) || (sConfig->Channel == ADC_CHANNEL_VREFINT))){
683 sil_orw_mem((uint32_t *)(TADR_ADC_BASE+TOFF_ADC_CCR), ADC_CCR_TSVREFE);
684 if((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR)){
685 sil_dly_nse(ADC_TEMPSENSOR_DELAY_US*1000);
686 }
687 }
688 return E_OK;
689}
690
691/*
692 * ADCアナログウォッチドック設定
693 * parameter1 hadc: ADCハンドラへのポインタ
694 * parameter2 AnalogWDGConfig: アナログウォッチドック設定構造体へのポインタ
695 * return ERコード
696 */
697ER
698adc_setupwatchdog(ADC_Handle_t* hadc, ADC_AnalogWDGConf_t* AnalogWDGConfig)
699{
700 if(hadc == NULL || AnalogWDGConfig == NULL)
701 return E_PAR;
702
703 /*
704 * 割込み設定
705 */
706 sil_modw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_AWDIE, AnalogWDGConfig->ITMode);
707
708 /*
709 * モード設定
710 */
711 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), (ADC_CR1_AWDSGL | ADC_CR1_JAWDEN | ADC_CR1_AWDEN));
712
713 /* Set the analog watchdog enable mode */
714 sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), AnalogWDGConfig->WatchdogMode);
715 sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_HTR), AnalogWDGConfig->HighThreshold);
716
717 /*
718 * HIGH/LOWのスレッシュホールド設定
719 */
720 sil_wrw_mem((uint32_t *)(hadc->base+TOFF_ADC_LTR), AnalogWDGConfig->LowThreshold);
721 sil_andw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), ADC_CR1_AWDCH);
722
723 /*
724 * 対応チャネル設定
725 */
726 sil_orw_mem((uint32_t *)(hadc->base+TOFF_ADC_CR1), AnalogWDGConfig->Channel);
727 return E_OK;
728}
729
730
Note: See TracBrowser for help on using the repository browser.