| /**************************************************************************** |
| * arch/arm/src/am335x/am335x_lowputc.c |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. The |
| * ASF licenses this file to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the |
| * License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| * |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Included Files |
| ****************************************************************************/ |
| |
| #include <nuttx/config.h> |
| |
| #include <stdint.h> |
| |
| #include <arch/irq.h> |
| #include <arch/board/board.h> |
| |
| #include "arm_internal.h" |
| #include "am335x_config.h" |
| #include "am335x_gpio.h" |
| #include "am335x_pinmux.h" |
| #include "hardware/am335x_uart.h" |
| |
| /**************************************************************************** |
| * Pre-processor Definitions |
| ****************************************************************************/ |
| |
| /* Select UART parameters for the selected console */ |
| |
| #if defined(CONFIG_UART0_SERIAL_CONSOLE) |
| # define CONSOLE_BASE AM335X_UART0_VADDR |
| # define CONSOLE_BAUD CONFIG_UART0_BAUD |
| # define CONSOLE_BITS CONFIG_UART0_BITS |
| # define CONSOLE_PARITY CONFIG_UART0_PARITY |
| # define CONSOLE_2STOP CONFIG_UART0_2STOP |
| #elif defined(CONFIG_UART1_SERIAL_CONSOLE) |
| # define CONSOLE_BASE AM335X_UART1_VADDR |
| # define CONSOLE_BAUD CONFIG_UART1_BAUD |
| # define CONSOLE_BITS CONFIG_UART1_BITS |
| # define CONSOLE_PARITY CONFIG_UART1_PARITY |
| # define CONSOLE_2STOP CONFIG_UART1_2STOP |
| #elif defined(CONFIG_UART2_SERIAL_CONSOLE) |
| # define CONSOLE_BASE AM335X_UART2_VADDR |
| # define CONSOLE_BAUD CONFIG_UART2_BAUD |
| # define CONSOLE_BITS CONFIG_UART2_BITS |
| # define CONSOLE_PARITY CONFIG_UART2_PARITY |
| # define CONSOLE_2STOP CONFIG_UART2_2STOP |
| #elif defined(CONFIG_UART3_SERIAL_CONSOLE) |
| # define CONSOLE_BASE AM335X_UART3_VADDR |
| # define CONSOLE_BAUD CONFIG_UART3_BAUD |
| # define CONSOLE_BITS CONFIG_UART3_BITS |
| # define CONSOLE_PARITY CONFIG_UART3_PARITY |
| # define CONSOLE_2STOP CONFIG_UART3_2STOP |
| #elif defined(CONFIG_UART4_SERIAL_CONSOLE) |
| # define CONSOLE_BASE AM335X_UART4_VADDR |
| # define CONSOLE_BAUD CONFIG_UART4_BAUD |
| # define CONSOLE_BITS CONFIG_UART4_BITS |
| # define CONSOLE_PARITY CONFIG_UART4_PARITY |
| # define CONSOLE_2STOP CONFIG_UART4_2STOP |
| #elif defined(CONFIG_UART5_SERIAL_CONSOLE) |
| # define CONSOLE_BASE AM335X_UART5_VADDR |
| # define CONSOLE_BAUD CONFIG_UART5_BAUD |
| # define CONSOLE_BITS CONFIG_UART5_BITS |
| # define CONSOLE_PARITY CONFIG_UART5_PARITY |
| # define CONSOLE_2STOP CONFIG_UART5_2STOP |
| #elif defined(HAVE_SERIAL_CONSOLE) |
| # error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" |
| #endif |
| |
| /* Get word length setting for the console */ |
| |
| #if CONSOLE_BITS == 5 |
| # define CONSOLE_LCR_DLS UART_LCR_DLS_5BITS |
| #elif CONSOLE_BITS == 6 |
| # define CONSOLE_LCR_DLS UART_LCR_DLS_6BITS |
| #elif CONSOLE_BITS == 7 |
| # define CONSOLE_LCR_DLS UART_LCR_DLS_7BITS |
| #elif CONSOLE_BITS == 8 |
| # define CONSOLE_LCR_DLS UART_LCR_DLS_8BITS |
| #elif defined(HAVE_SERIAL_CONSOLE) |
| # error "Invalid CONFIG_UARTn_BITS setting for console " |
| #endif |
| |
| /* Get parity setting for the console */ |
| |
| #if CONSOLE_PARITY == 0 |
| # define CONSOLE_LCR_PAR UART_LCR_PARITY_NONE |
| #elif CONSOLE_PARITY == 1 |
| # define CONSOLE_LCR_PAR UART_LCR_PARITY_ODD |
| #elif CONSOLE_PARITY == 2 |
| # define CONSOLE_LCR_PAR UART_LCR_PARITY_EVEN |
| #elif CONSOLE_PARITY == 3 |
| #elif defined(HAVE_SERIAL_CONSOLE) |
| # error "Invalid CONFIG_UARTn_PARITY setting for CONSOLE" |
| #endif |
| |
| /* Get stop-bit setting for the console and UART0-3 */ |
| |
| #if CONSOLE_2STOP != 0 |
| # define CONSOLE_LCR_STOP UART_LCR_STOP_2BITS |
| #else |
| # define CONSOLE_LCR_STOP UART_LCR_STOP_1BITS |
| #endif |
| |
| /* LCR and FCR values for the console */ |
| |
| #define CONSOLE_LCR_VALUE (CONSOLE_LCR_DLS | CONSOLE_LCR_PAR | \ |
| CONSOLE_LCR_STOP) |
| #define CONSOLE_FCR_VALUE (UART_FCR_FIFO_EN | UART_FCR_RFT_60CHAR | \ |
| UART_FCR_TFT_56CHAR) |
| |
| /* SCLK is the UART input clock. |
| * |
| * Through experimentation, it has been found that the serial clock is |
| * OSC24M |
| */ |
| |
| #define AM335X_SCLK 48000000 |
| |
| /* The output baud rate is equal to the serial clock (SCLK) frequency |
| * divided by sixteen times the value of the baud rate divisor, as follows: |
| * |
| * baud rate = Fsclk / (16 * divisor). |
| */ |
| |
| #define CONSOLE_DL (AM335X_SCLK / (CONSOLE_BAUD << 4)) |
| |
| /**************************************************************************** |
| * Public Functions |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Name: arm_lowputc |
| * |
| * Description: |
| * Output one byte on the serial console |
| * |
| ****************************************************************************/ |
| |
| void arm_lowputc(char ch) |
| { |
| #if defined(HAVE_UART_DEVICE) && defined(HAVE_SERIAL_CONSOLE) |
| /* Wait for the transmitter to be available */ |
| |
| while ((getreg32(CONSOLE_BASE + AM335X_UART_LSR_OFFSET) & |
| UART_LSR_THRE) == 0) |
| { |
| } |
| |
| /* Send the character */ |
| |
| putreg32((uint32_t)ch, CONSOLE_BASE + AM335X_UART_THR_OFFSET); |
| while ((getreg32(CONSOLE_BASE + AM335X_UART_LSR_OFFSET) & |
| UART_LSR_THRE) == 0) |
| { |
| } |
| #endif |
| } |
| |
| /**************************************************************************** |
| * Name: am335x_lowsetup |
| * |
| * Description: |
| * This performs basic initialization of the UART used for the serial |
| * console. Its purpose is to get the console output available as soon |
| * as possible. |
| * |
| ****************************************************************************/ |
| |
| void am335x_lowsetup(void) |
| { |
| #ifdef HAVE_UART_DEVICE |
| /* Enable power and clocking to the UART peripheral */ |
| |
| #warning Missing logic |
| |
| /* Configure UART pins for the selected CONSOLE. If there are multiple |
| * pin options for a given UART, the the applicable option must be |
| * disambiguated in the board.h header file. |
| */ |
| |
| #if defined(CONFIG_UART0_SERIAL_CONSOLE) |
| am335x_gpio_config(GPIO_UART0_TXD); |
| am335x_gpio_config(GPIO_UART0_RXD); |
| #elif defined(CONFIG_UART1_SERIAL_CONSOLE) |
| am335x_gpio_config(GPIO_UART1_TXD); |
| am335x_gpio_config(GPIO_UART1_RXD); |
| #elif defined(CONFIG_UART2_SERIAL_CONSOLE) |
| am335x_gpio_config(GPIO_UART2_TXD); |
| am335x_gpio_config(GPIO_UART2_RXD); |
| #elif defined(CONFIG_UART3_SERIAL_CONSOLE) |
| am335x_gpio_config(GPIO_UART3_TXD); |
| am335x_gpio_config(GPIO_UART3_RXD); |
| #elif defined(CONFIG_UART4_SERIAL_CONSOLE) |
| am335x_gpio_config(GPIO_UART4_TXD); |
| am335x_gpio_config(GPIO_UART4_RXD); |
| #elif defined(CONFIG_UART5_SERIAL_CONSOLE) |
| am335x_gpio_config(GPIO_UART5_TXD); |
| am335x_gpio_config(GPIO_UART5_RXD); |
| #endif |
| |
| #if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) |
| /* Configure the console (only) */ |
| |
| #if 0 |
| /* Performing Software Reset of the module. */ |
| |
| putreg32(UART_SYSC_SRESET | getreg32(CONSOLE_BASE + |
| AM335X_UART_SYSC_OFFSET), |
| CONSOLE_BASE + AM335X_UART_SYSC_OFFSET); |
| |
| /* Wait until the process of Module Reset is complete. */ |
| |
| while (!(getreg32(CONSOLE_BASE + AM335X_UART_SYSS_OFFSET) & |
| UART_SYSS_RESET_DONE)) |
| { |
| } |
| #endif |
| |
| /* Put UART to disabled mode */ |
| |
| putreg32(UART_MDR1_MODE_DISABLE, CONSOLE_BASE + AM335X_UART_MDR1_OFFSET); |
| |
| /* Enter configuration mode and enable access to Latch Divisor DLAB=1 */ |
| |
| putreg32(UART_LCR_CONFIG_MODE_B, CONSOLE_BASE + AM335X_UART_LCR_OFFSET); |
| |
| /* Set Divisor values to zero to be able to write FCR correctly */ |
| |
| putreg32(0, CONSOLE_BASE + AM335X_UART_DLH_OFFSET); |
| putreg32(0, CONSOLE_BASE + AM335X_UART_DLL_OFFSET); |
| |
| /* Enable writing FCR[5:4] */ |
| |
| putreg32(UART_EFR_ENHANCEDEN, CONSOLE_BASE + AM335X_UART_EFR_OFFSET); |
| |
| /* Exit configuration mode and enable access to Latch Divisor DLAB=1 */ |
| |
| putreg32(UART_LCR_CONFIG_MODE_A, CONSOLE_BASE + AM335X_UART_LCR_OFFSET); |
| |
| /* Clear FIFOs */ |
| |
| putreg32(UART_FCR_RFIFO_CLEAR | UART_FCR_TFIFO_CLEAR, |
| CONSOLE_BASE + AM335X_UART_FCR_OFFSET); |
| |
| /* Configure the FIFOs */ |
| |
| putreg32(CONSOLE_FCR_VALUE, CONSOLE_BASE + AM335X_UART_FCR_OFFSET); |
| |
| /* Set the BAUD divisor */ |
| |
| putreg32((CONSOLE_DL >> 8) & UART_DLH_MASK, |
| CONSOLE_BASE + AM335X_UART_DLH_OFFSET); |
| putreg32(CONSOLE_DL & UART_DLL_MASK, |
| CONSOLE_BASE + AM335X_UART_DLL_OFFSET); |
| |
| /* Clear DLAB */ |
| |
| putreg32(CONSOLE_LCR_VALUE, CONSOLE_BASE + AM335X_UART_LCR_OFFSET); |
| |
| /* Enable Auto-Flow Control in the Modem Control Register */ |
| |
| #if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) |
| # warning Missing logic |
| #endif |
| |
| putreg32(UART_MDR1_MODE_16X, CONSOLE_BASE + AM335X_UART_MDR1_OFFSET); |
| #endif |
| #endif /* HAVE_UART_DEVICE */ |
| } |