6cc948eef8
git-svn-id: file:///srv/dev-disk-by-uuid-17e88007-4d0c-45e0-8757-cacfcc458630/repositories/svn/Diplomarbeit@113 9fe90eed-be63-e94b-8204-d34ff4c2ff93
620 lines
17 KiB
C
620 lines
17 KiB
C
/******************************************************************************
|
|
*
|
|
* $RCSfile: $
|
|
* $Revision: $
|
|
*
|
|
* This module provides interface routines to the LPC ARM UARTs.
|
|
* Copyright 2004, R O SoftWare
|
|
* No guarantees, warrantees, or promises, implied or otherwise.
|
|
* May be used for hobby or commercial purposes provided copyright
|
|
* notice remains intact.
|
|
*
|
|
* Modified by Martin Thomas for LPC23xx 24xx
|
|
*****************************************************************************/
|
|
#include "app_types.h"
|
|
#include "LPC_REGS.h"
|
|
#include "sys_config.h"
|
|
|
|
#include "uart.h"
|
|
|
|
#ifndef USHRT_MAX
|
|
#define USHRT_MAX 16
|
|
#endif
|
|
|
|
#include "armVIC.h"
|
|
#include "uartISR.h"
|
|
|
|
uint8_t uart0_rx_buffer[UART0_RX_BUFFER_SIZE];
|
|
uint16_t uart0_rx_insert_idx, uart0_rx_extract_idx;
|
|
uint8_t uart0_tx_buffer[UART0_TX_BUFFER_SIZE];
|
|
uint16_t uart0_tx_insert_idx, uart0_tx_extract_idx;
|
|
int uart0_tx_running;
|
|
|
|
uint8_t uart1_rx_buffer[UART1_RX_BUFFER_SIZE];
|
|
uint16_t uart1_rx_insert_idx, uart1_rx_extract_idx;
|
|
uint8_t uart1_tx_buffer[UART1_TX_BUFFER_SIZE];
|
|
uint16_t uart1_tx_insert_idx, uart1_tx_extract_idx;
|
|
int uart1_tx_running;
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart0Init()
|
|
*
|
|
* Description:
|
|
* This function initializes the UART for async mode
|
|
*
|
|
* Calling Sequence:
|
|
* baudrate divisor - use UART_BAUD macro
|
|
* mode - see typical modes (uart.h)
|
|
* fmode - see typical fmodes (uart.h)
|
|
*
|
|
* Returns:
|
|
* void
|
|
*
|
|
* NOTE: uart0Init(UART_BAUD(9600), UART_8N1, UART_FIFO_8);
|
|
*
|
|
*****************************************************************************/
|
|
void uart0Init(uint16_t baud, uint8_t mode, uint8_t fmode)
|
|
{
|
|
// set port pins for UART0
|
|
// mthomas PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
|
|
// set port pins for UART0
|
|
// PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
|
|
U0_TX_PINSEL_REG = ( U0_TX_PINSEL_REG & ~U0_TX_PINMASK ) | U0_TX_PINSEL;
|
|
U0_RX_PINSEL_REG = ( U0_RX_PINSEL_REG & ~U0_RX_PINMASK ) | U0_RX_PINSEL;
|
|
|
|
// Set CLOCK for UART0 device (4x)
|
|
// PCLKSEL0 = 0x00000040;
|
|
|
|
// Set CLOCK for UART0 device (/2)
|
|
PCLKSEL0 &= 0xFFFFFF7F;
|
|
PCLKSEL0 |= 0x00000080;
|
|
|
|
U0IER = 0x00; // disable all interrupts
|
|
U0IIR; // clear interrupt ID
|
|
U0RBR; // clear receive register
|
|
U0LSR; // clear line status register
|
|
|
|
// set the baudrate
|
|
U0LCR = ULCR_DLAB_ENABLE; // select divisor latches
|
|
U0DLL = (uint8_t)baud; // set for baud low byte
|
|
U0DLM = (uint8_t)(baud >> 8); // set for baud high byte
|
|
|
|
// set the number of characters and other
|
|
// user specified operating parameters
|
|
U0LCR = (mode & ~ULCR_DLAB_ENABLE);
|
|
U0FCR = fmode;
|
|
|
|
// initialize the interrupt vector
|
|
VICIntSelect &= ~VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART0);
|
|
VICIntEnClr = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART0);
|
|
VICVectAddr6 = (uint32_t)uart0ISR;
|
|
VICVectPriority6 = 0xF;
|
|
VICIntEnable = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART0);
|
|
|
|
// initialize the transmit data queue
|
|
uart0_tx_extract_idx = uart0_tx_insert_idx = 0;
|
|
uart0_tx_running = 0;
|
|
|
|
// initialize the receive data queue
|
|
uart0_rx_extract_idx = uart0_rx_insert_idx = 0;
|
|
|
|
// enable receiver interrupts
|
|
U0IER = UIER_RBR;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart0Putch()
|
|
*
|
|
* Description:
|
|
* This function puts a character into the UART output queue for
|
|
* transmission.
|
|
*
|
|
* Calling Sequence:
|
|
* character to be transmitted
|
|
*
|
|
* Returns:
|
|
* ch on success, -1 on error (queue full)
|
|
*
|
|
*****************************************************************************/
|
|
int uart0Putch(int ch)
|
|
{
|
|
uint16_t temp;
|
|
unsigned cpsr;
|
|
|
|
temp = (uart0_tx_insert_idx + 1) % UART0_TX_BUFFER_SIZE;
|
|
|
|
if (temp == uart0_tx_extract_idx)
|
|
return -1; // no room
|
|
|
|
cpsr = disableIRQ(); // disable global interrupts
|
|
U0IER &= ~UIER_THRE; // disable TX interrupts
|
|
restoreIRQ(cpsr); // restore global interrupts
|
|
|
|
// check if in process of sending data
|
|
if (uart0_tx_running)
|
|
{
|
|
// add to queue
|
|
uart0_tx_buffer[uart0_tx_insert_idx] = (uint8_t)ch;
|
|
uart0_tx_insert_idx = temp;
|
|
}
|
|
else
|
|
{
|
|
// set running flag and write to output register
|
|
uart0_tx_running = 1;
|
|
U0THR = (uint8_t)ch;
|
|
}
|
|
|
|
cpsr = disableIRQ(); // disable global interrupts
|
|
U0IER |= UIER_THRE; // enable TX interrupts
|
|
restoreIRQ(cpsr); // restore global interrupts
|
|
|
|
return (uint8_t)ch;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart0Space()
|
|
*
|
|
* Description:
|
|
* This function gets the available space in the transmit queue
|
|
*
|
|
* Calling Sequence:
|
|
* void
|
|
*
|
|
* Returns:
|
|
* available space in the transmit queue
|
|
*
|
|
*****************************************************************************/
|
|
uint16_t uart0Space(void)
|
|
{
|
|
int space;
|
|
|
|
if ((space = (uart0_tx_extract_idx - uart0_tx_insert_idx)) <= 0)
|
|
space += UART0_TX_BUFFER_SIZE;
|
|
|
|
return (uint16_t)(space - 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart0Puts()
|
|
*
|
|
* Description:
|
|
* This function writes a NULL terminated 'string' to the UART output
|
|
* queue, returning a pointer to the next character to be written.
|
|
*
|
|
* Calling Sequence:
|
|
* address of the string
|
|
*
|
|
* Returns:
|
|
* a pointer to the next character to be written
|
|
* (\0 if full string is written)
|
|
*
|
|
*****************************************************************************/
|
|
const char *uart0Puts(const char *string)
|
|
{
|
|
register char ch;
|
|
|
|
while ((ch = *string) && (uart0Putch(ch) >= 0))
|
|
string++;
|
|
|
|
return string;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart0Write()
|
|
*
|
|
* Description:
|
|
* This function writes 'count' characters from 'buffer' to the UART
|
|
* output queue.
|
|
*
|
|
* Calling Sequence:
|
|
*
|
|
*
|
|
* Returns:
|
|
* 0 on success, -1 if insufficient room, -2 on error
|
|
* NOTE: if insufficient room, no characters are written.
|
|
*
|
|
*****************************************************************************/
|
|
int uart0Write(const char *buffer, uint16_t count)
|
|
{
|
|
if (count > uart0Space())
|
|
return -1;
|
|
|
|
while (count && (uart0Putch(*buffer++) >= 0))
|
|
count--;
|
|
|
|
return (count ? -2 : 0);
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart0TxEmpty()
|
|
*
|
|
* Description:
|
|
* This function returns the status of the UART transmit data
|
|
* registers.
|
|
*
|
|
* Calling Sequence:
|
|
* void
|
|
*
|
|
* Returns:
|
|
* FALSE - either the tx holding or shift register is not empty
|
|
* !FALSE - if both the tx holding & shift registers are empty
|
|
*
|
|
*****************************************************************************/
|
|
int uart0TxEmpty(void)
|
|
{
|
|
return (U0LSR & (ULSR_THRE | ULSR_TEMT)) == (ULSR_THRE | ULSR_TEMT);
|
|
}
|
|
|
|
int uart0RxEmpty(void)
|
|
{
|
|
if (uart0_rx_insert_idx == uart0_rx_extract_idx) // check if character is available
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart0TxFlush()
|
|
*
|
|
* Description:
|
|
* This function removes all characters from the UART transmit queue
|
|
* (without transmitting them).
|
|
*
|
|
* Calling Sequence:
|
|
* void
|
|
*
|
|
* Returns:
|
|
* void
|
|
*
|
|
*****************************************************************************/
|
|
void uart0TxFlush(void)
|
|
{
|
|
unsigned cpsr;
|
|
|
|
U0FCR |= UFCR_TX_FIFO_RESET; // clear the TX fifo
|
|
|
|
// "Empty" the transmit buffer.
|
|
cpsr = disableIRQ(); // disable global interrupts
|
|
U0IER &= ~UIER_THRE; // disable TX interrupts
|
|
restoreIRQ(cpsr); // restore global interrupts
|
|
uart0_tx_insert_idx = uart0_tx_extract_idx = 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart0Getch()
|
|
*
|
|
* Description:
|
|
* This function gets a character from the UART receive queue
|
|
*
|
|
* Calling Sequence:
|
|
* void
|
|
*
|
|
* Returns:
|
|
* character on success, -1 if no character is available
|
|
*
|
|
*****************************************************************************/
|
|
int uart0Getch(void)
|
|
{
|
|
uint8_t ch;
|
|
|
|
if (uart0_rx_insert_idx == uart0_rx_extract_idx) // check if character is available
|
|
return -1;
|
|
|
|
ch = uart0_rx_buffer[uart0_rx_extract_idx++]; // get character, bump pointer
|
|
uart0_rx_extract_idx %= UART0_RX_BUFFER_SIZE; // limit the pointer
|
|
return ch;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart1Init()
|
|
*
|
|
* Description:
|
|
* This function initializes the UART for async mode
|
|
*
|
|
* Calling Sequence:
|
|
* baudrate divisor - use UART_BAUD macro
|
|
* mode - see typical modes (uart.h)
|
|
* fmode - see typical fmodes (uart.h)
|
|
*
|
|
* Returns:
|
|
* void
|
|
*
|
|
* NOTE: uart1Init(UART_BAUD(9600), UART_8N1, UART_FIFO_8);
|
|
*
|
|
*****************************************************************************/
|
|
void uart1Init(uint16_t baud, uint8_t mode, uint8_t fmode)
|
|
{
|
|
// set port pins for UART1
|
|
// mthomas PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL;
|
|
U1_TX_PINSEL_REG = ( U1_TX_PINSEL_REG & ~U1_TX_PINMASK ) | U1_TX_PINSEL;
|
|
U1_RX_PINSEL_REG = ( U1_RX_PINSEL_REG & ~U1_RX_PINMASK ) | U1_RX_PINSEL;
|
|
|
|
U1IER = 0x00; // disable all interrupts
|
|
U1IIR; // clear interrupt ID
|
|
U1RBR; // clear receive register
|
|
U1LSR; // clear line status register
|
|
|
|
// Set CLOCK for UART1 device (4x)
|
|
//PCLKSEL0 = 0x00000100;
|
|
|
|
// Set CLOCK for UART1 device (div 2)
|
|
PCLKSEL0 &= 0xFFFFFCFF;
|
|
PCLKSEL0 |= 0x00000200;
|
|
|
|
// set the baudrate
|
|
U1LCR = ULCR_DLAB_ENABLE; // select divisor latches
|
|
U1DLL = (uint8_t)baud; // set for baud low byte
|
|
U1DLM = (uint8_t)(baud >> 8); // set for baud high byte
|
|
|
|
// set the number of characters and other
|
|
// user specified operating parameters
|
|
U1LCR = (mode & ~ULCR_DLAB_ENABLE);
|
|
U1FCR = fmode;
|
|
|
|
// initialize the interrupt vector
|
|
VICIntSelect &= ~VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART1);
|
|
VICIntEnClr = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART1);
|
|
VICVectAddr7 = (uint32_t)uart1ISR;
|
|
VICVectPriority7 = 0x0F;
|
|
VICIntEnable = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART1);
|
|
|
|
uart1_tx_extract_idx = uart1_tx_insert_idx = 0;
|
|
uart1_tx_running = 0;
|
|
|
|
// initialize data queues
|
|
uart1_rx_extract_idx = uart1_rx_insert_idx = 0;
|
|
|
|
// enable receiver interrupts
|
|
U1IER |= UIER_RBR;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart1Putch()
|
|
*
|
|
* Description:
|
|
* This function puts a character into the UART output queue for
|
|
* transmission.
|
|
*
|
|
* Calling Sequence:
|
|
* ch - character to be transmitted
|
|
*
|
|
* Returns:
|
|
* ch on success, -1 on error (queue full)
|
|
*
|
|
*****************************************************************************/
|
|
int uart1Putch(int ch)
|
|
{
|
|
uint16_t temp;
|
|
unsigned cpsr;
|
|
|
|
temp = (uart1_tx_insert_idx + 1) % UART1_TX_BUFFER_SIZE;
|
|
|
|
if (temp == uart1_tx_extract_idx)
|
|
return -1; // no room
|
|
|
|
cpsr = disableIRQ(); // disable global interrupts
|
|
U1IER &= ~UIER_THRE; // disable TX interrupts
|
|
restoreIRQ(cpsr); // restore global interrupts
|
|
|
|
// check if in process of sending data
|
|
if (uart1_tx_running)
|
|
{
|
|
// add to queue
|
|
uart1_tx_buffer[uart1_tx_insert_idx] = (uint8_t)ch;
|
|
uart1_tx_insert_idx = temp;
|
|
}
|
|
else
|
|
{
|
|
// set running flag and write to output register
|
|
uart1_tx_running = 1;
|
|
U1THR = (uint8_t)ch;
|
|
}
|
|
|
|
cpsr = disableIRQ(); // disable global interrupts
|
|
U1IER |= UIER_THRE; // enable TX interrupts
|
|
restoreIRQ(cpsr); // restore global interrupts
|
|
|
|
return (uint8_t)ch;
|
|
}
|
|
|
|
int uart1Putch_block(int ch)
|
|
{
|
|
while ( !uart1Space() ) {
|
|
; // wait for space available
|
|
}
|
|
return uart1Putch(ch);
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart1Space()
|
|
*
|
|
* Description:
|
|
* This function gets the available space in the transmit queue
|
|
*
|
|
* Calling Sequence:
|
|
* void
|
|
*
|
|
* Returns:
|
|
* available space in the transmit queue
|
|
*
|
|
*****************************************************************************/
|
|
uint16_t uart1Space(void)
|
|
{
|
|
int space;
|
|
|
|
if ((space = (uart1_tx_extract_idx - uart1_tx_insert_idx)) <= 0)
|
|
space += UART1_TX_BUFFER_SIZE;
|
|
|
|
return (uint16_t)(space - 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart1Puts()
|
|
*
|
|
* Description:
|
|
* This function writes a NULL terminated 'string' to the UART output
|
|
* queue, returning a pointer to the next character to be written.
|
|
*
|
|
* Calling Sequence:
|
|
* address of the string
|
|
*
|
|
* Returns:
|
|
* a pointer to the next character to be written
|
|
* (\0 if full string is written)
|
|
*
|
|
*****************************************************************************/
|
|
const char *uart1Puts(const char *string)
|
|
{
|
|
register char ch;
|
|
|
|
while ((ch = *string) && (uart1Putch(ch) >= 0))
|
|
string++;
|
|
|
|
return string;
|
|
}
|
|
|
|
const char *uart1Puts_block(const char *string)
|
|
{
|
|
register char ch;
|
|
|
|
while ((ch = *string) && (uart1Putch_block(ch) >= 0))
|
|
string++;
|
|
|
|
return string;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart1Write()
|
|
*
|
|
* Description:
|
|
* This function writes 'count' characters from 'buffer' to the UART
|
|
* output queue.
|
|
*
|
|
* Calling Sequence:
|
|
*
|
|
*
|
|
* Returns:
|
|
* 0 on success, -1 if insufficient room, -2 on error
|
|
* NOTE: if insufficient room, no characters are written.
|
|
*
|
|
*****************************************************************************/
|
|
int uart1Write(const char *buffer, uint16_t count)
|
|
{
|
|
if (count > uart1Space())
|
|
return -1;
|
|
|
|
while (count && (uart1Putch(*buffer++) >= 0))
|
|
count--;
|
|
|
|
return (count ? -2 : 0);
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart1TxEmpty()
|
|
*
|
|
* Description:
|
|
* This function returns the status of the UART transmit data
|
|
* registers.
|
|
*
|
|
* Calling Sequence:
|
|
* void
|
|
*
|
|
* Returns:
|
|
* FALSE - either the tx holding or shift register is not empty
|
|
* !FALSE - if both the tx holding & shift registers are empty
|
|
*
|
|
*****************************************************************************/
|
|
int uart1TxEmpty(void)
|
|
{
|
|
return (U1LSR & (ULSR_THRE | ULSR_TEMT)) == (ULSR_THRE | ULSR_TEMT);
|
|
}
|
|
|
|
int uart1RxEmpty(void)
|
|
{
|
|
if (uart1_rx_insert_idx == uart1_rx_extract_idx) // check if character is available
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart1TxFlush()
|
|
*
|
|
* Description:
|
|
* This function removes all characters from the UART transmit queue
|
|
* (without transmitting them).
|
|
*
|
|
* Calling Sequence:
|
|
* void
|
|
*
|
|
* Returns:
|
|
* void
|
|
*
|
|
*****************************************************************************/
|
|
void uart1TxFlush(void)
|
|
{
|
|
unsigned cpsr;
|
|
|
|
U1FCR |= UFCR_TX_FIFO_RESET; // clear the TX fifo
|
|
|
|
// "Empty" the transmit buffer.
|
|
cpsr = disableIRQ(); // disable global interrupts
|
|
U1IER &= ~UIER_THRE; // disable TX interrupts
|
|
restoreIRQ(cpsr); // restore global interrupts
|
|
uart1_tx_insert_idx = uart1_tx_extract_idx = 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart1Getch()
|
|
*
|
|
* Description:
|
|
* This function gets a character from the UART receive queue
|
|
*
|
|
* Calling Sequence:
|
|
* void
|
|
*
|
|
* Returns:
|
|
* character on success, -1 if no character is available
|
|
*
|
|
*****************************************************************************/
|
|
int uart1Getch(void)
|
|
{
|
|
uint8_t ch;
|
|
|
|
if (uart1_rx_insert_idx == uart1_rx_extract_idx) // check if character is available
|
|
return -1;
|
|
|
|
ch = uart1_rx_buffer[uart1_rx_extract_idx++]; // get character, bump pointer
|
|
uart1_rx_extract_idx %= UART1_RX_BUFFER_SIZE; // limit the pointer
|
|
return ch;
|
|
}
|
|
|