Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

266 linhas
8.2 KiB

  1. /*******************************************************************************
  2. * *
  3. * Copyright 2012 Rheinmetall Canada Inc. *
  4. * *
  5. * No part of this document may be reproduced, stored in *
  6. * a retrieval system, or transmitted, in any form or by any means, *
  7. * electronic, mechanical, photocopying, recording, or otherwise, *
  8. * without the prior written permission of Rheinmetall Canada Inc. *
  9. * *
  10. *******************************************************************************/
  11. /*
  12. Description:
  13. This is a template file for standard C header file.
  14. */
  15. /* ************************************************************************** */
  16. /* Revision:
  17. ### 20120521 JFM
  18. Original version.
  19. ### YYYYMMDD Initial, Bug Identification
  20. Change description.
  21. */
  22. /* ************************************************************************** */
  23. /* Includes */
  24. #include "define.h"
  25. #include "ADC.h"
  26. #include "HallAcquisition.h"
  27. #include "digitalio.h"
  28. #include "PAStatus.h"
  29. /* Globals */
  30. unsigned int guiADCMode;
  31. unsigned short egADCMotPhaseA;
  32. unsigned short egADCMotPhaseB;
  33. unsigned short egADCMotPhaseC;
  34. /* Implementation */
  35. //----------------------------------------------------------------------------
  36. void InitADC(void)
  37. {
  38. //At boot, init ADC in normal mode...
  39. guiADCMode = ADC_NORMAL_MODE;
  40. //configure input pins as analog inputs.
  41. TRISBbits.TRISB3 = 1;
  42. AD1PCFGbits.PCFG3 = 0;
  43. TRISBbits.TRISB4 = 1;
  44. AD1PCFGbits.PCFG4 = 0;
  45. TRISBbits.TRISB5 = 1;
  46. AD1PCFGbits.PCFG5 = 0;
  47. TRISBbits.TRISB8 = 1;
  48. AD1PCFGbits.PCFG8 = 0;
  49. TRISBbits.TRISB9 = 1;
  50. AD1PCFGbits.PCFG9 = 0;
  51. TRISBbits.TRISB11 = 1;
  52. AD1PCFGbits.PCFG11 = 0;
  53. TRISBbits.TRISB12 = 1;
  54. AD1PCFGbits.PCFG12 = 0;
  55. TRISBbits.TRISB13 = 1;
  56. AD1PCFGbits.PCFG13 = 0;
  57. AD1CON1 = 0;
  58. AD1CON2 = 0;
  59. AD1CON3 = 0;
  60. //configure output format (unsigned int 16 bits)
  61. AD1CON1bits.FORM = 0b000;
  62. //configure clock source and prescaling
  63. AD1CON3bits.ADRC = 0; //Use Peripheral clock
  64. AD1CON3bits.ADCS = 4; //Acording to datasheet TAD must be min 83.33ns --> minimal prescaler applied to TPBclk = 8 --> Conversion time ~= 100ns
  65. //AD1CON3bits.SAMC = 1; //Used in automatic sampling mode (scan mode). Shall be augmented if results are not accurate. See datasheet.
  66. AD1CON3bits.SAMC = 30; //Used in automatic sampling mode (scan mode). Shall be augmented if results are not accurate. See datasheet.
  67. }
  68. //----------------------------------------------------------------------------
  69. //----------------------------------------------------------------------------
  70. int ADCEnterHallACQMode(void)
  71. {
  72. //configure ADC module
  73. AD1CON1bits.ON = 0; //stop ADC to reconfigure.
  74. IEC1bits.AD1IE = 0; //disable ADC interrupt for now
  75. AD1CHS = 0; //Reset channel source since input source is controlled by hardware in scan mode.
  76. AD1CON2 = 0;
  77. AD1CSSL = 0;
  78. AD1CON1bits.SSRC = 0b111; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
  79. // AD1CON1bits.SSRC = 0b000; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
  80. AD1CON1bits.CLRASAM = 1;
  81. AD1CON1bits.ASAM = 1;
  82. //configure scan mode
  83. AD1CON2bits.CSCNA = 1; //enable scan mode
  84. AD1CON2bits.SMPI = 2; //Generate interrupt after the 3rd conversion.
  85. AD1CSSLbits.CSSL11= 1; //select Phase A input in scan sequence
  86. AD1CSSLbits.CSSL12= 1; //select Phase B input in scan sequence
  87. AD1CSSLbits.CSSL13= 1; //select Phase C input in scan sequence
  88. AD1CON1bits.SAMP = 1 ;
  89. IPC6bits.AD1IP = 5;
  90. IPC6bits.AD1IS = 3;
  91. IFS1bits.AD1IF = 0;
  92. IEC1bits.AD1IE = 1; //enable ADC interrupt
  93. AD1CON1bits.ON = 1; //enable ADC.
  94. guiADCMode = ADC_HALL_ACQ_MODE;
  95. return 1;
  96. }
  97. //----------------------------------------------------------------------------
  98. //----------------------------------------------------------------------------
  99. int ADCEnterTracesMode(void)
  100. {
  101. //trick to reuse code but force the good mode :)
  102. ADCEnterHallACQMode();
  103. guiADCMode = ADC_TRACE_MODE;
  104. return 1;
  105. }
  106. //----------------------------------------------------------------------------
  107. //----------------------------------------------------------------------------
  108. int ADCEnterCBITMode(void)
  109. {
  110. //configure ADC module
  111. AD1CON1bits.ON = 0; //stop ADC to reconfigure.
  112. IEC1bits.AD1IE = 0; //disable ADC interrupt for now
  113. AD1CHS = 0; //Reset channel source since input source is controlled by hardware in scan mode.
  114. AD1CON2 = 0;
  115. AD1CSSL = 0;
  116. AD1CON1bits.SSRC = 0b111; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
  117. // AD1CON1bits.SSRC = 0b000; //manual conversion start. Clearing SAMP starts conversion. See AD1CON3bits.SAMC for sampling time.
  118. AD1CON1bits.CLRASAM = 1;
  119. AD1CON1bits.ASAM = 1;
  120. //configure scan mode
  121. AD1CON2bits.CSCNA = 1; //enable scan mode
  122. AD1CON2bits.SMPI = 4; //Generate interrupt after the 5th conversion.
  123. AD1CSSLbits.CSSL3= 1; //select Vref input in scan sequence
  124. AD1CSSLbits.CSSL4= 1; //select 5V input in scan sequence
  125. AD1CSSLbits.CSSL5= 1; //select 3.3V input in scan sequence
  126. AD1CSSLbits.CSSL8= 1; //select Motor Thermistor input in scan sequence
  127. AD1CSSLbits.CSSL9= 1; //select Drive Thermistor input in scan sequence
  128. AD1CON1bits.SAMP = 1;
  129. IPC6bits.AD1IP = 5;
  130. IPC6bits.AD1IS = 3;
  131. IFS1bits.AD1IF = 0;
  132. IEC1bits.AD1IE = 1; //enable ADC interrupt
  133. AD1CON1bits.ON = 1; //enable ADC.
  134. guiADCMode = ADC_CBIT_MODE;
  135. return 1;
  136. }
  137. //----------------------------------------------------------------------------
  138. //----------------------------------------------------------------------------
  139. // Starts acquistion and conversion of the 3 phases. The 3 inputs are scanned
  140. // automatically by hardware and an interrupt is triggered when finished.
  141. //
  142. int ADCStartHallACQConversion(void)
  143. {
  144. AD1CON1bits.ASAM = 1;
  145. AD1CON1bits.SAMP = 1; //start sampling and start conversion. Interrupt will be generated when data is ready
  146. return 1;
  147. }
  148. //----------------------------------------------------------------------------
  149. //----------------------------------------------------------------------------
  150. int ADCStartTracesConversion(void)
  151. {
  152. AD1CON1bits.ASAM = 1;
  153. AD1CON1bits.SAMP = 1; //start sampling and start conversion. Interrupt will be generated when data is ready
  154. return 1;
  155. }
  156. //----------------------------------------------------------------------------
  157. //----------------------------------------------------------------------------
  158. int ADCStartCBITConversion(void)
  159. {
  160. if(guiADCMode == ADC_CBIT_MODE)
  161. {
  162. AD1CON1bits.ASAM = 1;
  163. AD1CON1bits.SAMP = 1; //start sampling and start conversion. Interrupt will be generated when data is ready
  164. return 1;
  165. }
  166. return 0;
  167. }
  168. //----------------------------------------------------------------------------
  169. //----------------------------------------------------------------------------
  170. int ADCStopConversion(void)
  171. {
  172. return 1;
  173. }
  174. //----------------------------------------------------------------------------
  175. int ADCGetMode(void)
  176. {
  177. return guiADCMode;
  178. }
  179. //----------------------------------------------------------------------------
  180. void __ISR(_ADC_VECTOR, ipl5) ADCInterrupt(void)
  181. {
  182. switch(guiADCMode)
  183. {
  184. case ADC_NORMAL_MODE:
  185. {
  186. break;
  187. }
  188. case ADC_CBIT_MODE:
  189. {
  190. estPAStatus.gusVoltageVref = ADC1BUF0;
  191. estPAStatus.gusVoltage5V = ADC1BUF1;
  192. estPAStatus.gusVoltage33V = ADC1BUF2;
  193. estPAStatus.gusVoltageThermMot = ADC1BUF3;
  194. estPAStatus.gusVoltageThermDrv = ADC1BUF4;
  195. estPAStatus.IsDataReady = 1;
  196. break;
  197. }
  198. case ADC_TRACE_MODE:
  199. {
  200. egADCMotPhaseA = ADC1BUF0;
  201. egADCMotPhaseB = ADC1BUF1;
  202. egADCMotPhaseC = ADC1BUF2;
  203. break;
  204. }
  205. case ADC_HALL_ACQ_MODE:
  206. {
  207. //Update data structure.
  208. if(gpstHallAcqDataPtr != 0 && gpstHallAcqDataPtr <= gpstHallAcqDataPtrEND)
  209. {
  210. gpstHallAcqDataPtr->MotPhaseA = ADC1BUF0;
  211. gpstHallAcqDataPtr->MotPhaseB = ADC1BUF1;
  212. gpstHallAcqDataPtr->MotPhaseC = ADC1BUF2;
  213. gpstHallAcqDataPtr->AnalogDataUpToDate = 1;
  214. }
  215. break;
  216. }
  217. }
  218. IFS1bits.AD1IF = 0;
  219. }
  220. //----------------------------------------------------------------------------
  221. //EOF