Dependencies:   mbed

UART0.c

Committer:
hugozijlmans
Date:
2010-12-02
Revision:
2:f034e862af1f

File content as of revision 2:f034e862af1f:

#include "LPC17xx.h"
#include "core_cm3.h"
#include "cmsis_nvic.h"
#include "UART0.h"
#include "main.h"
#include "LPC1768.h"

void UART0_interrupt_enable(void) {

    // Enable UART0 interrupt
    NVIC_EnableIRQ(UART0_IRQn);
}

void UART0_interrupt_disable(void) {

    // Disable UART0 interrupt
    NVIC_DisableIRQ(UART0_IRQn);
}

void UART0_IRQHandler(void) {

    // Determine the cause of the interrupt

    // If THRE then buffer is empty
    if ((U0IIR & 0x2) == 0x2)
        i_flags.UART0_tx_idle = 1;

    // If receive buffer contains a byte
    if ((U0IIR & 0x8) == 0x8) {
        i_flags.UART0_rx_idle = 0;
        UART0_rx_interrupt_disable();
    }

    // Clear the UART0 interrupt
    NVIC_ClearPendingIRQ(UART0_IRQn);

}

void UART0_init(void) {

    // Set UART0 interrupt priority
    NVIC_SetPriority(UART0_IRQn, 12);

    // Set RXD0/TXD0 to function UART0
    PINSEL0 &= ~(0xF0);
    PINSEL0 |= 0x50;

    // Select the UART0 clk
    UART0_select_clk();

    // Power the UART0
    PCONP |= PCUART0;

    // Set the UART0 Line Control Register
    U0LCR &= 0;
    U0LCR |= (1 << 1) | (1 << 0) // 8 bit
             | (1 << 2)            // 1 stop bit
             | (0 << 3)            // disable parity
             | (1 << 5) | (0 << 4) // force 1 stick parity
             | (0 << 6)            // disable break control
             | (1 << 7);           // divisor access bit enable

    // Set Baudrate 115200
    // DIVADDVAL 3
    // MULVAL 10
    // DLL 40
    // DLM 0
    // Error 0.1603%

    // Set Fractional Divider Register
    U0FDR = 0xA3;

    // Set Baudrate divisor
    U0DLL = 40;
    U0DLM = 0;

    // Set divisor access bit 0
    U0LCR &= ~(1 << 7);

    // Set Fifo control register
    U0FCR &= 0;
    U0FCR |= (1 << 7) | (1 << 6) // RX Fifo DMA @ 14 bytes
             | (1 << 3)            // 1 stop bit
             | (1 << 2)            // disable parity
             | (1 << 1)            // disable break control
             | (1 << 0);           // divisor access bit enable

    // Set interrupt enable sources THRE & RBR
    U0IER |= 3;

    // Set that the TX is idle
    i_flags.UART0_tx_idle = 1;
    // Set that the RX is idle
    i_flags.UART0_rx_idle = 1;

    // Connect the UART0 interrupt to the interrupt handler
    NVIC_SetVector(UART0_IRQn, (uint32_t)&UART0_IRQHandler);

    UART0_interrupt_enable();

}

void UART0_select_clk(void) {

    // Including work-around described in errata.lpc1768.pdf R04

    PLL0_disconnect();

    PLL0_disable();

    // Timer0 perhiperal clock select (01 = CCLK)
    PCLKSEL0 &= ~(PCLK_UART0_1 | PCLK_UART0_0);
    PCLKSEL0 |= PCLK_UART0_0;

    PLL0_enable();

    PLL0_connect();

}

void UART0_write(uint8_t byte) {

    // Send byte to writebuffer
    U0THR = byte;
}

uint8_t UART0_read(void) {

    // Read the RX FIFO
    uint8_t byte = U0RBR;
    
    UART0_rx_interrupt_enable();
    
    return byte;
}

void UART0_rx_interrupt_disable(void) {
    U0IER &= ~(1);
}

void UART0_rx_interrupt_enable(void) {
    U0IER |= 1;
}