]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/sys/_tms570_rpp/ti_drv_adc.c
Trigger context switch after ADC interrupts
[pes-rpp/rpp-lib.git] / rpp / src / sys / _tms570_rpp / ti_drv_adc.c
1 /** @file adc.c
2 *   @brief ADC Driver Source File
3 *   @date 04.January.2012
4 *   @version 03.01.00
5 *
6 *   This file contains:
7 *   - API Funcions
8 *   - Interrupt Handlers
9 *   .
10 *   which are relevant for the ADC driver.
11 */
12
13 /* Include Files */
14 #include "sys/ti_drv_adc.h"
15
16
17 /** @fn void adcInit(void)
18 *   @brief Initializes ADC Driver
19 *
20 *   This function initializes the ADC driver.
21 *
22 */
23 void adcInit(void)
24 {
25     /** @b Initialize @b ADC1: */
26
27     /** - Reset ADC module */
28     adcREG1->RSTCR = 1U;
29     adcREG1->RSTCR = 0U;
30
31     /** - Enable 12-BIT ADC  */
32     adcREG1->OPMODECR |= 0x80000000U;
33
34     /** - Setup prescaler */
35     adcREG1->CLOCKCR = 100/(1*1000000000/RPP_VCLK1_FREQ);       /* 100 = cycle time in ns */
36
37     /** - Setup memory boundaries */
38     adcREG1->BNDCR  =(8U << 16U)|(8U + 8U);
39     adcREG1->BNDEND = 2U;
40
41     /** - Setup event group conversion mode
42     *     - Setup data format
43     *     - Enable/Disable channel id in conversion result
44     *     - Enable/Disable continuous conversion
45     */
46     adcREG1->GxMODECR[0U] = ADC_12_BIT
47                           | 0x00000000U
48                           | 0x00000000U;
49
50     /** - Setup event group hardware trigger
51      *     - Setup hardware trigger edge
52      *     - Setup hardware trigger source
53      */
54     adcREG1->G0SRC = 0x00000000U
55                    | ADC1_EVENT;
56
57     /** - Setup event group sample window */
58     adcREG1->G0SAMP = 0U;
59
60     /** - Setup event group sample discharge
61     *     - Setup discharge prescaler
62     *     - Enable/Disable discharge
63     */
64     adcREG1->G0SAMPDISEN = 0U << 8U
65                          | 0x00000000U;
66
67     /** - Setup group 1 conversion mode
68     *     - Setup data format
69     *     - Enable/Disable channel id in conversion result
70     *     - Enable/Disable continuous conversion
71     */
72     adcREG1->GxMODECR[1U] = ADC_12_BIT
73                           | 0x00000020U
74                           | 0x00000000U
75                           | 0x00000000U;
76
77     /** - Setup group 1 hardware trigger
78      *     - Setup hardware trigger edge
79      *     - Setup hardware trigger source
80      */
81     adcREG1->G1SRC = 0x00000000U
82                    | ADC1_EVENT;
83
84     /** - Setup group 1 sample window */
85     adcREG1->G1SAMP = 0U;
86
87     /** - Setup group 1 sample discharge
88     *     - Setup discharge prescaler
89     *     - Enable/Disable discharge
90     */
91     adcREG1->G1SAMPDISEN = 0U << 8U
92                          | 0x00000000U;
93
94     /** - Setup group 2 conversion mode
95      *     - Setup data format
96      *     - Enable/Disable channel id in conversion result
97      *     - Enable/Disable continuous conversion
98      */
99     adcREG1->GxMODECR[2U] = ADC_12_BIT
100                           | 0x00000020U
101                           | 0x00000000U
102                           | 0x00000000U;
103
104     /** - Setup group 2 hardware trigger
105     *     - Setup hardware trigger edge
106     *     - Setup hardware trigger source
107     */
108     adcREG1->G2SRC = 0x00000000U
109                    | ADC1_EVENT;
110
111     /** - Setup group 2 sample window */
112     adcREG1->G2SAMP = 0U;
113
114     /** - Setup group 2 sample discharge
115     *     - Setup discharge prescaler
116     *     - Enable/Disable discharge
117     */
118     adcREG1->G2SAMPDISEN = 0U << 8U
119                          | 0x00000000U;
120
121     /** - Enable ADC module */
122     adcREG1->OPMODECR |= 0x80140001U;
123
124     /** - Wait for buffer inialisation complete */
125     while ((adcREG1->BUFINIT) != 0) { /* Wait */ }
126
127     /** - Setup parity */
128     adcREG1->PARCR = 0x00000005U;
129
130
131
132     /** @b Initialize @b ADC2: */
133
134     /** - Reset ADC module */
135     adcREG2->RSTCR = 1U;
136     adcREG2->RSTCR = 0U;
137
138     /** - Enable 12-BIT ADC  */
139     adcREG2->OPMODECR |= 0x80000000U;
140
141     /** - Setup prescaler */
142     adcREG2->CLOCKCR = 7U;
143
144     /** - Setup memory boundaries */
145     adcREG2->BNDCR  =(8U << 16U)|(8U + 8U);
146     adcREG2->BNDEND = 2U;
147
148     /** - Setup event group conversion mode
149     *     - Setup data format
150     *     - Enable/Disable channel id in conversion result
151     *     - Enable/Disable continuous conversion
152     */
153     adcREG2->GxMODECR[0U] = ADC_12_BIT
154                           | 0x00000000U
155                           | 0x00000000U;
156
157     /** - Setup event group hardware trigger
158     *     - Setup hardware trigger edge
159     *     - Setup hardware trigger source
160     */
161     adcREG2->G0SRC = 0x00000000U
162                    | ADC2_EVENT;
163
164     /** - Setup event group sample window */
165     adcREG2->G0SAMP = 0U;
166
167     /** - Setup event group sample discharge
168     *     - Setup discharge prescaler
169     *     - Enable/Disable discharge
170     */
171     adcREG2->G0SAMPDISEN = 0U << 8U
172                          | 0x00000000U;
173
174     /** - Setup group 1 conversion mode
175     *     - Setup data format
176     *     - Enable/Disable channel id in conversion result
177     *     - Enable/Disable continuous conversion
178     */
179     adcREG2->GxMODECR[1U] = ADC_12_BIT
180                           | 0x00000020U
181                           | 0x00000000U
182                           | 0x00000000U;
183
184     /** - Setup group 1 hardware trigger
185     *     - Setup hardware trigger edge
186     *     - Setup hardware trigger source
187     */
188     adcREG2->G1SRC = 0x00000000U
189                    | ADC2_EVENT;
190
191
192     /** - Setup group 1 sample window */
193     adcREG2->G1SAMP = 0U;
194
195     /** - Setup group 1 sample discharge
196     *     - Setup discharge prescaler
197     *     - Enable/Disable discharge
198     */
199     adcREG2->G1SAMPDISEN = 0U << 8U
200                          | 0x00000000U;
201
202     /** - Setup group 2 conversion mode
203     *     - Setup data format
204     *     - Enable/Disable channel id in conversion result
205     *     - Enable/Disable continuous conversion
206     */
207     adcREG2->GxMODECR[2U] = ADC_12_BIT
208                           | 0x00000000U
209                           | 0x00000000U
210                           | 0x00000000U;
211
212     /** - Setup group 2 hardware trigger
213     *     - Setup hardware trigger edge
214     *     - Setup hardware trigger source
215     */
216     adcREG2->G2SRC = 0x00000000U
217                    | ADC2_EVENT;
218
219     /** - Setup group 2 sample window */
220     adcREG2->G2SAMP = 0U;
221
222     /** - Setup group 2 sample discharge
223     *     - Setup discharge prescaler
224     *     - Enable/Disable discharge
225     */
226     adcREG2->G2SAMPDISEN = 0U << 8U
227                          | 0x00000000U;
228
229     /** - Enable ADC module */
230     adcREG2->OPMODECR |= 0x80140001U;
231
232     /** - Wait for buffer inialisation complete */
233     while ((adcREG2->BUFINIT) != 0) { /* Wait */ }
234
235     /** - Setup parity */
236     adcREG2->PARCR = 0x00000005U;
237
238     /**   @note This function has to be called before the driver can be used.\n
239     *           This function has to be executed in priviledged mode.\n
240     */
241 }
242
243
244 /** - s_adcSelect is used as constant table for channel selection */
245 static const uint32_t s_adcSelect[2U][3U] =
246 {
247     // TODO configure another group for AD2IN[0,14,15]
248
249     // ADC1, Group0
250   //_BV( 0) |
251   //_BV( 1) |
252   //_BV( 2) |
253   //_BV( 3) |
254   //_BV( 4) |
255   //_BV( 5) |
256   //_BV( 6) |
257   //_BV( 7) |
258   //_BV( 8) |
259   //_BV( 9) |
260   //_BV(10) |
261   //_BV(11) |
262   //_BV(12) |
263   //_BV(13) |
264   //_BV(14) |
265   //_BV(15) |
266          0x0,
267
268
269     // ADC1, Group1
270     // AD1IN[0-7] used for AIN
271     // See tms570_trm.pdf p. 817 (809)
272     _BV( 0) |
273     _BV( 1) |
274     _BV( 2) |
275     _BV( 3) |
276     _BV( 4) |
277     _BV( 5) |
278     _BV( 6) |
279     _BV( 7) |
280     _BV( 8) |
281     _BV( 9) |
282     _BV(10) |
283     _BV(11) |
284   //_BV(12) |
285   //_BV(13) |
286   //_BV(14) |
287   //_BV(15) |
288          0x0,
289
290     // ADC1, Group2
291   //_BV( 0) |
292   //_BV( 1) |
293   //_BV( 2) |
294   //_BV( 3) |
295   //_BV( 4) |
296   //_BV( 5) |
297   //_BV( 6) |
298   //_BV( 7) |
299   //_BV( 8) |
300   //_BV( 9) |
301   //_BV(10) |
302   //_BV(11) |
303   //_BV(12) |
304   //_BV(13) |
305   //_BV(14) |
306   //_BV(15) |
307          0x0,
308
309     // ADC2, Group0
310   //_BV( 0) |
311   //_BV( 1) |
312   //_BV( 2) |
313   //_BV( 3) |
314   //_BV( 4) |
315   //_BV( 5) |
316   //_BV( 6) |
317   //_BV( 7) |
318   //_BV( 8) |
319   //_BV( 9) |
320   //_BV(10) |
321   //_BV(11) |
322   //_BV(12) |
323   //_BV(13) |
324   //_BV(14) |
325   //_BV(15) |
326          0x0,
327
328     // ADC2, Group1
329     // AD2IN[2-7] used for HOUT-IFBK
330   //_BV( 0) |
331   //_BV( 1) |
332     _BV( 2) |
333     _BV( 3) |
334     _BV( 4) |
335     _BV( 5) |
336     _BV( 6) |
337     _BV( 7) |
338   //_BV( 8) |
339   //_BV( 9) |
340   //_BV(10) |
341   //_BV(11) |
342   //_BV(12) |
343   //_BV(13) |
344   //_BV(14) |
345   //_BV(15) |
346          0x0,
347
348     // ADC2, Group2
349   //_BV( 0) |
350   //_BV( 1) |
351   //_BV( 2) |
352   //_BV( 3) |
353   //_BV( 4) |
354   //_BV( 5) |
355   //_BV( 6) |
356   //_BV( 7) |
357   //_BV( 8) |
358   //_BV( 9) |
359   //_BV(10) |
360   //_BV(11) |
361   //_BV(12) |
362   //_BV(13) |
363   //_BV(14) |
364   //_BV(15) |
365          0x0
366 };
367
368                                       // ADC, Group
369 static const uint32_t s_adcFiFoSize[2U][3U] =
370 {
371     {0U, 12U, 0U},
372     {0U,  6U, 0U}
373 };
374
375 /** @fn void adcStartConversion(adcBASE_t *adc, uint32_t group)
376 *   @brief Starts an ADC conversion
377 *   @param[in] adc Pointer to ADC module:
378 *              - adcREG1: ADC1 module pointer
379 *              - adcREG2: ADC2 module pointer
380 *   @param[in] group Hardware group of ADC module:
381 *              - adcGROUP0: ADC event group
382 *              - adcGROUP1: ADC group 1
383 *              - adcGROUP2: ADC group 2
384 *
385 *   This function starts a conversion of the ADC hardware group.
386 *
387 *   @note The function adcInit has to be called before this function can be
388 *          used.
389 */
390 void adcStartConversion(adcBASE_t *adc, uint32_t group)
391 {
392     uint32_t index = adc == adcREG1 ? 0U : 1U;
393
394     // Setup FiFo size
395     //  - For ADC1 Group1 see tms570_trm.pdf p. 796 (788)
396     adc->GxINTCR[group] = s_adcFiFoSize[index][group];
397
398     // Start Conversion
399     //  - For ADC1 Group1 see tms570_trm.pdf p. 817 (809)
400     adc->GxSEL[group] = s_adcSelect[index][group];
401 }
402
403
404 /** @fn void adcStopConversion(adcBASE_t *adc, uint32_t group)
405 *   @brief Stops an ADC conversion
406 *   @param[in] adc Pointer to ADC module:
407 *              - adcREG1: ADC1 module pointer
408 *              - adcREG2: ADC2 module pointer
409 *   @param[in] group Hardware group of ADC module:
410 *              - adcGROUP0: ADC event group
411 *              - adcGROUP1: ADC group 1
412 *              - adcGROUP2: ADC group 2
413 *
414 *   This function stops a convesion of the ADC hardware group.
415 *
416 *   @note The function adcInit has to be called before this function can be
417 *          used.
418 */
419 void adcStopConversion(adcBASE_t *adc, uint32_t group)
420 {
421     /** - Stop Conversion */
422     adc->GxSEL[group] = 0U;
423 }
424
425
426 /**
427  * Resets FiFo read and write pointer.
428  *
429  * @param[in] adc       Pointer to ADC module:
430  *                          - adcREG1: ADC1 module pointer
431  *                          - adcREG2: ADC2 module pointer
432  * @param[in] group     Hardware group of ADC module:
433  *                          - adcGROUP0: ADC event group
434  *                          - adcGROUP1: ADC group 1
435  *                          - adcGROUP2: ADC group 2
436  *
437  * @note The function adcInit has to be called before this function can be
438  *        used.\n
439  *        The conversion should be stopped before calling this function.
440  *
441  */
442 void adcResetFiFo(adcBASE_t *adc, uint32_t group)
443 {
444     /** - Reset FiFo */
445     adc->GxFIFORESETCR[group] = 1U;
446 }
447
448
449
450 /**
451  * Gets converted a ADC values.
452  *
453  * @param[in] adc       Pointer to ADC module:
454  *                          - adcREG1: ADC1 module pointer
455  *                          - adcREG2: ADC2 module pointer
456  * @param[in] group     Hardware group of ADC module:
457  *                          - adcGROUP0: ADC event group
458  *                          - adcGROUP1: ADC group 1
459  *                          - adcGROUP2: ADC group 2
460  * @param[out] data Pointer to store ADC converted data.
461  *
462  * @return The function will return the number of converted values copied
463  *          into data buffer.
464  *
465  * @note The function adcInit has to be called before this function can be
466  *        used.\n
467  *        The user is responsible to initialize the message box.
468  *
469  */
470 uint32_t adcGetData(adcBASE_t *adc, uint32_t group, adcData_t *data)
471 {
472     uint32_t  i;
473     uint32_t  buf;
474     uint32_t  mode;
475     uint32_t  index = adc == adcREG1 ? 0U : 1U;
476     uint32_t  count;
477     if(adc->GxINTCR[group] >= 256U) {
478         count = s_adcFiFoSize[index][group];
479     } else {
480         count = s_adcFiFoSize[index][group] - (uint32_t)(adc->GxINTCR[group] & 0xFF);
481     }
482     adcData_t *ptr = data;
483
484     mode = ((adc->GxMODECR[group]) & 0x00000300U);
485
486     if(mode == ADC_12_BIT) {
487
488         // Get conversion data and channel/pin id
489         for (i = 0; i < count; i++) {
490             buf        = adc->GxBUF[group].BUF0;
491             ptr->value = (uint16_t)(buf & 0xFFFU);
492             ptr->id    = (uint32_t)((buf >> 16U) & 0x1FU);
493             ptr++;
494         }
495
496     } else {
497
498         // Get conversion data and channel/pin id
499         for (i = 0; i < count; i++) {
500             buf        = adc->GxBUF[group].BUF0;
501             ptr->value = (uint16_t)(buf & 0x3FFU);
502             ptr->id    = (uint32_t)((buf >> 10U) & 0x1FU);
503             ptr++;
504         }
505       }
506
507     adc->GxINTFLG[group] = 9U;
508
509     return count;
510 }
511
512
513 /**
514  * Checks if FiFo buffer is full.
515  *
516  * @param[in] adc       Pointer to ADC module:
517  *                          - adcREG1: ADC1 module pointer
518  *                          - adcREG2: ADC2 module pointer
519  * @param[in] group     Hardware group of ADC module:
520  *                          - adcGROUP0: ADC event group
521  *                          - adcGROUP1: ADC group 1
522  *                          - adcGROUP2: ADC group 2
523  *
524  * @return The function will return:
525  *                         - 0: When FiFo buffer is not full
526  *                         - 1: When FiFo buffer is full
527  *                         - 3: When FiFo buffer overflow occured
528  *
529  *
530  * @note The function adcInit has to be called before this function can be
531  *        used.
532  *
533  */
534 uint32_t adcIsFifoFull(adcBASE_t *adc, uint32_t group)
535 {
536     // Read FiFo flag
537     uint32_t flags = adc->GxINTFLG[group] & 3U;
538     return flags;
539 }
540
541
542 /**
543  * Checks if Conversion is complete.
544  *
545  * @param[in] adc       Pointer to ADC module:
546  *                          - adcREG1: ADC1 module pointer
547  *                          - adcREG2: ADC2 module pointer
548  * @param[in] group     Hardware group of ADC module:
549  *                          - adcGROUP0: ADC event group
550  *                          - adcGROUP1: ADC group 1
551  *                          - adcGROUP2: ADC group 2
552  * @return The function will return:
553  *                         - 0: When is not finished
554  *                         - 8: When conversion is complete
555  *
556  * @note The function adcInit has to be called before this function can be
557  *        used.
558 */
559 uint32_t adcIsConversionComplete(adcBASE_t *adc, uint32_t group)
560 {
561     uint32_t flags;
562
563     /** - Read conversion flags */
564     flags = adc->GxINTFLG[group] & 8U;
565
566     return flags;
567 }
568
569
570 /**
571  * Computes offset error using Calibration mode.
572  *
573  * @param[in] adc Pointer to ADC module:
574  *              - adcREG1: ADC1 module pointer
575  *              - adcREG2: ADC2 module pointer
576  *              - adcREG3: ADC3 module pointer
577  *
578  * @note The function adcInit has to be called before this function can be
579  *        used.
580  */
581 void adcCalibration(adcBASE_t *adc)
582 {
583     uint32_t conv_val[5] = {0, 0, 0, 0, 0}, loop_index = 0;
584     uint32_t offset_error = 0;
585     uint32_t backup_mode;
586
587     /** - Backup Mode before Calibration  */
588     backup_mode = adc->OPMODECR;
589
590     /** - Enable 12-BIT ADC  */
591     adcREG1->OPMODECR |= 0x80000000U;
592
593     /* Disable all channels for conversion */
594     adc->GxSEL[0]=0x00;
595     adc->GxSEL[1]=0x00;
596     adc->GxSEL[2]=0x00;
597
598     for(loop_index = 0; loop_index < 4; loop_index++) {
599
600         /* Disable Self Test and Calibration mode */
601         adc->CALCR = 0x0;
602
603         switch(loop_index) {
604
605             case 0 :    /* Test 1 : Bride En = 0 , HiLo =0 */
606                         adc->CALCR=0x0;
607                         break;
608
609             case 1 :    /* Test 1 : Bride En = 0 , HiLo =1 */
610                         adc->CALCR=0x0100;
611                         break;
612
613             case 2 :    /* Test 1 : Bride En = 1 , HiLo =0 */
614                         adc->CALCR=0x0200;
615                         break;
616
617             case 3 :    /* Test 1 : Bride En = 1 , HiLo =1 */
618                         adc->CALCR=0x0300;
619                         break;
620         }
621
622         /* Enable Calibration mode */
623         adc->CALCR |= 0x1;
624
625         /* Start calibration conversion */
626         adc->CALCR |= 0x00010000;
627
628         /* Wait for calibration conversion to complete */
629         while((adc->CALCR & 0x00010000) == 0x00010000);
630
631         /* Read converted value */
632         conv_val[loop_index] = adc->CALR;
633     }
634
635     /* Disable Self Test and Calibration mode */
636     adc->CALCR = 0x0;
637
638     /* Compute the Offset error correction value */
639     conv_val[4] = conv_val[0] + conv_val[1] + conv_val[2] + conv_val[3];
640
641     conv_val[4] = (conv_val[4] / 4);
642
643     offset_error=conv_val[4]-0x7FF;
644
645     /* Write the offset error to the Calibration register */
646     /* Load 2;s complement of the computed value to ADCALR register */
647     offset_error = ~offset_error;
648     offset_error = offset_error & 0xFFF;
649     offset_error = offset_error+1;
650
651     adc->CALR = offset_error;
652
653     // - Restore Mode after Calibration
654     adc->OPMODECR = backup_mode;
655 }
656
657
658 /** @fn void adcMidPointCalibration(adcBASE_t *adc)
659 *   @brief Computes offset error using Mid Point Calibration mode
660 *   @param[in] adc Pointer to ADC module:
661 *              - adcREG1: ADC1 module pointer
662 *              - adcREG2: ADC2 module pointer
663 *              - adcREG3: ADC3 module pointer
664 *   This function computes offset error using Mid Point Calibration mode
665 *
666 *   @note The function adcInit has to be called before this function can be
667 *          used.
668 */
669 uint32_t adcMidPointCalibration(adcBASE_t *adc)
670 {
671     uint32_t conv_val[3] = {0, 0, 0}, loop_index = 0;
672     uint32_t offset_error = 0;
673     uint32_t backup_mode;
674
675     /** - Backup Mode before Calibration  */
676     backup_mode = adc->OPMODECR;
677
678     /** - Enable 12-BIT ADC  */
679     adcREG1->OPMODECR |= 0x80000000U;
680
681     /* Disable all channels for conversion */
682     adc->GxSEL[0]=0x00;
683     adc->GxSEL[1]=0x00;
684     adc->GxSEL[2]=0x00;
685
686     for(loop_index=0;loop_index<2;loop_index++) {
687
688         /* Disable Self Test and Calibration mode */
689         adc->CALCR=0x0;
690
691         switch(loop_index) {
692
693             case 0 :    /* Test 1 : Bride En = 0 , HiLo =0 */
694                         adc->CALCR=0x0;
695                         break;
696
697             case 1 :    /* Test 1 : Bride En = 0 , HiLo =1 */
698                         adc->CALCR=0x0100;
699                         break;
700
701         }
702
703         /* Enable Calibration mode */
704         adc->CALCR |= 0x1;
705
706         /* Start calibration conversion */
707         adc->CALCR |= 0x00010000;
708
709         /* Wait for calibration conversion to complete */
710         while((adc->CALCR & 0x00010000) == 0x00010000);
711
712         /* Read converted value */
713         conv_val[loop_index]= adc->CALR;
714     }
715
716     /* Disable Self Test and Calibration mode */
717     adc->CALCR = 0x0;
718
719     /* Compute the Offset error correction value */
720     conv_val[2] = (conv_val[0]) + (conv_val[1]);
721
722     conv_val[2] = (conv_val[2] / 2);
723
724     offset_error = conv_val[2] - 0x7FF;
725
726     /* Write the offset error to the Calibration register           */
727     /* Load 2's complement of the computed value to ADCALR register */
728     offset_error = ~offset_error;
729     offset_error = offset_error & 0xFFF;
730     offset_error = offset_error + 1;
731
732     adc->CALR = offset_error;
733
734     // - Restore Mode after Calibration
735     adc->OPMODECR = backup_mode;
736
737     return offset_error;
738 }
739
740
741 /** @fn void adcEnableNotification(adcBASE_t *adc, uint32_t group)
742  *  @brief Enable notification
743  *  @param[in] adc Pointer to ADC module:
744  *             - adcREG1: ADC1 module pointer
745  *             - adcREG2: ADC2 module pointer
746  *             - adcREG3: ADC3 module pointer
747  *  @param[in] group Hardware group of ADC module:
748  *             - adcGROUP0: ADC event group
749  *             - adcGROUP1: ADC group 1
750  *             - adcGROUP2: ADC group 2
751  *
752  *  This function will enable the notification of a conversion.
753  *  In single conversion mode for conversion complete and
754  *  in continuous conversion mode when the FiFo buffer is full.
755  *
756  *  @note The function adcInit has to be called before this function can be
757  *         used.\n
758  *         This function should be called before the conversion is started.
759  */
760 void adcEnableNotification(adcBASE_t *adc, uint32_t group)
761 {
762     uint32_t notif = adc->GxMODECR[group] & 2U ? 1U : 8U;
763
764     adc->GxINTENA[group] = notif;
765 }
766
767
768 /** @fn void adcDisableNotification(adcBASE_t *adc, uint32_t group)
769  *  @brief Disable notification
770  *  @param[in] adc Pointer to ADC module:
771  *             - adcREG1: ADC1 module pointer
772  *             - adcREG2: ADC2 module pointer
773  *             - adcREG3: ADC3 module pointer
774  *  @param[in] group Hardware group of ADC module:
775  *             - adcGROUP0: ADC event group
776  *             - adcGROUP1: ADC group 1
777  *             - adcGROUP2: ADC group 2
778  *
779  *  This function will disable the notification of a conversion.
780  *
781  *  @note The function adcInit has to be called before this function can be
782  *         used.
783  */
784 void adcDisableNotification(adcBASE_t *adc, uint32_t group)
785 {
786     adc->GxINTENA[group] = 0U;
787 }
788
789
790 /** @fn void adc1Group0Interrupt(void)
791  *  @brief ADC1 Event Group Interrupt Handler
792  */
793 #pragma INTERRUPT(adc1Group0Interrupt, IRQ)
794 void adc1Group0Interrupt(void)
795 {
796     portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
797     adcNotification(adcREG1, adcGROUP0, &xHigherPriorityTaskWoken);
798     adcREG1->GxINTFLG[0U] = _BV(3) | _BV(0);
799     portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
800 }
801
802
803 /** @fn void adc1Group1Interrupt(void)
804  *  @brief ADC1 Group 1 Interrupt Handler
805  */
806 #pragma INTERRUPT(adc1Group1Interrupt, IRQ)
807 void adc1Group1Interrupt(void)
808 {
809     portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
810     adcNotification(adcREG1, adcGROUP1, &xHigherPriorityTaskWoken);
811     // For ADC1 Group1 see tms570_trm.pdf p. 791 (783)
812     adcREG1->GxINTFLG[1U] = _BV(3) | _BV(0);
813     portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
814 }
815
816
817 /** @fn void adc1Group2Interrupt(void)
818  *  @brief ADC1 Group 2 Interrupt Handler
819  */
820 #pragma INTERRUPT(adc1Group2Interrupt, IRQ)
821 void adc1Group2Interrupt(void)
822 {
823     portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
824     adcNotification(adcREG1, adcGROUP2, &xHigherPriorityTaskWoken);
825     adcREG1->GxINTFLG[2U] = _BV(3) | _BV(0);;
826     portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
827 }
828
829
830 /** @fn void adc2Group0Interrupt(void)
831  *  @brief ADC2 Event Group Interrupt Handler
832  */
833 #pragma INTERRUPT(adc2Group0Interrupt, IRQ)
834 void adc2Group0Interrupt(void)
835 {
836     portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
837     adcNotification(adcREG2, adcGROUP0, &xHigherPriorityTaskWoken);
838     adcREG2->GxINTFLG[0U] = _BV(3) | _BV(0);
839     portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
840 }
841
842
843 /** @fn void adc2Group1Interrupt(void)
844  *  @brief ADC2 Group 1 Interrupt Handler
845  */
846 #pragma INTERRUPT(adc2Group1Interrupt, IRQ)
847 void adc2Group1Interrupt(void)
848 {
849     portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
850     adcNotification(adcREG2, adcGROUP1, &xHigherPriorityTaskWoken);
851     adcREG2->GxINTFLG[1U] = _BV(3) | _BV(0);
852     portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
853 }
854
855
856 /** @fn void adc2Group2Interrupt(void)
857  *  @brief ADC2 Group 2 Interrupt Handler
858  */
859 #pragma INTERRUPT(adc2Group2Interrupt, IRQ)
860 void adc2Group2Interrupt(void)
861 {
862     portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
863     adcNotification(adcREG2, adcGROUP2, &xHigherPriorityTaskWoken);
864     adcREG2->GxINTFLG[2U] = _BV(3) | _BV(0);
865     portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
866 }
867