Services and Modeling for Embedded Software Development
Embecosm divider strip
Prev  Next

7.5.2.  Test Program to Run on the Or1ksim ISS

The test program, uart-loop.c is a simple polling loop back driver of the UART. Characters are read and immediately echoed back.

A volatile structure is declared for the UART registers, with #defined constants for the base address and the register bits of interest.

#define BASEADDR   0x90000000
#define BAUD_RATE        9600
#define CLOCK_RATE  100000000           // 100 Mhz

struct uart16450
{
  volatile unsigned char  buf;          // R/W: Rx & Tx buffer when DLAB=0  
  volatile unsigned char  ier;          // R/W: Interrupt Enable Register   
  volatile unsigned char  iir;          // R: Interrupt ID Register         
  volatile unsigned char  lcr;          // R/W: Line Control Register       
  volatile unsigned char  mcr;          // W: Modem Control Register        
  volatile unsigned char  lsr;          // R: Line Status Register          
  volatile unsigned char  msr;          // R: Modem Status Register         
  volatile unsigned char  scr;          // R/W: Scratch Register            
};

#define UART_LSR_TEMT   0x40            // Transmitter serial register empty
#define UART_LSR_THRE   0x20            // Transmitter holding register empty
#define UART_LSR_DR     0x01            // Receiver data ready

#define UART_LCR_DLAB   0x80            // Divisor latch access bit
#define UART_LCR_8BITS  0x03		// 8 bit data bits
	  

The utility functions to set and clear flags in the UART (see Section 6.5) are reused here, modified for C rather than C++ and volatile register arguments. They are included from the file binutils.c

#include "bitutils.c"
	  

The main program declares a pointer to the UART register structure, uart, at the base address. Initialization requires setting the divisor latch, to divide the main clock down to 16 x the baud rate and setting 8-bit data.

  volatile struct uart16450 *uart = (struct uart16450 *)BASEADDR;
  unsigned short int         divisor;

  divisor = CLOCK_RATE/16/BAUD_RATE;            // DL is for 16x baud rate

  set( &(uart->lcr), UART_LCR_DLAB );           // Set the divisor latch
  uart->buf  = (unsigned char)( divisor       & 0x00ff);
  uart->ier  = (unsigned char)((divisor >> 8) & 0x00ff);
  clr( &(uart->lcr), UART_LCR_DLAB );

  set( &(uart->lcr), UART_LCR_8BITS );		// Set 8 bit data
  packet
	  

The remainder of the program is a perpetual loop:

  while( 1 ) {
    unsigned char  ch;

    do {                        // Loop until a char is available
      ;
    } while( is_clr(uart->lsr, UART_LSR_DR) );

    ch = uart->buf;

    simputs( "Read: '" );       // Log what was read
    simputc( ch );
    simputs( "'\n" );

    do {                        // Loop until the transmit register is free
      ;
    } while( is_clr( uart->lsr, UART_LSR_TEMT | UART_LSR_THRE ) );
      
    uart->buf = ch;
  }
	  

The source code for the UART loopback program may be found in progs-or32/uart-loop.c in the distribution. It will be built using the OpenRISC 1000 tool chain as part of the overall system build.

Embecosm divider strip