263 lines
8.3 KiB
ArmAsm
Executable File
263 lines
8.3 KiB
ArmAsm
Executable File
/**************************************************************************
|
|
* arch/arm/src/lpc2378/lpc23xx_lowputc.S
|
|
*
|
|
* Copyright (C) 2010 Rommel Marcelo. All rights reserved.
|
|
* Author: Rommel Marcelo
|
|
*
|
|
* This file is part of the NuttX RTOS and based on the lpc2148 port:
|
|
*
|
|
* Copyright (C) 2010 Gregory Nutt. All rights reserved.
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
|
* used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
* Included Files
|
|
**************************************************************************/
|
|
|
|
#include <nuttx/config.h>
|
|
#include "up_internal.h"
|
|
#include "up_arch.h"
|
|
#include "lpc23xx_pinsel.h"
|
|
#include "lpc23xx_scb.h"
|
|
#include "lpc23xx_uart.h"
|
|
|
|
/**************************************************************************
|
|
* Pre-processor Definitions
|
|
**************************************************************************/
|
|
@ //-- Pins
|
|
@ PINSEL0 |= (0x01<<4) | //-- P0.2 TXD0
|
|
@ (0x01<<6); //-- P0.3 RXD0
|
|
@PCLKSEL0 |= (0x01 << 6); //-- bit 7:6 =01-> Clock div = 1 for UART0
|
|
|
|
#if defined(CONFIG_UART0_SERIAL_CONSOLE)
|
|
# define UARTxBASE UART0_BASE_ADDR
|
|
# define PINSELECT LPC23XX_PINSEL0
|
|
# define UARTxPCLKSEL 0xE01FC1A8
|
|
# define PCLKSEL_MASK U0_PCLKSEL_MASK
|
|
# define UARTxPINSEL UART0_PINSEL
|
|
# define UARTxPINMASK UART0_PINMASK
|
|
# define UARTxBAUD CONFIG_UART0_BAUD
|
|
# define UARTxBITS CONFIG_UART0_BITS
|
|
# define UARTxPARITY CONFIG_UART0_PARITY
|
|
# define UARTx2STOP CONFIG_UART0_2STOP
|
|
#elif defined(CONFIG_UART1_SERIAL_CONSOLE)
|
|
# define UARTxBASE UART1_BASE_ADDR
|
|
/* # define PINSELECT LPC23XX_PINSEL1 only Uart0/Uart2 share same Pinsel */
|
|
# define UARTxPCLKSEL 0xE01FC1A8
|
|
# define PCLKSEL_MASK U1_PCLKSEL_MASK
|
|
# define UARTxPINSEL UART1_PINSEL
|
|
# define UARTxPINMASK UART1_PINMASK
|
|
# define UARTxBAUD CONFIG_UART1_BAUD
|
|
# define UARTxBITS CONFIG_UART1_BITS
|
|
# define UARTxPARITY CONFIG_UART1_PARITY
|
|
# define UARTx2STOP CONFIG_UART1_2STOP
|
|
#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
|
|
# define UARTxBASE UART2_BASE_ADDR
|
|
# define PINSELECT LPC23XX_PINSEL0
|
|
# define UARTxPCLKSEL 0xE01FC1AC
|
|
# define PCLKSEL_MASK U2_PCLKSEL_MASK
|
|
# define UARTxPINSEL UART2_PINSEL
|
|
# define UARTxPINMASK UART2_PINMASK
|
|
# define UARTxBAUD CONFIG_UART2_BAUD
|
|
# define UARTxBITS CONFIG_UART2_BITS
|
|
# define UARTxPARITY CONFIG_UART2_PARITY
|
|
# define UARTx2STOP CONFIG_UART2_2STOP
|
|
#elif defined(CONFIG_UART3_SERIAL_CONSOLE)
|
|
# define PINSELECT LPC23XX_PINSEL0
|
|
# define UARTxBASE UART3_BASE_ADDR
|
|
# define UARTxPCLKSEL 0xE01FC1AC
|
|
# define PCLKSEL_MASK U2_PCLKSEL_MASK
|
|
# define UARTxPINSEL UART3_PINSEL
|
|
# define UARTxPINMASK UART3_PINMASK
|
|
# define UARTxBAUD CONFIG_UART3_BAUD
|
|
# define UARTxBITS CONFIG_UART3_BITS
|
|
# define UARTxPARITY CONFIG_UART3_PARITY
|
|
# define UARTx2STOP CONFIG_UART3_2STOP
|
|
#else
|
|
# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting"
|
|
#endif
|
|
|
|
#if UARTxBITS == 5
|
|
# define LCR_CHAR LCR_CHAR_5
|
|
#elif UARTxBITS == 6
|
|
# define LCR_CHAR LCR_CHAR_6
|
|
#elif UARTxBITS == 7
|
|
# define LCR_CHAR LCR_CHAR_7
|
|
#elif UARTxBITS == 8
|
|
# define LCR_CHAR LCR_CHAR_8
|
|
#else
|
|
# error "No CONFIG_UARTn_BITS Setting"
|
|
#endif
|
|
|
|
#if UARTxPARITY == 0
|
|
# define LCR_PAR LCR_PAR_NONE
|
|
#elif UARTxPARITY == 1
|
|
# define LCR_PAR LCR_PAR_ODD
|
|
#elif UARTxPARITY == 2
|
|
# define LCR_PAR LCR_PAR_EVEN
|
|
#elif UARTxPARITY == 3
|
|
# define LCR_PAR LCR_PAR_MARK
|
|
#elif UARTxPARITY == 4
|
|
# define LCR_PAR LCR_PAR_SPACE
|
|
#else
|
|
# error "No CONFIG_UARTn_PARITY Setting"
|
|
#endif
|
|
|
|
#if UARTx2STOP != 0
|
|
# define LCR_STOP LCR_STOP_2
|
|
#else
|
|
# define LCR_STOP LCR_STOP_1
|
|
#endif
|
|
|
|
#define LCR_VALUE (LCR_CHAR | LCR_PAR | LCR_STOP)
|
|
#define FCR_VALUE (FCR_FIFO_TRIG8 | FCR_TX_FIFO_RESET | \
|
|
FCR_RX_FIFO_RESET | FCR_FIFO_ENABLE)
|
|
@#define MULVAL (12 << 4)
|
|
@#define DIVADDVAL 3
|
|
/**************************************************************************
|
|
* Private Types
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
* Private Function Prototypes
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
* Global Variables
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
* Private Variables
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
* Private Functions
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
* Public Functions
|
|
**************************************************************************/
|
|
|
|
/**************************************************************************
|
|
* Name: up_lowputc
|
|
**************************************************************************/
|
|
|
|
/* This assembly language version has the advantage that it does not
|
|
* require a C stack and uses only r0-r1. Hence it can be used during
|
|
* early boot phases.
|
|
*/
|
|
|
|
.text
|
|
.global up_lowputc
|
|
.type up_lowputc, function
|
|
up_lowputc:
|
|
/* On entry, r0 holds the character to be printed */
|
|
|
|
ldr r1, =UARTxBASE
|
|
strb r0, [r1, #UART_THR_OFFSET]
|
|
|
|
/* Wait for the byte to be transferred */
|
|
|
|
1: ldr r0, [r1, #UART_LSR_OFFSET]
|
|
ands r0, #LSR_TEMT /* Transmitter empty */
|
|
beq 1b
|
|
|
|
/* And return */
|
|
|
|
mov pc, lr
|
|
.size up_lowputc, . - up_lowputc
|
|
|
|
/* This performs basic initialization of the UART. This can be called very
|
|
* early in initialization because it does not depend on having a stack. It
|
|
* modifies r0-r2 and r14.
|
|
*/
|
|
|
|
.text
|
|
.globl up_lowsetup
|
|
.type up_lowsetup, function
|
|
up_lowsetup:
|
|
/* Configure PINSEL0 */
|
|
|
|
ldr r0, =PINSELECT /* TODO: generalize this for different uart pins */
|
|
ldr r1, [r0]
|
|
ldr r2, =(~UARTxPINMASK)
|
|
and r1, r2
|
|
|
|
ldr r2, =(UARTxPINSEL)
|
|
orr r1, r2
|
|
str r1, [r0]
|
|
|
|
/* Power Up Uart0 */
|
|
ldr r0, =UARTxPCLKSEL /* PCLKSEL0 address */
|
|
ldr r1, [r0]
|
|
ldr r2, =(~PCLKSEL_MASK)
|
|
and r1, r2
|
|
|
|
ldr r2, =(U0_PCLKSEL)
|
|
orr r1, r2
|
|
str r1, [r0]
|
|
|
|
/* Configure parity, data bits, stop bits and set DLAB=1 */
|
|
|
|
ldr r0, =UARTxBASE
|
|
mov r1, #(LCR_VALUE | LCR_DLAB_ENABLE)
|
|
strb r1, [r0, #UART_LCR_OFFSET]
|
|
|
|
/* Set the BAUD divisor */
|
|
|
|
mov r1, #((MULVAL << 4) | DIVADDVAL)
|
|
strb r1, [r0, #UART_FDR_OFFSET]
|
|
|
|
mov r1, #DLMVAL
|
|
strb r1, [r0, #UART_DLM_OFFSET]
|
|
|
|
mov r1, #DLLVAL
|
|
strb r1, [r0, #UART_DLL_OFFSET]
|
|
|
|
/* Clear DLAB and Set format 8N1 */
|
|
|
|
mov r1, #LCR_VALUE
|
|
strb r1, [r0, #UART_LCR_OFFSET]
|
|
|
|
/* Configure the FIFOs */
|
|
|
|
mov r1, #FCR_VALUE
|
|
strb r1, [r0, #UART_FCR_OFFSET]
|
|
|
|
mov r1, #LCR_VALUE
|
|
strb r1, [r0, #UART_LCR_OFFSET]
|
|
|
|
/* And return */
|
|
|
|
mov pc, lr
|
|
.size up_lowsetup, . - up_lowsetup
|
|
.end
|