Open Lighting Architecture  0.9.6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SPIOutput.h
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU Library General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15  *
16  * SPIOutput.h
17  * An RDM-controllable SPI device. Takes up to one universe of DMX.
18  * Copyright (C) 2013 Simon Newton
19  */
20 
21 #ifndef PLUGINS_SPI_SPIOUTPUT_H_
22 #define PLUGINS_SPI_SPIOUTPUT_H_
23 
24 #include <memory>
25 #include <string>
27 #include "ola/DmxBuffer.h"
29 #include "ola/rdm/UID.h"
30 #include "ola/stl/STLUtils.h"
31 #include "ola/rdm/ResponderOps.h"
32 #include "ola/rdm/ResponderPersonality.h"
34 
35 namespace ola {
36 namespace plugin {
37 namespace spi {
38 
40  public:
41  struct Options {
42  std::string device_label;
43  uint8_t pixel_count;
44  uint8_t output_number;
45 
46  explicit Options(uint8_t output_number, const std::string &spi_device_name)
47  : device_label("SPI Device - " + spi_device_name),
48  pixel_count(25), // For the https://www.adafruit.com/products/738
49  output_number(output_number) {
50  }
51  };
52 
53  SPIOutput(const ola::rdm::UID &uid,
54  class SPIBackendInterface *backend,
55  const Options &options);
56  ~SPIOutput();
57 
58  std::string GetDeviceLabel() const;
59  bool SetDeviceLabel(const std::string &device_label);
60  uint8_t GetPersonality() const;
61  bool SetPersonality(uint16_t personality);
62  uint16_t GetStartAddress() const;
63  bool SetStartAddress(uint16_t start_address);
64  unsigned int PixelCount() const { return m_pixel_count; }
65 
66  std::string Description() const;
67  bool WriteDMX(const DmxBuffer &buffer);
68 
72  ola::rdm::RDMCallback *callback);
73 
74  private:
78  class RDMOps : public ola::rdm::ResponderOps<SPIOutput> {
79  public:
80  static RDMOps *Instance() {
81  if (!instance)
82  instance = new RDMOps();
83  return instance;
84  }
85 
86  private:
87  RDMOps() : ola::rdm::ResponderOps<SPIOutput>(PARAM_HANDLERS) {}
88 
89  static RDMOps *instance;
90  };
91 
92  class SPIBackendInterface *m_backend;
93  const uint8_t m_output_number;
94  std::string m_spi_device_name;
95  const ola::rdm::UID m_uid;
96  const unsigned int m_pixel_count;
97  std::string m_device_label;
98  uint16_t m_start_address; // starts from 1
99  bool m_identify_mode;
100  std::auto_ptr<ola::rdm::PersonalityCollection> m_personality_collection;
101  std::auto_ptr<ola::rdm::PersonalityManager> m_personality_manager;
102  ola::rdm::Sensors m_sensors;
103  std::auto_ptr<ola::rdm::NetworkManagerInterface> m_network_manager;
104 
105  // DMX methods
106  bool InternalWriteDMX(const DmxBuffer &buffer);
107 
108  void IndividualWS2801Control(const DmxBuffer &buffer);
109  void CombinedWS2801Control(const DmxBuffer &buffer);
110  void IndividualLPD8806Control(const DmxBuffer &buffer);
111  void CombinedLPD8806Control(const DmxBuffer &buffer);
112  void IndividualP9813Control(const DmxBuffer &buffer);
113  void CombinedP9813Control(const DmxBuffer &buffer);
114  void IndividualAPA102Control(const DmxBuffer &buffer);
115  void CombinedAPA102Control(const DmxBuffer &buffer);
116 
117  unsigned int LPD8806BufferSize() const;
118  void WriteSPIData(const uint8_t *data, unsigned int length);
119 
120  // RDM methods
121  ola::rdm::RDMResponse *GetDeviceInfo(
122  const ola::rdm::RDMRequest *request);
123  ola::rdm::RDMResponse *GetProductDetailList(
124  const ola::rdm::RDMRequest *request);
125  ola::rdm::RDMResponse *GetDeviceModelDescription(
126  const ola::rdm::RDMRequest *request);
127  ola::rdm::RDMResponse *GetManufacturerLabel(
128  const ola::rdm::RDMRequest *request);
129  ola::rdm::RDMResponse *GetDeviceLabel(
130  const ola::rdm::RDMRequest *request);
131  ola::rdm::RDMResponse *SetDeviceLabel(
132  const ola::rdm::RDMRequest *request);
133  ola::rdm::RDMResponse *GetSoftwareVersionLabel(
134  const ola::rdm::RDMRequest *request);
135  ola::rdm::RDMResponse *GetDmxPersonality(
136  const ola::rdm::RDMRequest *request);
137  ola::rdm::RDMResponse *SetDmxPersonality(
138  const ola::rdm::RDMRequest *request);
139  ola::rdm::RDMResponse *GetPersonalityDescription(
140  const ola::rdm::RDMRequest *request);
141  ola::rdm::RDMResponse *GetDmxStartAddress(
142  const ola::rdm::RDMRequest *request);
143  ola::rdm::RDMResponse *SetDmxStartAddress(
144  const ola::rdm::RDMRequest *request);
145  ola::rdm::RDMResponse *GetIdentify(
146  const ola::rdm::RDMRequest *request);
147  ola::rdm::RDMResponse *SetIdentify(
148  const ola::rdm::RDMRequest *request);
149  ola::rdm::RDMResponse *GetSensorDefinition(
150  const ola::rdm::RDMRequest *request);
151  ola::rdm::RDMResponse *GetSensorValue(
152  const ola::rdm::RDMRequest *request);
153  ola::rdm::RDMResponse *SetSensorValue(
154  const ola::rdm::RDMRequest *request);
155  ola::rdm::RDMResponse *RecordSensor(
156  const ola::rdm::RDMRequest *request);
157  ola::rdm::RDMResponse *GetListInterfaces(
158  const ola::rdm::RDMRequest *request);
159  ola::rdm::RDMResponse *GetInterfaceLabel(
160  const ola::rdm::RDMRequest *request);
161  ola::rdm::RDMResponse *GetInterfaceHardwareAddressType1(
162  const ola::rdm::RDMRequest *request);
163  ola::rdm::RDMResponse *GetIPV4CurrentAddress(
164  const ola::rdm::RDMRequest *request);
165  ola::rdm::RDMResponse *GetIPV4DefaultRoute(
166  const ola::rdm::RDMRequest *request);
167  ola::rdm::RDMResponse *GetDNSHostname(
168  const ola::rdm::RDMRequest *request);
169  ola::rdm::RDMResponse *GetDNSDomainName(
170  const ola::rdm::RDMRequest *request);
171  ola::rdm::RDMResponse *GetDNSNameServer(
172  const ola::rdm::RDMRequest *request);
173 
174  // Helpers
175  uint8_t P9813CreateFlag(uint8_t red, uint8_t green, uint8_t blue);
176  static uint8_t CalculateAPA102LatchBytes(uint16_t pixel_count);
177 
178  static const uint8_t SPI_MODE;
179  static const uint8_t SPI_BITS_PER_WORD;
180  static const uint16_t SPI_DELAY;
181  static const uint32_t SPI_SPEED;
182  static const uint16_t WS2801_SLOTS_PER_PIXEL;
183  static const uint16_t LPD8806_SLOTS_PER_PIXEL;
184  static const uint16_t P9813_SLOTS_PER_PIXEL;
185  static const uint16_t P9813_SPI_BYTES_PER_PIXEL;
186  static const uint16_t APA102_SLOTS_PER_PIXEL;
187  static const uint16_t APA102_SPI_BYTES_PER_PIXEL;
188  static const uint16_t APA102_START_FRAME_BYTES;
189 
191  PARAM_HANDLERS[];
192 };
193 } // namespace spi
194 } // namespace plugin
195 } // namespace ola
196 #endif // PLUGINS_SPI_SPIOUTPUT_H_