I am currently working with the Rocket Chip repo to generate a 32-bit width microcontroller. I removed the debug module (The SimDTM or SimJTAG) for compiling on VCS 2014, so for debugging purpose I need to add GPIO and UART. I added the GPIO and UART modules from the Sifive-Blocks repo, and then modified the configuration of the Rocketchip accordingly (Add WithUART and WithGPIO into Configs, add HasPeripheryUART and HasPeripheryUARTModuleImp into ExampleRocketSubsystem etc.).
Then, in order to write to the UART, I wrote a UartStdOutInit() function as below:
void UartStdOutInit(void)
{
*uartaddr32(UART_DIV) = DIVISOR;
*uartaddr32(UART_TXEN) = TRUE; // tx enabled, stop bit 1 bit
*uartaddr32(UART_RXEN) = TRUE; //rx enabled
return;
}
With the header file like this:
#ifndef _UART_CONF_H
#define _UART_CONF_H
#define TRUE 1
#define FALSE 0
#define ERROR -1
typedef unsigned int U32; //U32 is 32-bit length
#define UART_ADDR 0x54000000
#define UART_TXFIFO 0x00
#define UART_RXFIFO 0x04
#define UART_TXEN 0x08
#define UART_TXMARK 0x0a
#define UART_RXEN 0x0c
#define UART_RXMARK 0x0e
#define UART_IE 0x10
#define UART_IP 0x14
#define UART_DIV 0x18
#define UART_PARITY 0x1c
#define UART_WIRE4 0x20
#define UART_EITHER8OR9 0x24 \
#define uartaddr32(offset) ((volatile U32 *)(UART_ADDR + offset))
#define DIVISOR 868 //10000000/115200 -1
/*Function declaration*/
void UartStdOutInit(void);
#endif
But after calling the Init function, I wasn't able to use either printf() or putchar() to write to my UART. If I used them, nothing will appear at the Txd line. The only way I can write to my UART is to create a new function like this:
void uartputchar(unsigned char c)
{
*uartaddr32(UART_TXFIFO) = c;
}
And call it from a new print() function. Then my Txd line will toggle, and the data can be captured by a UART_capture module. But in this way I cannot use format strings, and it has been a big obstacle for my debugging process (still possible to hardcode through, but will be very messy and tedious). I have tried to find other resources but cannot, as most of them are doing FPGA projects or working from a IDE. Can anyone tell me what is missing or what is wrong with my UART implementation? Thank you very much!
I found out that the
printrelated functions are not the ones defined instdio.h, but rather the ones defined insyscalls.c-- actually insyscalls.cthere are#undefto overwrite system functions likeputchar(). So if I replace the function content ofputchar()insyscalls.cwith my ownuartputchar(), theprintf()will work with all the formatting etc. that have already been defined insyscalls.c.