Understanding SHAKTI UART Protocol: Registers & Functions

  • Post author:
  • Reading time:4 mins read
  • Post category:Tutorials
You are currently viewing Understanding SHAKTI UART Protocol: Registers & Functions

Shakti “E Class” has 2 Universal Asynchronous Receiver Transmitter (UART) ports and “C Class” has 3 Universal Asynchronous Receiver Transmitter (UART) ports. In this tutorial, we are going to discuss how Universal Asynchronous Receiver/Transmitter (UART) protocol works and its various registers and functions.


The UART that is going to transmit data receives the data from a data bus. Then, the data bus is used to send data to the UART by another device like a CPU, memory, or micro-controller. Data is transferred from the data bus to the transmitting UART in parallel form. After the transmitting UART gets the parallel data from the data bus, it adds a start bit, a parity bit, and a stop bit, creating the data packet. Then, the data packet is sent out serially, bit by bit at the Tx pin.

The receiving UART reads the data packet bit by bit at its Rx pin. The receiving UART then converts the data back into parallel form and removes the start bit, parity bit, and stop bits. Finally, the receiving UART transfers the data packet in parallel to the data bus on the receiving end.


Understanding UART registers

Let’s see the registers available in UART. From platform.h we can see that the UART 0 address starts at 11300. As we can see the OFFSET is 100, UART1 starts at address 11400. In uart.h, we can see the struct to access UART registers as 32 bit registers.

Registerstruct nameSizeAddress UART0Address UART1
Baud rate registerunsigned short baud16bits1130011400
Reserveunsigned short reserv016bits1130211402
Transmission register unsigned int tx_reg32bits1130411404
Receive registerunsigned int rcv_reg32bits1130811408
Status registerunsigned char status8bits1130c1140c
Reserveunsigned char reserv18bits1130d1140d
Reserveunsigned short reserv216bits1130e1140e
Delayunsigned short delay16bits1131011410
Reserveunsigned short reserv316bits1131211412
Controlunsigned short control16bits1131411414
Reserveunsigned short reserv516bits1131611416
Interrupt enableunsigned char ien8bits1131811418
Reserveunsigned char reserv68bits1131911419
Reserveunsigned short reserv716bits1131a1141a
Input qualification cyclesunsigned char iqcycles8bits1131c1141c
Reserveunsigned char reserv88bits1131d1141d
Reserveunsigned short reserv916bits1131e1141e
RX FIFO size
configuration register
unsigned char rx_threshold8bits1132011420
Reserveunsigned char reserv108bits1132111421
Reserveunsigned short reserv1116bits1132211422

Now, lets open three terminals for SHAKTI

  1. Miniterm connected to UART0
  2. OpenOCD

Now we are going to try transmitting and reading from the UART directly using UART registers. Also, using the functions. Lets see just how to do that!

Step1: Setting the Baud rate for the UART instance’s register

The baud rate is a measure of the number of bits per second that can be transmitted or received by the UART. Clock frequency for SHAKTI is 50 MHz.

Baud count = Internal clock frequency/( 16* Baud rate)

You can do this by calling the set_baud_rate function or by writing the hex value directly onto the address of the baud rate register.

Baud rateCalculationDecimal valueHex value
960050,000,000/ (16*19200)325.5 (326)146
1920050,000,000/ (16*19200)162.7 (163)a3
3840050,000,000/ (16*38400)81.351
5760050,000,000/ (16*57600)54.236
11520050,000,000/ (16*115200)27.11b

For instance, if you want to set the baud rate for UART 0 as 19200,

  • write 0xa3 to address 11300
  • Use function, set_baud_rate(uart_instance[0], 19200);

Setting baud rate as 19200 through RISC-V GDB, use the following command

set {short}0x11300=0x00a3

Step 2: Write data to the UART Instance

This is similar to the putchar function. Now we are going to print a character to the Miniterm which is connected to UART 0. This can be done in two ways,

  • use write_uart_character(uart_instance[0],'B');
  • Write ascii value of char ‘B’ onto the tx_reg i.e address 11304

Writing character ‘B’ to the miniterm through GDB

set {unsigned char}0x11304=66 #66 is the ASCII value of B
Miniterm Output after write

Step 3: Read data from the UART instance

This is similar to getchar function. Now we are going to read a char from miniterm that is connected to UART0. This can be done in two ways,

  • Use read_uart_character(uart_instance[0], &t); //t is a variable
  • Read the address of rx_reg i.e 11308

For instance, Reading the char pressed from the RISC-V GDB, use the following command

x/c 0x11308 #displays char at the memory location.

Pressing q, w, e from the miniterm and checking the address location 11308 simultaneously

Simple UART program to read and write to UART 0

include "uart.h"

void main()
    int t;
    set_baud_rate(uart_instance[0], 19200); 
    write_uart_string (uart_instance[0], "\n Hello World from UART0");
    printf("\n Press any char to check UART0 is reading the char successfully\n");
   read_uart_character(uart_instance[0], &t); // Read the data    
   if(t != 0 )     
       printf("\n Character '%c' read successfully ", t);         
Fig. Output

Check out this article on “How to print “Hello World” on Shakti using Arduino IDE?

This Post Has One Comment

  1. Dishant

    Please make a blog on XADC, I cannot get correct values while reading from an external sensor.

Leave a Reply