Open Lighting Architecture  0.9.4
 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>
26 #include "ola/DmxBuffer.h"
28 #include "ola/rdm/UID.h"
29 #include "ola/stl/STLUtils.h"
30 #include "ola/rdm/ResponderOps.h"
31 #include "ola/rdm/ResponderPersonality.h"
33 
34 namespace ola {
35 namespace plugin {
36 namespace spi {
37 
39  public:
40  struct Options {
41  std::string device_label;
42  uint8_t pixel_count;
43  uint8_t output_number;
44 
45  explicit Options(uint8_t output_number, const std::string &spi_device_name)
46  : device_label("SPI Device - " + spi_device_name),
47  pixel_count(25), // For the https://www.adafruit.com/products/738
48  output_number(output_number) {
49  }
50  };
51 
52  SPIOutput(const ola::rdm::UID &uid,
53  class SPIBackendInterface *backend,
54  const Options &options);
55  ~SPIOutput();
56 
57  std::string GetDeviceLabel() const;
58  bool SetDeviceLabel(const std::string &device_label);
59  uint8_t GetPersonality() const;
60  bool SetPersonality(uint16_t personality);
61  uint16_t GetStartAddress() const;
62  bool SetStartAddress(uint16_t start_address);
63  unsigned int PixelCount() const { return m_pixel_count; }
64 
65  std::string Description() const;
66  bool WriteDMX(const DmxBuffer &buffer);
67 
69  void RunIncrementalDiscovery(ola::rdm::RDMDiscoveryCallback *callback);
70  void SendRDMRequest(const ola::rdm::RDMRequest *request,
71  ola::rdm::RDMCallback *callback);
72 
73  private:
77  class RDMOps : public ola::rdm::ResponderOps<SPIOutput> {
78  public:
79  static RDMOps *Instance() {
80  if (!instance)
81  instance = new RDMOps();
82  return instance;
83  }
84 
85  private:
86  RDMOps() : ola::rdm::ResponderOps<SPIOutput>(PARAM_HANDLERS) {}
87 
88  static RDMOps *instance;
89  };
90 
91  class SPIBackendInterface *m_backend;
92  const uint8_t m_output_number;
93  std::string m_spi_device_name;
94  const ola::rdm::UID m_uid;
95  const unsigned int m_pixel_count;
96  std::string m_device_label;
97  uint16_t m_start_address; // starts from 1
98  bool m_identify_mode;
99  std::auto_ptr<ola::rdm::PersonalityCollection> m_personality_collection;
100  std::auto_ptr<ola::rdm::PersonalityManager> m_personality_manager;
101  ola::rdm::Sensors m_sensors;
102 
103  // DMX methods
104  bool InternalWriteDMX(const DmxBuffer &buffer);
105  void IndividualWS2801Control(const DmxBuffer &buffer);
106  void CombinedWS2801Control(const DmxBuffer &buffer);
107  void IndividualLPD8806Control(const DmxBuffer &buffer);
108  void CombinedLPD8806Control(const DmxBuffer &buffer);
109  void IndividualP9813Control(const DmxBuffer &buffer);
110  void CombinedP9813Control(const DmxBuffer &buffer);
111  unsigned int LPD8806BufferSize() const;
112  void WriteSPIData(const uint8_t *data, unsigned int length);
113 
114  // RDM methods
115  const ola::rdm::RDMResponse *GetDeviceInfo(
116  const ola::rdm::RDMRequest *request);
117  const ola::rdm::RDMResponse *GetProductDetailList(
118  const ola::rdm::RDMRequest *request);
119  const ola::rdm::RDMResponse *GetDeviceModelDescription(
120  const ola::rdm::RDMRequest *request);
121  const ola::rdm::RDMResponse *GetManufacturerLabel(
122  const ola::rdm::RDMRequest *request);
123  const ola::rdm::RDMResponse *GetDeviceLabel(
124  const ola::rdm::RDMRequest *request);
125  const ola::rdm::RDMResponse *SetDeviceLabel(
126  const ola::rdm::RDMRequest *request);
127  const ola::rdm::RDMResponse *GetSoftwareVersionLabel(
128  const ola::rdm::RDMRequest *request);
129  const ola::rdm::RDMResponse *GetDmxPersonality(
130  const ola::rdm::RDMRequest *request);
131  const ola::rdm::RDMResponse *SetDmxPersonality(
132  const ola::rdm::RDMRequest *request);
133  const ola::rdm::RDMResponse *GetPersonalityDescription(
134  const ola::rdm::RDMRequest *request);
135  const ola::rdm::RDMResponse *GetDmxStartAddress(
136  const ola::rdm::RDMRequest *request);
137  const ola::rdm::RDMResponse *SetDmxStartAddress(
138  const ola::rdm::RDMRequest *request);
139  const ola::rdm::RDMResponse *GetIdentify(
140  const ola::rdm::RDMRequest *request);
141  const ola::rdm::RDMResponse *SetIdentify(
142  const ola::rdm::RDMRequest *request);
143  const ola::rdm::RDMResponse *GetSensorDefinition(
144  const ola::rdm::RDMRequest *request);
145  const ola::rdm::RDMResponse *GetSensorValue(
146  const ola::rdm::RDMRequest *request);
147  const ola::rdm::RDMResponse *SetSensorValue(
148  const ola::rdm::RDMRequest *request);
149  const ola::rdm::RDMResponse *RecordSensor(
150  const ola::rdm::RDMRequest *request);
151 
152 
153  // Helpers
154  uint8_t P9813CreateFlag(uint8_t red, uint8_t green, uint8_t blue);
155 
156  static const uint8_t SPI_MODE;
157  static const uint8_t SPI_BITS_PER_WORD;
158  static const uint16_t SPI_DELAY;
159  static const uint32_t SPI_SPEED;
160  static const uint16_t WS2801_SLOTS_PER_PIXEL;
161  static const uint16_t LPD8806_SLOTS_PER_PIXEL;
162  static const uint16_t P9813_SLOTS_PER_PIXEL;
163  static const uint16_t P9813_SPI_BYTES_PER_PIXEL;
164 
166  PARAM_HANDLERS[];
167 };
168 } // namespace spi
169 } // namespace plugin
170 } // namespace ola
171 #endif // PLUGINS_SPI_SPIOUTPUT_H_