HOME       UP       PREV       FURTHER NOTES       NEXT (Typical IP Blocks)  

Programmed I/O

Input and output operations are made by a program running on the processor.

Disadvantage: Inefficient - too much polling for general use. Interrupt driven I/O is more efficient.
//Macro definitions for C preprocessor
//Enable a C program to access a hardware
//UART using PIO or interrupts.

#define IO_BASE 0xFFFC1000 // or whatever

#define U_SEND 0x10 #define U_RECEIVE 0x14 #define U_CONTROL 0x18 #define U_STATUS 0x1C

#define UART_SEND() \ (*((volatile char *)(IO_BASE+U_SEND))) #define UART_RECEIVE() \ (*((volatile char *)(IO_BASE+U_RECEIVE))) #define UART_CONTROL() \ (*((volatile char *)(IO_BASE+U_CONTROL))) #define UART_STATUS() \ (*((volatile char *)(IO_BASE+U_STATUS)))

#define UART_STATUS_RX_EMPTY (0x80) #define UART_STATUS_TX_EMPTY (0x40)

#define UART_CONTROL_RX_INT_ENABLE (0x20) #define UART_CONTROL_TX_INT_ENABLE (0x10)

The receiver spins until the empty flag in the status register goes away. Reading the data register makes the status register go empty again. The actual hardware device might have a receive FIFO, so instead of going empty, the next character from the FIFO would become available straightaway:
  char uart_polled_read()
  {
     while (UART_STATUS() &
        UART_STATUS_RX_EMPTY) continue;
     return UART_RECEIVE();
  }
The output function is exactly the same in principle, except it spins while the device is still busy with any data written previously:
  uart_polled_write(char d)
  {
     while (!(UART_STATUS() & 
       UART_STATUS_TX_EMPTY)) continue;
     UART_SEND() = d;
  }


23: (C) 2008-15, DJ Greaves, University of Cambridge, Computer Laboratory.