Jump to content
43oh

Sample code for Rob's f5510 usb dev board


Recommended Posts

Sample code for Rob's msp430f5510 usb dev kit from the store

 

This code is a modified version of the sample code from TI.

This will get you a basic working UART. This is the echo example.

 

//******************************************************************************
// 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 <msp430f5510.h>
//#include "cust_def.h"
//#define __even_in_range(A, (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;
}
}

 

In the attached file is the mspgcc version with make file f5510uart.zip

Link to post
Share on other sites

Here's my example for communication over USB-CDC based on the TI example:

 

/***
   Standard-Includes
***/

#include "stdbool.h"

/***
   USB-Includes
***/

#include "USB_config/descriptors.h"

#include "USB_API/types.h"
#include "USB_API/device.h"
#include "USB_API/usb.h"
#include "USB_API/UsbCdc.h"
#include "usbConstructs.h"

/***
   HAL-Includes
***/

#include "F5510/HAL_UCS.h"
#include "F5510/HAL_PMM.h"

/***
   USB-Variables
***/

// Flag set by event handler to indicate data has been received into USB buffer
volatile BYTE bCDCDataReceived_event = false;

#define BUFFER_SIZE 64
char dataBuffer[bUFFER_SIZE] = "";

/***
   Send data
***/

void SendData(BYTE output) {
   WORD x = 0;
   BYTE out[1] = { output };

   // send it over USB
   if (cdcSendDataWaitTilDone(out, 1, CDC0_INTFNUM, 0)) {
       // it failed for some reason; abort and leave the
       USBCDC_abortSend(&x, CDC0_INTFNUM);
   }
}

/***
   Handling of incomming data
***/

void DataHandling(BYTE input) {
     // DO SOMETHING
}

/***
   MAIN
***/

void main(void) {
   // Stop watchdog timer
   WDTCTL = WDTPW + WDTHOLD;

// Higher Vcore needed for 24 MHz
   SetVCore(PMMCOREV_3);

   // enable XT2 pins
   P5SEL |= 0x0C;

   UCSCTL6 |= XT2DRIVE_2;

   // Start crystal
   UCSCTL6 &= ~XT2OFF;

   // wait at least 2ms for XT2 to settle
   __delay_cycles(50000);

   // Clear all OSC fault Flags
   UCSCTL7 = 0;

   // MCLK = XT2-Freq.
   SELECT_MCLK(SELM__XT2CLK);

   // full speed
   MCLK_DIV(1);

// Initialization of USB module
   // Init USB
   USB_init();

   // Enable all USB event handling routines
   USB_setEnabledEvents(kUSB_allUsbEvents);

   // See if we're already attached physically to USB, and if so, connect to it
   // Normally applications don't invoke the event handlers, but this is an exception.
   if (USB_connectionInfo() & kUSB_vbusPresent) {
       if (USB_enable() == kUSB_succeed) {
           USB_reset();
           USB_connect();
       }
   }

   // enable interrupts
   __bis_SR_register(GIE);

   // main loop
   while (1) {
       // ST_ENUM_ACTIVE
       if ((USBPWRCTL & USBBGVBV) && (USBCNF & PUR_EN) && (bEnumerationStatus == ENUMERATION_COMPLETE) && (!(bFunctionSuspended == TRUE))) {
           while (bCDCDataReceived_event) {
               // Clear flag early -- just in case execution breaks below because of an error
               bCDCDataReceived_event = false;

               // Count has the number of bytes received into dataBuffer
               WORD count = cdcReceiveDataInBuffer((BYTE*) dataBuffer,    BUFFER_SIZE, CDC0_INTFNUM);

               // process incomming data
               WORD c = 0;
               while (c < count) {
                   DataHandling(dataBuffer[c]);
                   c++;
               }
           }
       }
   }
}

Link to post
Share on other sites

Dual Uart for the F5510

 

//******************************************************************************
// 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 <msp430f5510.h>
#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;
 }
}

 

In theory you could have 2 UART and 2 SPI , or 2 SPI and 1 I2C or any combination that equals up to 8 ports (P4.x)

If I am correct you have 2 x UCA and 2 x UCB to use on this one.

FYI this is just sample code to get you the basic setup.

Link to post
Share on other sites

Printf from the forums,

http://forum.43oh.com/topic/396-getting-printf-working/page__hl__printf

 

Main Clock runs at 8Mhz, in the end it will go into a while loop, printing "hello world" over and over again

Tested and works

 

//******************************************************************************
//******************************************************************************
#include <msp430f5510.h>
#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", "\r\n*** printf() test ***\r\n");
 putchar(c);
 s = "test";
 c = 'X';
 i = -12345;
 u = 12345;
 l = -1234567890;
 n = 1234567890;
 x = 0xABCD;
 printf("String		 %s\r\n", s);
__delay_cycles(250000);
 printf("Char			 %c\r\n", c);
__delay_cycles(250000);
 printf("Integer %i\r\n", i);
__delay_cycles(250000);
 printf("Unsigned		 %u\r\n", u);
__delay_cycles(250000);
 printf("Long			 %l\r\n", l);
__delay_cycles(250000);
 printf("uNsigned loNg %n\r\n", n);
 __delay_cycles(250000);
 printf("heX			 %x\r\n", x);
 __delay_cycles(250000);
 printf("multiple args %s %c %i %u %l %n %x\r\n", s, c, i, u, l, n, x);
 __delay_cycles(250000);
 printf("\r\n*** Done ***\r\n");
__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] = '\0';								 // 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 = '\0';

	 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 == '\0') 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] = '\0';
											 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();
//}

Link to post
Share on other sites

quick custom definitions for IAR and CCS compatibility

 

/* 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, (A)

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.

×
×
  • Create New...