Skip to content

Commit

Permalink
Added support for MSP430G2553
Browse files Browse the repository at this point in the history
Added set of #defines to differentiate between the originally targeted
MSP430FR5739 and the MSP430G2553 that I wanted to use (because it
currently comes with the TI MSP430 Launchpad). MSP430G2553 has some
different register names and no DMA support.
  • Loading branch information
infinityis committed Jul 13, 2014
1 parent 17a39c3 commit c1c574d
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 52 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ One 3-bit and one 4-bit encoding was implemented for a SPI clock speed as low as
* __
* ONE : 110 |_
*
* SPI Clock around 2.66MHz
*
* the bti in the middle defines the value
*
* data stream: 0x23 0 0 1 0 0 0 1 1
Expand Down
119 changes: 83 additions & 36 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@
#define NUMBEROFLEDS 15
#define ENCODING 3 // possible values 3 and 4

//For MSP430G2553, this works for up to 32 LEDs with encoding of 4, or 39 LEDs with encoding of 3. Beyond that it seems to use too much memory.

/*
* In places with preprocessor directives like: #if defined(UCA0CTLW0)
* the code is checking to see what capabilities exist for the target microcontroller.
* If the value in question is defined, it means that a certain capabilities exist or
* register names differ, and code appropriate to the device will be used.
*/

void configClock(void);
void configSPI(void);
void sendBuffer(uint8_t* buffer, ledcount_t ledCount);
void sendBufferDma(uint8_t* buffer, ledcount_t ledCount);
void shiftLed(ledcolor_t* leds, ledcount_t ledCount);


int main(void) {

// buffer to store encoded transport data
Expand Down Expand Up @@ -68,14 +75,14 @@ int main(void) {
while(1) {
// blank all LEDs
fillFrameBufferSingleColor(&blankLed, NUMBEROFLEDS, frameBuffer, ENCODING);
sendBufferDma(frameBuffer, NUMBEROFLEDS);
sendBuffer(frameBuffer, NUMBEROFLEDS);
__delay_cycles(0x100000);

// Animation - Part1
// set one LED after an other (one more with each round) with the colors from the LEDs array
fillFrameBuffer(leds, NUMBEROFLEDS, frameBuffer, ENCODING);
for(update=1; update <= NUMBEROFLEDS; update++) {
sendBufferDma(frameBuffer, update);
sendBuffer(frameBuffer, update);
__delay_cycles(0xFFFFF);
}
__delay_cycles(0xFFFFFF);
Expand All @@ -85,7 +92,7 @@ int main(void) {
for(update=0; update < 15*8; update++) {
shiftLed(leds, NUMBEROFLEDS);
fillFrameBuffer(leds, NUMBEROFLEDS, frameBuffer, ENCODING);
sendBufferDma(frameBuffer, NUMBEROFLEDS);
sendBuffer(frameBuffer, NUMBEROFLEDS);
__delay_cycles(0x7FFFF);
}

Expand All @@ -95,19 +102,19 @@ int main(void) {
for(colorIdx=0; colorIdx < 0xFF; colorIdx++) {
led.red = colorIdx + 1;
fillFrameBufferSingleColor(&led, NUMBEROFLEDS, frameBuffer, ENCODING);
sendBufferDma(frameBuffer, NUMBEROFLEDS);
sendBuffer(frameBuffer, NUMBEROFLEDS);
__delay_cycles(0x1FFFF);
}
for(colorIdx=0; colorIdx < 0xD0; colorIdx++) {
led.green = colorIdx;
fillFrameBufferSingleColor(&led, NUMBEROFLEDS, frameBuffer, ENCODING);
sendBufferDma(frameBuffer, NUMBEROFLEDS);
sendBuffer(frameBuffer, NUMBEROFLEDS);
__delay_cycles(0x2FFFF);
}
for(colorIdx=0; colorIdx < 0x50; colorIdx++) {
led.blue = colorIdx;
fillFrameBufferSingleColor(&led, NUMBEROFLEDS, frameBuffer, ENCODING);
sendBufferDma(frameBuffer, NUMBEROFLEDS);
sendBuffer(frameBuffer, NUMBEROFLEDS);
__delay_cycles(0x3FFFF);
}
__delay_cycles(0xFFFFF);
Expand All @@ -127,61 +134,101 @@ void shiftLed(ledcolor_t* leds, ledcount_t ledCount) {
}

// copy bytes from the buffer to SPI transmit register
// should be reworked to use DMA
void sendBuffer(uint8_t* buffer, ledcount_t ledCount) {
uint16_t bufferIdx;
for (bufferIdx=0; bufferIdx < (ENCODING * sizeof(ledcolor_t) * ledCount); bufferIdx++) {
while (!(UCA0IFG & UCTXIFG)); // wait for TX buffer to be ready
UCA0TXBUF_L = buffer[bufferIdx];
}
__delay_cycles(300);
}

void sendBufferDma(uint8_t* buffer, ledcount_t ledCount) {
DMA0SA = (__SFR_FARPTR) buffer; // source address
#if defined(DMA0CTL_) //used for MSP430FR5739 (and similar)
//If DMA exists for the microcontroller, this code will make use of it
DMA0SA = (__SFR_FARPTR) buffer; // source address
DMA0DA = (__SFR_FARPTR) &UCA0TXBUF_L; // destination address
// single transfer, source increment, source and destination byte access, interrupt enable
DMACTL0 = DMA0TSEL__UCA0TXIFG; // DMA0 trigger input
DMACTL0 = DMA0TSEL__UCA0TXIFG; // DMA0 trigger input
DMA0SZ = (ENCODING * sizeof(ledcolor_t) * ledCount);
DMA0CTL = DMADT_0 | DMASRCINCR_3 | DMASRCBYTE | DMADSTBYTE | DMAEN; //| DMAIE;
DMA0CTL = DMADT_0 | DMASRCINCR_3 | DMASRCBYTE | DMADSTBYTE | DMAEN;

//start DMA
UCA0IFG ^= UCTXIFG;
UCA0IFG ^= UCTXIFG;
#else
uint16_t bufferIdx;
for (bufferIdx=0; bufferIdx < (ENCODING * sizeof(ledcolor_t) * ledCount); bufferIdx++) {
// wait for TX buffer to be ready
#if defined(UCA0TXIFG) //used for MSP430G2553 (and similar)
while (!(IFG2 & UCA0TXIFG));
#elif defined(UCA0IFG) //used for MSP430FR5739 (and similar)
while (!(UCA0IFG & UCTXIFG));
#endif

#if defined(UCA0TXBUF_) //used for MSP430FR5739 (and similar) where the USCI TX buffer is two bytes in size
UCA0TXBUF_L = buffer[bufferIdx];
#else //used for MSP430G2553 and similar where the USCI TX buffer is one byte in size
UCA0TXBUF = buffer[bufferIdx];
#endif

}
__delay_cycles(300);
#endif
}

// configure MCLK and SMCLK to be sourced by DCO with a frequency of
// 8Mhz (3-bit encoding)
// 6.7MHz (4-bit encoding)




void configClock(void) {
#if defined(CSCTL0_) //used for MSP430FR5739 (and similar)
// configure MCLK and SMCLK to be sourced by DCO with a frequency of
// 8Mhz (3-bit encoding)
// 6.7MHz (4-bit encoding)
CSCTL0_H = 0xA5;
#if ENCODING == 3
CSCTL1 = DCOFSEL_3; // DCO frequency setting = 8MHz
#else
CSCTL1 = DCOFSEL_2; // DCO frequency setting = 6.7MHz
#endif
#if ENCODING == 3
CSCTL1 = DCOFSEL_3; // DCO frequency setting = 8MHz
#else
CSCTL1 = DCOFSEL_2; // DCO frequency setting = 6.7MHz
#endif
CSCTL2 = SELS__DCOCLK + SELM__DCOCLK;
CSCTL3 = DIVS__1 + DIVM__1;
#else //used for MSP430G2553 (and similar)
// configure MCLK and SMCLK to be sourced by DCO with a frequency of 16Mhz
BCSCTL1 = CALBC1_16MHZ; //DCO frequency setting 16MHz
DCOCTL = CALDCO_16MHZ;

BCSCTL2 = DIVS_0 + DIVM_0 + SELM_0; //set MCLK and SMCLK to the DCO clock of 16MHz
#endif
}

void configSPI(void) {

#if defined(UCA0CTLW0) //used for MSP430FR5739 (and similar)
UCA0CTLW0 |= UCSWRST; // **Put state machine in reset**
UCA0CTLW0 |= UCMST + UCSYNC + UCCKPL + UCMSB; // 3-pin, 8-bit SPI master
// Clock polarity high, MSB
UCA0CTLW0 |= UCSSEL__SMCLK; // SMCLK

#if ENCODING == 3
UCA0BR0 = 3; // SPICLK 8MHz/3 = 2.66MHz
#if ENCODING == 3
UCA0BR0 = 3; // SPICLK 8MHz/3 = 2.66MHz
UCA0BR1 = 0;
#else
UCA0BR0 = 2; // SPICLK 6.7MHz/2 = 3.35MHz
#else
UCA0BR0 = 2; // SPICLK 6.7MHz/2 = 3.35MHz
UCA0BR1 = 0;
#endif
#endif
UCA0MCTLW = 0; // No modulation
UCA0CTLW0 &= ~UCSWRST;
#else //used for MSP430G2553 (and similar)
UCA0CTL1 |= UCSWRST; //hold USCI A0 in reset

UCA0CTL0 = UCCKPH | UCMSB | UCMST | UCMODE_0 | UCSYNC;
UCA0CTL1 = UCSSEL_2 | UCSWRST; // Clock from SMCLK; hold in reset
#if ENCODING == 3
UCA0BR0 = 6; // SPICLK 16MHz/6 = 2.66MHz
UCA0BR1 = 0;
#else
UCA0BR0 = 5; // SPICLK 16MHz/5 = 3.2MHz
UCA0BR1 = 0; // 3.2MHz provides 0.31us per bit, so 4 bit operation results in
// 0.31us (within 0.15us of both 0.40us and 0.45us) and and 0.93us (within 0.15us of 0.80us and 0.85us)
#endif

P1SEL = BIT1 + BIT2; //need to set P1SEL to assign pins to the USCI peripheral
P1SEL2 = BIT1 + BIT2; //need to set P1SEL to assign pins to the USCI peripheral

UCA0CTL1 &= ~UCSWRST; //release USCI A0 to operate normally
#endif

// UCB0SIMO = LED data signal on P2.0
P2SEL0 &= ~BIT0;
P2SEL1 |= BIT0;
}
17 changes: 9 additions & 8 deletions ws2812/ws2812.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*
*/

#define BIT0 0x01

#include "ws2812.h"

Expand Down Expand Up @@ -112,22 +113,22 @@ void encodeData3bit(ledcolor_t* led, uint8_t* output) {
// right shift bits
shiftRegister = grbLED[colorIdx];
shiftRegister >>= 1; // 1 shift from original
output[outputIdx+0] |= (shiftRegister & BIT6); // source bit 7
output[outputIdx+1] |= (shiftRegister & BIT2); // source bit 3
output[outputIdx+0] |= (shiftRegister & 0x40); // shiftregister bit 6, source bit 7
output[outputIdx+1] |= (shiftRegister & 0x04); // shiftregister bit 2, source bit 3
shiftRegister >>= 2; // 3 shifts from original
output[outputIdx+0] |= (shiftRegister & BIT3); // source bit 6
output[outputIdx+0] |= (shiftRegister & 0x08); // shiftregister bit 3, source bit 6
shiftRegister >>= 2; // 5 shifts from original
output[outputIdx+0] |= (shiftRegister & BIT0); // source bit 5
output[outputIdx+0] |= (shiftRegister & 0x01); // shiftregister bit 0, source bit 5

// left shift bits
shiftRegister = grbLED[colorIdx];
shiftRegister <<= 1; // 1 shift from original
output[outputIdx+1] |= (shiftRegister & BIT5); // source bit 4
output[outputIdx+2] |= (shiftRegister & BIT1); // source bit 0
output[outputIdx+1] |= (shiftRegister & 0x20); // shiftregister bit 5, source bit 4
output[outputIdx+2] |= (shiftRegister & 0x02); // shiftregister bit 1, source bit 0
shiftRegister <<= 2; // 3 shifts from original
output[outputIdx+2] |= (shiftRegister & BIT4); // source bit 1
output[outputIdx+2] |= (shiftRegister & 0x10); // shiftregister bit 4, source bit 1
shiftRegister <<= 2; // 5 shifts from original
output[outputIdx+2] |= (shiftRegister & BIT7); // source bit 2
output[outputIdx+2] |= (shiftRegister & 0x80); // shiftregister bit 7, source bit 2

outputIdx += 3; // next three bytes (color)
}
Expand Down
9 changes: 1 addition & 8 deletions ws2812/ws2812.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
#include <stdint.h>

#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
//removed the BIT0, BIT1, etc. #defines as it conflicted with those in the microcontroller-specific header files

typedef struct {
uint8_t red;
Expand Down

0 comments on commit c1c574d

Please sign in to comment.