Simple mbed library with macros

Dependents:   SimpleTimer SimpleUART SimpleTimer Stoppuhr1

serial.h

Committer:
Alkorin
Date:
2010-11-13
Revision:
5:b3aa0a49e21f
Parent:
4:afddc4848b6c
Child:
6:9e1310782abf

File content as of revision 5:b3aa0a49e21f:

#ifndef __SERIAL_H__
#define __SERIAL_H__

#include "mbed_globals.h"
#include "interrupts.h"

/*    Simple Serial Managment     *
 * The interrupt handler is :     *
 * SERIAL_INTERRUPT_HANDLER(void) */
 
// Serial port (Choose UARTn (0,2,3))
#define UART_NUMBER UART0
#define UART_BASE TOKENPASTE2(LPC_,UART_NUMBER)

// Peripheral Clock Selection registers (See 4.7.3 p56)
#define UART0_PCLK ((LPC_SC->PCLKSEL0 >>  6) & 0x03)
#define UART2_PCLK ((LPC_SC->PCLKSEL1 >> 16) & 0x03)
#define UART3_PCLK ((LPC_SC->PCLKSEL1 >> 18) & 0x03)
#define UART_PCLK TOKENPASTE2(UART_NUMBER,_PCLK)

// Interrupt handlers
#define SERIAL_INTERRUPT_HANDLER extern "C" void __irq TOKENPASTE2(UART_NUMBER,_IRQHandler)

/** Bits **/
// RBR Interrupt Enable (UnIER, 14.4.4 p302)
#define RBR_INT_BIT 0
// Receiver Data Ready (UnLSR, 14.4.8 p306)
#define RDR_BIT 0
// Transmitter Holding Register Empty (UnLSR, 14.4.8 p306)
#define THRE_BIT 5
// RBR Interrupt Enable (UnIER, 14.4.4 p302)
#define SERIAL_INT_RX 1
// THRE Interrupt Enable (UnIER, 14.4.4 p302)
#define SERIAL_INT_TX 2
// Divisor Latch Access Bit (UnLCR, 14.4.7 p306)
#define DLA_BIT 7

/** Macros **/
#define SERIAL_PUTCHAR(c)               while (GET_BIT_VALUE(UART_BASE->LSR, THRE_BIT) == 0); \
                                        UART_BASE->THR = c;

#define SERIAL_DATA_TO_READ()           (GET_BIT_VALUE(UART_BASE->LSR, RDR_BIT) == 1)

#define SERIAL_GETCHAR()                (UART_BASE->RBR)

// Enable interrupt for RX or TX (SERIAL_INT_RX and SERIAL_INT_TX)
#define SERIAL_ENABLE_INTERRUPT(value)  UART_BASE->IER = value; \
                                        ENABLE_INTERRUPT(TOKENPASTE2(UART_NUMBER,_IRQn));
                                        
#define SERIAL_INIT()                   LPC_SC->PCONP |=  (1UL << 3);       \
                                        UART_BASE->FCR = 0x07;              \
                                        UART_BASE->LCR = 0x03;              \
                                        LPC_SC->PCLKSEL0    &= ~(3UL << 6); \
                                        LPC_SC->PCLKSEL0    |=  (1UL << 6); \
                                        LPC_PINCON->PINSEL0 &= ~(1UL << 4); \
                                        LPC_PINCON->PINSEL0 |=  (1UL << 4); \
                                        LPC_PINCON->PINSEL0 &= ~(1UL << 6); \
                                        LPC_PINCON->PINSEL0 |=  (1UL << 6); \

// See 14.4.5 p303
inline int SERIAL_CHECK_INTERRUPT(void) {
    uint32_t serialStatus = UART_BASE->IIR;

    if (serialStatus & 1) // IntStatus, 1 = No Interrupt is pending.
        return 0;

    serialStatus = (serialStatus >> 1) & 0x3; // IntId, 2 = More than threshold data to read, 6 = Some caracters to read
    if (serialStatus != 2 && serialStatus != 6)
        return 0;

    return 1;
}

inline void SERIAL_SETBAUD(unsigned int baud) {
    // Peripheral Clock Selection register bit values (See Table 42, p57)
    static int divisors[4] = { 4, 1, 2, 8 };
    
    uint16_t divisorValue = ((SystemCoreClock / 16 / baud) * divisors[UART_PCLK]);
    
    SET_BIT_VALUE(UART_BASE->LCR, DLA_BIT, 1);
    UART_BASE->DLM = (uint8_t) (divisorValue >> 8);
    UART_BASE->DLL = (uint8_t)  divisorValue;
    SET_BIT_VALUE(UART_BASE->LCR, DLA_BIT, 0);
}

#endif