In My Second ModusToolbox 2.0 Project I wrote about the project-creator tool and built a TCPWMSquareWave project for the CY8CKIT-062-WIFI-BT kit. Today I am going to add a library to the project and enable printf() through a device UART. Wooooooo! First, let's take a look at the libraries we already have (which came in with the code example project that I cloned last week).
There are two TARGET_* folders, which are the kit BSPs. Then there are things like capsense and psoc6pdl. Each folder contains a library and we are going to add a new one. I do this by starting the library-manager from my shell.
$ ~/ModusToolbox/tools_2.0/library-manager/library-manager.exe &
After a short while the tool pops up and shows the BSPs that you can use. It also lists more that you can add, if you like.
Switching to the "Libraries" tab I can see the ones that are already on disk. Check the "retarget-io" box and press "Apply" to add that library.
A quick look at the folders shows that the manager has added the new folder and a .lib file (more on that next time).
Now that we have added the library, let's write a bit of code to try it out. Start by adding these two include files. These bring in the function definitions for the retarget-io library and also the C run-time printf() function, which is pretty much the raison d'etre of this blog.
Note that I am using the angley bracketty thingies around stdio.h, also known as the less than and greater than signs, and probably a more mature and professional name as well. That is just because I am grabbing the header from a system rather than user path. It turns out that you can just use the regular quotes in ModusToolbox projects if you want but, if you set up your compiler paths using -J instead of -I, then angley thingies it must be!
Now we need to tell printf() where to print. Here is the code to do that - put it in main() somewhere after the call to cybsp_init() and before the PWM code. The cy_retarget_io_init() function sets up the UART that gets used when printf() has formatted the string and is sending out the characters via __write(), which is in libs/retarget-io/cy_retarget_io.c. Note that __write() is the function used by the GNU compiler printf() implementation. If you build with the Arm Compiler then the library automatically sets up fputc() instead - so you can change compilers and continue to print without torture!
result = cy_retarget_io_init( CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE );
CY_ASSERT( result == CY_RSLT_SUCCESS );
printf( "TCPWM Square Wave started...\r\n" );
To check this works just run "make program" and connect up a terminal emulator.
Woo hoo! Looks like I got it right. Now I am going to make another change with the library manager - switching to a new target board. I have touched on this before but switching hardware is really easy in ModusToolbox. The only essential change is to edit the "TARGET" rule in the Makefile. That works for command line builds but, as we saw in the comments for Re-Targeting My ModusToolbox 2.0 project, it does not regenerate the launch configurations for the IDE. So, to avoid confusion it is probably best to use the library-manager. There is a handy drop-down menu for that and so I have made it a habit to use that to change the BSP. Just choose the board, as shown here, then press "Apply" to safely switch the default BSP for your project.
As before, all I need to do now is "make program" (and remember to connect the new board to my laptop!). It works like a charm!
Now I have to admit that I kinda glossed over two things today. Firstly, I talked about the libraries but did not explain how the manager knows where to get them and how to update them, so I'll fix that soon. I also told you about the cy_retarget_io_init() function and completely glossed over where the arguments come from! I do not like the idea of you guys blindly copying the code and not understanding it fully - that makes me feel itchy - so I'll explain that too. Honest. I promise... next time!