You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

101 lines
3.0 KiB

  1. #include "config.h"
  2. #include "timer.h"
  3. /* Setup a 16-bit timer to overflow at the specified frequency
  4. timer = 1-9
  5. freq = Hz, or 0 to disable the timer.
  6. interrupt = 1 to enable interrupt, 0 to disable
  7. */
  8. int timer_setup_16bit(int timer, uint32_t freq, int ie)
  9. {
  10. uint32_t period;
  11. uint16_t prescale;
  12. if (timer < 1 || timer > 9)
  13. return -1;
  14. if (freq == 0) {
  15. switch(timer) {
  16. case 1: T1CONbits.TON = 0; return 0;
  17. case 2: T2CONbits.TON = 0; return 0;
  18. case 3: T3CONbits.TON = 0; return 0;
  19. case 4: T4CONbits.TON = 0; return 0;
  20. case 5: T5CONbits.TON = 0; return 0;
  21. case 6: T6CONbits.TON = 0; return 0;
  22. case 7: T7CONbits.TON = 0; return 0;
  23. case 8: T8CONbits.TON = 0; return 0;
  24. case 9: T9CONbits.TON = 0; return 0;
  25. }
  26. }
  27. /* Figure out timer prescaler and period values. Max period
  28. is 65535 (PRx = 65534) so we can still attain 100% duty
  29. cycle when using a timer for PWM. */
  30. if ((period = FCY / (freq * 1L)) <= 65535)
  31. prescale = 0;
  32. else if ((period = FCY / (freq * 8L)) <= 65535)
  33. prescale = 1;
  34. else if ((period = FCY / (freq * 64L)) <= 65535)
  35. prescale = 2;
  36. else if ((period = FCY / (freq * 256L)) <= 65535)
  37. prescale = 3;
  38. else
  39. prescale = 3, period = 65535;
  40. if (period > 0)
  41. period -= 1;
  42. switch (timer) {
  43. #define __timer_setup_case(x) \
  44. case x: \
  45. T##x##CONbits.TON = 0; \
  46. T##x##CONbits.TCKPS = prescale; \
  47. PR##x = period; \
  48. T##x##CONbits.TON = 1; \
  49. break
  50. __timer_setup_case(1);
  51. __timer_setup_case(2);
  52. __timer_setup_case(3);
  53. __timer_setup_case(4);
  54. __timer_setup_case(5);
  55. __timer_setup_case(6);
  56. __timer_setup_case(7);
  57. __timer_setup_case(8);
  58. __timer_setup_case(9);
  59. #undef __timer_setup_case
  60. }
  61. /* Enable interrupt if requested */
  62. timer_clear_txif(timer);
  63. switch (timer) {
  64. case 1: IEC0bits.T1IE = ie; break;
  65. case 2: IEC0bits.T2IE = ie; break;
  66. case 3: IEC0bits.T3IE = ie; break;
  67. case 4: IEC1bits.T4IE = ie; break;
  68. case 5: IEC1bits.T5IE = ie; break;
  69. case 6: IEC2bits.T6IE = ie; break;
  70. case 7: IEC3bits.T7IE = ie; break;
  71. case 8: IEC3bits.T8IE = ie; break;
  72. case 9: IEC3bits.T9IE = ie; break;
  73. }
  74. return 0;
  75. }
  76. /* sleep for between "ms" and "ms+1" milliseconds */
  77. void msleep(int ms)
  78. {
  79. static int initialized = 0;
  80. if (!initialized) {
  81. timer_setup_16bit(1, 1000, 0);
  82. initialized = 1;
  83. }
  84. /* Very basic, assumes timer1 is set up at 1 khz */
  85. while (ms-- >= 0) {
  86. IFS0bits.T1IF = 0;
  87. while(IFS0bits.T1IF == 0)
  88. continue;
  89. }
  90. }