servo.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*********************************************************************
  2. *
  3. * Servo library for Fraise pic18f device
  4. * Uses TIMER5 !
  5. *
  6. *********************************************************************
  7. * Author Date Comment
  8. *********************************************************************
  9. * Antoine Rousseau jan 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 <servo.h>
  27. static unsigned char *NextPort,*Port[8];
  28. static unsigned char NextMask,Mask[8];
  29. static unsigned int Val[8];
  30. static unsigned char Count=0;
  31. t_delay servoDelay;
  32. #define SERVO_LOOP_TIME 18000 //micros
  33. // Timer macros
  34. #define TIMER 5
  35. //determine PIE/PIR/IPR number
  36. #if TIMER<=2
  37. #define TIMERPNUM 1
  38. #elif TIMER==3
  39. #define TIMERPNUM 2
  40. #else
  41. #define TIMERPNUM 5
  42. #endif
  43. #define TIMER_ON_(Timer) T##Timer##CONbits.TMR##Timer##ON
  44. #define TIMER_ON CALL_FUN(TIMER_ON_,TIMER)
  45. #define TIMER_IF_(Timer,TimerPNum) PIR##TimerPNum##bits.TMR##Timer##IF
  46. #define TIMER_IF CALL_FUN2(TIMER_IF_,TIMER,TIMERPNUM)
  47. #define TIMER_H_(Timer) TMR##Timer##H
  48. #define TIMER_H CALL_FUN(TIMER_H_,TIMER)
  49. #define TIMER_L_(Timer) TMR##Timer##L
  50. #define TIMER_L CALL_FUN(TIMER_L_,TIMER)
  51. #define TIMER_INIT_T(Timer,TimerPNum) \
  52. T##Timer##CON=0; \
  53. T##Timer##CONbits.T##Timer##CKPS0=1; /* prescaler 2 (->8MHz at 64MHz) */\
  54. T##Timer##CONbits.T##Timer##RD16=1; /* 16bits */\
  55. PIE##TimerPNum##bits.TMR##Timer##IE=1; /* enable timer interrupt */\
  56. IPR##TimerPNum##bits.TMR##Timer##IP=1; /* high priority */\
  57. PIR##TimerPNum##bits.TMR##Timer##IF=0;
  58. #define TIMER_INIT CALL_FUN2(TIMER_INIT_T,TIMER,TIMERPNUM)
  59. void servoInit()
  60. {
  61. unsigned char i;
  62. TIMER_INIT;
  63. for(i=0;i<8;i++) {
  64. Port[i]=NULL;
  65. Val[i]=0;
  66. }
  67. Count=0;
  68. delayStart(servoDelay, SERVO_LOOP_TIME);
  69. }
  70. void servoSetPort(unsigned char num,unsigned char *port,unsigned char mask)
  71. {
  72. Port[num]=port;
  73. Mask[num]=mask;
  74. Val[num]=0;
  75. }
  76. void servoSet(unsigned char num,unsigned int val)
  77. {
  78. Val[num]=val;
  79. }
  80. void servoRewind(void)
  81. {
  82. Count=0;
  83. }
  84. void servoService(void)
  85. {
  86. unsigned int val;
  87. if(delayFinished(servoDelay)) {
  88. servoRewind();
  89. delayStart(servoDelay, SERVO_LOOP_TIME);
  90. }
  91. if(Count>7) return;
  92. if(TIMER_ON) return;
  93. if(Val[Count]==0) {
  94. Count++;
  95. return;
  96. }
  97. NextPort=Port[Count];
  98. NextMask=Mask[Count];
  99. val=~Val[Count];
  100. TIMER_H=val>>8;
  101. TIMER_L=val&255;
  102. TIMER_IF=0;
  103. __critical {
  104. //*NextPort=(*NextPort)|NextMask;
  105. FSR0L=(unsigned char)NextPort;
  106. FSR0H=(unsigned int)NextPort>>8;
  107. INDF0|=NextMask;
  108. TIMER_ON=1;
  109. }
  110. Count++;
  111. }
  112. void servoHighInterrupt(void)
  113. {
  114. if(!TIMER_IF) return;
  115. /* *NextPort&=(~NextMask); */
  116. FSR0L=(unsigned char)NextPort;
  117. FSR0H=(unsigned int)NextPort>>8;
  118. INDF0&=(~NextMask);
  119. TIMER_ON=0;
  120. TIMER_IF=0;
  121. }
  122. void servoReceive()
  123. {
  124. unsigned char c, c2;
  125. unsigned int i = 0;
  126. c=fraiseGetChar();
  127. if(c == 254) {
  128. fraiseSendCopy();
  129. c2=fraiseGetChar();
  130. if(c2 < 8) printf("%d %d\n",c2,Val[c2]);
  131. }
  132. else if(c < 8) {
  133. i = fraiseGetChar()<<8;
  134. i += fraiseGetChar();
  135. Val[c]=i;
  136. }
  137. }