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