analog.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /*********************************************************************
  2. *
  3. * Analog library for Fraise pic18f device
  4. *
  5. *
  6. *********************************************************************
  7. * Author Date Comment
  8. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  9. * Antoine Rousseau march 2013 Original.
  10. ********************************************************************/
  11. /*
  12. # This program is free software; you can redistribute it and/or
  13. # modify it under the terms of the GNU General Public License
  14. # as published by the Free Software Foundation; either version 2
  15. # of the License, or (at your option) any later version.
  16. #
  17. # This program is distributed in the hope that it will be useful,
  18. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. # GNU General Public License for more details.
  21. # You should have received a copy of the GNU General Public License
  22. # along with this program; if not, write to the Free Software
  23. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  24. # MA 02110-1301, USA.
  25. */
  26. #include "analog.h"
  27. #define CHANNELS_GROUPS ((ANALOG_MAX_CHANNELS+7)/8)
  28. static int Value[ANALOG_MAX_CHANNELS];
  29. static int oldValue[ANALOG_MAX_CHANNELS];
  30. static int inValue[ANALOG_MAX_CHANNELS]; // input values
  31. static int Max[ANALOG_MAX_CHANNELS];
  32. static int Min[ANALOG_MAX_CHANNELS];
  33. static int Dist[ANALOG_MAX_CHANNELS]; // distance of oldValue from inValue
  34. static unsigned char Scaling=0; // 1 when scaling
  35. static unsigned char Selected[CHANNELS_GROUPS];
  36. static unsigned char HWChan[ANALOG_MAX_CHANNELS];
  37. static unsigned char Pins[ANALOG_MAX_CHANNELS];
  38. static int Threshold=ANALOG_THRESHOLD;
  39. static char Mode = AMODE_NUM;
  40. #define MINMAX_MARGIN ANALOG_MINMAX_MARGIN
  41. /*#define bitset(var,bitno) ((var) |= (1 << (bitno)))
  42. #define bitclr(var,bitno) ((var) &= ~(1 << (bitno)))
  43. #define bittst(var,bitno) (var & (1 << (bitno)))*/
  44. #define isSelected(num) (bittst(Selected[num>>3],num&7))
  45. void analogInit()
  46. {
  47. unsigned char i;
  48. for(i=0;i<CHANNELS_GROUPS;i++) {
  49. Selected[i]=0;
  50. }
  51. for(i=0;i<ANALOG_MAX_CHANNELS;i++) {
  52. Value[i]=0;
  53. inValue[i]=0;
  54. oldValue[i]=0;
  55. Min[i]=0;
  56. Max[i]=0x7FFF;
  57. Pins[i]=255;
  58. }
  59. ADCON2=0b10101111; //right justified, 12 AD, RC
  60. ADCON1=0; //0->Vdd
  61. ADCON0=1; //on, channel 0
  62. ADCON0bits.GO=1; // go !
  63. }
  64. void analogInitTouch(){
  65. CTMUCONH = 0x00;
  66. CTMUCONL = 0x90;
  67. CTMUICON = 0x03; //55uA
  68. CTMUCONHbits.CTMUEN = 1; //Enable CTMU
  69. }
  70. void analogSelectAdc(unsigned char chan,unsigned char hwchan )
  71. {
  72. bitset(Selected[chan>>3],chan&7);
  73. HWChan[chan]=hwchan;
  74. Pins[chan]=255;
  75. }
  76. void analogSelectAdcTouch(unsigned char chan,unsigned char hwchan, unsigned char *port, unsigned char bit)
  77. {
  78. bitset(Selected[chan>>3],chan&7);
  79. HWChan[chan]=hwchan;
  80. Pins[chan]=(((unsigned int)(port-&PORTA)&7)<<4) + (bit&7);
  81. }
  82. void analogDeselect(unsigned char chan)
  83. {
  84. bitclr(Selected[chan>>3],chan&7);
  85. }
  86. unsigned char analogService(void)
  87. {
  88. static unsigned char chan=0, conv=0;
  89. int v;
  90. unsigned char pin;
  91. if(ADCON0bits.GO) return chan;
  92. if(conv) {
  93. v = Value[chan];
  94. // v = oldv-oldv/N+ADres = ((ADres*N)+oldv*(N-1))/N : v = N*lowpass[N](ADres) N=2^ANALOG_FILTER
  95. pin = Pins[chan];
  96. if(pin != 255) {
  97. bitclr(*(&TRISA+(pin>>4)),pin&7);
  98. bitclr(*(&LATA+(pin>>4)),pin&7);
  99. }
  100. Value[chan] = v - (v>>ANALOG_FILTER) + ADRESL+(ADRESH<<8);
  101. if(Scaling == 1) {
  102. v = Value[chan];
  103. if(v < (Min[chan]-MINMAX_MARGIN)) Min[chan] = v+MINMAX_MARGIN;
  104. if(v > (Max[chan]+MINMAX_MARGIN)) Max[chan] = v-MINMAX_MARGIN;
  105. }
  106. conv=0;
  107. }
  108. chan++;
  109. if(chan >= ANALOG_MAX_CHANNELS) chan = 0;
  110. if(isSelected(chan)) {
  111. ADCON0=(HWChan[chan] << 2) + 1;
  112. pin = Pins[chan];
  113. if(pin != 255) {
  114. bitset(*(&TRISA+(pin>>4)),pin&7);// set channel to digital input
  115. bitset(*(__data unsigned char*)((int)&ANSELA + (pin>>4)),pin&7);// set channel to analog input
  116. CTMUCONHbits.IDISSEN = 1; // Drain any charge on the A/D circuit
  117. Nop(); Nop();
  118. CTMUCONHbits.IDISSEN = 0; // Stop discharge of A/D circuit
  119. CTMUCONLbits.EDG2STAT = 0; // Make sure edge2 is 0
  120. __critical{
  121. CTMUCONLbits.EDG1STAT = 1; // Set edge1 - Start Charge
  122. Nop(); Nop(); Nop(); Nop();
  123. Nop(); Nop(); Nop(); Nop();
  124. Nop(); Nop(); Nop(); Nop();
  125. Nop(); Nop(); Nop(); Nop();
  126. Nop(); Nop(); Nop(); Nop();
  127. CTMUCONLbits.EDG1STAT = 0; //Clear edge1 - Stop Charge
  128. }
  129. }
  130. ADCON0bits.GO = 1;
  131. conv = 1;
  132. }
  133. return chan;
  134. }
  135. char analogSend()
  136. {
  137. static unsigned char chan = 0;
  138. unsigned char loop = 0, count = 0, len = 0;
  139. int v, d;
  140. static unsigned char buf[13] = { 'B' }; //'B' + 3x4 chars
  141. while((count < 4) && (loop++ < ANALOG_MAX_CHANNELS)){
  142. chan++;
  143. if(chan >= ANALOG_MAX_CHANNELS) {
  144. chan = 0;
  145. }
  146. if(! isSelected(chan)) continue;
  147. v = Value[chan];
  148. if(Mode & AMODE_SCALE) { // scale :
  149. if(v < Min[chan]) v = 0;
  150. else if(v > Max[chan]) v = ANALOG_SCALED_MAX;
  151. else v = (unsigned int)(
  152. ((ANALOG_SCALED_MAX+1UL) * (v - Min[chan])) /
  153. (Max[chan] - Min[chan]) );
  154. if(v <= Threshold ) v = 0;
  155. else if(v >= (ANALOG_SCALED_MAX - Threshold))
  156. v = ANALOG_SCALED_MAX;
  157. }
  158. d = v - oldValue[chan];
  159. if(d < 0) d = -d;
  160. count++;
  161. if(d <= Threshold) continue;
  162. oldValue[chan] = v;
  163. if(Mode & AMODE_CROSS) {
  164. if(Dist[chan] != 0) {
  165. d = v - inValue[chan];
  166. if((d != 0) && ((d > 0) == (Dist[chan] > 0))) {
  167. Dist[chan] = d;
  168. continue;
  169. }
  170. else Dist[chan] = 0;
  171. }
  172. }
  173. if(Mode & AMODE_NUM) {
  174. if( !len ) buf[len++] = 'B';
  175. buf[len++] = chan + 100;
  176. buf[len++] = v >> 8;
  177. buf[len++] = v & 255;
  178. }
  179. else printf("C A %d %d\n",chan,v);
  180. }
  181. if((len != 0) && (Mode & AMODE_NUM)) {
  182. buf[len++] = '\n';
  183. fraiseSend(buf,len);
  184. }
  185. return count;
  186. }
  187. void analogSetMode(unsigned char mode) // scale : bit0 = scale_on ; bit1 = num_on(=text_off) ; bit2 = cross_inval
  188. {
  189. Mode = mode;
  190. }
  191. void analogSet(unsigned char chan, int val)
  192. {
  193. int d;
  194. inValue[chan] = val;
  195. d = oldValue[chan] - val;
  196. Dist[chan] = d;
  197. if(d < 0) d = -d;
  198. if(d < 3) d = 0;
  199. if(d == 0) Dist[chan] = 0;
  200. }
  201. int analogGet(unsigned char chan)
  202. {
  203. return Value[chan];
  204. }
  205. int analogGetDistance(unsigned char chan)
  206. {
  207. return Dist[chan];
  208. }
  209. void analogScaling(unsigned char scaling) // when scaling, min and max are updated each sample
  210. {
  211. unsigned char i;
  212. if(scaling==1) {
  213. for(i=0;i<ANALOG_MAX_CHANNELS;i++) {
  214. Min[i]=0x7FFF;
  215. Max[i]=0;
  216. }
  217. }
  218. Scaling=scaling;
  219. }
  220. #define EEDECLARE(x) \
  221. EEdeclareInt(&Max[x]); \
  222. EEdeclareInt(&Min[x])
  223. void analogDeclareEE()
  224. {
  225. #if ANALOG_MAX_CHANNELS > 0
  226. EEDECLARE(0);
  227. EEDECLARE(1);
  228. EEDECLARE(2);
  229. EEDECLARE(3);
  230. #endif
  231. #if ANALOG_MAX_CHANNELS > 4
  232. EEDECLARE(4);
  233. EEDECLARE(5);
  234. EEDECLARE(6);
  235. EEDECLARE(7);
  236. #endif
  237. #if ANALOG_MAX_CHANNELS > 8
  238. EEDECLARE(8);
  239. EEDECLARE(9);
  240. EEDECLARE(10);
  241. EEDECLARE(11);
  242. #endif
  243. #if ANALOG_MAX_CHANNELS > 12
  244. EEDECLARE(12);
  245. EEDECLARE(13);
  246. EEDECLARE(14);
  247. EEDECLARE(15);
  248. #endif
  249. }