Jump to content
Sign in to follow this  
fj604

Interfacing the Launchpad with MAX6957 SPI LED Driver

Recommended Posts

MAX6957 can be a useful tool: a LED driver + I/O expander, giving you 20 ports (PDIP) or 28 port (surface mount) selectable as:

- constant current sink LED driver

- input

- input with pullup

- output

 

Here is a demo code for the Launchpad (MSP430G2231) using hardware SPI:

 

/*
*  Interfacing MSP430G2231 to MAX6957 SPI LED driver and I/O expander

Pins   MSP430G2231                  MAX6957
       1 DVCC        -----------   28 V+
       3 P1.1 (CS)   -----------   27 CS
       7 P1.5/SCLK   -----------   25 SCLK
       8 P1.6/SDO    -----------   26 DIN
       9 P1.7/SDI    -/\/10K\/\-    4 DOUT
      14 DVSS        -----------    2 GND    -----------   GND
                                    3 GND    -----------   GND
                                    1 ISET   -/\/39K\/\-   GND
                                   12 P19    -----------   LED1
                                   13 P20    -----------   LED2
                                   14 P21    -----------   LED3
                                    8 P15    ----/ -----   GND

Upon startup, LED1-3 will light up for about 1.5 seconds, then LED2-3 will start glowing intermittently.
While a button on P15 is pushed, LED1 will change brightness. 

*/

#include 

#define PIN_CS		BIT1
#define DELAY 		40000

void spi_init(void)
{
   P1DIR = PIN_CS;                                         // Set CS to output
   P1OUT = PIN_CS;                                         // CS to high
USICTL0 =  USIPE7 | USIPE6 | USIPE5 | USIMST | USIOE;	// SDI enable, SDO enable, SCLK enable, Master mode, Data output enable, release
USICTL1 = USICKPH | USIIE;								// CKPH = 1, Interrupt Enable
USICKCTL = USIDIV_7 | USISSEL_2 ;						// Clock / 128, SMCLK;
}

void timer_init(void)
{
   TACTL = TASSEL_2 | MC_0;        // SMCLK, stop timer
   TACCTL0 = CCIE;                 // Enable timer compare interrupt
} 

void sleep(unsigned int count)
{
   TACCR0 = count;             // Load top value in compare register
   TACTL |= TACLR | MC_1;      // Clear counter, start timer in up mode
   _low_power_mode_0();        // Sleep in LPM0 until interrupt
   TACTL &= ~MC_1;             // Stop timer
}

unsigned int cmd(unsigned char addr, unsigned char data)
{
P1OUT &= ~PIN_CS;              // Take CS low
USISRH = addr;                 // Load address to high byte
USISRL = data;                 // Load data to low byte
USICNT = USI16B | 16;          // 16 bit transfer
_low_power_mode_0();           // sleep in LPM0 until interrupt
   P1OUT |= PIN_CS;               // Take CS high
return USISR;
}

void sense(void)
{
   static unsigned char g=0;
cmd(0x2F | BIT7, 0);           // Turn high bit on to read register 0x2F for port 15
if (!(cmd(0, 0) & BIT0))       // Send No-op command and check bit 0 = button pushed
       cmd(0x19, g++ << 4);       // Increase brightness of LED on port 19
}	

void leds(unsigned char v)
{
cmd(0x1A, v | (0x0F-v) << 4);  // control brightness of LEDs on ports 20-21 
sense();
}

void main(void)
{
signed char i=0;               

WDTCTL = WDTPW + WDTHOLD;   // Disable WDT
spi_init();
   timer_init();
   _enable_interrupts();

cmd(0x0C, 0x00);		    // set ports 16-19 to LED
cmd(0x0D, 0x00);       		// set ports 20-23 to LED
cmd(0x0B, 0xFF);			// set ports 12-15 to GPIO Input with pullup
cmd(0x33, 0x01);			// Port 19 on
cmd(0x34, 0x01);			// Port 20 on
cmd(0x35, 0x01);			// Port 21 on
cmd(0x07, 0x01);			// Display test on
_delay_cycles(1500000);		//	~ 1.5s pause
cmd(0x07, 0x00);			// Display test off
cmd(0x04, BIT0 | BIT6);		// Individual segment current control, normal operation
for (;
{
	for (i=0; i<0x10; i++)
	{
		leds(i);
		sleep(DELAY);
	}
	for (i=0x0F; i>=0; i--)
	{
		leds(i);
           sleep(DELAY);
	}
}
}

#pragma vector=USI_VECTOR
__interrupt void usi_interrupt(void)
{
   USICTL1 &= ~USIIFG;             // Clear interrupt flag
   _low_power_mode_off_on_exit();  // Return from LPM
}

#pragma vector=TIMERA0_VECTOR
__interrupt void timer_A_interrupt(void)
{
   _low_power_mode_off_on_exit();  // Return from LPM
}

 

I figured that a 10K resistor is needed as without it MAX6957 would just stop - but I still cannot figure out why - any ideas?

 

I also have the I2C version - MAX6956 - stay tuned ;)

Share this post


Link to post
Share on other sites
Might it be this? (Also the MAX6957 data sheet page 7, towards the bottom.)

 

Pardon my ignorance, but if MSP430's SDI is already high impedance (is it?), then why does MAX6957 have to have a 10K resistor on DOUT? (I feel like I am missing something fundamental - like SDI not being high impedance in SPI mode)

Share this post


Link to post
Share on other sites

I have not tried reading from it yet. I am leaving DOUT floating while only telling it to glow my blinkies, and it does not seem to cause any ill effect.

 

USI SDI being high impedance isn't mentioned explicitly in SLAU144, but it is mentioned wrt. USCI I2C (p. 458), which may be for a reason or may as well be an omission, I don't know.

 

Try implementing one of the methods in Maxim Appnote 1879 without changing anything else. Does that thaw your 6957?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...