blob: 91915bfaf39a251601ff14d75e85e160e2ccde8a [file] [log] [blame]
Comran Morshed33ad1692015-12-06 18:53:02 +00001#ifndef FRC971_WPILIB_LPD8806_H_
2#define FRC971_WPILIB_LPD8806_H_
3
4#include <memory>
5#include <atomic>
6
John Park33858a32018-09-28 23:05:48 -07007#include "aos/mutex/mutex.h"
Comran Morshed33ad1692015-12-06 18:53:02 +00008
9#include "SPI.h"
Brian Silvermancee260a2015-12-24 16:27:51 -080010#undef ERROR
Comran Morshed33ad1692015-12-06 18:53:02 +000011
12namespace frc971 {
13namespace wpilib {
14
15// Handles sending out colors to a string of LPD8806 LED drivers with a chip to
16// gate the clock+data lines attached to SPI CS1.
17//
18// This is currently implemented by sending data for an entire 64 LED strip
19// right after receiving a gyro message to avoid interfering with the SPI
20// transactions for the gyro.
21//
22// This is designed to be passed into ::std::thread's constructor so it will run
23// as a separate thread.
24class LPD8806 {
25 public:
26 // chips is the number of actual chips in the string. There will be twice this
27 // many LEDs.
28 LPD8806(int chips);
29
30 // For ::std::thread to call.
31 //
32 // Loops until Quit() is called writing values out.
33 void operator()();
34
35 void Quit() { run_ = false; }
36
37 int chips() const { return chips_; }
38
39 // Sets the color to be sent out next refresh cycle for a given LED.
40 // red, green, and blue are 0-1 (inclusive).
41 void SetColor(int led, uint32_t hex_color);
42
43 private:
44 struct LED {
45 uint8_t green;
46 uint8_t red;
47 uint8_t blue;
48 };
49
50 enum Type { GREEN, RED, BLUE };
51
52 static_assert(sizeof(LED[4]) == 12, "LED needs to pack into arrays nicely");
53
54 uint8_t TranslateColor(uint32_t hex_color, Type type);
55
56 const int chips_;
57 int next_led_to_send_ = 0;
58
59 ::std::unique_ptr<LED[]> data_;
60 ::aos::Mutex data_mutex_;
61
62 ::std::unique_ptr<SPI> spi_;
63
64 ::std::atomic<bool> run_{true};
65};
66
67} // namespace wpilib
68} // namespace frc971
69
70#endif // FRC971_WPILIB_LPD8806_H_