2 * @brief ADC Driver Source File
3 * @date 04.January.2012
10 * which are relevant for the ADC driver.
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-15] used on the HDK
328 // AD2IN[0-7] used on HDK but the rpp layer is not ready for reading ADC2
368 static const uint32_t s_adcFiFoSize[2U][3U] =
374 /** @fn void adcStartConversion(adcBASE_t *adc, uint32_t group)
375 * @brief Starts an ADC conversion
376 * @param[in] adc Pointer to ADC module:
377 * - adcREG1: ADC1 module pointer
378 * - adcREG2: ADC2 module pointer
379 * @param[in] group Hardware group of ADC module:
380 * - adcGROUP0: ADC event group
381 * - adcGROUP1: ADC group 1
382 * - adcGROUP2: ADC group 2
384 * This function starts a conversion of the ADC hardware group.
386 * @note The function adcInit has to be called before this function can be
389 void adcStartConversion(adcBASE_t *adc, uint32_t group)
391 uint32_t index = adc == adcREG1 ? 0U : 1U;
394 // - For ADC1 Group1 see tms570_trm.pdf p. 796 (788)
395 adc->GxINTCR[group] = s_adcFiFoSize[index][group];
398 // - For ADC1 Group1 see tms570_trm.pdf p. 817 (809)
399 adc->GxSEL[group] = s_adcSelect[index][group];
403 /** @fn void adcStopConversion(adcBASE_t *adc, uint32_t group)
404 * @brief Stops an ADC conversion
405 * @param[in] adc Pointer to ADC module:
406 * - adcREG1: ADC1 module pointer
407 * - adcREG2: ADC2 module pointer
408 * @param[in] group Hardware group of ADC module:
409 * - adcGROUP0: ADC event group
410 * - adcGROUP1: ADC group 1
411 * - adcGROUP2: ADC group 2
413 * This function stops a convesion of the ADC hardware group.
415 * @note The function adcInit has to be called before this function can be
418 void adcStopConversion(adcBASE_t *adc, uint32_t group)
420 /** - Stop Conversion */
421 adc->GxSEL[group] = 0U;
426 * Resets FiFo read and write pointer.
428 * @param[in] adc Pointer to ADC module:
429 * - adcREG1: ADC1 module pointer
430 * - adcREG2: ADC2 module pointer
431 * @param[in] group Hardware group of ADC module:
432 * - adcGROUP0: ADC event group
433 * - adcGROUP1: ADC group 1
434 * - adcGROUP2: ADC group 2
436 * @note The function adcInit has to be called before this function can be
438 * The conversion should be stopped before calling this function.
441 void adcResetFiFo(adcBASE_t *adc, uint32_t group)
444 adc->GxFIFORESETCR[group] = 1U;
450 * Gets converted a ADC values.
452 * @param[in] adc Pointer to ADC module:
453 * - adcREG1: ADC1 module pointer
454 * - adcREG2: ADC2 module pointer
455 * @param[in] group Hardware group of ADC module:
456 * - adcGROUP0: ADC event group
457 * - adcGROUP1: ADC group 1
458 * - adcGROUP2: ADC group 2
459 * @param[out] data Pointer to store ADC converted data.
461 * @return The function will return the number of converted values copied
464 * @note The function adcInit has to be called before this function can be
466 * The user is responsible to initialize the message box.
469 uint32_t adcGetData(adcBASE_t *adc, uint32_t group, adcData_t *data)
474 uint32_t index = adc == adcREG1 ? 0U : 1U;
476 if(adc->GxINTCR[group] >= 256U) {
477 count = s_adcFiFoSize[index][group];
479 count = s_adcFiFoSize[index][group] - (uint32_t)(adc->GxINTCR[group] & 0xFF);
481 adcData_t *ptr = data;
483 mode = ((adc->GxMODECR[group]) & 0x00000300U);
485 if(mode == ADC_12_BIT) {
487 // Get conversion data and channel/pin id
488 for (i = 0; i < count; i++) {
489 buf = adc->GxBUF[group].BUF0;
490 ptr->value = (uint16_t)(buf & 0xFFFU);
491 ptr->id = (uint32_t)((buf >> 16U) & 0x1FU);
497 // Get conversion data and channel/pin id
498 for (i = 0; i < count; i++) {
499 buf = adc->GxBUF[group].BUF0;
500 ptr->value = (uint16_t)(buf & 0x3FFU);
501 ptr->id = (uint32_t)((buf >> 10U) & 0x1FU);
506 adc->GxINTFLG[group] = 9U;
513 * Checks if FiFo buffer is full.
515 * @param[in] adc Pointer to ADC module:
516 * - adcREG1: ADC1 module pointer
517 * - adcREG2: ADC2 module pointer
518 * @param[in] group Hardware group of ADC module:
519 * - adcGROUP0: ADC event group
520 * - adcGROUP1: ADC group 1
521 * - adcGROUP2: ADC group 2
523 * @return The function will return:
524 * - 0: When FiFo buffer is not full
525 * - 1: When FiFo buffer is full
526 * - 3: When FiFo buffer overflow occured
529 * @note The function adcInit has to be called before this function can be
533 uint32_t adcIsFifoFull(adcBASE_t *adc, uint32_t group)
536 uint32_t flags = adc->GxINTFLG[group] & 3U;
542 * Checks if Conversion is complete.
544 * @param[in] adc Pointer to ADC module:
545 * - adcREG1: ADC1 module pointer
546 * - adcREG2: ADC2 module pointer
547 * @param[in] group Hardware group of ADC module:
548 * - adcGROUP0: ADC event group
549 * - adcGROUP1: ADC group 1
550 * - adcGROUP2: ADC group 2
551 * @return The function will return:
552 * - 0: When is not finished
553 * - 8: When conversion is complete
555 * @note The function adcInit has to be called before this function can be
558 uint32_t adcIsConversionComplete(adcBASE_t *adc, uint32_t group)
562 /** - Read conversion flags */
563 flags = adc->GxINTFLG[group] & 8U;
570 * Computes offset error using Calibration mode.
572 * @param[in] adc Pointer to ADC module:
573 * - adcREG1: ADC1 module pointer
574 * - adcREG2: ADC2 module pointer
575 * - adcREG3: ADC3 module pointer
577 * @note The function adcInit has to be called before this function can be
580 void adcCalibration(adcBASE_t *adc)
582 uint32_t conv_val[5] = {0, 0, 0, 0, 0}, loop_index = 0;
583 uint32_t offset_error = 0;
584 uint32_t backup_mode;
586 /** - Backup Mode before Calibration */
587 backup_mode = adc->OPMODECR;
589 /** - Enable 12-BIT ADC */
590 adcREG1->OPMODECR |= 0x80000000U;
592 /* Disable all channels for conversion */
597 for(loop_index = 0; loop_index < 4; loop_index++) {
599 /* Disable Self Test and Calibration mode */
604 case 0 : /* Test 1 : Bride En = 0 , HiLo =0 */
608 case 1 : /* Test 1 : Bride En = 0 , HiLo =1 */
612 case 2 : /* Test 1 : Bride En = 1 , HiLo =0 */
616 case 3 : /* Test 1 : Bride En = 1 , HiLo =1 */
621 /* Enable Calibration mode */
624 /* Start calibration conversion */
625 adc->CALCR |= 0x00010000;
627 /* Wait for calibration conversion to complete */
628 while((adc->CALCR & 0x00010000) == 0x00010000);
630 /* Read converted value */
631 conv_val[loop_index] = adc->CALR;
634 /* Disable Self Test and Calibration mode */
637 /* Compute the Offset error correction value */
638 conv_val[4] = conv_val[0] + conv_val[1] + conv_val[2] + conv_val[3];
640 conv_val[4] = (conv_val[4] / 4);
642 offset_error=conv_val[4]-0x7FF;
644 /* Write the offset error to the Calibration register */
645 /* Load 2;s complement of the computed value to ADCALR register */
646 offset_error = ~offset_error;
647 offset_error = offset_error & 0xFFF;
648 offset_error = offset_error+1;
650 adc->CALR = offset_error;
652 // - Restore Mode after Calibration
653 adc->OPMODECR = backup_mode;
657 /** @fn void adcMidPointCalibration(adcBASE_t *adc)
658 * @brief Computes offset error using Mid Point Calibration mode
659 * @param[in] adc Pointer to ADC module:
660 * - adcREG1: ADC1 module pointer
661 * - adcREG2: ADC2 module pointer
662 * - adcREG3: ADC3 module pointer
663 * This function computes offset error using Mid Point Calibration mode
665 * @note The function adcInit has to be called before this function can be
668 uint32_t adcMidPointCalibration(adcBASE_t *adc)
670 uint32_t conv_val[3] = {0, 0, 0}, loop_index = 0;
671 uint32_t offset_error = 0;
672 uint32_t backup_mode;
674 /** - Backup Mode before Calibration */
675 backup_mode = adc->OPMODECR;
677 /** - Enable 12-BIT ADC */
678 adcREG1->OPMODECR |= 0x80000000U;
680 /* Disable all channels for conversion */
685 for(loop_index=0;loop_index<2;loop_index++) {
687 /* Disable Self Test and Calibration mode */
692 case 0 : /* Test 1 : Bride En = 0 , HiLo =0 */
696 case 1 : /* Test 1 : Bride En = 0 , HiLo =1 */
702 /* Enable Calibration mode */
705 /* Start calibration conversion */
706 adc->CALCR |= 0x00010000;
708 /* Wait for calibration conversion to complete */
709 while((adc->CALCR & 0x00010000) == 0x00010000);
711 /* Read converted value */
712 conv_val[loop_index]= adc->CALR;
715 /* Disable Self Test and Calibration mode */
718 /* Compute the Offset error correction value */
719 conv_val[2] = (conv_val[0]) + (conv_val[1]);
721 conv_val[2] = (conv_val[2] / 2);
723 offset_error = conv_val[2] - 0x7FF;
725 /* Write the offset error to the Calibration register */
726 /* Load 2's complement of the computed value to ADCALR register */
727 offset_error = ~offset_error;
728 offset_error = offset_error & 0xFFF;
729 offset_error = offset_error + 1;
731 adc->CALR = offset_error;
733 // - Restore Mode after Calibration
734 adc->OPMODECR = backup_mode;
740 /** @fn void adcEnableNotification(adcBASE_t *adc, uint32_t group)
741 * @brief Enable notification
742 * @param[in] adc Pointer to ADC module:
743 * - adcREG1: ADC1 module pointer
744 * - adcREG2: ADC2 module pointer
745 * - adcREG3: ADC3 module pointer
746 * @param[in] group Hardware group of ADC module:
747 * - adcGROUP0: ADC event group
748 * - adcGROUP1: ADC group 1
749 * - adcGROUP2: ADC group 2
751 * This function will enable the notification of a conversion.
752 * In single conversion mode for conversion complete and
753 * in continuous conversion mode when the FiFo buffer is full.
755 * @note The function adcInit has to be called before this function can be
757 * This function should be called before the conversion is started.
759 void adcEnableNotification(adcBASE_t *adc, uint32_t group)
761 uint32_t notif = adc->GxMODECR[group] & 2U ? 1U : 8U;
763 adc->GxINTENA[group] = notif;
767 /** @fn void adcDisableNotification(adcBASE_t *adc, uint32_t group)
768 * @brief Disable notification
769 * @param[in] adc Pointer to ADC module:
770 * - adcREG1: ADC1 module pointer
771 * - adcREG2: ADC2 module pointer
772 * - adcREG3: ADC3 module pointer
773 * @param[in] group Hardware group of ADC module:
774 * - adcGROUP0: ADC event group
775 * - adcGROUP1: ADC group 1
776 * - adcGROUP2: ADC group 2
778 * This function will disable the notification of a conversion.
780 * @note The function adcInit has to be called before this function can be
783 void adcDisableNotification(adcBASE_t *adc, uint32_t group)
785 adc->GxINTENA[group] = 0U;
789 /** @fn void adc1Group0Interrupt(void)
790 * @brief ADC1 Event Group Interrupt Handler
792 #pragma INTERRUPT(adc1Group0Interrupt, IRQ)
793 void adc1Group0Interrupt(void)
795 adcNotification(adcREG1, adcGROUP0);
796 adcREG1->GxINTFLG[0U] = _BV(3) | _BV(0);
800 /** @fn void adc1Group1Interrupt(void)
801 * @brief ADC1 Group 1 Interrupt Handler
803 #pragma INTERRUPT(adc1Group1Interrupt, IRQ)
804 void adc1Group1Interrupt(void)
806 adcNotification(adcREG1, adcGROUP1);
807 // For ADC1 Group1 see tms570_trm.pdf p. 791 (783)
808 adcREG1->GxINTFLG[1U] = _BV(3) | _BV(0);
812 /** @fn void adc1Group2Interrupt(void)
813 * @brief ADC1 Group 2 Interrupt Handler
815 #pragma INTERRUPT(adc1Group2Interrupt, IRQ)
816 void adc1Group2Interrupt(void)
818 adcNotification(adcREG1, adcGROUP2);
819 adcREG1->GxINTFLG[2U] = _BV(3) | _BV(0);;
823 /** @fn void adc2Group0Interrupt(void)
824 * @brief ADC2 Event Group Interrupt Handler
826 #pragma INTERRUPT(adc2Group0Interrupt, IRQ)
827 void adc2Group0Interrupt(void)
829 adcNotification(adcREG2, adcGROUP0);
830 adcREG2->GxINTFLG[0U] = _BV(3) | _BV(0);
834 /** @fn void adc2Group1Interrupt(void)
835 * @brief ADC2 Group 1 Interrupt Handler
837 #pragma INTERRUPT(adc2Group1Interrupt, IRQ)
838 void adc2Group1Interrupt(void)
840 adcNotification(adcREG2, adcGROUP1);
841 adcREG2->GxINTFLG[1U] = _BV(3) | _BV(0);
845 /** @fn void adc2Group2Interrupt(void)
846 * @brief ADC2 Group 2 Interrupt Handler
848 #pragma INTERRUPT(adc2Group2Interrupt, IRQ)
849 void adc2Group2Interrupt(void)
851 adcNotification(adcREG2, adcGROUP2);
852 adcREG2->GxINTFLG[2U] = _BV(3) | _BV(0);