/*
    SA1100_UART.h, Copyright  (c) by Silvio Dragone & David Reist,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.

    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.

    For further information, please visit http://www.tik.ee.ethz.ch/~topsy

    This software is provided under the terms of the GNU General Public Licence.

    A full copy of the GNU GPL is provided in the file COPYING found in the 
    development root of Topsy.
*/

#ifndef _SA1100_UART_H_
#define _SA1100_UART_H_

#include "types.h"
#include "MMHeapMemory.h"
#include "IODevice.h"
#include "Configuration.h"


/* SA1100 UART_SR Register */
#define PARITY_ERROR_SR        0x1        /* 1: a parity error occurred in next data */
#define FRAMING_ERROR_SR       0x2        /* 1: a framing error occurred in next data */
#define TX_FIFO_READY          0x4        /* 1: room for at least 1 Byte of data (= not full)*/
#define RX_OVERRUN             0x8        /* 1: Rx FIFO overrun */
#define RX_FIFO_READY          0x10       /* 1: Rx FIFO contains at least 1 Byte of data (=not empty) */
#define TX_FIFO_EMPTY          0x20       /* 1: Tx FIFO empty */
#define RX_FIFO_FULL           0x40       /* 1: Rx FIFO full */
#define TX_FIFO_FULL           0x80       /* 1: Tx FIFO full */
#define RXD_PIN                0x100      /* 1: RXD pin state (diagnostics only) */

//-CJ defiened in IOHal.h
//-CJ#define UART_SR_REGISTER       0x90003400UL /* UART_SR register address */


/* SA1100 UART_CR Register */
#define TRANSMIT_BREAK         0x1        /* 1: assert TXD pin low */
#define PARITY_ENABLE          0x2        /* 0: no parity, 1: parity */
#define PARITY_SELECT          0x4        /* 0: even, 1: odd */
#define STOP_BIT_SELECT        0x8        /* 0: 1 stop bit, 1: 2 stop bit */
#define RX_INTERRUPT_ENABLE    0x10       /* 0: disabled, 1: enabled (interrupt when Rx FIFO not empty) */
#define DATA_SIZE_SELECT_MASK  0x60       /* bit 6..5 (0x20 | 0x40),
					   * 0x0: 5 bit
					   * 0x1: 6
					   * 0x2: 7
					   * 0x3: 8     */
#define UART_ENABLE            0x80       /* 0: disabled, 1: enabled */
#define TX_INTERRUPT_ENABLE    0x100      /* 0: disabled, 1: enabled (interrupt when Tx FIFO empty) */
#define UART_INTERRUPT_SELECT  0x200      /* 0: IRQ, 1: FIQ */
#define BAUD_RATE_DIVISOR_MASK 0x3FF0000  /* bit 25..16 (10 bit),
					   * 0x2FF:   300 BAUD
					   * 0xBF:   1200
					   * 0x5F:   2400
					   * 0x2F:   4800
					   * 0x17:   9600
					   * 0xB:   19200
					   * 0x5:   38400
					   * 0x3:   57600
					   * 0x1:  115200
					   * 0x0:  230400      */

#define UART_CR_REGISTER       0x90003800 /* UART_CR register address */


/* SA1100 UART_DR Register */
#define UART_DATA_MASK         0xFF       /* bit 7..0,
					   * read: read data from Rx FIFO,
					   * write: write data to Tx FIFO */
#define PARITY_ERROR_DR        0x100      /* 1: a parity error occurred */
#define FRAMING_ERROR_DR       0x200      /* 1: a framing error occurred */
#define RX_OVERFLOW            0x400      /* 1: a Rx overrun occurred, data following to current was lost */

#define UART_DR_REGISTER       0x90003C00 /* UART_DR register address */


#define SA1100_UART_BUFSIZE    128        /* size taken from mips port */
#define UART_REGISTER_SET_SIZE 0x20       /* size for one channel */

typedef struct devSA1100_UARTDesc_t {
    unsigned long in, out;
} devSA1100_UARTDesc;

typedef devSA1100_UARTDesc* devFIFO_Ptr;

void  devSA1100_UART_interruptHandler(IODevice this);
Error devSA1100_UART_init(IODevice this);
Error devSA1100_UART_read(IODevice this, ThreadId threadId, char* buffer, long int* size);
Error devSA1100_UART_write(IODevice this, ThreadId threadId, char* buffer, long int* size);
Error devSA1100_UART_close(IODevice this);

#endif
