MSP430F5510 sample code for RobG’s USB dev board

Just a few pieces of sample code that I have thrown together to get a good understanding of how to make a f5510 work for me.

Also you can find more work of mine at http://43oh.com

The board that I am working with

http://store.43oh.com/index.php?route=product/product&product_id=93

 

 //******************************************************************************
// MSP430F550x Demo - USCI_A1, 9600 UART, SMCLK, LPM0, Echo with over-sampling
//
// Description: Echo a received character, RX ISR used. Normal mode is LPM0.
// USCI_A1 RX interrupt triggers TX Echo.
// If UCOS16=1, UCBRx=Fbrclk/(16*Baudrate)
// Baud rate divider with UCBRx = 1MHz/(16*9600) = ~6.8
// ACLK = REFO = ~32768Hz, MCLK = SMCLK = default DCO = 32 x ACLK = 1048576Hz
// See User Guide for baud rate divider table
//
// MSP430F550x
// -----------------
// /|| |
// | | |
// --|RST |
// | |
// | P4.4/UCA0TXD|------------>
// | | 9600 - 8N1 (un sure which is which)
// | P4.5/UCA0RXD|<------------
//
// D. Archbold
// Texas Instruments Inc.
// March 2010
// Built with CCSv4 and IAR Embedded Workbench Version: 4.21
//******************************************************************************
// modified by Justin Solarski for use with Robs f5510 usb board
#include
//#include "cust_def.h"
//#define __even_in_range(A,B) (A) //defined for mspgcc
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P4SEL = BIT5+BIT4; // P3.4,5 = USCI_A0 TXD/RXD
UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
UCA1CTL1 |= UCSSEL_2; // SMCLK
UCA1BR0 = 6; // 1MHz 9600 (see User's Guide)
UCA1BR1 = 0; // 1MHz 9600
UCA1MCTL = UCBRS_0 + UCBRF_13 + UCOS16; // Modln UCBRSx=0, UCBRFx=0,
// over sampling
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA1IE |= UCRXIE; // Enable USCI_A0 RX interrupt
__bis_SR_register(LPM3_bits + GIE); // Enter LPM0, interrupts enabled
__no_operation(); // For debugger
}
// Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
switch(__even_in_range(UCA1IV,4))
{
case 0:break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
while (!(UCA1IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
UCA1TXBUF = UCA1RXBUF; // TX -> RXed character
break;
case 4:break; // Vector 4 - TXIFG
default: break;
}
}

Multi UART

//******************************************************************************
// MSP430x550x Demo - Port Mapping Port4; Single runtime configuration
// With Dual UART
//
// 4.5 -->UCA1RXD
// 4.4 -->UCA1TXD
//
// 4.1 -->UCA0RXD
// 4.2 -->UCA0TXD
//
// D. Archbold
// Texas Instruments Inc.
// April 2009
// Built with CCSv4 and IAR Embedded Workbench Version: 4.21
//******************************************************************************
//modified by justin solarski
//for use with Rob's 5510 usb dev board

#include
#include “cust_def.h”
// Function Definition
void Port_Mapping(void);
void Uart_Init0(void);
void Uart_Init1(void);
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
Port_Mapping();
P4SEL = BIT5+BIT4+BIT1+BIT2; // P3.4,5 = USCI_A0 TXD/RXD
Uart_Init0();
Uart_Init1();

__bis_SR_register(LPM0_bits + GIE); // Enter LPM3
__no_operation(); // For debugger
}
void Port_Mapping(void)
{
unsigned char i;
volatile unsigned char *ptr;
__disable_interrupt(); // Disable Interrupts before altering Port Mapping registers
PMAPPWD = 0x02D52; // Enable Write-access to modify port mapping registers

#ifdef PORT_MAP_RECFG
PMAPCTL = PMAPRECFG; // Allow reconfiguration during runtime
#endif

P4MAP1 = PM_UCA0RXD;
P4MAP2 = PM_UCA0TXD;

PMAPPWD = 0; // Disable Write-Access to modify port mapping registers
#ifdef PORT_MAP_EINT
__enable_interrupt(); // Re-enable all interrupts
#endif

}
//*********************************************************************************
//init uart 1
void Uart_Init1(void)
{
UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
UCA1CTL1 |= UCSSEL_2; // SMCLK
UCA1BR0 = 6; // 1MHz 9600 (see User’s Guide)
UCA1BR1 = 0; // 1MHz 9600
UCA1MCTL = UCBRS_0 + UCBRF_13 + UCOS16; // Modln UCBRSx=0, UCBRFx=0,
// over sampling
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA1IE |= UCRXIE; // Enable USCI_A0 RX interrupt

}
//*********************************************************************************
//init uart 0
void Uart_Init0(void)
{
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 6; // 1MHz 9600 (see User’s Guide)
UCA0BR1 = 0; // 1MHz 9600
UCA0MCTL = UCBRS_0 + UCBRF_13 + UCOS16; // Modln UCBRSx=0, UCBRFx=0,
// over sampling
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt

}
// Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
switch(__even_in_range(UCA0IV,4))
{
case 0:break; // Vector 0 – no interrupt
case 2: // Vector 2 – RXIFG
while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = UCA0RXBUF; // TX -> RXed character
break;
case 4:break; // Vector 4 – TXIFG
default: break;
}
}

// Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
switch(__even_in_range(UCA1IV,4))
{
case 0:break; // Vector 0 – no interrupt
case 2: // Vector 2 – RXIFG
while (!(UCA1IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
UCA1TXBUF = UCA1RXBUF; // TX -> RXed character
break;
case 4:break; // Vector 4 – TXIFG
default: break;
}
}

PrintF

//******************************************************************************
//******************************************************************************
#include
#include "cust_def.h"
#include "stdarg.h"
void Uart_Init1(void);
//*****************************************************************************
/* Printf functions */
void Clk_Init(void);
void putchar(unsigned char byte);
void linesUp(unsigned char lines);
int prints(char *string, unsigned char width, unsigned char pad);
int printi(long int i, unsigned char b, unsigned char sg, unsigned char width, unsigned char pad, unsigned char letbase);
int printf(char *format, ...);
//*****************************************************************************
/* printf defines */
#define PAD_RIGHT 0x01
#define PAD_ZERO 0x02
#define PRINT_BUF_LEN 12
//*****************************************************************************
char *s;
char c;
int i;
unsigned u;
long int l;
long unsigned n;
unsigned x;

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
Clk_Init();
P4SEL = BIT5+BIT4;
Uart_Init1();
__bis_SR_register( GIE); // Enter LPM3
printf(“%s”, “rn*** printf() test ***rn”);
putchar©;
s = “test”;
c = ‘X’;
i = -12345;
u = 12345;
l = -1234567890;
n = 1234567890;
x = 0xABCD;
printf(“String %srn”, s);
__delay_cycles(250000);
printf(“Char %crn”, c);
__delay_cycles(250000);
printf(“Integer %irn”, i);
__delay_cycles(250000);
printf(“Unsigned %urn”, u);
__delay_cycles(250000);
printf(“Long %lrn”, l);
__delay_cycles(250000);
printf(“uNsigned loNg %nrn”, n);
__delay_cycles(250000);
printf(“heX %xrn”, x);
__delay_cycles(250000);
printf(“multiple args %s %c %i %u %l %n %xrn”, s, c, i, u, l, n, x);
__delay_cycles(250000);
printf(“rn*** Done ***rn”);
__delay_cycles(250000);
while(1)
{
printf(” hello world “,”n”);
__delay_cycles(250000);
}

__bis_SR_register(LPM0_bits + GIE); // Enter LPM3
__no_operation(); // For debugger
}
//*********************************************************************************
void Clk_Init(void)
{
UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFO
UCSCTL4 |= SELA_2; // Set ACLK = REFO
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
// Loop until XT1,XT2 & DCO stabilizes – In this case only DCO has to stabilize
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag

__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation
UCSCTL2 |= 249; // Set DCO Multiplier for 8MHz
// (N + 1) * FLLRef = Fdco
// (249 + 1) * 32768 = 8MHz
__bic_SR_register(SCG0); // Enable the FLL control loop
// Worst-case settling time for the DCO when the DCO range bits have been
// changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
// UG for optimization.
// 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
__delay_cycles(250000);
}
//*********************************************************************************
//init uart 1
void Uart_Init1(void)
{
UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
UCA1CTL1 |= UCSSEL_2; // SMCLK
UCA1BR0 = 65; // 8MHz 9600 (see User’s Guide)
UCA1BR1 = 3; // 8MHz 9600
UCA1MCTL = UCBRS_2 + UCBRF_0; // Modln UCBRSx=0, UCBRFx=0, + UCOS16
// over sampling
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
//UCA1IE |= UCRXIE; // Enable USCI_A0 RX interrupt

}
//*********************************************************************************
//printf source from http://forum.43oh.com/topic/396-getting-printf-working/page__hl__printf
/*——————————————————————-
DESCRIPTION: Send one char in TX buffer, if it is not busy. Wait until not busy.
INPUTS: One char.
OUTPUTS: Send all the char in TX buffer.
RETURNS: None.
———————————————————————*/

// Modify this routine so that it points to YOUR UART (zeke)
void putchar(unsigned char byte)
{
while (!(UCA1IFG&UCTXIFG));
//while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA1TXBUF = byte; // Load Tx register that clear UCA0TXIFG
}

/*——————————————————————-
DESCRIPTION: Move numbers of lines up in the HyperTerminal.
INPUTS: None.
OUTPUTS: Line up to TX buffer.
RETURNS: None.
———————————————————————*/

void linesUp(unsigned char lines)
{
unsigned char i;
for (i = 0; i < lines; ++i)
{
putchar(0x1b);
putchar(0x5b);
putchar(0x41);
}
}

/*——————————————————————-
DESCRIPTION: Send out charater strings with defined width, justification
and padding. Width = 0 or width < string length means unlimited width. Normal padding is space and left justification, but it can pad ‘0’ or pad to the right side, depending on pad value. pad justification padding char bxxxxxx00 left ‘ ‘ bxxxxxx1x right ‘ ‘ or ‘0’ bxxxxxxx1 left or right ‘0’ INPUTS: Valid string and special charater in form of “n” for example refered by pointer *string. Output field width. Justification and padding flag pad. OUTPUTS: Sent formated string to com port output. RETURNS: Total of chars sent. ———————————————————————*/ int prints(char *string, unsigned char width, unsigned char pad) { int pc = 0; unsigned char padchar = ‘ ‘; // The pading char is space normally if (width > 0) // If output width is defined
{
unsigned char len = 0;
char *ptr;
for (ptr = string; *ptr; ++ptr) ++len; // Calculate string length and put it in len
if (len >= width) width = 0; // If string is longer than width, then width is not applicable define as zero
else width -= len; // Else redefine width as padding spaces
if (pad & PAD_ZERO) padchar = ‘0’; // If padding char is zero, then get padchar as zero ready instead of original space
}
if (!(pad & PAD_RIGHT)) // If not right padding – left justification
{
for (; width > 0; –width) // If ther is padding width. Output padding char as ‘0’ or ‘ ‘.
{
putchar (padchar);
++pc;
}
}
for (; *string ; ++string) // Output the full string
{
putchar (*string);
++pc;
}
for (; width > 0; –width) { // Write padding char to the right if normal left justification
putchar (padchar);
++pc;
}
return pc; // Return the output char number
}

/*——————————————————————-
* DESCRIPTION: Print 32 bit signed interger in dec or hex. In specific
* width, padding and justification using prints(). Use 12 byte buffer
* which is enough for 32 bit int.
* INPUTS: Up to 32 byte signed interger i. Counting base: 10 or 16.
* Sign flag sg. Output string width. padding and justification flag.
* Leter base for number conversion.
* OUTPUTS: Sent formated interger as string to com port output.
* RETURNS: Total of chars sent.
———————————————————————*/

int printi(long int i, unsigned char b, unsigned char sg, unsigned char width, unsigned char pad, unsigned char letbase)
{
char print_buf[PRINT_BUF_LEN]; // Interger as string array
char *s;
char neg = 0;
unsigned long int t;
unsigned long int u = i;
int pc = 0;

if (i == 0) // If output char is 0, then just output it with padding and width.
{
print_buf[0] = ‘0’;
print_buf[1] = ‘’; // Always remenber to put string end
return prints(print_buf, width, pad); //Print out zero and done.
}

if (sg && (b == 10) && (i < 0)) // If it is a negative int, then record the ‘-‘ and number as positive { neg = 1; u = -i; } s = print_buf + PRINT_BUF_LEN-1; // Point s to the end of the output buffer and put a null there. *s = ‘’; while (u) // Convert the positive int to string with whatever counting base, dec, or hex. { t = u % b; if( t >= 10 )
t += letbase – ‘0’ – 10;
*–s = t + ‘0’;
u /= b;
}

if (neg)
{ // If it is a negative number
if( width && (pad & PAD_ZERO) )
{ // If there is width, right justified and pad with zero, output negative sign.
putchar (‘-‘);
++pc;
–width;
}
else *–s = ‘-‘; // Otherwise put the ‘-‘ to string buffer.

}
return pc + prints (s, width, pad); // Output the string buffer and return the output counter.
}

/*——————————————————————-
* DESCRIPTION: short form of printf. Print argument strings with mixed
* varables (string or interger)inside formated.
* INPUTS: Argument string pointer.
* OUTPUTS: print out the argument with style using prints() and printi().
* RETURNS: Total of chars sent.
* Warning!!! varables and constant numbers even 0, must casted with
* (long int)in printf(), if it is going to print out using
* format “u”, “d”, “X” and “x”! Or the complier will assigned
* 16-bit for data smaller than 16 bit and the argument pointer
* will fetch a wrong 32-bit data and the argument point
* increament will be in wrong size.
* Limitations: 1) It treats all interger as 32 bit data only.
* 2) No floating point data presentation.
* 3) Has left/right alignment with 0 padding.
* 4) Has format code “s”, “d”, “X”, “x”, “u” and “c” only.
———————————————————————*/

int printf(char *format, …)
{
int width, pad;
int pc = 0;
char scr[2];
va_list args;
va_start(args, format);

for (; *format != 0; ++format) {
if (*format == ‘%’) {
++format;
width = pad = 0;
if (*format == ‘’) break;
if (*format == ‘%’) goto out;
if (*format == ‘-‘) {
++format;
pad = PAD_RIGHT;
}
while (*format == ‘0’) {
++format;
pad |= PAD_ZERO;
}
for ( ; *format >= ‘0’ && *format <= ‘9’; ++format) {
width *= 10;
width += *format – ‘0’;
}
if( *format == ‘s’ ) {
char *s = (char *)va_arg( args, int );
pc += prints (s?s:”(null)”, width, pad);
continue;
}
if( *format == ‘d’ ) {
pc += printi (va_arg( args, long int ), 10, 1, width, pad, ‘a’);
continue;
}
if( *format == ‘x’ ) {
pc += printi (va_arg( args, long int ), 16, 0, width, pad, ‘a’);
continue;
}
if( *format == ‘X’ ) {
pc += printi (va_arg( args, long int ), 16, 0, width, pad, ‘A’);
continue;
}
if( *format == ‘u’ ) {
pc += printi (va_arg( args, long int ), 10, 0, width, pad, ‘a’);
continue;
}
if( *format == ‘c’ ) { // char are converted to int then pushed on the stack
scr[0] = (char)va_arg( args, int );
scr[1] = ‘’;
pc += prints (scr, width, pad);
continue;
}
}
else {
out:
putchar(*format);
++pc;
}
}
va_end( args );
return pc;
}

//#pragma vector=USCI_A1_VECTOR
//__interrupt void USCI_A1_ISR(void)
//{
//nop();
//}

 

the custom header

/* custom defines for IAR CCS syntax
Used for compatibility with UBS TI API */
//released under no licence, open to the public.
//By J. Solarski justin@justinstech.org

#define __no_init
#define __data16
#define __even_in_range(A,B)

sorry the code tags suck on WP, please bare with me until it is fixed.
if you need the code right away, please go to 43oh forums