RSeries astromech firmware
LedControlMAX7221.h
Go to the documentation of this file.
1 
2 #ifndef LedControlMAX7221_h
3 #define LedControlMAX7221_h
4 
5 #include "ReelTwo.h"
6 
8 class LedControl
9 {
10 public:
11  LedControl()
12  {
13  }
14 
15  enum {
16  kMaxBrightness = 15
17  };
18 
23  virtual byte addDevice(byte count = 1) = 0;
24 
25  virtual int getDeviceCount() = 0;
26 
27  virtual bool isPowered(byte device) = 0;
28 
29  virtual void setPower(byte device, bool onState, byte numDevices = 1) = 0;
30 
31  virtual void setScanLimit(byte device, byte limit, byte numDevices = 1) = 0;
32 
33  virtual void setIntensity(byte device, byte intensity, byte numDevices = 1) = 0;
34 
35  virtual void clearDisplay(byte device, byte numDevices = 1) = 0;
36 
46  virtual void setLed(byte device, int row, int column, boolean state) = 0;
47 
56  virtual void setRow(byte device, int row, byte value) = 0;
57 
66  virtual void setRowNoCache(byte device, int row, byte value) = 0;
67 
76  virtual void setColumn(byte device, int column, byte value) = 0;
77 
78  virtual byte getRow(byte device, byte row) = 0;
79 
80  void setAllPower(bool onState)
81  {
82  setPower(0, onState, getDeviceCount());
83  }
84 
85  void clearAllDisplays()
86  {
87  clearDisplay(0, getDeviceCount());
88  }
89 
96  static byte randomRow(byte randomMode)
97  {
98  switch(randomMode)
99  {
100  case 0: // stage -3
101  return (random(256)&random(256)&random(256)&random(256));
102  case 1: // stage -2
103  return (random(256)&random(256)&random(256));
104  case 2: // stage -1
105  return (random(256)&random(256));
106  case 3: // legacy "blocky" mode
107  return random(256);
108  case 4: // stage 1
109  return (random(256)|random(256));
110  case 5: // stage 2
111  return (random(256)|random(256)|random(256));
112  case 6: // stage 3
113  return (random(256)|random(256)|random(256)|random(256));
114  }
115  return random(256);
116  }
117 };
118 
128 template <byte numDevices>
129 class LedControlMAX7221 : public LedControl
130 {
131 public:
135  LedControlMAX7221(byte dataPin, byte clkPin, byte csPin) :
136  fIndex(0),
137  fPowerMask(0),
138  fSPI_MOSI(dataPin),
139  fSPI_CLK(clkPin),
140  fSPI_CS(csPin)
141  {
142  pinMode(fSPI_MOSI, OUTPUT);
143  pinMode(fSPI_CLK, OUTPUT);
144  pinMode(fSPI_CS, OUTPUT);
145  digitalWrite(fSPI_CS, HIGH);
146  // set everything to 0xff so clearDisplay will zero out
147  for (byte i = 0; i < sizeof(fBits); i++)
148  fBits[i] = ~0;
149  for (byte i = 0; i < numDevices; i++)
150  {
151  spiTransfer(i, kOP_DISPLAYTEST, 0);
152  //scanlimit is set to max on startup
153  setScanLimit(i, 7);
154  //decode is done in source
155  spiTransfer(i, kOP_DECODEMODE, 0);
156  clearDisplay(i);
157  setIntensity(i, kBrightness);
158  setPower(i, false);
159  }
160  }
161 
166  virtual byte addDevice(byte count = 1) override
167  {
168  byte idx = fIndex;
169  fIndex += count;
170  return idx;
171  }
172 
176  virtual int getDeviceCount() override
177  {
178  return numDevices;
179  }
180 
184  virtual bool isPowered(byte device) override
185  {
186  return (device < numDevices) ? ((fPowerMask & (1<<device)) != 0) : false;
187  }
188 
196  virtual void setPower(byte device, bool onState, byte count = 1) override
197  {
198  while (count-- != 0 && device < numDevices)
199  {
200  bool shutdown = !onState;
201  fPowerMask = (onState) ? (fPowerMask | (1<<device)) : (fPowerMask & ~(1<<device));
202  spiTransfer(device, kOP_SHUTDOWN, !shutdown);
203  device++;
204  }
205  }
206 
215  virtual void setScanLimit(byte device, byte limit, byte count = 1) override
216  {
217  while (count-- != 0 && device < numDevices && limit < 8)
218  {
219  spiTransfer(device, kOP_SCANLIMIT, limit);
220  device++;
221  }
222  }
223 
230  virtual void setIntensity(byte device, byte intensity, byte count = 1) override
231  {
232  while (count-- != 0 && device < numDevices && intensity < 16)
233  {
234  spiTransfer(device, kOP_INTENSITY, intensity);
235  device++;
236  }
237  }
238 
244  virtual void clearDisplay(byte device, byte count = 1) override
245  {
246  while (count-- != 0 && device < numDevices)
247  {
248  byte* status = &fBits[device * 8];
249  for (int i = 1; i < 9; i++, status++)
250  {
251  if (*status != 0)
252  {
253  *status = 0;
254  spiTransfer(device, i, 0);
255  }
256  }
257  device++;
258  }
259  }
260 
270  virtual void setLed(byte device, int row, int column, boolean state) override
271  {
272  if (device < numDevices &&
273  row >= 0 && row < 8 && column >= 0 && column < 8)
274  {
275  byte* status = &fBits[device * 8 + row];
276  byte val = B10000000 >> column;
277  if (state)
278  {
279  val |= *status;
280  }
281  else
282  {
283  val = ~val;
284  val &= *status;
285  }
286  if (*status != val)
287  {
288  *status = val;
289  spiTransfer(device, row + 1, val);
290  }
291  }
292  }
293 
302  virtual void setRow(byte device, int row, byte value) override
303  {
304  if (device < numDevices && row >= 0 && row < 8)
305  {
306  byte* status = &fBits[device * 8 + row];
307  if (*status != value)
308  {
309  *status = value;
310  spiTransfer(device, row + 1, value);
311  }
312  }
313  }
314 
323  virtual void setRowNoCache(byte device, int row, byte value) override
324  {
325  if (device < numDevices && row >= 0 && row < 8)
326  {
327  byte* status = &fBits[device * 8 + row];
328  *status = value;
329  spiTransfer(device, row + 1, value);
330  }
331  }
332 
341  virtual void setColumn(byte device, int column, byte value) override
342  {
343  byte val;
344  if (device < numDevices && column >= 0 && column < 8)
345  {
346  for (int row = 0; row < 8; row++)
347  {
348  val = value >> (7 - row);
349  val = val & 0x01;
350  setLed(device, row, column, val);
351  }
352  }
353  }
354 
358  virtual byte getRow(byte device, byte row) override
359  {
360  return (device < numDevices && row < 8) ? fBits[device * 8 + row] : 0;
361  }
362 
363 private:
364  /* Send out a single command to the device */
365  void spiTransfer(byte device, volatile byte opcode, volatile byte data)
366  {
367  //Create an array with the data to shift out
368  int offset = device * 2;
369  for (byte i = 0; i < sizeof(fSPIData); i++)
370  fSPIData[i] = (byte)0;
371  //put our device data into the array
372  fSPIData[offset + 1] = opcode;
373  fSPIData[offset] = data;
374  //enable the line
375  digitalWrite(fSPI_CS, LOW);
376  //Now shift out the data
377  for (byte i = sizeof(fSPIData); i > 0; i--)
378  shiftOut(fSPI_MOSI, fSPI_CLK, MSBFIRST, fSPIData[i - 1]);
379  //latch the data onto the display
380  digitalWrite(fSPI_CS, HIGH);
381  }
382 
383  byte fIndex;
384  byte fPowerMask;
385  byte fBits[8 * numDevices];
386  byte fSPIData[2 * numDevices];
387  byte fSPI_MOSI;
388  byte fSPI_CLK;
389  byte fSPI_CS;
390 
391  const int kBrightness = 15;
392  enum {
393  kOP_DECODEMODE = 9,
394  kOP_INTENSITY = 10,
395  kOP_SCANLIMIT = 11,
396  kOP_SHUTDOWN = 12,
397  kOP_DISPLAYTEST = 15
398  };
399 };
400 
401 #endif
LedControlMAX7221::getRow
virtual byte getRow(byte device, byte row) override
Definition: LedControlMAX7221.h:358
ReelTwo.h
LedControlMAX7221::isPowered
virtual bool isPowered(byte device) override
Definition: LedControlMAX7221.h:184
LedControlMAX7221::setColumn
virtual void setColumn(byte device, int column, byte value) override
Set all 8 Led's in a column to a new state Params: device address of the display column column which ...
Definition: LedControlMAX7221.h:341
LedControlMAX7221::setLed
virtual void setLed(byte device, int row, int column, boolean state) override
Set the status of a single Led.
Definition: LedControlMAX7221.h:270
LedControlMAX7221
LED MAX7221 device chain.
Definition: LedControlMAX7221.h:129
LedControlMAX7221::clearDisplay
virtual void clearDisplay(byte device, byte count=1) override
Switch all Leds on the display off.
Definition: LedControlMAX7221.h:244
LedControlMAX7221::LedControlMAX7221
LedControlMAX7221(byte dataPin, byte clkPin, byte csPin)
Constructor.
Definition: LedControlMAX7221.h:135
LedControlMAX7221::setRow
virtual void setRow(byte device, int row, byte value) override
Set all 8 Led's in a row to a new state Params: device address of the display row row which is to be ...
Definition: LedControlMAX7221.h:302
LedControlMAX7221::setScanLimit
virtual void setScanLimit(byte device, byte limit, byte count=1) override
Set the number of digits (or rows) to be displayed.
Definition: LedControlMAX7221.h:215
LedControlMAX7221::setRowNoCache
virtual void setRowNoCache(byte device, int row, byte value) override
Set all 8 Led's in a row to a new state (no cache) Params: device address of the display row row whic...
Definition: LedControlMAX7221.h:323
LedControlMAX7221::getDeviceCount
virtual int getDeviceCount() override
Definition: LedControlMAX7221.h:176
LedControlMAX7221::setIntensity
virtual void setIntensity(byte device, byte intensity, byte count=1) override
Set the brightness of the display.
Definition: LedControlMAX7221.h:230
LedControlMAX7221::setPower
virtual void setPower(byte device, bool onState, byte count=1) override
Enable/disable power Params : device The address of the display to control status If true the device ...
Definition: LedControlMAX7221.h:196
LedControlMAX7221::addDevice
virtual byte addDevice(byte count=1) override
Add device to chain and return index.
Definition: LedControlMAX7221.h:166