Jump to content
43oh

Tiny printf() - C version


Recommended Posts

  • 1 month later...
  • Replies 60
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

This is a tiny printf() function that can be used with the chips that come with the Launchpad. Code size is about 640 bytes with CCS.   There are 7 format specifiers: %c - Character %s - String %

CCS requires labels in asm code to begin in the first column, so leading spaces will cause problems. This is typical for assembler code.   Firefox may have problems with copy/paste from the forum. C

This code was written when the MSP430 Lauchpad shipped with chips that had 128 bytes of RAM, 2k of flash, and no hardware serial port. So it was important to keep code very compact and a software UART

Posted Images

  • 1 month later...

This is a tiny printf() function that can be used with the chips that come with the Launchpad. Code size is about 640 bytes with CCS.

 

Hi,

Could you please help me with rewriting this function so that it prints to pre-allocated char array like sprintf does? I'm currently struggling with passing addresses to pointers which I think is neccessary, but I got lost.

void usprintf(char* str, char* format, ...)
{
	char c;
	int i;
	long n;

	va_list a;
	va_start(a, format);
	while (c = *format++)
	{
		if (c == '%')
		{
			switch (c = *format++)
			{
			case 's':                       // String
				//usputs(str, va_arg(a, char*));
				break;
			case 'c':                       // Char
				usputc(&str, va_arg(a, char));
				break;
			case 'i':                       // 16 bit Integer
			case 'u':                       // 16 bit Unsigned
				i = va_arg(a, int);
				if (c == 'i' && i < 0)
					i = -i, usputc(&str, '-');
				xtoa((unsigned) i, dv + 5);
				break;
			case 'l':                       // 32 bit Long
			case 'n':                       // 32 bit uNsigned loNg
				n = va_arg(a, long);
				if (c == 'l' && n < 0)
					n = -n, usputc(&str, '-');
				xtoa((unsigned long) n, dv);
				break;
			case 'x':                       // 16 bit heXadecimal
				i = va_arg(a, int);
				puth(i >> 12);
				puth(i >> 8);
				puth(i >> 4);
				puth(i);
				break;
			case 0:
				return;
			default:
				goto bad_fmt;
			}
		}
		else
			bad_fmt: usputc(&str, c);
	}
	*str++ = '\0';
	va_end(a);
}

void usputc(char** target_str, unsigned char c)
{
	printf("usputc, adress str: %u\n\r",**target_str);
	**target_str++;
}


static void usxtoa(char* str, unsigned long x, const unsigned long *dp)
{
	char c;
	unsigned long d;
	if (x)
	{
		while (x < *dp)
			++dp;
		do
		{
			d = *dp++;
			c = '0';
			while (x >= d)
				++c, x -= d;
			usputc(&str, c);
		} while (!(d & 1));
	}
	else
		usputc(&str, '0');
}

When I call it the program stucks somewhere in case 'c' but stepping into the usputc function does not even work. I have to take a deeper study on pointers obviously.

Link to post
Share on other sites
  • 7 months later...

Hi guys, 

 

that's the first time I'm working with a microcontroller.

 

It will be in a separate file - serial.asm
I totally forgot about putc()

Working project attached.

 

I'm just trying to use tiny printf() but it doesn't work. I'm using CC430F6137. I don't really understand the serial.asm file, so I don't know what I have to change to fix it (except "msp430g2231.h", which I changed to "msp430.h"). I don't get any error when i debug it.

 

Maybe someone can help me. THX!!

Link to post
Share on other sites

This code was written when the MSP430 Lauchpad shipped with chips that had 128 bytes of RAM, 2k of flash, and no hardware serial port. So it was important to keep code very compact and a software UART was needed.

 

Your F6137 chip has many hardware UARTS - so it would be wise to use them rather than software UART. Just write a putc() function that sends a char to the UART and you don't need the assembly code.

Link to post
Share on other sites
  • 4 months later...
  • 1 year later...

Does anyone have a working version of this for the msp430g2553 ?  I'm trying to get this to work for a class I'm teaching so that the students can use printf during their development.  I've used the one in Energia with this board and it works really nice, but I really need it to work with CCS 6.1.

 

I've downloaded just about every version on this post and none of them seem to work for me.

 

I tried this one:
http://www.msp430launchpad.com/2012/06/using-printf.html

Modified it per the comments so it wouldn't use the external clock.

 

I've tried the one with the serial.asm, without it, without the crystal.

 

Unfortunately some of the links here on this forum post are no longer working.

 

Here is what I have done so far.

 

1.  setup the jumpers as mentioned - mine are setup horizontally.

2.  updated code in initUART() to not use the external clock, but I'm not sure of the other two lines if they are still used or not.  Unfortunately, I;m still learning how to use all the different registers.  Also, aren't there some corresponding updates required to InitTimer() ?

 

    UCA0CTL1 &= ~UCSWRST;   // **Initialize USCI state machine**
    IE2 |= UCA0RXIE;                    // Enable USCI_A0 RX interrupt

 

4.  Timer seems to be firing. LED1 toggles every 7 seconds.  I have put a breakpoint there and it hits there.

 

5.  when I use putty, I don't see any output coming out of on the terminal.  I've set it to 9600, n, 8, 1.  Tried No flow control and also Xon/Xoff.

 

Any help is greatly appreciated.
 

Once this is working, I definitely want to get this published/updated somewhere so that others can benefit from it.

 

 

printf.zip

Link to post
Share on other sites

@@djarami I took a look at your code changes.

 

Seems that you have fallen into a rookie mistake. The original code made use of ACLK, (with a 32kHz crystal)

You want to use the code without an external crystal, so you've switch the code to use the internal 1MHz DCO. running into SCLK.

 

Unfortunately the LPM3 disables this clock source, since it uses more power than ACLK. So you need to alter the sleep mode to LPM0, which just disables the CPU.

              __bis_SR_register(LPM0_bits + GIE);		// Enter LPM0

The code is working on my bench with this one modification, when you press 't' in your console you should see some printf formatted statements get printed to screen.

Link to post
Share on other sites

Thank you.  Definitely learning here and getting my arms around this.

 

For completeness, I also made the corresponding change in:

 

__interrupt void USCI0RX_ISR(void)

...

        __bic_SR_register_on_exit(LPM0_bits);

...

 

I am still having one more problem and I'm afraid that it maybe another rookie thing and I'm hoping someone can help me.  The problem is that the terminal output coming out of realterm and also putty is unreadable.  The input is also not recognizable either.  The code is setup up to configure the port read/write to 9600 but I'm afraid that its not working that way.

 

... tried to put a picture of realterm here but it would let me post with it in here..

 

One detail on this is that I'm running on a Mac with VMWare Fusion and the port is Com3.  Nothing comes through Com1.

 

I wish TI would support the MSP430G2553 on their new CCS Beta for Mac.

 

Appreciate any help.

Link to post
Share on other sites

@@djarami Interesting. It sounds like you might be connecting to the Debbuggers UART, not the Application UART.

 

For reference, I was unable to get any of my Launchpad G2's to work with their Application UART channel. ( I'm on windows 10. LP's: 2x v1.5, 1x v1.4, both bought early )

When I've tried to connect every application; from putty, Arduino, to CCS's built in terminal all seem to freeze up until I unplug the LP.

 

The Debugging on the larger Launchpads is much better, I used jumpers to bridge across, everything worked fine then.

Link to post
Share on other sites

@@djarami Interesting. It sounds like you might be connecting to the Debbuggers UART, not the Application UART.

 

For reference, I was unable to get any of my Launchpad G2's to work with their Application UART channel. ( I'm on windows 10. LP's: 2x v1.5, 1x v1.4, both bought early )

When I've tried to connect every application; from putty, Arduino, to CCS's built in terminal all seem to freeze up until I unplug the LP.

 

The Debugging on the larger Launchpads is much better, I used jumpers to bridge across, everything worked fine then.

I've checked and I'm connecting to the Application UART.  I have a Com1 and a Com3 and Com3 is the application UART according to the Device Manager.  Output does come out on Com3 but not on Com1.  The problem is that the output is not legible.

 

I installed Energia and serial output from Serial.print() is definitely working and going out on Com3 and not Com1.  Interestingly, I closed energia and left the device running and started up Realterm and opened up Com3/9600 baud and I'm seeing the print output coming out.

 

I hope I can figure this out soon.

 

I'm thinking of trying the serial sample code from this blog http://www.msp430launchpad.com/2010/07/launchpads-example-project-ripped-open.html

Link to post
Share on other sites

I've checked and I'm connecting to the Application UART.  I have a Com1 and a Com3 and Com3 is the application UART according to the Device Manager.  Output does come out on Com3 but not on Com1.  The problem is that the output is not legible.

 

I installed Energia and serial output from Serial.print() is definitely working and going out on Com3 and not Com1.  Interestingly, I closed energia and left the device running and started up Realterm and opened up Com3/9600 baud and I'm seeing the print output coming out.

 

I hope I can figure this out soon.

 

I'm thinking of trying the serial sample code from this blog http://www.msp430launchpad.com/2010/07/launchpads-example-project-ripped-open.html

Ok, got it working now.   I think installing Energia unclogged some bits somewhere and after going back at looking at my code, somehow I had reverted back to using the ACLK.  Once I switched it back to using SMCLK and things are working now.

As far as using the serial sample code I referenced above, not much came out of that - I'll save that for another rainy day.

Thanks for all the help.

Link to post
Share on other sites
  • 2 weeks later...

Project_Work.zip

 

Hello All,
 
Am using MSP432 and tried using the printf() which was shared earlier to check if my interrupt buffer is behaving well. I tried the code have suggested but have 2 warnings In CCS

1. 154-D Conversion of Non-Zero Integer to Pointer

2. 169-D argument of type "int" is incompatible with parameter of type " char*"
 
Have attached my project. Please suggest where am going wrong.
 
Thanks
Kumar

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...