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 + 12U);
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-23] used on the HydCtr board
336 // AD2IN[0-7] used on HDK but the rpp layer is not ready for reading ADC2
376 static const uint32_t s_adcFiFoSize[2U][3U] =
382 /** @fn void adcStartConversion(adcBASE_t *adc, uint32_t group)
383 * @brief Starts an ADC conversion
384 * @param[in] adc Pointer to ADC module:
385 * - adcREG1: ADC1 module pointer
386 * - adcREG2: ADC2 module pointer
387 * @param[in] group Hardware group of ADC module:
388 * - adcGROUP0: ADC event group
389 * - adcGROUP1: ADC group 1
390 * - adcGROUP2: ADC group 2
392 * This function starts a conversion of the ADC hardware group.
394 * @note The function adcInit has to be called before this function can be
397 void adcStartConversion(adcBASE_t *adc, uint32_t group)
399 uint32_t index = adc == adcREG1 ? 0U : 1U;
402 // - For ADC1 Group1 see tms570_trm.pdf p. 796 (788)
403 adc->GxINTCR[group] = s_adcFiFoSize[index][group];
406 // - For ADC1 Group1 see tms570_trm.pdf p. 817 (809)
407 adc->GxSEL[group] = s_adcSelect[index][group];
411 /** @fn void adcStopConversion(adcBASE_t *adc, uint32_t group)
412 * @brief Stops an ADC conversion
413 * @param[in] adc Pointer to ADC module:
414 * - adcREG1: ADC1 module pointer
415 * - adcREG2: ADC2 module pointer
416 * @param[in] group Hardware group of ADC module:
417 * - adcGROUP0: ADC event group
418 * - adcGROUP1: ADC group 1
419 * - adcGROUP2: ADC group 2
421 * This function stops a convesion of the ADC hardware group.
423 * @note The function adcInit has to be called before this function can be
426 void adcStopConversion(adcBASE_t *adc, uint32_t group)
428 /** - Stop Conversion */
429 adc->GxSEL[group] = 0U;
434 * Resets FiFo read and write pointer.
436 * @param[in] adc Pointer to ADC module:
437 * - adcREG1: ADC1 module pointer
438 * - adcREG2: ADC2 module pointer
439 * @param[in] group Hardware group of ADC module:
440 * - adcGROUP0: ADC event group
441 * - adcGROUP1: ADC group 1
442 * - adcGROUP2: ADC group 2
444 * @note The function adcInit has to be called before this function can be
446 * The conversion should be stopped before calling this function.
449 void adcResetFiFo(adcBASE_t *adc, uint32_t group)
452 adc->GxFIFORESETCR[group] = 1U;
458 * Gets converted a ADC values.
460 * @param[in] adc Pointer to ADC module:
461 * - adcREG1: ADC1 module pointer
462 * - adcREG2: ADC2 module pointer
463 * @param[in] group Hardware group of ADC module:
464 * - adcGROUP0: ADC event group
465 * - adcGROUP1: ADC group 1
466 * - adcGROUP2: ADC group 2
467 * @param[out] data Pointer to store ADC converted data.
469 * @return The function will return the number of converted values copied
472 * @note The function adcInit has to be called before this function can be
474 * The user is responsible to initialize the message box.
477 uint32_t adcGetData(adcBASE_t *adc, uint32_t group, adcData_t *data)
482 uint32_t index = adc == adcREG1 ? 0U : 1U;
484 if(adc->GxINTCR[group] >= 256U) {
485 count = s_adcFiFoSize[index][group];
487 count = s_adcFiFoSize[index][group] - (uint32_t)(adc->GxINTCR[group] & 0xFF);
489 adcData_t *ptr = data;
491 mode = ((adc->GxMODECR[group]) & 0x00000300U);
493 if(mode == ADC_12_BIT) {
495 // Get conversion data and channel/pin id
496 for (i = 0; i < count; i++) {
497 buf = adc->GxBUF[group].BUF0;
498 ptr->value = (uint16_t)(buf & 0xFFFU);
499 ptr->id = (uint32_t)((buf >> 16U) & 0x1FU);
505 // Get conversion data and channel/pin id
506 for (i = 0; i < count; i++) {
507 buf = adc->GxBUF[group].BUF0;
508 ptr->value = (uint16_t)(buf & 0x3FFU);
509 ptr->id = (uint32_t)((buf >> 10U) & 0x1FU);
514 adc->GxINTFLG[group] = 9U;
521 * Checks if FiFo buffer is full.
523 * @param[in] adc Pointer to ADC module:
524 * - adcREG1: ADC1 module pointer
525 * - adcREG2: ADC2 module pointer
526 * @param[in] group Hardware group of ADC module:
527 * - adcGROUP0: ADC event group
528 * - adcGROUP1: ADC group 1
529 * - adcGROUP2: ADC group 2
531 * @return The function will return:
532 * - 0: When FiFo buffer is not full
533 * - 1: When FiFo buffer is full
534 * - 3: When FiFo buffer overflow occured
537 * @note The function adcInit has to be called before this function can be
541 uint32_t adcIsFifoFull(adcBASE_t *adc, uint32_t group)
544 uint32_t flags = adc->GxINTFLG[group] & 3U;
550 * Checks if Conversion is complete.
552 * @param[in] adc Pointer to ADC module:
553 * - adcREG1: ADC1 module pointer
554 * - adcREG2: ADC2 module pointer
555 * @param[in] group Hardware group of ADC module:
556 * - adcGROUP0: ADC event group
557 * - adcGROUP1: ADC group 1
558 * - adcGROUP2: ADC group 2
559 * @return The function will return:
560 * - 0: When is not finished
561 * - 8: When conversion is complete
563 * @note The function adcInit has to be called before this function can be
566 uint32_t adcIsConversionComplete(adcBASE_t *adc, uint32_t group)
570 /** - Read conversion flags */
571 flags = adc->GxINTFLG[group] & 8U;
578 * Computes offset error using Calibration mode.
580 * @param[in] adc Pointer to ADC module:
581 * - adcREG1: ADC1 module pointer
582 * - adcREG2: ADC2 module pointer
583 * - adcREG3: ADC3 module pointer
585 * @note The function adcInit has to be called before this function can be
588 void adcCalibration(adcBASE_t *adc)
590 uint32_t conv_val[5] = {0, 0, 0, 0, 0}, loop_index = 0;
591 uint32_t offset_error = 0;
592 uint32_t backup_mode;
594 /** - Backup Mode before Calibration */
595 backup_mode = adc->OPMODECR;
597 /** - Enable 12-BIT ADC */
598 adcREG1->OPMODECR |= 0x80000000U;
600 /* Disable all channels for conversion */
605 for(loop_index = 0; loop_index < 4; loop_index++) {
607 /* Disable Self Test and Calibration mode */
612 case 0 : /* Test 1 : Bride En = 0 , HiLo =0 */
616 case 1 : /* Test 1 : Bride En = 0 , HiLo =1 */
620 case 2 : /* Test 1 : Bride En = 1 , HiLo =0 */
624 case 3 : /* Test 1 : Bride En = 1 , HiLo =1 */
629 /* Enable Calibration mode */
632 /* Start calibration conversion */
633 adc->CALCR |= 0x00010000;
635 /* Wait for calibration conversion to complete */
636 while((adc->CALCR & 0x00010000) == 0x00010000);
638 /* Read converted value */
639 conv_val[loop_index] = adc->CALR;
642 /* Disable Self Test and Calibration mode */
645 /* Compute the Offset error correction value */
646 conv_val[4] = conv_val[0] + conv_val[1] + conv_val[2] + conv_val[3];
648 conv_val[4] = (conv_val[4] / 4);
650 offset_error=conv_val[4]-0x7FF;
652 /* Write the offset error to the Calibration register */
653 /* Load 2;s complement of the computed value to ADCALR register */
654 offset_error = ~offset_error;
655 offset_error = offset_error & 0xFFF;
656 offset_error = offset_error+1;
658 adc->CALR = offset_error;
660 // - Restore Mode after Calibration
661 adc->OPMODECR = backup_mode;
665 /** @fn void adcMidPointCalibration(adcBASE_t *adc)
666 * @brief Computes offset error using Mid Point Calibration mode
667 * @param[in] adc Pointer to ADC module:
668 * - adcREG1: ADC1 module pointer
669 * - adcREG2: ADC2 module pointer
670 * - adcREG3: ADC3 module pointer
671 * This function computes offset error using Mid Point Calibration mode
673 * @note The function adcInit has to be called before this function can be
676 uint32_t adcMidPointCalibration(adcBASE_t *adc)
678 uint32_t conv_val[3] = {0, 0, 0}, loop_index = 0;
679 uint32_t offset_error = 0;
680 uint32_t backup_mode;
682 /** - Backup Mode before Calibration */
683 backup_mode = adc->OPMODECR;
685 /** - Enable 12-BIT ADC */
686 adcREG1->OPMODECR |= 0x80000000U;
688 /* Disable all channels for conversion */
693 for(loop_index=0;loop_index<2;loop_index++) {
695 /* Disable Self Test and Calibration mode */
700 case 0 : /* Test 1 : Bride En = 0 , HiLo =0 */
704 case 1 : /* Test 1 : Bride En = 0 , HiLo =1 */
710 /* Enable Calibration mode */
713 /* Start calibration conversion */
714 adc->CALCR |= 0x00010000;
716 /* Wait for calibration conversion to complete */
717 while((adc->CALCR & 0x00010000) == 0x00010000);
719 /* Read converted value */
720 conv_val[loop_index]= adc->CALR;
723 /* Disable Self Test and Calibration mode */
726 /* Compute the Offset error correction value */
727 conv_val[2] = (conv_val[0]) + (conv_val[1]);
729 conv_val[2] = (conv_val[2] / 2);
731 offset_error = conv_val[2] - 0x7FF;
733 /* Write the offset error to the Calibration register */
734 /* Load 2's complement of the computed value to ADCALR register */
735 offset_error = ~offset_error;
736 offset_error = offset_error & 0xFFF;
737 offset_error = offset_error + 1;
739 adc->CALR = offset_error;
741 // - Restore Mode after Calibration
742 adc->OPMODECR = backup_mode;
748 /** @fn void adcEnableNotification(adcBASE_t *adc, uint32_t group)
749 * @brief Enable notification
750 * @param[in] adc Pointer to ADC module:
751 * - adcREG1: ADC1 module pointer
752 * - adcREG2: ADC2 module pointer
753 * - adcREG3: ADC3 module pointer
754 * @param[in] group Hardware group of ADC module:
755 * - adcGROUP0: ADC event group
756 * - adcGROUP1: ADC group 1
757 * - adcGROUP2: ADC group 2
759 * This function will enable the notification of a conversion.
760 * In single conversion mode for conversion complete and
761 * in continuous conversion mode when the FiFo buffer is full.
763 * @note The function adcInit has to be called before this function can be
765 * This function should be called before the conversion is started.
767 void adcEnableNotification(adcBASE_t *adc, uint32_t group)
769 uint32_t notif = adc->GxMODECR[group] & 2U ? 1U : 8U;
771 adc->GxINTENA[group] = notif;
775 /** @fn void adcDisableNotification(adcBASE_t *adc, uint32_t group)
776 * @brief Disable notification
777 * @param[in] adc Pointer to ADC module:
778 * - adcREG1: ADC1 module pointer
779 * - adcREG2: ADC2 module pointer
780 * - adcREG3: ADC3 module pointer
781 * @param[in] group Hardware group of ADC module:
782 * - adcGROUP0: ADC event group
783 * - adcGROUP1: ADC group 1
784 * - adcGROUP2: ADC group 2
786 * This function will disable the notification of a conversion.
788 * @note The function adcInit has to be called before this function can be
791 void adcDisableNotification(adcBASE_t *adc, uint32_t group)
793 adc->GxINTENA[group] = 0U;
797 /** @fn void adc1Group0Interrupt(void)
798 * @brief ADC1 Event Group Interrupt Handler
800 #pragma INTERRUPT(adc1Group0Interrupt, IRQ)
801 void adc1Group0Interrupt(void)
803 adcNotification(adcREG1, adcGROUP0);
804 adcREG1->GxINTFLG[0U] = _BV(3) | _BV(0);
808 /** @fn void adc1Group1Interrupt(void)
809 * @brief ADC1 Group 1 Interrupt Handler
811 #pragma INTERRUPT(adc1Group1Interrupt, IRQ)
812 void adc1Group1Interrupt(void)
814 adcNotification(adcREG1, adcGROUP1);
815 // For ADC1 Group1 see tms570_trm.pdf p. 791 (783)
816 adcREG1->GxINTFLG[1U] = _BV(3) | _BV(0);
820 /** @fn void adc1Group2Interrupt(void)
821 * @brief ADC1 Group 2 Interrupt Handler
823 #pragma INTERRUPT(adc1Group2Interrupt, IRQ)
824 void adc1Group2Interrupt(void)
826 adcNotification(adcREG1, adcGROUP2);
827 adcREG1->GxINTFLG[2U] = _BV(3) | _BV(0);;
831 /** @fn void adc2Group0Interrupt(void)
832 * @brief ADC2 Event Group Interrupt Handler
834 #pragma INTERRUPT(adc2Group0Interrupt, IRQ)
835 void adc2Group0Interrupt(void)
837 adcNotification(adcREG2, adcGROUP0);
838 adcREG2->GxINTFLG[0U] = _BV(3) | _BV(0);
842 /** @fn void adc2Group1Interrupt(void)
843 * @brief ADC2 Group 1 Interrupt Handler
845 #pragma INTERRUPT(adc2Group1Interrupt, IRQ)
846 void adc2Group1Interrupt(void)
848 adcNotification(adcREG2, adcGROUP1);
849 adcREG2->GxINTFLG[1U] = _BV(3) | _BV(0);
853 /** @fn void adc2Group2Interrupt(void)
854 * @brief ADC2 Group 2 Interrupt Handler
856 #pragma INTERRUPT(adc2Group2Interrupt, IRQ)
857 void adc2Group2Interrupt(void)
859 adcNotification(adcREG2, adcGROUP2);
860 adcREG2->GxINTFLG[2U] = _BV(3) | _BV(0);