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.

printf for UART TM4C123

I am beginner with this TM4C and have just learnt the basics of the board. I need to use the printf function for UART. the problem is the program gives no build error or warning but show no output on putty.
Any help would be appreciated.

UART initialization(UART.c)

#include <stdio.h>
#include "UART.h"
#include "tm4c123gh6pm.h"

void UART_Init(void){
  SYSCTL_RCGCUART_R |= 0x01;            
  SYSCTL_RCGCGPIO_R |= 0x01;            
  while((SYSCTL_PRGPIO_R&0x01) == 0){};
  UART0_CTL_R &= ~UART_CTL_UARTEN;      
  UART0_IBRD_R = 27;                    
  UART0_FBRD_R = 8;                     
                                        
  UART0_LCRH_R = (UART_LCRH_WLEN_8|UART_LCRH_FEN);
  UART0_CTL_R |= UART_CTL_UARTEN;       
  GPIO_PORTA_AFSEL_R |= 0x03;           
  GPIO_PORTA_DEN_R |= 0x03;             
                                        
  GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R&0xFFFFFF00)+0x00000011;
  GPIO_PORTA_AMSEL_R &= ~0x03;
}


char InChar(void)
{
  while((UART0_FR_R&UART_FR_RXFE)!=0);
  return((char)(UART0_DR_R&0xFF));
}


void OutChar(char data)
{
  while((UART0_FR_R&UART_FR_TXFF)!=0);
  UART0_DR_R = data;
}



void OutString(char *pt)
{
  while(*pt)
		{
    OutChar(*pt);
    pt++;
  }
}


void InString(char *inptr, unsigned long max) 
{
int length=0;
char character;
  character = InChar();
  while(character != ENTER_Key)
		{
    if(character == BS_Key)
			{
      if(length)
				{
        inptr--;
        length--;
        OutChar(BS_Key);
      }
    }
    else if(length < max)
		{
      *inptr = character;
      inptr++;
      length++;
      OutChar(character);
    }
    character = InChar();
  }
  *inptr = 0;
}

void OutENTER_LF()
{
	OutChar(ENTER_Key);
	OutChar(LF);
}

int fputc(int ch, FILE *f)
{
	if((ch==10)||(ch==13)||(ch==27))
	{
		OutChar(13);
		OutChar(10);
		return 1;
	}
	OutChar(ch);
	return 1;
}

int fgetc(FILE *f)
{
	char ch= InChar();
	OutChar(ch);
	return ch;
}

int ferror(FILE *f)
{
	return EOF;
}

And the main file is
main.c

#include "tm4c123gh6pm.h"
#include "PLL.h"
#include "UART.h"

#include <stdio.h>


int main(void)
{
	PLL_Init();  // 50MHz
	UART_Init();
	printf("Using printf!!!\n");
}

thanks in advance.

  • Abdullah Zahid said:
    problem is the program gives no build error or warning but show no output on putty.  

    My friend - you've done a nice job in presenting your code and describing your issue - good that.

    Yet - you present a (growing) trend here - which as a small, tech biz owner - I find unsettling.  Your code is (primarily) in the "Direct Register" format - which opens WIDE the chance for errors - and significantly adds to the time, effort and complexity froced upon your (hapless) forum helpers.  (none of this "your" fault - but it is a "Forum reality" - and one which you must recognize...)

    I realize that a certain "course" has chosen this method of "instruction."   And I know that as small biz owner - our doors would long ago have (closed) - if we allowed our new hires and interns - to code in this manner.  (clients do have certain "delivery expectations" - these are (rarely) if ever satisfied via Direct Register)   One would hope that a famed University would have this awareness - groom their students so that they are (more) employable...

    Direct Register forces you (and helpers) to open the MCU manual - and then perform a copious study - of each/every impacted register.   And to catch every "nook/cranny" - and even minor usage details.   In stark contrast - vendor's APIs have done all, "Heavy Lifting" for you - and they've long been tested/verified - by thousands.   Your Direct Register code is (pardon) "Always an adventure" and causes eyes to cross/water (bit more than normal) in it's debug.

    Suspect that your search (and find) of vendor's standard/detailed API examples (all in "C" using vendor's quite excellent APIs) will significantly assist.  xxxWare/examples/peripherals/UART/Uart_echo or similar should be quite illuminating.

    This vendor most likely would not have made their past acquisition of founding MCU firm - if not for that vendor's powerful API.  Use of Direct Register (was) past "de rigeur" - but proves more handicap than learning aid - in "post dinosaur" era - imho...

    KISS rules (API usage/exploitation)  - obscure, error-prone/welcoming ways (Direct Register) - not so much...

  • This is the pain migrating from "general computing" to "bare metal" - a lot of the stuff that is presented to you as a given in any "normal" C course simply doesn't work well in the micro world. Printf is one such example, malloc & friends would be another.

    I don't fully grasp what is your strategy in trying to redirect stdout to the UART, but there actually is a "supported" way to do that. I did it some time back, but have since realized it doesn't make sense to use so much resources on printf. What I had to do was a series of "compatibility" functions, like SERIAL_open, SERIAL_close, SERIAL_write, etc (where SERIAL is a name for the new "output device driver"), then register those functions with add_device(), which is buried somewhere in the TI libc that you can find somewhere under your CCS installation. If you decide to go that route, remember to increase your stack size in your project settings or you will soon find yourself scratching your head when nothing works as it should...

    All that said, I don't really recommend that approach. It makes much more sense to have the micro output simple formats (albeit probably not so well human-readable) and then have the probably more capable computer that reads that output interpret it into something more friendly.

    And last, maybe you should take a look at the utils/uartstdio.h,c files in your TivaWare distribution - you'll find that a lot of the TI supplied examples use them. Also, as cb1 already said, do avoid using the direct register access model until you've got a solid grasp of the API side of things. If you really must, you can then gradually migrate to using register accesses.

    One more thing - I can only see one comment in your whole program. Especially when using the very condensed register names, you simply cannot read that code fluidly! Do yourself a favor and comment your code.
  • cb1_mobile said:
    I realize that a certain "course" has chosen this method of "instruction."   And I know that as small biz owner - our doors would long ago have (closed) - if we allowed our new hires and interns - to code in this manner.  (clients do have certain "delivery expectations" - these are (rarely) if ever satisfied via

     Hi CB1, I find your word excessive to this post for two reason:

     This poster showed know how to realize printf support and I also try'd to do this way in the past. Problem is not his good knowledge, most of the embedded compiler has printf skeleton but it is there just to be and is not enough to do standard coding due is incomplete or untested also on bigger expensive compiler firm.

     This poster also has read manual to do simple UART register I/O on its own so it require a honour of good behaving in front of a problem.

     This one is just one compiler issue than TIVA but not a poster lack of knowledge, just experience but this is another thing and I prefer a good one to all screamer are here.

     So to Zahid welcome to our forum, just try usartstdio than bare printf or get some example or better enjoy the embedded OSes like TIRTOS or FreeRTOS. (uCOSIII and uCLinux too)

  • Roberto Romano said:
    I find your word excessive to this post

    If, "simplifying, speeding & enhancing code readability/understanding" are, "excessive" - then I'm, "Guilty as charged!"

    Rejection of the many (and huge) advantages of vendor's API is "not" the way to go when "training" for entry into the tech world...

  • cb1_mobile said:
    Rejection of the many (and huge) advantages of vendor's API is "not" the way to go when "training" for entry into the tech world...

     Worst issue here is forever the non privacy as from other Tech forum readable only to was subscribed and also to non specialized area. This and a lot of other require a beginner area and also some programming guide area.

     This area need leave all in one huge sandbox castle don't survive a day when real information are needed for year.

     We never need the beginner coming here and say here is my program...

     What when I need solve one real issue? Yes I now know Amit but think about real professional come here with an issue? What think about a lot of hobbyst using this platform? My idea is O my dear.. another Arduino forum.. I need search another firm for my silicon.

     Beginner are welcome but in SPECIFIV area not the one MUST be dedicated to professional arena.

     Is this a support tools from eng. or just an excuse from commercial move to fire out some FAE targeting them as useless?

  • Hi,

    I agree with Roberto to "just try uartstdio than bare printf". I have not tried printf either for Tiva MCU's.

    I have read posts before that the cause why printf does not work is because of "insufficient heap". So, if you have "insufficient heap", increase its size, and then see if printf works after that.

    - kel
  • Markel Robregado said:
    I have read posts before that the cause why printf does not work is because of "insufficient heap". So, if you have "insufficient heap", increase its size, and then see if printf works after that.

     Hi Markel, same cause of incomplete printf is same of Heap and memory allocation so what about malloc and associates when no OS is in place with rule on how to manage dynamic memory?

     To have stack and Heap correctly working you need a memory allocator and garbage collector too otherwise you run out of space in a while.

     Heap in a bare metal case has no sense as for files devices descriptor disoriented mee too on microcontroller, microprocessors and MSDOS too...

     So how to increase what is non defined too to have a non implemented thing to work???

     Markel, GOOD rock solid knowledge is better than forum collected.. Take forever care of what is under the hood from solid course or book.

     I learned how OS are built and how they have to be built then we observed the M$ selling what worst and old knowledge is vanishing.

    Still I say an OS has to serve better all is around not have a faster processor then hang on kernel or user program. So it sell prehistoric coding and all are buying it changing computer instead of efficiency.

     On bare metal you can build a solid environment or a M$ like hash but on embedded world you lose before sell one.

     On CP/M old good era and PC bare metal I used solid device driver we shared on group as Library, here you have no other than using an OS or have a good device driver and library too.