MAX6956  1.0
MAX6956i2Clibrary
 All Data Structures Files Functions Variables Macros
MAX6956.cpp
Go to the documentation of this file.
1 // I2Cdev library collection - MAX6956 I2C device class
2 // Based on Maxim MAX6956 datasheet 19-2414; Rev 4; 6/10
3 //
4 // 2013-12-15 by Tom Beighley <tomthegeek@gmail.com>
5 // I2C Device Library hosted at http://www.i2cdevlib.com
6 //
7 // Changelog:
8 // 2013-12-15 - initial release
9 //
10 
11 /* ============================================
12 I2Cdev device library code is placed under the MIT license
13 Copyright (c) 2013 Tom Beighley
14 
15 Permission is hereby granted, free of charge, to any person obtaining a copy
16 of this software and associated documentation files (the "Software"), to deal
17 in the Software without restriction, including without limitation the rights
18 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19 copies of the Software, and to permit persons to whom the Software is
20 furnished to do so, subject to the following conditions:
21 
22 The above copyright notice and this permission notice shall be included in
23 all copies or substantial portions of the Software.
24 
25 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31 THE SOFTWARE.
32 ===============================================
33 */
34 
35 #include "MAX6956.h"
36 
42 }
43 
49 MAX6956::MAX6956(uint8_t address) {
50  devAddr = address;
51 }
52 
55  // Need this in setup() or here.
56  // Fastwire::setup(400, false);
57  reset();
58 
64  I2Cdev::writeByte(devAddr, MAX6956_RA_CONFIG_P7P6P5P4, 0x55);
65  I2Cdev::writeByte(devAddr, MAX6956_RA_CONFIG_P11P10P9P8, 0x55);
66 }
67 
73  if (I2Cdev::readByte(devAddr, MAX6956_RA_CONFIGURATION, buffer) == 1) {
74  return true;
75  }
76  return false;
77 }
78 
81  disableAllPorts(); // set Port RA 0x2C-0x3F to 0
82  setGlobalCurrent(0x00); // Set global current to minimum on
83  setConfigReg(0x00); // Shutdown Enabled,Current Control = Global, Transition Detection Disabled
84  setInputMask(0x00); // Set Input register mask to 0
85  setTestMode(false); // disable test mode
86  configAllPorts(MAX6956_INPUT_WO_PULL); // Configure all inputs as MAX6956_INPUT_WO_PULL
87  setAllPortsCurrent(0x00); // Set current RA 0x16-01F to 0
88 }
89 
95  I2Cdev::readByte(devAddr, MAX6956_RA_CONFIGURATION, buffer);
96  return buffer[0];
97 }
102 void MAX6956::setConfigReg(uint8_t config) {
103  I2Cdev::writeByte(devAddr, MAX6956_RA_CONFIGURATION, config);
104 }
105 
112  return buffer[0];
113 }
118 void MAX6956::setPower(bool power) {
119  I2Cdev::writeBit(devAddr, MAX6956_RA_CONFIGURATION, MAX6956_CONFIG_POWER_BIT, power);
120 }
126  buffer[0] = !(buffer[0]);
128 }
129 
136  return buffer[0];
137 }
146 }
147 
154  return buffer[0];
155 }
163  I2Cdev::writeBit(devAddr, MAX6956_RA_CONFIGURATION, MAX6956_CONFIG_TRANSITION_BIT, transition);
164 }
165 
166 // Global Current
173  return buffer[0];
174 }
179 void MAX6956::setGlobalCurrent(uint8_t current) {
180  I2Cdev::writeByte(devAddr, MAX6956_RA_GLOBAL_CURRENT, current);
181 }
182 
183 // Test mode
190  return buffer[0];
191 }
196 void MAX6956::setTestMode(bool test) {
197  I2Cdev::writeByte(devAddr, MAX6956_RA_DISPLAY_TEST, test);
198 }
199 
200 // Input mask register
206  I2Cdev::readByte(devAddr, MAX6956_RA_TRANSITION_DETECT, buffer);
207  return buffer[0];
208 }
209 
214 void MAX6956::setInputMask(uint8_t mask) {
215  I2Cdev::writeByte(devAddr, MAX6956_RA_TRANSITION_DETECT, mask);
216 }
217 
218 
265 void MAX6956::configPort(uint8_t port, uint8_t portConfig) {
266  uint8_t bitPosition = (((port - 44) % 4) * 2) + 1; // bit position to start flipping
267  uint8_t pcArrayIndex = (port - 44) / 4; // array index
268  uint8_t portConfigRA = pcArrayIndex + 11; // port config register
269  I2Cdev::writeBits(devAddr, portConfigRA, bitPosition, 2, portConfig);
270  // Update portConfig array
271  bitPosition--; // Remove 1 bit offset
272  portsConfig[pcArrayIndex] &= ~(3 << bitPosition);
273  portsConfig[pcArrayIndex] |= portConfig << bitPosition;
274 }
275 
285 void MAX6956::configPorts(uint8_t lower, uint8_t upper, uint8_t portConfig) {
286 
287  Serial.print("lower ");
288  Serial.print(lower, HEX);
289  Serial.print(" upper ");
290  Serial.print(upper, HEX);
291  Serial.print(" portConfig ");
292  Serial.println(portConfig, BIN);
293 
294  uint8_t bitPosition = 0;
295  uint8_t pcArrayIndex = 0;
296  uint8_t portConfigRA = 0;
297  uint8_t i = lower;
298 
299  while ( i <= upper ) {
300  bitPosition = (((i - 44) % 4) * 2) + 1; // bit position to start flipping
301  pcArrayIndex = (i - 44) / 4; // array index
302  portConfigRA = pcArrayIndex + 11; // port config register
303  Serial.print("i ");
304  Serial.print(i);
305  Serial.print(" bitPosition ");
306  Serial.print(bitPosition);
307  Serial.print(" pcArrayIndex");
308  Serial.print(pcArrayIndex);
309  Serial.print(" portConfigRA ");
310  Serial.println(portConfigRA, HEX);
311  I2Cdev::writeBits(devAddr, portConfigRA, bitPosition, 2, portConfig);
312  // Update portConfig array
313  Serial.print("portsConfig ");
314  Serial.print(portsConfig[pcArrayIndex], BIN);
315  bitPosition--; // Remove 1 bit offset
316  portsConfig[pcArrayIndex] &= ~(3 << bitPosition); //3 == B00000011 Shift over correct number of bits then invert to create the mask
317  portsConfig[pcArrayIndex] |= portConfig << bitPosition;
318  Serial.print(" >> ");
319  Serial.println(portsConfig[pcArrayIndex], BIN);
320  i++;
321  }
322 
323 }
324 
332 void MAX6956::configAllPorts(uint8_t portConfig) {
333  // build byte with config bits shifted to all 4 slots
334  portConfig = portConfig << 6 + portConfig << 4 + portConfig << 2 + portConfig;
335  // copy byte to portsConfig array slots
336  memset (portsConfig, portConfig, 5);
337  // write bytes all at once to device
338  I2Cdev::writeBytes(devAddr, MAX6956_RA_CONFIG_P15P14P13P12, 5, portsConfig);
339 }
340 
346 void MAX6956::setPortLevel(uint8_t port, uint8_t power) {
347  if ( port >= 44 && port <= 63 && power >= 0 && power <= 15 ) {
348  //power = sqrt(2) * power; // Convert linear to log scale
349 
350  psArrayIndex = (port - 44) / 8; // array index
351  psBitPosition = (port - 44) % 8; // bit position to flip
352 
353  if ( power > 0 ) {
354  // When not at 100% power decrement power by one because 0 is
355  // really an "on" power level and the lower levels are more important.
356  if ( power < 15 ) power--;
357 
358  // Calculate current register from port address
359  // set current bit offset
360  if ( port % 2 ) { //port is odd
361  portCurrentRA = (port - 1) / 2;
362  portCurrentBit = 7;
363  }
364  else {
365  portCurrentRA = port / 2;
366  portCurrentBit = 3;
367  }
368 
369  // Write changes
370  I2Cdev::writeBits(devAddr, portCurrentRA, portCurrentBit, 4, power); // Write changes
371  I2Cdev::writeByte(devAddr, port, MAX6956_ON); // turn on port
372 
373  #ifdef MAX6956_SERIAL_DEBUG
374  Serial.print("port ");
375  Serial.print(port);
376  Serial.print(" portCurrentBit ");
377  Serial.print(portCurrentBit);
378  Serial.print(" portCurrentRA ");
379  Serial.print(portCurrentRA, HEX);
380  Serial.print(" power ");
381  Serial.println(power );
382  #endif
383  // Update portStatus array
385  } else {
386  I2Cdev::writeByte(devAddr, port, MAX6956_OFF); // turn off port
387  portsStatus[psArrayIndex] &= ~(1 << psBitPosition); // Update portStatus array
388 
389  #ifdef MAX6956_SERIAL_DEBUG
390  Serial.print("port ");
391  Serial.print(port);
392  Serial.println(" is off");
393  #endif
394  }
395  }
396 }
397 
398 
404 void MAX6956::setPortCurrent(uint8_t port, uint8_t power) {
405  if ( port >= 44 && port <= 63 && power >= 0 && power <= 15 ) {
406  //power = sqrt(2) * power; /** TODO Convert linear to log scale */
407 
408  psArrayIndex = (port - 44) / 8; // array index
409  psBitPosition = (port - 44) % 8; // bit position to flip
410 
411  // Calculate current register from port address
412  // set current bit offset
413  if ( port % 2 ) { //port is odd
414  portCurrentRA = (port - 1) / 2;
415  portCurrentBit = 7;
416  }
417  else {
418  portCurrentRA = port / 2;
419  portCurrentBit = 3;
420  }
421 
422  // Write changes
423  I2Cdev::writeBits(devAddr, portCurrentRA, portCurrentBit, 4, power); // Write changes
424  I2Cdev::writeByte(devAddr, port, MAX6956_ON); // turn on port
425 
426  #ifdef MAX6956_SERIAL_DEBUG
427  Serial.print("port ");
428  Serial.print(port);
429  Serial.print(" portCurrentBit ");
430  Serial.print(portCurrentBit);
431  Serial.print(" portCurrentRA ");
432  Serial.print(portCurrentRA, HEX);
433  Serial.print(" power ");
434  Serial.println(power );
435  #endif
436  // Update portStatus array
438  }
439 }
444 void MAX6956::setAllPortsCurrent(uint8_t power) {
446  I2Cdev::writeByte(devAddr, portCurrentRA, power);
447  }
448 }
449 
454  // set portStatus array to all 1's
455  memset (portsStatus, 0xFF, 3);
456  // write bytes
457  I2Cdev::writeByte(devAddr, MAX6956_RA_PORTS12_19, portsStatus[0]);
458  I2Cdev::writeByte(devAddr, MAX6956_RA_PORTS20_27, portsStatus[1]);
459  I2Cdev::writeByte(devAddr, MAX6956_RA_PORTS28_31, portsStatus[2]);
460 }
461 
464  // set portStatus array to all 0's
465  memset (portsStatus, 0x00, 3);
466  // write bytes
467  I2Cdev::writeByte(devAddr, MAX6956_RA_PORTS12_19, portsStatus[0]);
468  I2Cdev::writeByte(devAddr, MAX6956_RA_PORTS20_27, portsStatus[1]);
469  I2Cdev::writeByte(devAddr, MAX6956_RA_PORTS28_31, portsStatus[2]);
470 }
uint8_t devAddr
Holds the current device address.
Definition: MAX6956.h:555
uint8_t portCurrentRA
Holder for port current register.
Definition: MAX6956.h:558
uint8_t psArrayIndex
array index
Definition: MAX6956.h:560
void enableAllPorts()
Definition: MAX6956.cpp:453
bool getEnableTransitionDetection()
Definition: MAX6956.cpp:152
#define MAX6956_RA_GLOBAL_CURRENT
Definition: MAX6956.h:102
uint8_t getInputMask()
Definition: MAX6956.cpp:205
void disableAllPorts()
Definition: MAX6956.cpp:463
bool getEnableIndividualCurrent()
Definition: MAX6956.cpp:134
#define MAX6956_RA_DISPLAY_TEST
Definition: MAX6956.h:165
void setPower(bool power)
Definition: MAX6956.cpp:118
#define MAX6956_INPUT_WO_PULL
Definition: MAX6956.h:408
#define MAX6956_ON
Definition: MAX6956.h:412
#define MAX6956_OFF
Definition: MAX6956.h:411
#define MAX6956_CONFIG_POWER_BIT
0 = Shutdown, 1 = Normal operation
Definition: MAX6956.h:343
void configPort(uint8_t port, uint8_t portConfig)
Definition: MAX6956.cpp:265
void setAllPortsCurrent(uint8_t power)
0-15, 0 = min brightness (not off) 15 = max
Definition: MAX6956.cpp:444
#define MAX6956_RA_CONFIG_P15P14P13P12
Definition: MAX6956.h:205
void configPorts(uint8_t lower, uint8_t upper, uint8_t portConfig)
Definition: MAX6956.cpp:285
uint8_t portsConfig[5]
Definition: MAX6956.h:527
uint8_t getGlobalCurrent()
Definition: MAX6956.cpp:171
#define MAX6956_DISPLAY_TEST_BIT
0 = Normal operation, 1 = Display test
Definition: MAX6956.h:391
#define MAX6956_RA_CONFIGURATION
Definition: MAX6956.h:137
bool getTestMode()
Definition: MAX6956.cpp:188
uint8_t psBitPosition
bit position
Definition: MAX6956.h:561
#define MAX6956_RA_PORTS20_27
Definition: MAX6956.h:325
#define MAX6956_RA_PORTS28_31
data bits D0-D3; D4-D7 read as 0
Definition: MAX6956.h:336
#define MAX6956_RA_PORTS12_19
Definition: MAX6956.h:317
uint8_t portsStatus[3]
Definition: MAX6956.h:552
void initialize()
Definition: MAX6956.cpp:54
void setConfigReg(uint8_t config)
Definition: MAX6956.cpp:102
bool getPower()
Definition: MAX6956.cpp:110
void configAllPorts(uint8_t portConfig)
Definition: MAX6956.cpp:332
void setEnableTransitionDetection(bool transition)
Definition: MAX6956.cpp:162
#define MAX6956_RA_CURRENT_0xP31P30
Definition: MAX6956.h:254
void setEnableIndividualCurrent(bool global)
Definition: MAX6956.cpp:144
void setPortCurrent(uint8_t port, uint8_t power)
0-15 brightness levels.
Definition: MAX6956.cpp:404
#define MAX6956_GLOBAL_CURRENT_LENGTH
nybble long
Definition: MAX6956.h:348
uint8_t portCurrentBit
Holder for the current bit offset.
Definition: MAX6956.h:559
#define MAX6956_RA_CURRENT_0xP13P12
Definition: MAX6956.h:245
void setPortLevel(uint8_t port, uint8_t power)
0 = off, 1-15 brightness levels.
Definition: MAX6956.cpp:346
MAX6956()
Definition: MAX6956.cpp:40
#define MAX6956_GLOBAL_CURRENT_BIT
Global current start bit.
Definition: MAX6956.h:347
#define MAX6956_CONFIG_TRANSITION_BIT
0 = Disabled, 1 = Enabled
Definition: MAX6956.h:345
#define MAX6956_RA_CONFIG_P11P10P9P8
Definition: MAX6956.h:204
#define MAX6956_RA_CONFIG_P7P6P5P4
Definition: MAX6956.h:203
uint8_t buffer[1]
Buffer for reading data from the device.
Definition: MAX6956.h:556
void setGlobalCurrent(uint8_t current)
Definition: MAX6956.cpp:179
void reset()
Definition: MAX6956.cpp:80
bool testConnection()
Definition: MAX6956.cpp:72
void setTestMode(bool test)
Definition: MAX6956.cpp:196
void togglePower()
Definition: MAX6956.cpp:124
uint8_t portConfig
Holder for port config bit pair.
Definition: MAX6956.h:557
#define MAX6956_RA_TRANSITION_DETECT
Definition: MAX6956.h:152
void setInputMask(uint8_t mask)
Definition: MAX6956.cpp:214
#define MAX6956_DEFAULT_ADDRESS
Definition: MAX6956.h:72
#define MAX6956_CONFIG_GLOBAL_CURRENT_BIT
0 = Global control, 1 = Individual control
Definition: MAX6956.h:344
uint8_t getConfigReg()
Definition: MAX6956.cpp:94