This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I am developing software for the MSP430 using TI's CCS v5.1 with the MAVRK code libraries (recent update, April 2012) and I have found a rather mind-boggling lack of support for common format specifiers in the standard C library function sprintf(). Here's the issues I've uncovered so far, and note that I am early int he development on my project:
1) does not support width, precision, or leading 0 specifiers, e.g. "%04X" to print and integer with exactly 4 ASCII hex characters with leading 0's; stuck with just "%x"
2) Does not support long integers (%ld)
3) short integer support using "%d" is unsigned (treated like "%u").
How can this library be so lacking in what is standard in every other embedded C library I've ever used, dating back to the 1990's on 8-bit 8051 microcontrollers?
Are there any formatted sprintf() libraries anywhere I can use with the MSP 430 under CCS 5.1, or can I get them with an upgrade of some type, or do I have to go back to cave man days and reinvent the wheel to get what should be basic C library functionality in my project?
Based upon your results, you seem to be using "minimal" printf support. Have you tried selecting "nofloat" or "full" support as described in Printf support in compiler?
Thank you so much for the great tip, Chester. I was unaware of this printf support compile option, buried as it is on the Library Function Assumption tab of the Advanced Options for the MSP430 compiler in CCS5.1. My MAVRK project was indeed set for minimal printf support.
If only these other options (nofloat, full) worked correctly, I'd be home free. However, when I turn either of them on, my whole program starts misbehaving very badly. The first issue is the most obvious and is directly tied to printf support that "breaks" in the other two modes. The rest appears to be more indirectly related but is much more troubling and insidious:
1) The %x option seems to break and not print all the characters in "nofloat" and "full" printf support modes. . I've tried %x, %2x, and %02x (in both upper 'X' and lower 'x' case) to no avail; I only get the 1st of the two hex digits, the most significant nybble. %x only works correctly in minimal support. Example:
sprintf(buf, "%x\r\n ", ADS1x9x_Version_ID_Number);
mvk_UART_Debug_PrintF_Flush (buf, strlen(buf));
The above code prints "92" on the TUSB port in minimal printf support mode, but only "9" in the other two modes.
2) My entire program starts exhibiting erratic behavior. I am running a program derived from the MAVRK ADS1298-MSP430F5438_Demo_Project. I have the QT interface disabled so I can control it via Hyperterminal. This is why I want formatted printing. However, the behavior changes based on the level of printf support I compile with:
a) When I build with the printf support set for "nofloat", my program hangs in the Error trap during ADS1298 init because it says the SPI port is in use while trying to send the default constant table to the ADS1298. This hangup occurs after I have successfully read the correct ADS1298 version code and sent a message reporting that fact to the TUSB UART port (with only the "9" of the code 92 displaying as described above), so I know SPI has already operated correctly.
b) When I build with the printf support set for "full", I don't seem to have any problems in the ADS1298 init, but when I start continuous conversion and reads in the main loop via Hyperterminal command, I never get any data coming back from the ADS1298. I can start and stop conversion all day along and get nothing out of it. Again, this works fine when I use minimal printf support (other than the format of the conversion data that I print). If I use the debugger to step my way into the conversion enabling, it seems to hang in an SPI transaction waiting for the SPI_Data_Received_Flag to be set by an interrupt that apparently never comes.
Bottom line is that it seems that the printf support modes of "nofloat" and "full" seem to mess up the SPI interrupt handling with the ADS1298 interface. It just doesn't seem like it should interfere with something unrelated to it. Again, with "minimal" printf support, my program works correctly and reliably. I just can't print the ADS data formatted properly as signed long integers without the full printf support. This format, of course, is what i need to import it and graph it easily in Excel.
Is there something else I am missing here? I hope you can help me further, because I am wasting many precious development hours debugging my debugging code instead of developing application code and analyzing ADS1298 data streams. Thanks!
Which version of the MSP430 Compiler are you using?
Version 4.0.0, which was the version originally installed with CCS 5.1, had the following bug:
------------------------------------------------------------------------------
FIXED SDSCM00042077
------------------------------------------------------------------------------
Summary : Printf only prints first character of argument correctly
Fixed in : 4.0.1
Severity : S2 - Major
Affected Component : Runtime Support Libraries (RTS)
Description:
Printf only prints first character of argument correctly.
For example, printf("%d\n", 123 ) is printed as 1cÿ
Thank you for the additional tip. I was indeed running 4.0.0 of the MSP430 compiler tools. However, I just completed the upgrade to CCS 5.2 with MSP430 Compiler Tools v4.0.2 and the identical problems continue -- incorrect printing and erratic SPI interrupt handling behavior.
I am confused, because one of these symptoms is exactly as described in your excerpt from the bug report that purports to be fixed in v4.0.1, and I'm now at 4.0.2 with the same symptom: sprintf{"%x", 0x92) is printed as "9ÿ" in "nofloat" and "full" printf support modes (it still prints correctly with "minimal" printf support).
Where did you find the bug report/change record? I would like to review all such notices as are available.
Also, is this purely a function of CCS implementation of the MSP430 compiler tool chain, or is it more inherent in TI's MSP430 support. In other words, would IAR have the same issue?
There is a DefectHistory.txt file in the root directory of the MSP430 Compiler directory, e.g. in C:\ti\ccsv5\tools\compiler\msp430_4.0.2, that contains the bug reports.
Also, after you installed v4.0.2. did you change the compiler version in the CCS project?
After a new compiler is installed, newly created projects use the new compiler but any existing projects aren't updated. Under CCS Project Properties -> CCS General -> Advanced settings -> Compiler version you select the compiler version used for the project.
IAR has its own runtime library, i.e. IAR shouldn't have the same issue.
Thank you once again Chester. I was unaware of the compiler version selection in the CCS project settings. I've now chnaged to using 4.0.2, and in fact the incorrect character printing with printf() has been fixed. TI should put you on their payroll with all your jewels of wisdom.
Unfortunately, I still am having major problems with SPI interrupt handling when I compile with nofloat or full printf support, but I'm beginning to think that I've got real-time conflicts between SPI and UART interrupts, and/or I'm starving my main loop when I have the added overhead of more extensive printf libraries. The ADS1298 is running at 250 samples per second with SPI reads of 216 bits per sample, which I am trying to print out to the TUSB UART in my main loop.
I guess I'll try breaking apart the MAVRK code structure to see if I can optimize the execution and find the source of conflicts. It just seems like there shouldn't be such interaction between the addition of a more extensive library for printf and the real-time operation of the MAVRK code.
Thanks again for all your answers, they have all been most helpful. If you have any clues on this more insidious behavior, your input is always appreciated. Cheers!
Thanks, but I still relatively new here. TI would be better off getting Jens-Michael Gross on their payroll! The only reason I knew the solution to your printf() problem was that I had previously discovered them the hard way...Andrew Barmeyer said:TI should put you on their payroll with all your jewels of wisdom.
printf operations can be quite time consuming, on the order of thousands of MCLK cycles (where the actual duration depends upon the number and type of arguments. What you could do is write a program just to measure the time of the printf calls in isolation, without the other interrupt related code. That will allow you to estimate the CPU load involved in the printf calls.Andrew Barmeyer said:I guess I'll try breaking apart the MAVRK code structure to see if I can optimize the execution and find the source of conflicts. It just seems like there shouldn't be such interaction between the addition of a more extensive library for printf and the real-time operation of the MAVRK code.
CCS has the ability to measure the clock cycles taken, but as noted by the Code Composer clock thread there are some issues with clock cycle measurement...
Good idea :) But since I don't use CCS (or IAR), I'm not the best source for detailed instructions how to 'bugfix' them.Chester Gillon said:TI would be better off getting Jens-Michael Gross on their payroll!
Bout the other problem, well, you don't write which of the ~400 MSP you use.
In the 2x family, USCIA and USCIB module share one interrupt for RX and one for TX. It may be that you get problems with your UART and SPI code there if you're not careful.
Also, the double-bufferign of the USCI can raise some unexpected quirks in the program flow if one doesn't take care for all implicaitons of this double-buffering. Especially if the load increaes and timings get tighter.
IIRC, the latest MSP430DLL has this at least partially fixed. Personally, I prefer toggling a port pin and checking it with a digital scope or logic analyzer. This is much more 'real time' than any debuger access :)Chester Gillon said:CCS has the ability to measure the clock cycles taken, but as noted by the Code Composer clock thread there are some issues with clock cycle measurement...
I had a problem with sprintf and didn't have a clue about how to fix it.
I was able to solve the problem after reading the invaluable information presented here.
Thank you all
Mark
unrelated to the original question, sorry.
Andrew, do you happen to have a documentation of the code you used to communicate with the ADS1289? That's next on my TODO list and I would appreciate any help to kickstart that task.
Thanks
Andreas
**Attention** This is a public forum