2 * @brief ADC Driver Source File
3 * @date 04.January.2012
10 * which are relevant for the ADC driver.
14 #include "sys/ti_drv_adc.h"
17 /** @fn void adcInit(void)
18 * @brief Initializes ADC Driver
20 * This function initializes the ADC driver.
25 /** @b Initialize @b ADC1: */
27 /** - Reset ADC module */
31 /** - Enable 12-BIT ADC */
32 adcREG1->OPMODECR |= 0x80000000U;
34 /** - Setup prescaler */
35 adcREG1->CLOCKCR = 100/(1*1000000000/RPP_VCLK1_FREQ); /* 100 = cycle time in ns */
37 /** - Setup memory boundaries */
38 adcREG1->BNDCR =(8U << 16U)|(8U + 8U);
41 /** - Setup event group conversion mode
43 * - Enable/Disable channel id in conversion result
44 * - Enable/Disable continuous conversion
46 adcREG1->GxMODECR[0U] = ADC_12_BIT
50 /** - Setup event group hardware trigger
51 * - Setup hardware trigger edge
52 * - Setup hardware trigger source
54 adcREG1->G0SRC = 0x00000000U
57 /** - Setup event group sample window */
60 /** - Setup event group sample discharge
61 * - Setup discharge prescaler
62 * - Enable/Disable discharge
64 adcREG1->G0SAMPDISEN = 0U << 8U
67 /** - Setup group 1 conversion mode
69 * - Enable/Disable channel id in conversion result
70 * - Enable/Disable continuous conversion
72 adcREG1->GxMODECR[1U] = ADC_12_BIT
77 /** - Setup group 1 hardware trigger
78 * - Setup hardware trigger edge
79 * - Setup hardware trigger source
81 adcREG1->G1SRC = 0x00000000U
84 /** - Setup group 1 sample window */
87 /** - Setup group 1 sample discharge
88 * - Setup discharge prescaler
89 * - Enable/Disable discharge
91 adcREG1->G1SAMPDISEN = 0U << 8U
94 /** - Setup group 2 conversion mode
96 * - Enable/Disable channel id in conversion result
97 * - Enable/Disable continuous conversion
99 adcREG1->GxMODECR[2U] = ADC_12_BIT
104 /** - Setup group 2 hardware trigger
105 * - Setup hardware trigger edge
106 * - Setup hardware trigger source
108 adcREG1->G2SRC = 0x00000000U
111 /** - Setup group 2 sample window */
112 adcREG1->G2SAMP = 0U;
114 /** - Setup group 2 sample discharge
115 * - Setup discharge prescaler
116 * - Enable/Disable discharge
118 adcREG1->G2SAMPDISEN = 0U << 8U
121 /** - Enable ADC module */
122 adcREG1->OPMODECR |= 0x80140001U;
124 /** - Wait for buffer inialisation complete */
125 while ((adcREG1->BUFINIT) != 0) { /* Wait */ }
127 /** - Setup parity */
128 adcREG1->PARCR = 0x00000005U;
132 /** @b Initialize @b ADC2: */
134 /** - Reset ADC module */
138 /** - Enable 12-BIT ADC */
139 adcREG2->OPMODECR |= 0x80000000U;
141 /** - Setup prescaler */
142 adcREG2->CLOCKCR = 7U;
144 /** - Setup memory boundaries */
145 adcREG2->BNDCR =(8U << 16U)|(8U + 8U);
146 adcREG2->BNDEND = 2U;
148 /** - Setup event group conversion mode
149 * - Setup data format
150 * - Enable/Disable channel id in conversion result
151 * - Enable/Disable continuous conversion
153 adcREG2->GxMODECR[0U] = ADC_12_BIT
157 /** - Setup event group hardware trigger
158 * - Setup hardware trigger edge
159 * - Setup hardware trigger source
161 adcREG2->G0SRC = 0x00000000U
164 /** - Setup event group sample window */
165 adcREG2->G0SAMP = 0U;
167 /** - Setup event group sample discharge
168 * - Setup discharge prescaler
169 * - Enable/Disable discharge
171 adcREG2->G0SAMPDISEN = 0U << 8U
174 /** - Setup group 1 conversion mode
175 * - Setup data format
176 * - Enable/Disable channel id in conversion result
177 * - Enable/Disable continuous conversion
179 adcREG2->GxMODECR[1U] = ADC_12_BIT
184 /** - Setup group 1 hardware trigger
185 * - Setup hardware trigger edge
186 * - Setup hardware trigger source
188 adcREG2->G1SRC = 0x00000000U
192 /** - Setup group 1 sample window */
193 adcREG2->G1SAMP = 0U;
195 /** - Setup group 1 sample discharge
196 * - Setup discharge prescaler
197 * - Enable/Disable discharge
199 adcREG2->G1SAMPDISEN = 0U << 8U
202 /** - Setup group 2 conversion mode
203 * - Setup data format
204 * - Enable/Disable channel id in conversion result
205 * - Enable/Disable continuous conversion
207 adcREG2->GxMODECR[2U] = ADC_12_BIT
212 /** - Setup group 2 hardware trigger
213 * - Setup hardware trigger edge
214 * - Setup hardware trigger source
216 adcREG2->G2SRC = 0x00000000U
219 /** - Setup group 2 sample window */
220 adcREG2->G2SAMP = 0U;
222 /** - Setup group 2 sample discharge
223 * - Setup discharge prescaler
224 * - Enable/Disable discharge
226 adcREG2->G2SAMPDISEN = 0U << 8U
229 /** - Enable ADC module */
230 adcREG2->OPMODECR |= 0x80140001U;
232 /** - Wait for buffer inialisation complete */
233 while ((adcREG2->BUFINIT) != 0) { /* Wait */ }
235 /** - Setup parity */
236 adcREG2->PARCR = 0x00000005U;
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
244 /** - s_adcSelect is used as constant table for channel selection */
245 static const uint32_t s_adcSelect[2U][3U] =
247 // TODO configure another group for AD2IN[0,14,15]
270 // AD1IN[0-7] used for AIN
271 // See tms570_trm.pdf p. 817 (809)
329 // AD2IN[2-7] used for HOUT-IFBK
369 static const uint32_t s_adcFiFoSize[2U][3U] =
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
385 * This function starts a conversion of the ADC hardware group.
387 * @note The function adcInit has to be called before this function can be
390 void adcStartConversion(adcBASE_t *adc, uint32_t group)
392 uint32_t index = adc == adcREG1 ? 0U : 1U;
395 // - For ADC1 Group1 see tms570_trm.pdf p. 796 (788)
396 adc->GxINTCR[group] = s_adcFiFoSize[index][group];
399 // - For ADC1 Group1 see tms570_trm.pdf p. 817 (809)
400 adc->GxSEL[group] = s_adcSelect[index][group];
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
414 * This function stops a convesion of the ADC hardware group.
416 * @note The function adcInit has to be called before this function can be
419 void adcStopConversion(adcBASE_t *adc, uint32_t group)
421 /** - Stop Conversion */
422 adc->GxSEL[group] = 0U;
427 * Resets FiFo read and write pointer.
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
437 * @note The function adcInit has to be called before this function can be
439 * The conversion should be stopped before calling this function.
442 void adcResetFiFo(adcBASE_t *adc, uint32_t group)
445 adc->GxFIFORESETCR[group] = 1U;
451 * Gets converted a ADC values.
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.
462 * @return The function will return the number of converted values copied
465 * @note The function adcInit has to be called before this function can be
467 * The user is responsible to initialize the message box.
470 uint32_t adcGetData(adcBASE_t *adc, uint32_t group, adcData_t *data)
475 uint32_t index = adc == adcREG1 ? 0U : 1U;
477 if(adc->GxINTCR[group] >= 256U) {
478 count = s_adcFiFoSize[index][group];
480 count = s_adcFiFoSize[index][group] - (uint32_t)(adc->GxINTCR[group] & 0xFF);
482 adcData_t *ptr = data;
484 mode = ((adc->GxMODECR[group]) & 0x00000300U);
486 if(mode == ADC_12_BIT) {
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);
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);
507 adc->GxINTFLG[group] = 9U;
514 * Checks if FiFo buffer is full.
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
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
530 * @note The function adcInit has to be called before this function can be
534 uint32_t adcIsFifoFull(adcBASE_t *adc, uint32_t group)
537 uint32_t flags = adc->GxINTFLG[group] & 3U;
543 * Checks if Conversion is complete.
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
556 * @note The function adcInit has to be called before this function can be
559 uint32_t adcIsConversionComplete(adcBASE_t *adc, uint32_t group)
563 /** - Read conversion flags */
564 flags = adc->GxINTFLG[group] & 8U;
571 * Computes offset error using Calibration mode.
573 * @param[in] adc Pointer to ADC module:
574 * - adcREG1: ADC1 module pointer
575 * - adcREG2: ADC2 module pointer
576 * - adcREG3: ADC3 module pointer
578 * @note The function adcInit has to be called before this function can be
581 void adcCalibration(adcBASE_t *adc)
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;
587 /** - Backup Mode before Calibration */
588 backup_mode = adc->OPMODECR;
590 /** - Enable 12-BIT ADC */
591 adcREG1->OPMODECR |= 0x80000000U;
593 /* Disable all channels for conversion */
598 for(loop_index = 0; loop_index < 4; loop_index++) {
600 /* Disable Self Test and Calibration mode */
605 case 0 : /* Test 1 : Bride En = 0 , HiLo =0 */
609 case 1 : /* Test 1 : Bride En = 0 , HiLo =1 */
613 case 2 : /* Test 1 : Bride En = 1 , HiLo =0 */
617 case 3 : /* Test 1 : Bride En = 1 , HiLo =1 */
622 /* Enable Calibration mode */
625 /* Start calibration conversion */
626 adc->CALCR |= 0x00010000;
628 /* Wait for calibration conversion to complete */
629 while((adc->CALCR & 0x00010000) == 0x00010000);
631 /* Read converted value */
632 conv_val[loop_index] = adc->CALR;
635 /* Disable Self Test and Calibration mode */
638 /* Compute the Offset error correction value */
639 conv_val[4] = conv_val[0] + conv_val[1] + conv_val[2] + conv_val[3];
641 conv_val[4] = (conv_val[4] / 4);
643 offset_error=conv_val[4]-0x7FF;
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;
651 adc->CALR = offset_error;
653 // - Restore Mode after Calibration
654 adc->OPMODECR = backup_mode;
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
666 * @note The function adcInit has to be called before this function can be
669 uint32_t adcMidPointCalibration(adcBASE_t *adc)
671 uint32_t conv_val[3] = {0, 0, 0}, loop_index = 0;
672 uint32_t offset_error = 0;
673 uint32_t backup_mode;
675 /** - Backup Mode before Calibration */
676 backup_mode = adc->OPMODECR;
678 /** - Enable 12-BIT ADC */
679 adcREG1->OPMODECR |= 0x80000000U;
681 /* Disable all channels for conversion */
686 for(loop_index=0;loop_index<2;loop_index++) {
688 /* Disable Self Test and Calibration mode */
693 case 0 : /* Test 1 : Bride En = 0 , HiLo =0 */
697 case 1 : /* Test 1 : Bride En = 0 , HiLo =1 */
703 /* Enable Calibration mode */
706 /* Start calibration conversion */
707 adc->CALCR |= 0x00010000;
709 /* Wait for calibration conversion to complete */
710 while((adc->CALCR & 0x00010000) == 0x00010000);
712 /* Read converted value */
713 conv_val[loop_index]= adc->CALR;
716 /* Disable Self Test and Calibration mode */
719 /* Compute the Offset error correction value */
720 conv_val[2] = (conv_val[0]) + (conv_val[1]);
722 conv_val[2] = (conv_val[2] / 2);
724 offset_error = conv_val[2] - 0x7FF;
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;
732 adc->CALR = offset_error;
734 // - Restore Mode after Calibration
735 adc->OPMODECR = backup_mode;
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
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.
756 * @note The function adcInit has to be called before this function can be
758 * This function should be called before the conversion is started.
760 void adcEnableNotification(adcBASE_t *adc, uint32_t group)
762 uint32_t notif = adc->GxMODECR[group] & 2U ? 1U : 8U;
764 adc->GxINTENA[group] = notif;
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
779 * This function will disable the notification of a conversion.
781 * @note The function adcInit has to be called before this function can be
784 void adcDisableNotification(adcBASE_t *adc, uint32_t group)
786 adc->GxINTENA[group] = 0U;
790 /** @fn void adc1Group0Interrupt(void)
791 * @brief ADC1 Event Group Interrupt Handler
793 #pragma INTERRUPT(adc1Group0Interrupt, IRQ)
794 void adc1Group0Interrupt(void)
796 adcNotification(adcREG1, adcGROUP0);
797 adcREG1->GxINTFLG[0U] = _BV(3) | _BV(0);
801 /** @fn void adc1Group1Interrupt(void)
802 * @brief ADC1 Group 1 Interrupt Handler
804 #pragma INTERRUPT(adc1Group1Interrupt, IRQ)
805 void adc1Group1Interrupt(void)
807 adcNotification(adcREG1, adcGROUP1);
808 // For ADC1 Group1 see tms570_trm.pdf p. 791 (783)
809 adcREG1->GxINTFLG[1U] = _BV(3) | _BV(0);
813 /** @fn void adc1Group2Interrupt(void)
814 * @brief ADC1 Group 2 Interrupt Handler
816 #pragma INTERRUPT(adc1Group2Interrupt, IRQ)
817 void adc1Group2Interrupt(void)
819 adcNotification(adcREG1, adcGROUP2);
820 adcREG1->GxINTFLG[2U] = _BV(3) | _BV(0);;
824 /** @fn void adc2Group0Interrupt(void)
825 * @brief ADC2 Event Group Interrupt Handler
827 #pragma INTERRUPT(adc2Group0Interrupt, IRQ)
828 void adc2Group0Interrupt(void)
830 adcNotification(adcREG2, adcGROUP0);
831 adcREG2->GxINTFLG[0U] = _BV(3) | _BV(0);
835 /** @fn void adc2Group1Interrupt(void)
836 * @brief ADC2 Group 1 Interrupt Handler
838 #pragma INTERRUPT(adc2Group1Interrupt, IRQ)
839 void adc2Group1Interrupt(void)
841 adcNotification(adcREG2, adcGROUP1);
842 adcREG2->GxINTFLG[1U] = _BV(3) | _BV(0);
846 /** @fn void adc2Group2Interrupt(void)
847 * @brief ADC2 Group 2 Interrupt Handler
849 #pragma INTERRUPT(adc2Group2Interrupt, IRQ)
850 void adc2Group2Interrupt(void)
852 adcNotification(adcREG2, adcGROUP2);
853 adcREG2->GxINTFLG[2U] = _BV(3) | _BV(0);