ser2neo: a serial port to NeoPixel ring bridge.

neopixel.cc 1.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // NeoPixel ring driver.
  2. //
  3. // Copyright 2015 Google Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. #include "neopixel.h"
  18. #include "serial.h"
  19. #include <avr/io.h>
  20. #include <avr/interrupt.h>
  21. #include <string.h>
  22. extern Serial serial;
  23. /// Initialise the hardware.
  24. void NeoPixel::init() {
  25. DDRB |= _BV(1);
  26. TCCR0A = _BV(WGM01) | _BV(WGM00) | _BV(COM0B1) | _BV(COM0B0);
  27. TCCR0B = _BV(WGM02) | _BV(CS00);
  28. static_assert(Reload > 15, "Inter-bit time is probably too short.");
  29. OCR0A = Reload;
  30. OCR0B = Low;
  31. }
  32. /// Set all the LEDs to off and restart at the first LED.
  33. void NeoPixel::clear() {
  34. p_ = bits_;
  35. memset(bits_, Low, sizeof(bits_));
  36. }
  37. /// Append a byte to the stream.
  38. void NeoPixel::append(uint8_t b) {
  39. if (p_ <= (bits_ + sizeof(bits_) - Tail - BitsPerColour)) {
  40. for (auto i = 0; i < BitsPerColour; i++) {
  41. *p_++ = (b & 0x80) ? High : Low;
  42. b <<= 1;
  43. }
  44. }
  45. }
  46. /// Write to the LEDs.
  47. void NeoPixel::write() {
  48. bits_[sizeof(bits_) - 1] = Stop;
  49. uint8_t *p = bits_;
  50. uint8_t *pend = bits_ + sizeof(bits_);
  51. cli();
  52. OCR0B = Stop;
  53. TIFR |= _BV(OCF0A);
  54. while (!(TIFR & _BV(OCF0A))) {
  55. }
  56. TIFR |= _BV(OCF0A);
  57. while (!(TIFR & _BV(OCF0A))) {
  58. }
  59. OCR0B = *p++;
  60. for (; p != pend; p++) {
  61. while (!(TIFR & _BV(OCF0A))) {
  62. }
  63. OCR0B = *p;
  64. TIFR |= _BV(OCF0A);
  65. }
  66. OCR0B = Stop;
  67. sei();
  68. }