Naze32 clone with Frysky receiver
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

cppm.c 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Combined-PPM signal generator
  3. *
  4. * The whole CPPM pulse should be 20ms long.
  5. * It contains 8 channels with 2ms each, followed
  6. * by 4ms of silence. One channel pulse varies between
  7. * 1 and 2 ms. They are seperated with a very short low
  8. * pulse of about 0.1ms.
  9. *
  10. * 20.000us
  11. * - 8 * 2.000us = 16.000us
  12. * - 9 * 100us = 900us
  13. * = 3.100us
  14. *
  15. * 1 2 3 4 5 6 7 8
  16. * ___ ___ ___ ___ ___ ___ ___ ___ __________
  17. * | | | | | | | | | | | | | | | | | | |
  18. * | | | | | | | | | | | | | | | | | | |
  19. * | | | | | | | | | | | | | | | | | | |
  20. * |_| |_| |_| |_| |_| |_| |_| |_| |_| |
  21. *
  22. * States:
  23. * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
  24. */
  25. #include <avr/io.h>
  26. #include <avr/interrupt.h>
  27. #include "cppm.h"
  28. #define MAX_STATES 17
  29. #define CHANNELS 8
  30. #define WHOLE_PULSE_WIDTH 20000
  31. #define PULSE_WIDTH 2000
  32. #define MAX_PULSE_WIDTH (CHANNELS * PULSE_WIDTH) // 16.000
  33. #define PULSE_LOW 100
  34. #define PULSE_LOW_SUM ((CHANNELS + 1) * PULSE_LOW) // 900
  35. #define MIN_WAIT (WHOLE_PULSE_WIDTH - MAX_PULSE_WIDTH - PULSE_LOW_SUM) // 3100
  36. #define TIME_AFTER_OVERFLOW 128
  37. #define TIME_MULTIPLIER 2
  38. volatile uint16_t cppmData[CHANNELS] = { 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500 };
  39. volatile uint16_t delaySum = 0;
  40. volatile uint8_t state = 0;
  41. volatile uint16_t triggerTimeRemaining = 0;
  42. #define NONE 0
  43. #define COMPARE_MATCH 1
  44. #define OVERFLOW 2
  45. volatile uint8_t triggerState = NONE;
  46. static void triggerIn(uint16_t us);
  47. static void nextState(void);
  48. void cppmInit(void) {
  49. // Set pin to output mode
  50. CPPM_DDR |= (1 << CPPM_PIN);
  51. // Start with a low pulse
  52. CPPM_PORT &= ~(1 << CPPM_PIN);
  53. TCCR0B |= (1 << CS01); // Prescaler: 8
  54. TIMSK |= (1 << TOIE0) | (1 << OCIE0A); // Enable Overflow and Compare Match Interrupt
  55. OCR0A = 0;
  56. state = 0;
  57. delaySum = MIN_WAIT;
  58. triggerIn(PULSE_LOW);
  59. }
  60. static void triggerIn(uint16_t us) {
  61. TCNT0 = 0; // Reset Timer
  62. if (us <= (TIME_AFTER_OVERFLOW - 1)) {
  63. triggerState = COMPARE_MATCH;
  64. OCR0A = us * TIME_MULTIPLIER;
  65. } else {
  66. triggerState = OVERFLOW;
  67. triggerTimeRemaining = us - TIME_AFTER_OVERFLOW;
  68. }
  69. }
  70. static void nextState(void) {
  71. state++;
  72. if (state > MAX_STATES) {
  73. state = 0;
  74. delaySum = MIN_WAIT;
  75. }
  76. if ((state % 2) == 0) {
  77. // pulse pause
  78. CPPM_PORT &= ~(1 << CPPM_PIN);
  79. triggerIn(PULSE_LOW);
  80. } else {
  81. CPPM_PORT |= (1 << CPPM_PIN);
  82. if (state <= 15) {
  83. // normal ppm pulse
  84. uint8_t index = state / 2;
  85. triggerIn(cppmData[index]);
  86. delaySum += PULSE_WIDTH - cppmData[index];
  87. } else {
  88. // sync pulse
  89. triggerIn(delaySum);
  90. }
  91. }
  92. }
  93. ISR(TIM0_OVF_vect) {
  94. if (triggerState == OVERFLOW) {
  95. if (triggerTimeRemaining == 0) {
  96. triggerState = NONE;
  97. nextState();
  98. } else {
  99. triggerIn(triggerTimeRemaining);
  100. }
  101. }
  102. }
  103. ISR(TIM0_COMPA_vect) {
  104. if (triggerState == COMPARE_MATCH) {
  105. triggerState = NONE;
  106. nextState();
  107. }
  108. }