DSP2803x_Adc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. //###########################################################################
  2. //
  3. // FILE: DSP2803x_Adc.c
  4. //
  5. // TITLE: DSP2803x ADC Initialization & Support Functions.
  6. //
  7. //###########################################################################
  8. // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V130 $
  9. // $Release Date: May 8, 2015 $
  10. // $Copyright: Copyright (C) 2009-2015 Texas Instruments Incorporated -
  11. // http://www.ti.com/ ALL RIGHTS RESERVED $
  12. //###########################################################################
  13. #include "DSP2803x_Device.h" // DSP2803x Headerfile Include File
  14. #include "DSP2803x_Examples.h" // DSP2803x Examples Include File
  15. #define ADC_usDELAY 1000L
  16. //---------------------------------------------------------------------------
  17. // InitAdc:
  18. //---------------------------------------------------------------------------
  19. // This function initializes ADC to a known state.
  20. //
  21. // NOTE: ADC INIT IS DIFFERENT ON 2803x DEVICES COMPARED TO OTHER 28X DEVICES
  22. //
  23. // *IMPORTANT*
  24. // IF RUNNING FROM FLASH, PLEASE COPY OVER THE SECTION "ramfuncs" FROM FLASH
  25. // TO RAM PRIOR TO CALLING InitSysCtrl(). THIS PREVENTS THE MCU FROM THROWING
  26. // AN EXCEPTION WHEN A CALL TO DELAY_US() IS MADE.
  27. //
  28. void InitAdc(void)
  29. {
  30. extern void DSP28x_usDelay(Uint32 Count);
  31. // *IMPORTANT*
  32. // The Device_cal function, which copies the ADC calibration values from TI reserved
  33. // OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
  34. // Boot ROM. If the boot ROM code is bypassed during the debug process, the
  35. // following function MUST be called for the ADC to function according
  36. // to specification. The clocks to the ADC MUST be enabled before calling this
  37. // function.
  38. // See the device data manual and/or the ADC Reference
  39. // Manual for more information.
  40. EALLOW;
  41. SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
  42. (*Device_cal)();
  43. EDIS;
  44. // To powerup the ADC the ADCENCLK bit should be set first to enable
  45. // clocks, followed by powering up the bandgap, reference circuitry, and ADC core.
  46. // Before the first conversion is performed a 5ms delay must be observed
  47. // after power up to give all analog circuits time to power up and settle
  48. // Please note that for the delay function below to operate correctly the
  49. // CPU_RATE define statement in the DSP2803x_Examples.h file must
  50. // contain the correct CPU clock period in nanoseconds.
  51. EALLOW;
  52. AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // Power ADC BG
  53. AdcRegs.ADCCTL1.bit.ADCREFPWD = 1; // Power reference
  54. AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // Power ADC
  55. AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // Enable ADC
  56. AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; // Select interal BG
  57. EDIS;
  58. DELAY_US(ADC_usDELAY); // Delay before converting ADC channels
  59. }
  60. void InitAdcAio()
  61. {
  62. EALLOW;
  63. /* Configure ADC pins using AIO regs*/
  64. // This specifies which of the possible AIO pins will be Analog input pins.
  65. // NOTE: AIO1,3,5,7-9,11,13,15 are analog inputs in all AIOMUX1 configurations.
  66. // Comment out other unwanted lines.
  67. GpioCtrlRegs.AIOMUX1.bit.AIO2 = 2; // Configure AIO2 for A2 (analog input) operation
  68. GpioCtrlRegs.AIOMUX1.bit.AIO4 = 2; // Configure AIO4 for A4 (analog input) operation
  69. GpioCtrlRegs.AIOMUX1.bit.AIO6 = 2; // Configure AIO6 for A6 (analog input) operation
  70. GpioCtrlRegs.AIOMUX1.bit.AIO10 = 2; // Configure AIO10 for B2 (analog input) operation
  71. GpioCtrlRegs.AIOMUX1.bit.AIO12 = 2; // Configure AIO12 for B4 (analog input) operation
  72. GpioCtrlRegs.AIOMUX1.bit.AIO14 = 2; // Configure AIO14 for B6 (analog input) operation
  73. EDIS;
  74. }
  75. /* AdcoffsetSelfCal-
  76. This function re-calibrates the ADC zero offset error by converting the VREFLO reference with
  77. the ADC and modifying the ADCOFFTRIM register. VREFLO is sampled by the ADC using an internal
  78. MUX select which connects VREFLO to A5 without sacrificing an external ADC pin. This
  79. function calls two other functions:
  80. - AdcChanSelect(channel) – selects the ADC channel to convert
  81. - AdcConversion() – initiates several ADC conversions and returns the average
  82. */
  83. void AdcOffsetSelfCal()
  84. {
  85. Uint16 AdcConvMean;
  86. EALLOW;
  87. AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; //Select internal reference mode
  88. AdcRegs.ADCCTL1.bit.VREFLOCONV = 1; //Select VREFLO internal connection on B5
  89. AdcChanSelect(13); //Select channel B5 for all SOC
  90. AdcRegs.ADCOFFTRIM.bit.OFFTRIM = 80; //Apply artificial offset (+80) to account for a negative offset that may reside in the ADC core
  91. AdcConvMean = AdcConversion(); //Capture ADC conversion on VREFLO
  92. AdcRegs.ADCOFFTRIM.bit.OFFTRIM = 80 - AdcConvMean; //Set offtrim register with new value (i.e remove artical offset (+80) and create a two's compliment of the offset error)
  93. AdcRegs.ADCCTL1.bit.VREFLOCONV = 0; //Select external ADCIN5 input pin on B5
  94. EDIS;
  95. }
  96. /* AdcChanSelect-
  97. This function selects the ADC channel to convert by setting all SOC channel selects to a single channel.
  98. * IMPORTANT * This function will overwrite previous SOC channel select settings. Recommend saving
  99. the previous settings.
  100. */
  101. void AdcChanSelect(Uint16 ch_no)
  102. {
  103. AdcRegs.ADCSOC0CTL.bit.CHSEL= ch_no;
  104. AdcRegs.ADCSOC1CTL.bit.CHSEL= ch_no;
  105. AdcRegs.ADCSOC2CTL.bit.CHSEL= ch_no;
  106. AdcRegs.ADCSOC3CTL.bit.CHSEL= ch_no;
  107. AdcRegs.ADCSOC4CTL.bit.CHSEL= ch_no;
  108. AdcRegs.ADCSOC5CTL.bit.CHSEL= ch_no;
  109. AdcRegs.ADCSOC6CTL.bit.CHSEL= ch_no;
  110. AdcRegs.ADCSOC7CTL.bit.CHSEL= ch_no;
  111. AdcRegs.ADCSOC8CTL.bit.CHSEL= ch_no;
  112. AdcRegs.ADCSOC9CTL.bit.CHSEL= ch_no;
  113. AdcRegs.ADCSOC10CTL.bit.CHSEL= ch_no;
  114. AdcRegs.ADCSOC11CTL.bit.CHSEL= ch_no;
  115. AdcRegs.ADCSOC12CTL.bit.CHSEL= ch_no;
  116. AdcRegs.ADCSOC13CTL.bit.CHSEL= ch_no;
  117. AdcRegs.ADCSOC14CTL.bit.CHSEL= ch_no;
  118. AdcRegs.ADCSOC15CTL.bit.CHSEL= ch_no;
  119. } //end AdcChanSelect
  120. /* AdcConversion -
  121. This function initiates several ADC conversions and returns the average. It uses ADCINT1 and ADCINT2
  122. to "ping-pong" between SOC0-7 and SOC8-15 and is referred to as "ping-pong" sampling.
  123. * IMPORTANT * This function will overwrite previous ADC settings. Recommend saving previous settings.
  124. */
  125. Uint16 AdcConversion(void)
  126. {
  127. Uint16 index, SampleSize, Mean, ACQPS_Value;
  128. Uint32 Sum;
  129. index = 0; //initialize index to 0
  130. SampleSize = 256; //set sample size to 256 (**NOTE: Sample size must be multiples of 2^x where is an integer >= 4)
  131. Sum = 0; //set sum to 0
  132. Mean = 999; //initialize mean to known value
  133. //Set the ADC sample window to the desired value (Sample window = ACQPS + 1)
  134. ACQPS_Value = 8;
  135. AdcRegs.ADCSOC0CTL.bit.ACQPS = ACQPS_Value;
  136. AdcRegs.ADCSOC1CTL.bit.ACQPS = ACQPS_Value;
  137. AdcRegs.ADCSOC2CTL.bit.ACQPS = ACQPS_Value;
  138. AdcRegs.ADCSOC3CTL.bit.ACQPS = ACQPS_Value;
  139. AdcRegs.ADCSOC4CTL.bit.ACQPS = ACQPS_Value;
  140. AdcRegs.ADCSOC5CTL.bit.ACQPS = ACQPS_Value;
  141. AdcRegs.ADCSOC6CTL.bit.ACQPS = ACQPS_Value;
  142. AdcRegs.ADCSOC7CTL.bit.ACQPS = ACQPS_Value;
  143. AdcRegs.ADCSOC8CTL.bit.ACQPS = ACQPS_Value;
  144. AdcRegs.ADCSOC9CTL.bit.ACQPS = ACQPS_Value;
  145. AdcRegs.ADCSOC10CTL.bit.ACQPS = ACQPS_Value;
  146. AdcRegs.ADCSOC11CTL.bit.ACQPS = ACQPS_Value;
  147. AdcRegs.ADCSOC12CTL.bit.ACQPS = ACQPS_Value;
  148. AdcRegs.ADCSOC13CTL.bit.ACQPS = ACQPS_Value;
  149. AdcRegs.ADCSOC14CTL.bit.ACQPS = ACQPS_Value;
  150. AdcRegs.ADCSOC15CTL.bit.ACQPS = ACQPS_Value;
  151. //Enable ping-pong sampling
  152. // Enabled ADCINT1 and ADCINT2
  153. AdcRegs.INTSEL1N2.bit.INT1E = 1;
  154. AdcRegs.INTSEL1N2.bit.INT2E = 1;
  155. // Disable continuous sampling for ADCINT1 and ADCINT2
  156. AdcRegs.INTSEL1N2.bit.INT1CONT = 0;
  157. AdcRegs.INTSEL1N2.bit.INT2CONT = 0;
  158. AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //ADCINTs trigger at end of conversion
  159. // Setup ADCINT1 and ADCINT2 trigger source
  160. AdcRegs.INTSEL1N2.bit.INT1SEL = 6; //EOC6 triggers ADCINT1
  161. AdcRegs.INTSEL1N2.bit.INT2SEL = 14; //EOC14 triggers ADCINT2
  162. // Setup each SOC's ADCINT trigger source
  163. AdcRegs.ADCINTSOCSEL1.bit.SOC0 = 2; //ADCINT2 starts SOC0-7
  164. AdcRegs.ADCINTSOCSEL1.bit.SOC1 = 2;
  165. AdcRegs.ADCINTSOCSEL1.bit.SOC2 = 2;
  166. AdcRegs.ADCINTSOCSEL1.bit.SOC3 = 2;
  167. AdcRegs.ADCINTSOCSEL1.bit.SOC4 = 2;
  168. AdcRegs.ADCINTSOCSEL1.bit.SOC5 = 2;
  169. AdcRegs.ADCINTSOCSEL1.bit.SOC6 = 2;
  170. AdcRegs.ADCINTSOCSEL1.bit.SOC7 = 2;
  171. AdcRegs.ADCINTSOCSEL2.bit.SOC8 = 1; //ADCINT1 starts SOC8-15
  172. AdcRegs.ADCINTSOCSEL2.bit.SOC9 = 1;
  173. AdcRegs.ADCINTSOCSEL2.bit.SOC10 = 1;
  174. AdcRegs.ADCINTSOCSEL2.bit.SOC11 = 1;
  175. AdcRegs.ADCINTSOCSEL2.bit.SOC12 = 1;
  176. AdcRegs.ADCINTSOCSEL2.bit.SOC13 = 1;
  177. AdcRegs.ADCINTSOCSEL2.bit.SOC14 = 1;
  178. AdcRegs.ADCINTSOCSEL2.bit.SOC15 = 1;
  179. DELAY_US(ADC_usDELAY); // Delay before converting ADC channels
  180. //ADC Conversion
  181. AdcRegs.ADCSOCFRC1.all = 0x00FF; // Force Start SOC0-7 to begin ping-pong sampling
  182. while( index < SampleSize ){
  183. //Wait for ADCINT1 to trigger, then add ADCRESULT0-7 registers to sum
  184. while (AdcRegs.ADCINTFLG.bit.ADCINT1 == 0){}
  185. AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Must clear ADCINT1 flag since INT1CONT = 0
  186. Sum += AdcResult.ADCRESULT0;
  187. Sum += AdcResult.ADCRESULT1;
  188. Sum += AdcResult.ADCRESULT2;
  189. Sum += AdcResult.ADCRESULT3;
  190. Sum += AdcResult.ADCRESULT4;
  191. Sum += AdcResult.ADCRESULT5;
  192. Sum += AdcResult.ADCRESULT6;
  193. // Wait for SOC9 conversion to start, which gives time for SOC7 conversion result
  194. while( AdcRegs.ADCSOCFLG1.bit.SOC9 == 1 ){}
  195. Sum += AdcResult.ADCRESULT7;
  196. //Wait for ADCINT2 to trigger, then add ADCRESULT8-15 registers to sum
  197. while (AdcRegs.ADCINTFLG.bit.ADCINT2 == 0){}
  198. AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //Must clear ADCINT2 flag since INT2CONT = 0
  199. Sum += AdcResult.ADCRESULT8;
  200. Sum += AdcResult.ADCRESULT9;
  201. Sum += AdcResult.ADCRESULT10;
  202. Sum += AdcResult.ADCRESULT11;
  203. Sum += AdcResult.ADCRESULT12;
  204. Sum += AdcResult.ADCRESULT13;
  205. Sum += AdcResult.ADCRESULT14;
  206. // Wait for SOC1 conversion to start, which gives time for SOC15 conversion result
  207. while( AdcRegs.ADCSOCFLG1.bit.SOC1 == 1 ){}
  208. Sum += AdcResult.ADCRESULT15;
  209. index+=16;
  210. } // end data collection
  211. //Disable ADCINT1 and ADCINT2 to STOP the ping-pong sampling
  212. AdcRegs.INTSEL1N2.bit.INT1E = 0;
  213. AdcRegs.INTSEL1N2.bit.INT2E = 0;
  214. while(AdcRegs.ADCSOCFLG1.all != 0){} // Wait for any pending SOCs to complete
  215. // Clear any pending interrupts
  216. AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
  217. AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;
  218. AdcRegs.ADCINTOVFCLR.bit.ADCINT1 = 1;
  219. AdcRegs.ADCINTOVFCLR.bit.ADCINT2 = 1;
  220. //reset RR pointer to 32, so that next SOC is SOC0
  221. AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 1;
  222. while( AdcRegs.SOCPRICTL.bit.SOCPRIORITY != 1 );
  223. AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 0;
  224. while( AdcRegs.SOCPRICTL.bit.SOCPRIORITY != 0 );
  225. Mean = Sum / SampleSize; //Calculate average ADC sample value
  226. return Mean; //return the average
  227. }//end AdcConversion
  228. //===========================================================================
  229. // End of file.
  230. //===========================================================================