373a8c32b2
git-svn-id: file:///srv/dev-disk-by-uuid-17e88007-4d0c-45e0-8757-cacfcc458630/repositories/svn/Diplomarbeit@55 9fe90eed-be63-e94b-8204-d34ff4c2ff93
333 lines
9.2 KiB
C
333 lines
9.2 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 "uart3.h"
|
|
|
|
#ifndef USHRT_MAX
|
|
#define USHRT_MAX 16
|
|
#endif
|
|
|
|
#include "armVIC.h"
|
|
#include "uart3ISR.h"
|
|
|
|
#define U3_TX_PINSEL_REG PINSEL0
|
|
#define U3_TX_PINSEL (2UL<<0) /* PINSEL4 Value for UART3 TX */
|
|
#define U3_TX_PINMASK (3UL<<0) /* PINSEL4 Mask for UART3 RX */
|
|
#define U3_RX_PINSEL_REG PINSEL0
|
|
#define U3_RX_PINSEL (2UL<<2) /* PINSEL4 Value for UART3 TX */
|
|
#define U3_RX_PINMASK (3UL<<2) /* PINSEL4 Mask for UART3 RX */
|
|
|
|
uint8_t uart3_rx_buffer[UART3_RX_BUFFER_SIZE];
|
|
uint16_t uart3_rx_insert_idx, uart3_rx_extract_idx;
|
|
uint8_t uart3_tx_buffer[UART3_TX_BUFFER_SIZE];
|
|
uint16_t uart3_tx_insert_idx, uart3_tx_extract_idx;
|
|
int uart3_tx_running;
|
|
t_uart3_txcomplete uart3_tx_complete_callback;
|
|
|
|
|
|
void uart3TxFinished(void);
|
|
|
|
void uart3Init(uint16_t baud, uint8_t mode, uint8_t fmode)
|
|
{
|
|
PCONP |= BIT( 25 ); // power on UART3
|
|
|
|
// set port pins for UART3
|
|
// mthomas PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
|
|
// set port pins for UART3
|
|
// PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
|
|
U3_TX_PINSEL_REG = ( U3_TX_PINSEL_REG & ~U3_TX_PINMASK ) | U3_TX_PINSEL;
|
|
U3_RX_PINSEL_REG = ( U3_RX_PINSEL_REG & ~U3_RX_PINMASK ) | U3_RX_PINSEL;
|
|
|
|
U3IER = 0x00; // disable all interrupts
|
|
U3IIR; // clear interrupt ID
|
|
U3RBR; // clear receive register
|
|
U3LSR; // clear line status register
|
|
|
|
// Set CLOCK for UART3 device (4x)
|
|
//PCLKSEL1 = 0x00040000;
|
|
|
|
// Set CLOCK for UART3 device (4x)
|
|
PCLKSEL1 &= 0xFFF7FFFF;
|
|
PCLKSEL1 |= 0x00080000;
|
|
|
|
// Preset callback function
|
|
uart3_tx_complete_callback = 0;
|
|
|
|
// set the baudrate
|
|
U3LCR = ULCR_DLAB_ENABLE; // select divisor latches
|
|
U3DLL = (uint8_t)baud; // set for baud low byte
|
|
U3DLM = (uint8_t)(baud >> 8); // set for baud high byte
|
|
|
|
// set the number of characters and other
|
|
// user specified operating parameters
|
|
U3LCR = (mode & ~ULCR_DLAB_ENABLE);
|
|
U3FCR = fmode;
|
|
|
|
// initialize the interrupt vector
|
|
VICIntSelect &= ~VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART3);
|
|
VICIntEnClr = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART3);
|
|
VICVectAddr29 = (uint32_t)uart3ISR;
|
|
VICVectPriority29 = 0xF;
|
|
VICIntEnable = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART3);
|
|
|
|
// initialize the transmit data queue
|
|
uart3_tx_extract_idx = uart3_tx_insert_idx = 0;
|
|
uart3_tx_running = 0;
|
|
|
|
// initialize the receive data queue
|
|
uart3_rx_extract_idx = uart3_rx_insert_idx = 0;
|
|
|
|
// enable receiver interrupts
|
|
U3IER = UIER_RBR;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart3Putch()
|
|
*
|
|
* 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 uart3Putch(int ch)
|
|
{
|
|
uint16_t temp;
|
|
unsigned cpsr;
|
|
|
|
temp = (uart3_tx_insert_idx + 1) % UART3_TX_BUFFER_SIZE;
|
|
|
|
if (temp == uart3_tx_extract_idx)
|
|
return -1; // no room
|
|
|
|
cpsr = disableIRQ(); // disable global interrupts
|
|
U3IER &= ~UIER_THRE; // disable TX interrupts
|
|
restoreIRQ(cpsr); // restore global interrupts
|
|
|
|
// check if in process of sending data
|
|
if (uart3_tx_running)
|
|
{
|
|
// add to queue
|
|
uart3_tx_buffer[uart3_tx_insert_idx] = (uint8_t)ch;
|
|
uart3_tx_insert_idx = temp;
|
|
}
|
|
else
|
|
{
|
|
// set running flag and write to output register
|
|
uart3_tx_running = 1;
|
|
U3THR = (uint8_t)ch;
|
|
}
|
|
|
|
cpsr = disableIRQ(); // disable global interrupts
|
|
U3IER |= UIER_THRE; // enable TX interrupts
|
|
restoreIRQ(cpsr); // restore global interrupts
|
|
|
|
return (uint8_t)ch;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart3Space()
|
|
*
|
|
* Description:
|
|
* This function gets the available space in the transmit queue
|
|
*
|
|
* Calling Sequence:
|
|
* void
|
|
*
|
|
* Returns:
|
|
* available space in the transmit queue
|
|
*
|
|
*****************************************************************************/
|
|
uint16_t uart3Space(void)
|
|
{
|
|
int space;
|
|
|
|
if ((space = (uart3_tx_extract_idx - uart3_tx_insert_idx)) <= 0)
|
|
space += UART3_TX_BUFFER_SIZE;
|
|
|
|
return (uint16_t)(space - 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart3Puts()
|
|
*
|
|
* 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 *uart3Puts(const char *string)
|
|
{
|
|
register char ch;
|
|
|
|
while ((ch = *string) && (uart3Putch(ch) >= 0))
|
|
string++;
|
|
|
|
return string;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart3Write()
|
|
*
|
|
* 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 uart3Write(const char *buffer, uint16_t count)
|
|
{
|
|
if (count > uart3Space())
|
|
return -1;
|
|
|
|
while (count && (uart3Putch(*buffer++) >= 0))
|
|
count--;
|
|
|
|
return (count ? -2 : 0);
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart3TxEmpty()
|
|
*
|
|
* 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 uart3TxEmpty(void)
|
|
{
|
|
return (U3LSR & (ULSR_THRE | ULSR_TEMT)) == (ULSR_THRE | ULSR_TEMT);
|
|
}
|
|
|
|
|
|
int uart3RxEmpty(void)
|
|
{
|
|
if (uart3_rx_insert_idx == uart3_rx_extract_idx) // check if character is available
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart3TxFlush()
|
|
*
|
|
* Description:
|
|
* This function removes all characters from the UART transmit queue
|
|
* (without transmitting them).
|
|
*
|
|
* Calling Sequence:
|
|
* void
|
|
*
|
|
* Returns:
|
|
* void
|
|
*
|
|
*****************************************************************************/
|
|
void uart3TxFlush(void)
|
|
{
|
|
unsigned cpsr;
|
|
|
|
U3FCR |= UFCR_TX_FIFO_RESET; // clear the TX fifo
|
|
|
|
// "Empty" the transmit buffer.
|
|
cpsr = disableIRQ(); // disable global interrupts
|
|
U3IER &= ~UIER_THRE; // disable TX interrupts
|
|
restoreIRQ(cpsr); // restore global interrupts
|
|
uart3_tx_insert_idx = uart3_tx_extract_idx = 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Function Name: uart3Getch()
|
|
*
|
|
* 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 uart3Getch(void)
|
|
{
|
|
uint8_t ch;
|
|
|
|
if (uart3_rx_insert_idx == uart3_rx_extract_idx) // check if character is available
|
|
return -1;
|
|
|
|
ch = uart3_rx_buffer[uart3_rx_extract_idx++]; // get character, bump pointer
|
|
uart3_rx_extract_idx %= UART3_RX_BUFFER_SIZE; // limit the pointer
|
|
return ch;
|
|
}
|
|
|
|
void uart3SubscribeTxFinished( t_uart3_txcomplete callback )
|
|
{
|
|
uart3_tx_complete_callback = callback;
|
|
}
|
|
|
|
void uart3UnsubsribeTxFinished( t_uart3_txcomplete callback )
|
|
{
|
|
uart3_tx_complete_callback = 0;
|
|
}
|
|
|
|
|
|
void uart3TxFinished(void)
|
|
{
|
|
if (uart3_tx_complete_callback != 0)
|
|
{
|
|
uart3_tx_complete_callback();
|
|
}
|
|
}
|
|
|
|
|