SLVA267B Mar 2007 – September 2018 MSP430F427 , TLC5940 , TLC5940-EP , TLC5941
TLC5941 COMMUNICATIONS FIRMWARE
;
;Scot Lester
;Texas Instruments Incorporated
;February 2008
;
;This firmware was written for the MSP430F427
;
;The hardware is configured to have one general
;purpose I/O port (GPIO) configured as all bits being
;outputs. For this example, 6 bits of port one are used to
;drive the TLC5941. Each of the six used GPIO pins of the MSP430
;are connected as follows:
;
; PIN NAME TLC5941 FUNCTION
;
; P1.0 BLANK
; P1.1 GSCLK=2MHz
; P1.2 SCLK
; P1.3 XLATCH
; P1.4 MODE
; P1.5 SIN
; P1.6 not used
; P1.7 not used
;
#include "msp430x42x.h"
;-------------------------------------------------------------------------------
; Definition of named constants
;-------------------------------------------------------------------------------
#define BLANK (0x01)
#define SCLK (0x04)
#define XLAT (0x08)
#define MODE (0x10)
#define SIN (0x20)
;P1OUT is equal to the memory address of output port.
;-------------------------------------------------------------------------------
; RESERVED RAM MEMORY FOR VARIABLES
;-------------------------------------------------------------------------------
; Dot Correction values are stored sequentially in 8 bit bytes.
; The TLC5941 only needs 6 bits of dot correction data so the
; dot correction data is stored left justified in the 8 bit byte
; the two least significant bits of each 8 bit byte are set
; to zero in this example but the firmware ignores these
; two bits so they can be any value.
; For example, a binary dot correction value of 101010b = 0x2A
; is stored as 10101000b = 0xA8
ORG 0200h ; Start of RAM
EVEN ; Align data on even boundary
Dot
DB 0xFC ;CH0
DB 0xFC ;CH1
DB 0xF4 ;CH2
DB 0xF8 ;CH3
DB 0xF8 ;CH4
DB 0xFC ;CH5
DB 0xF4 ;CH6
DB 0xF0 ;CH7
DB 0xF4 ;CH8
DB 0xFC ;CH9
DB 0xFC ;CH10
DB 0xFC ;CH11
DB 0xF8 ;CH12
DB 0xF4 ;CH13
DB 0xF4 ;CH14
DB 0xF8 ;CH15
;
;
; Grayscale values are stored sequentially in 16 bit words.
; The TLC5941 only needs 12 bits of grayscale so the
; grayscale data is stored left justified in the 16 bit word
; the four least significant bits of each 16 bit word are set
; to zero in this example but the firmware ignores these
; four bits so they can be any value.
; For example, a hex grayscale value of 0xFFF
; is stored as 0xFFF0
;
Grayscale
DW 0xAFF0 ;CH0
DW 0xF000 ;CH1
DW 0xF000 ;CH2
DW 0xC000 ;CH3
DW 0xD400 ;CH4
DW 0xE000 ;CH5
DW 0xB000 ;CH6
DW 0xF000 ;CH7
DW 0xFFF0 ;CH8
DW 0x0000 ;CH9
DW 0x0000 ;CH10
DW 0x13F0 ;CH11
DW 0x2380 ;CH12
DW 0xE980 ;CH13
DW 0x0450 ;CH14
DW 0xBA30 ;CH15
;-----------------------------------------------------------------
ORG 0C000h ; Starting Address of Program Space
;-----------------------------------------------------------------
RESET ;reset jump vector jumps to here to start execution.
;
;Program execution begins here after power up and reset
;Typical start up routines should be located here.
;Routines to initialize the stack pointer, watch dog timers, parallel I/O
;ports etc. etc.
;the General Purpose I/O port (P1) needs to be configured with bits 0:5
;set to outputs. At initialization, all output bits should be cleared to zero.
;this is not shown since it is processor specific.
;Bit P1.1 has a special configuration. The output bit is driven by the
;MSP’s internal oscillator which is set to 2MHz. This drives the
;grayscale clock of the TLC5941. Since the output signal is simply the
;system clock, there is no need for the firmware to manipulate this bit.
;The grayscale clock will run continuously.
MOV.W #600h,SP ;Initialize stack pointer to location 600 hex
MOV.W #WDTPW+WDTHOLD,&WDTCTL ; Stop Watchdog Timer
BIS.B #0xFF,&P1DIR ;make all port one GPIO pins outputs
BIS.B #0x02,&P1SEL ;p1.1 = peripheral module output for GSCLK signal.
MOV.B #0x00,&P1OUT ;Initialize all outputs to zero
BIC #GIE,SR ;Turn all interrupts off
;The following commands configure several clocks that are specific to the
;MSP430F427. These commands configure an internal phase locked loop (PLL)
;to generate a 2MHz stem clock from a 32.768KHz external crystal.
MOV.B #63,&SCFQCTL ;set MCLK=64*ACLK or 2MHz
MOV.B #FN_2,&SCFI0 ;set DCO range
BIS.B #02,&FLL_CTL1 ;set ACLK/4
BIC.B #01,&FLL_CTL1 ;set ACLK/4
BIS.B #XCAP18PF,&FLL_CTL0 ;Set load capacitance for xtal
;The following is a delay loop. This delay is needed to wait until the
;crystal oscillator is stable before continuing to execute code. This
;step is MSP430 specific.
MOV.W #10000,R15 ;Initial value for a delay loop
Xtal_Wait
DEC R15 ;Delay for 32 kHz crystal to
JNZ Xtal_Wait ;stabilize
;***********************************
;SET UP TIMER TO MAKE BLANK SIGNAL
;***********************************
;
;This section sets up a 16 bit timer with interrupt capability. The timer
;is configured to count up to the decimal number 4097. The timer clock signal
;is supplied by the system clock which is also the GSCLK. The timer will count 4097
;GSCLKS and then initiate an interrupt. The timer automatically clears to zero
;then starts to count again to 4097.
;The interrupt routine simply toggles the
;Parallel I/O pin that is connected to the BLANK signal of the TLC5941.
;The TLC5941 will receive 4096 GSCLKS and then get a pulse on the BLANK
;pin to reset the internal counters of the TLC5941
;
MOV.W #OUTMOD_3+CCIE,&CCTL0 ;CCR1 toggle/set
MOV.W #4097,&CCR0 ;load timer value
MOV.W #TASSEL_2+MC_1,&TACTL ;SMCLK, up mode
BIS.W #GIE,SR ;enable timer interrupt for BLANK signal
;since the grayscale clock run continuously, this timer is used to automatically
;send out BLANK signals to start new display frames.
;This method makes the grayscale clocking transparent to the rest of the
;firmware.
;***********************************
;SEND DC AND GS DATA TO TLC5941
;***********************************
CALL #DCOUT ;call routine to move dot correction
;data to TLC5941
CALL #GSOUT ;call routine to move grayscale
;data to TLC5941
mainloop
NOP
JMP mainloop ;infinite loop when done
;-----------------------------------------------------------------------
; SUBROUTINES
;-----------------------------------------------------------------------
;***************************************
;SEND GRAYSCALE DATA TO TLC5941
;***************************************
;
;shift out Grayscale data stored in RAM to TLC5941
;clocks out as MSB of channel 15 first then works down through bytes in memory
;shifts of 12 bits per channel for a total of 192 bits.
;
GSOUT
MOV.W #16,R12 ;Register 12 is a loop counter.
;Loop through 16 LEDs.
MOV.W #Grayscale,R13 ;load register 13 with the starting address of the
;grayscale data stored in RAM. R13 will point to the
;byte to shift out.
ADD.W #32,R13 ;Add 32 to the pointer so that R13 points to the byte after
;the last byte in the grayscale table. The first instruction
;in the following loop is a decrement instruction that will
;make R13 point at the last byte in the table.
ltagsdt
DEC.W R13 ;decrease the address pointer by one byte
MOV.B #08,R9 ;Load register R9 with the number of bits to shift out
;this value will be passed to the SHIFTOUT subroutine
;R13 points to the MSB first in memory so there are 8
;bits to shift out.
MOV.W R13,R8 ;Copy address pointer to R8.The SHIFTOUT
;routine uses R8 to point to the byte to shift out.
CALL #SHIFTOUT ;call subroutine to shift out data
DEC.W R13 ;decrement pointer one byte to point to LSB byte
MOV.B #0x04,R9 ;load R9 with the number of bits in the second byte
;to shift out. Only four bits remain to be shifted
MOV.W R13,R8 ;Copy address pointer to R8. The SHIFTOUT
;routine uses R8 to point to the byte to shift out.
CALL #SHIFTOUT ;call subroutine to shift out data
DEC.W R12 ;decrement loop counter by one
JNZ ltadcdt ;jump if not zero to continue looping
BIS.B #XLAT,&P1OUT ;set the I/O pin for XLATCH high to latch
;serial data into the TLC5941
BIC.B #XLAT,&P1OUT ;set XLATCH back to zero
BIS.B #SCLK,&P1OUT ;set the I/O pin for SLCK high to
;give SCLK one extra pulse after XLATCH
;this is only required if the previous dat sent
;to the TLC5941 was dot correction information
BIS.B #SCLK,&P1OUT ;set I/O pin for SCLK back to zero
RET ;return from subroutine
;*******************************************
;SEND DOT CORRECTION DATA TO TLC5941
;*******************************************
;
;
;shift out dot correction data stored in ram to TLC5941
;clocks out as MSB of channel 15 first then works down through bytes in memory
;shifts 6 bits per LED channel or 96 bits total.
;This routine is very similar to the Grayscale routine. The DCOUT and GSOUT
;routines could be combined together for some memory space savings by
;using some flags and conditional statements.
DCOUT
BIS.B #MODE,&P1OUT ;set I/O line that is tied to the MODE pin of
;the TLC5941 pin to one to enter DC mode
MOV.W #16,R12 ;Register 12 is a loop counter. Loop through 16 LEDs. MOV.W #Dot,R13
;load register 13 with the starting address of the
;dot correction data stored in RAM. R13 will point to the
;byte to shift out
ADD.W #16,R13 ;Add 16 to the pointer so that R13 points to the byte after
;the last byte in the dot correction table. The first
;instruction in the following loop is a decrement instruction
;that will make R13 point at the last byte in the table.
ltadcdt
DEC.W R13 ;decrease the address pointer by one byte
MOV.B #06,R9 ;Load register R9 with the number of bits to shift out
;this value will be passed to the SHIFTOUT subroutine
;there are 6 bits to shift out
MOV.W R13,R8 ;Copy address pointer to R8.The SHIFTOUT
;routine uses R8 to point to the byte to shift out.
CALL #SHIFTOUT ;call subroutine to shift out data
DEC.W R12 ;decrement loop counter by one
JNZ ltadcdt ;jump if not zero to continue looping
BIS.B #XLAT,&P1OUT ;set the I/O pin for XLATCH high to latch
;serial data into the TLC5941
BIC.B #XLAT,&P1OUT ;set XLATCH back to zero
BIC.B #10h,&P1OUT ;set the I/O line that is tied to the MODE pin of
;the TLC5941 pin to zero to set back to
;grayscale mode
RET ;return from subroutine
;*************************************
; SHIFT DATA OUT ROUTINE
;*************************************
;
;clock variable number of bits to TLC5941.
;clocks out as most significant bit first then works down through byte
;r8 = address of byte containing data to shift (word length)
;r9 = number of bits 1-8 to shift out (byte length)
;r10 used for temporary storage for shifting
;
;This routine shifts out a variable number of bits from a byte
;stored in the location pointed to by R8. The data to be sent
;is stored left aligned to the most significant bit.
;For example, a 6 bit value of 0x3F would be stored as 0xFC
;with the two least significant bits set to zero.
;
;Registers R8 and R9 are used to pass parameters to this routine.
;Prior to calling this routine, R8 should contain the address of the
;byte of data to be shifted out. R9 should contain the number of bits
;that need to be shifted out.
;R9 will be used as a loop counter in this routine. The contents of R9
;will not be preserved when returning form this routine.
SHIFTOUT
MOV.B @r8,r10 ;move the byte stored in the memory location
;pointed to by register 8 into register 10
ctbit
BIC.B #SIN,&P1OUT ;clear the bit controlling SIN to zero
BIT.B #80h,R10 ;test state of the most significant bit
;of the data remaining to be shifted out
;since we shift the MSB first, the software
;looks at the MSB of R10 to decide what data
;to shift out.
JZ sdateq0 ;if the bit to shift out is a zero then skip ahead
;because SIN was previously set to zero
BIS.B #SIN,&P1OUT ;The data to shift out is a one so set the bit
;controlling SIN to a one
sdateq0
BIS.B #SCLK,&P1OUT ;set the bit controlling SCLK to a one
BIC.B #SCLK,&P1OUT ;clear the bit controlling SCLK to a zero
;the last two commands pulse the SCLK
;signal which latches the data on SIN into
;the shift register of the TLC5941
RLA.B R10 ;shift the data stored in register 10
;one bit left.The LSB of R10 will have a zero
;shifted in.
DEC.B R9 ;decrement number of bits to send
JNZ ctbit ;jump if not zero. continue until all bits are sent
RET ;return from subroutine
;--------------------------------------------------------------
; INTERRUPT ROUTINES
;--------------------------------------------------------------
;--------------------------------------------------------------
;ISR: Interrupt Service Routine for Timer
;--------------------------------------------------------------
;
;timer interrupt routine
;when the timer count reaches 4097 it will issue an
;interrupt. The processor jumps to here to service the interrupt.
;This interrupt routine toggles the bit controlling the BLANK
;pin of the TLC5941. When the BLANK line of the TLC5941,
;it resets the internal grayscale counter and starts a new
;grayscale frame.
;
BIS.B #BLANK,&P1OUT ;Toggle bit controlling BLANK
BIC.B #BLANK,&P1OUT ;signal. First high then low.
RETI ;Return from ISR
;-----------------------------------------------------------------
; Interrupt Vectors
;-----------------------------------------------------------------
;
;this segment is used to define the interrupt vectors in memory
;
ORG 0FFFEh ; RESET Vector
DW RESET ;
ORG 0FFECh ; Timer Interrupt Vector
DW ISR ;
END