/****************************************************************************** * * $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 "uart2.h" #ifndef USHRT_MAX #define USHRT_MAX 16 #endif #include "armVIC.h" #include "uart2ISR.h" #define U2_TX_PINSEL_REG PINSEL4 #define U2_TX_PINSEL (2UL<<16) /* PINSEL4 Value for UART2 TX */ #define U2_TX_PINMASK (3UL<<16) /* PINSEL4 Mask for UART2 RX */ #define U2_RX_PINSEL_REG PINSEL4 #define U2_RX_PINSEL (2UL<<18) /* PINSEL4 Value for UART2 TX */ #define U2_RX_PINMASK (3UL<<18) /* PINSEL4 Mask for UART2 RX */ uint8_t uart2_rx_buffer[UART2_RX_BUFFER_SIZE]; uint16_t uart2_rx_insert_idx, uart2_rx_extract_idx; uint8_t uart2_tx_buffer[UART2_TX_BUFFER_SIZE]; uint16_t uart2_tx_insert_idx, uart2_tx_extract_idx; int uart2_tx_running; t_uart2_txcomplete uart2_tx_complete_callback; void uart2TxFinished(void); void uart2Init(uint16_t baud, uint8_t mode, uint8_t fmode) { PCONP |= BIT( 24 ); // power on UART2 // set port pins for UART2 // mthomas PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL; // set port pins for UART2 // PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL; U2_TX_PINSEL_REG = ( U2_TX_PINSEL_REG & ~U2_TX_PINMASK ) | U2_TX_PINSEL; U2_RX_PINSEL_REG = ( U2_RX_PINSEL_REG & ~U2_RX_PINMASK ) | U2_RX_PINSEL; U2IER = 0x00; // disable all interrupts U2IIR; // clear interrupt ID U2RBR; // clear receive register U2LSR; // clear line status register // Set CLOCK for UART2 device (4x) //PCLKSEL1 = 0x00010000; // Set CLOCK for UART2 device (div 2) PCLKSEL1 &= 0xFFFDFFFF; PCLKSEL1 |= 0x00020000; // Preset callback function to none uart2_tx_complete_callback = 0; // set the baudrate U2LCR = ULCR_DLAB_ENABLE; // select divisor latches U2DLL = (uint8_t)baud; // set for baud low byte U2DLM = (uint8_t)(baud >> 8); // set for baud high byte // set the number of characters and other // user specified operating parameters U2LCR = (mode & ~ULCR_DLAB_ENABLE); U2FCR = fmode; // initialize the interrupt vector VICIntSelect &= ~VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART2); VICIntEnClr = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART2); VICVectAddr28 = (uint32_t)uart2ISR; VICVectPriority28 = 0xF; VICIntEnable = VIC_CHAN_TO_MASK(VIC_CHAN_NUM_UART2); // initialize the transmit data queue uart2_tx_extract_idx = uart2_tx_insert_idx = 0; uart2_tx_running = 0; // initialize the receive data queue uart2_rx_extract_idx = uart2_rx_insert_idx = 0; // enable receiver interrupts U2IER = UIER_RBR; } /****************************************************************************** * * Function Name: uart2Putch() * * 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 uart2Putch(int ch) { uint16_t temp; unsigned cpsr; temp = (uart2_tx_insert_idx + 1) % UART2_TX_BUFFER_SIZE; if (temp == uart2_tx_extract_idx) return -1; // no room cpsr = disableIRQ(); // disable global interrupts U2IER &= ~UIER_THRE; // disable TX interrupts restoreIRQ(cpsr); // restore global interrupts // check if in process of sending data if (uart2_tx_running) { // add to queue uart2_tx_buffer[uart2_tx_insert_idx] = (uint8_t)ch; uart2_tx_insert_idx = temp; } else { // set running flag and write to output register uart2_tx_running = 1; U2THR = (uint8_t)ch; } cpsr = disableIRQ(); // disable global interrupts U2IER |= UIER_THRE; // enable TX interrupts restoreIRQ(cpsr); // restore global interrupts return (uint8_t)ch; } /****************************************************************************** * * Function Name: uart2Space() * * Description: * This function gets the available space in the transmit queue * * Calling Sequence: * void * * Returns: * available space in the transmit queue * *****************************************************************************/ uint16_t uart2Space(void) { int space; if ((space = (uart2_tx_extract_idx - uart2_tx_insert_idx)) <= 0) space += UART2_TX_BUFFER_SIZE; return (uint16_t)(space - 1); } /****************************************************************************** * * Function Name: uart2Puts() * * 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 *uart2Puts(const char *string) { register char ch; while ((ch = *string) && (uart2Putch(ch) >= 0)) string++; return string; } /****************************************************************************** * * Function Name: uart2Write() * * 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 uart2Write(const char *buffer, uint16_t count) { if (count > uart2Space()) return -1; while (count && (uart2Putch(*buffer++) >= 0)) count--; return (count ? -2 : 0); } /****************************************************************************** * * Function Name: uart2TxEmpty() * * 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 uart2TxEmpty(void) { return (U2LSR & (ULSR_THRE | ULSR_TEMT)) == (ULSR_THRE | ULSR_TEMT); } int uart2RxEmpty(void) { if (uart2_rx_insert_idx == uart2_rx_extract_idx) // check if character is available { return 1; } else { return 0; } } /****************************************************************************** * * Function Name: uart2TxFlush() * * Description: * This function removes all characters from the UART transmit queue * (without transmitting them). * * Calling Sequence: * void * * Returns: * void * *****************************************************************************/ void uart2TxFlush(void) { unsigned cpsr; U2FCR |= UFCR_TX_FIFO_RESET; // clear the TX fifo // "Empty" the transmit buffer. cpsr = disableIRQ(); // disable global interrupts U2IER &= ~UIER_THRE; // disable TX interrupts restoreIRQ(cpsr); // restore global interrupts uart2_tx_insert_idx = uart2_tx_extract_idx = 0; } /****************************************************************************** * * Function Name: uart2Getch() * * 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 uart2Getch(void) { uint8_t ch; if (uart2_rx_insert_idx == uart2_rx_extract_idx) // check if character is available return -1; ch = uart2_rx_buffer[uart2_rx_extract_idx++]; // get character, bump pointer uart2_rx_extract_idx %= UART2_RX_BUFFER_SIZE; // limit the pointer return ch; } void uart2SubscribeTxFinished( t_uart2_txcomplete callback ) { uart2_tx_complete_callback = callback; } void uart2UnsubsribeTxFinished( t_uart2_txcomplete callback ) { uart2_tx_complete_callback = 0; } void uart2TxFinished(void) { if (uart2_tx_complete_callback != 0) { uart2_tx_complete_callback(); } }