LED Strip uC controlling with MSP430

Thread Starter

tindel

Joined Sep 16, 2012
939
http://moderndevice.com/new-products/new-product-serial-led-strips/

http://www.mikroshop.ch/pdf/UCS1903.pdf

I received a couple meters of the above led strip to play with for Christmas... for the life of me I can't figure out how to program it with the MSP430G2553... the software they have is for an AVR. When I asked for this for Christmas I thought it was suppose to use a SPI bus which is easy enough to program - turns out it uses a discrete signal not conforming to any serial bus that I'm aware of.

The difficulty comes from the timing diagram shown in the second link. To transmit a 0 there has to be 0.5us high followed immediately by 2.0us of low, and a 1 has to have 2.0us of high followed by 0.5us of low signal. At 16MHz, the 0.5us pulse is only 8 clock cycles. Which makes this tough... to add to the difficulty, I believe this strip uses the high speed mode decreasing the minimum clock cycle interval to 4.

I'm not sure how to do this with any accuracy. It's not conforming to a serial protocol of any type that I'm aware of. I'm guessing there is a way to use the timer on the MSP430, but I'm not quite sure how to attack it... any tips? Maybe I just set the IO bit and then delay the desired clock cycles before then return changing the state again?
 

joeyd999

Joined Jun 6, 2011
6,279
Yes, this looks like a (proprietary?) one-wire signalling protocol. I've not seen it before, and, IMHO, it's pretty silly -- there are better ways to do it.

There is only 150 ns allowable error for the edge times. This is going to be tough by bit-banging.

Perhaps there is a driver IC as a companion to convert a more standard stream (UART, SPI, IIC) into this protocol?
 
Last edited:

joeyd999

Joined Jun 6, 2011
6,279
Ok...been thinking about this. I might approach it like this:

Use the on-chip uart, clocked at 4Mbaud (slow version) or 8Mbaud (fast version), and set for 1 start bit (high) and 1 stop bit (low).

Each code sent to the LED chip will have the pattern serialized as b'1xxxxxxxx0', where the x's are the codes below, and each bit time will be 0.25uS (or 0.125uS in fast mode):

Each byte is sent as eight consecutive transfers of the following pattern:

To send a 0 bit, write b'10000000' to the transmit register
To send a 1 bit, write b'11111110' to the transmit register

You'll only have 2.5 microseconds between successive writes, so all your data will need to be pre-packaged in an array, and the data shifted out in a tight loop.

The hardware will take care of the edge times, so you shouldn't have a problem.

Good Luck!

Edit: Oh, a reset can be done by pausing data transmission.
 

joeyd999

Joined Jun 6, 2011
6,279
Also, using 1/2 the baud rate detailed above, you could pack 2 bits into one byte transfer, using these codes:

00 - b'00001000'
01 - b'00001111'
10 - b'11101000'
11 - b'11101111'
 

joeyd999

Joined Jun 6, 2011
6,279
As a sanity check, I wanted to see if I could do this on a PIC. The answer is yes, but only with a 64Mhz clock, and the 2 bits per byte transfer.
 

joeyd999

Joined Jun 6, 2011
6,279
In PIC18 asm, here is how I would do it (the code to set up the USART is not shown):

Code:
txdata	lfsr	0,array			;point to array of data

	movlw	low (-bytecount)	;load number of bytes to send
	movwf	bytectr
	movlw	high (-bytecount)
	movwf	bytectr+1

dobyte	movlw	4		;send 4 doublets per byte 
	movwf	dblctr

dublet	rlncf	indf0,f		;simultaneously shift bytes,
	rlncf	indf0,f		;   and multiply least 2 by 4 for jump

	movf	indf0,w		;bits 2 & 3 are important
	andlw	b'1100'		;mask them
	addwf	pcl,f		;and use as index into jump table

c00	movlw	b'00001000'	;code for doublet '00'
	bra	load

c01	movlw	b'00001111'	;code for doublet '01'
	bra	load

c10	movlw	b'11101000'	;code for doublet '10'
	bra	load

c11	movlw	b'11101111'	;code for doublet '11'
	bra	load

load	btfss	pir1,txif	;txreg empty?
	bra	load		;  no, wait

	movwf	txreg		;yes, send new code

	decfsz	dblctr,f	;all doublets done?
	bra	dublet		;no, do more

	movf	postinc0,f	;point to next byte

	incfsz	bytectr,f	;do for all bytes
	bra	dobyte
	incfsz	bytectr+1,f
	bra	dobyte

	return			;done.
 
Last edited:

joeyd999

Joined Jun 6, 2011
6,279
I got the codes wrong (my stupid head forgot LSBs are sent first). The proper codes are:

00 - b'00010000'
01 - b'00010111'
10 - b'11110000'
11 - b'11110111'
 

joeyd999

Joined Jun 6, 2011
6,279
Also, I had an error in my bit shifting. Here is a fully corrected version:

Code:
txdata	lfsr	0,array			;point to array of data

	movlw	low (-bytecount)	;load number of bytes to send
	movwf	bytectr
	movlw	high (-bytecount)
	movwf	bytectr+1

	rlncf	indf0,f		;pre-align lsbs for jump table
	rlncf	indf0,f

dobyte	movlw	4		;send 4 doublets per byte 
	movwf	dblctr

dublet	movf	indf0,w		;bits 2 & 3 are important
	andlw	b'1100'		;mask them
	addwf	pcl,f		;and use as index into jump table

c00	movlw	b'00010000'	;code for doublet '00'
	bra	load

c01	movlw	b'00010111'	;code for doublet '01'
	bra	load

c10	movlw	b'11110000'	;code for doublet '10'
	bra	load

c11	movlw	b'11110111'	;code for doublet '11'
	bra	load

load	btfss	pir1,txif	;txreg empty?
	bra	load		;  no, wait

	movwf	txreg		;yes, send new code

	rrncf	indf0,f		;shift for next two bits
	rrncf	indf0,f

	decfsz	dblctr,f	;all doublets done?
	bra	dublet		;no, do more

	movf	postinc0,f	;point to next byte

	incfsz	bytectr,f	;do for all bytes
	bra	dobyte
	incfsz	bytectr+1,f
	bra	dobyte

	return			;done.
 

Thread Starter

tindel

Joined Sep 16, 2012
939
Wow - ask and I'll receive! Thanks joeyd999. A couple reasons I don't think this will work with an MSP430:
  • Maximum clock rate is 16MHz (on the G2553) so I don't think you could get the bit shifting through fast enough between UART writes.
  • Start bit is always LOW. You could probably go through an inverting buffer to make it work and invert all of the logic but at 8Mbaud - maybe not...
  • You have to hold the bit in reset for 24us for the data to be asserted... UART is nominally high.
Regardless - I've decided to pursue sending this back in favor of an SPI bus driven one that will be more friendly to the MSP430 family... I don't feel like experimenting and being out 50 bucks... or it laying around collecting dust.
 
Top