PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

91 lines
3.2KB

  1. #include "IRremote.h"
  2. #include "IRremoteInt.h"
  3. //+=============================================================================
  4. void IRsend::sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz)
  5. {
  6. // Set IR carrier frequency
  7. enableIROut(hz);
  8. for (unsigned int i = 0; i < len; i++) {
  9. if (i & 1) space(buf[i]) ;
  10. else mark (buf[i]) ;
  11. }
  12. space(0); // Always end with the LED off
  13. }
  14. //+=============================================================================
  15. // Sends an IR mark for the specified number of microseconds.
  16. // The mark output is modulated at the PWM frequency.
  17. //
  18. void IRsend::mark (unsigned int time)
  19. {
  20. TIMER_ENABLE_PWM; // Enable pin 3 PWM output
  21. if (time > 0) custom_delay_usec(time);
  22. }
  23. //+=============================================================================
  24. // Leave pin off for time (given in microseconds)
  25. // Sends an IR space for the specified number of microseconds.
  26. // A space is no output, so the PWM output is disabled.
  27. //
  28. void IRsend::space (unsigned int time)
  29. {
  30. TIMER_DISABLE_PWM; // Disable pin 3 PWM output
  31. if (time > 0) IRsend::custom_delay_usec(time);
  32. }
  33. //+=============================================================================
  34. // Enables IR output. The khz value controls the modulation frequency in kilohertz.
  35. // The IR output will be on pin 3 (OC2B).
  36. // This routine is designed for 36-40KHz; if you use it for other values, it's up to you
  37. // to make sure it gives reasonable results. (Watch out for overflow / underflow / rounding.)
  38. // TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B
  39. // controlling the duty cycle.
  40. // There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A)
  41. // To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin.
  42. // A few hours staring at the ATmega documentation and this will all make sense.
  43. // See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details.
  44. //
  45. void IRsend::enableIROut (int khz)
  46. {
  47. // FIXME: implement ESP32 support, see IR_TIMER_USE_ESP32 in boarddefs.h
  48. #ifndef ESP32
  49. // Disable the Timer2 Interrupt (which is used for receiving IR)
  50. TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt
  51. pinMode(TIMER_PWM_PIN, OUTPUT);
  52. digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low
  53. // COM2A = 00: disconnect OC2A
  54. // COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted
  55. // WGM2 = 101: phase-correct PWM with OCRA as top
  56. // CS2 = 000: no prescaling
  57. // The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A.
  58. TIMER_CONFIG_KHZ(khz);
  59. #endif
  60. }
  61. //+=============================================================================
  62. // Custom delay function that circumvents Arduino's delayMicroseconds limit
  63. void IRsend::custom_delay_usec(unsigned long uSecs) {
  64. if (uSecs > 4) {
  65. unsigned long start = micros();
  66. unsigned long endMicros = start + uSecs - 4;
  67. if (endMicros < start) { // Check if overflow
  68. while ( micros() > start ) {} // wait until overflow
  69. }
  70. while ( micros() < endMicros ) {} // normal wait
  71. }
  72. //else {
  73. // __asm__("nop\n\t"); // must have or compiler optimizes out
  74. //}
  75. }