Printf with USBUART

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
duno_297731
Level 3
Level 3
10 sign-ins 10 replies posted 10 questions asked

Hi,

   

So, I'm trying to get the USBUART on a CY8CKIT-059 to act as a virtual COM port and I have everything working except being able to use printf().  

   

I've read through other forum posts on the subject that recommend "modifying _write" function, but I'm not sure how to do that.  I think maybe the example was for a true UART or something because it didn't make much sense to me; like I'm missing some other declaration or header in the beginning to tie it all together.  I've been referring to:
http://www.cypress.com/forum/psoc-5-device-programming/how-do-i-do-printf-function-psoc5

   

 

   

I have attached my whole test code, but below is the beginning:

   

 

   

#include <device.h>
#include "stdio.h"

   

#if (CY_PSOC5LP)
/* For GCC compiler revise _write() function */
int _write(int file, char *ptr, int len)
    {
        int i;
        for (i = 0; i < len; i++)
        {
            USBUART_1_PutChar(*ptr++);
        }
        return(len);
    }
#endif /* CY_PSOC5 */

0 Likes
10 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Would you mind to post your complete project, so that we all can have a look at all of your settings? To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file. Which hardware are you using? A Cypress Kit?? Which one???

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Project seems OK. There could be an issue with the Windows USB-drivers, do (did) you get a message that all needed drivers were installed successfully?

   

 

   

Bob

0 Likes
duno_297731
Level 3
Level 3
10 sign-ins 10 replies posted 10 questions asked

the USBUART is working well (both input and output work through PUTTY).  I'm just trying to get the printf() working.  

   

I'm not as concerned with input, as I only plan to get single characters from keyboard, so I can use the built-in input functions.  I would like a GETC or something, but it's not crucial.   I just really want standard printf() so I don't have to do a bunch of string reformats every time and I can more easily integrate example code.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Do not forget to increase the heap (in .cydwr, System-tab) to 200, use newlib-nano (in build settings) and when using floats allow formatting by newlib-nano

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

This might help -

   

 

   

http://japan.cypress.com/forum/psoc-5-device-programming/how-do-i-do-printf-function-psoc5

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

Hello, some one have been configured two serial ports (hardware, with tx, rx and interrupt by rx byte) on psoc 5LP, I´m Trying to do with CY8CKIT-059 , I have been configured all but only one serial port it´s ok. Please somebody can help me?, Thanks

0 Likes
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

yamirbo104,

   

do not hijack an old thread, please start a new one. You question is unrelated.

0 Likes
lock attach
Attachments are accessible only for community members.
JaPh_4667081
Level 2
Level 2
First like received First like given

I realize I'm raising a dead post here. But I ran into the same exact issue and found the solution. This is also the top google result for "psoc usbuart printf" so I figured this might help someone else.

The OP was on the right track modifying the _write function for printf. However, the USBUART module is not always ready to receive data. You must wait for it to clear before putting the data on the line. The code below is a modified version of the UART Full Duplex example in the debug.c file. Originally it printed to UART. The changes direct printf to use the USBUART.

/* For GCC compiler revise _write() function for printf functionality */

    int _write(int file, char *ptr, int len)

    {

        int i;

        file = file;

        for (i = 0; i < len; i++)

        {

            //Old line that prints to the UART

            //UART_PutChar(*ptr++);         //Set printf to use serial line

           

            //New lines to print to the USBUART

            while (0u == USBUART_CDCIsReady()){} //Wait for USB to be ready for data

            USBUART_PutChar(*ptr++);        //Set printf to use USB line

        }

        return (len);

    }

I have attached a modified version of the USBUART example project. I have made some notable changes to the example project.

  • Increased the heap size
  • Added the following to enable floats in printf
    • asm (".global _printf_float");
    • asm (".global _scanf_float");
  • Added the following to disable printf buffering which causes weird print delays for large heaps
    • setbuf(stdout, NULL);
  • I commented out the LCD prints since I am not using the LCD
  • I added a simple timer isr to do non-blocking delays.

This example will print out:

Hello World!
How are you today?

Using the printf method for "Hello World!" and the UABUART_PutString method for "How are you Today?" to demonstrate both.

Hope this helps someone!

I recently realized that this is blocking if the USB port is not plugged in and a terminal loaded to receive the characters. You can check to see if the system is ready by making the following modification and make printf not block if the device is not ready.

/* For GCC compiler revise _write() function for printf functionality */

int _write(int file, char *ptr, int len)

{

    int i;

    file = file;

    for (i = 0; i < len; i++)

    {

        //Old line that prints to the UART

        //UART_PutChar(*ptr++);         //Set printf to use serial line

        //Check if USB is configured and ready to receive to prevent blocking

        if ((0u != USBUART_GetConfiguration()) &&

            (0u != (USBUART_GetLineControl() & USBUART_LINE_CONTROL_DTR)))

        {

            while (0u == USBUART_CDCIsReady()){} //Wait for USB to be ready for data

            USBUART_PutChar(*ptr++);             //Set printf to use USB line

        }

    }

    return (len);

}