| /**************************************************************************** |
| * arch/arm/src/nrf91/nrf91_lowputc.c |
| * |
| * 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 <stdbool.h> |
| #include <assert.h> |
| |
| #include "arm_internal.h" |
| #include "hardware/nrf91_memorymap.h" |
| #include "hardware/nrf91_uarte.h" |
| |
| #include "nrf91_config.h" |
| #include "nrf91_clockconfig.h" |
| #include "nrf91_gpio.h" |
| #include "nrf91_lowputc.h" |
| |
| #include <arch/board/board.h> |
| |
| /**************************************************************************** |
| * Pre-processor Definitions |
| ****************************************************************************/ |
| |
| #ifdef HAVE_UART_CONSOLE |
| |
| #ifdef CONFIG_UART0_SERIAL_CONSOLE |
| # define CONSOLE_BASE NRF91_UART0_BASE |
| # define CONSOLE_BAUD CONFIG_UART0_BAUD |
| # define CONSOLE_BITS CONFIG_UART0_BITS |
| # define CONSOLE_PARITY CONFIG_UART0_PARITY |
| # define CONSOLE_2STOP CONFIG_UART0_2STOP |
| # define CONSOLE_TX_PIN BOARD_UART0_TX_PIN |
| # define CONSOLE_RX_PIN BOARD_UART0_RX_PIN |
| #elif CONFIG_UART1_SERIAL_CONSOLE |
| # define CONSOLE_BASE NRF91_UART1_BASE |
| # define CONSOLE_BAUD CONFIG_UART1_BAUD |
| # define CONSOLE_BITS CONFIG_UART1_BITS |
| # define CONSOLE_PARITY CONFIG_UART1_PARITY |
| # define CONSOLE_2STOP CONFIG_UART1_2STOP |
| # define CONSOLE_TX_PIN BOARD_UART1_TX_PIN |
| # define CONSOLE_RX_PIN BOARD_UART1_RX_PIN |
| #endif |
| |
| /**************************************************************************** |
| * Private Data |
| ****************************************************************************/ |
| |
| /* UART console configuration */ |
| |
| static const struct uart_config_s g_console_config = |
| { |
| .baud = CONSOLE_BAUD, |
| .parity = CONSOLE_PARITY, |
| .bits = CONSOLE_BITS, |
| .stopbits2 = CONSOLE_2STOP, |
| .txpin = CONSOLE_TX_PIN, |
| .rxpin = CONSOLE_RX_PIN, |
| }; |
| #endif /* HAVE_UART_CONSOLE */ |
| |
| /**************************************************************************** |
| * Private Functions |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Name: nrf91_setbaud |
| * |
| * Description: |
| * Configure the UART BAUD. |
| * |
| ****************************************************************************/ |
| |
| #ifdef HAVE_UART_DEVICE |
| static void nrf91_setbaud(uintptr_t base, const struct uart_config_s *config) |
| { |
| uint32_t br = 0; |
| |
| switch (config->baud) |
| { |
| case 1200: |
| { |
| br = UART_BAUDRATE_1200; |
| break; |
| } |
| |
| case 2400: |
| { |
| br = UART_BAUDRATE_2400; |
| break; |
| } |
| |
| case 4800: |
| { |
| br = UART_BAUDRATE_4800; |
| break; |
| } |
| |
| case 9600: |
| { |
| br = UART_BAUDRATE_9600; |
| break; |
| } |
| |
| case 14400: |
| { |
| br = UART_BAUDRATE_14400; |
| break; |
| } |
| |
| case 19200: |
| { |
| br = UART_BAUDRATE_19200; |
| break; |
| } |
| |
| case 28800: |
| { |
| br = UART_BAUDRATE_28800; |
| break; |
| } |
| |
| #ifdef UART_BAUDRATE_31250 |
| case 31250: |
| { |
| br = UART_BAUDRATE_31250; |
| break; |
| } |
| #endif |
| |
| case 38400: |
| { |
| br = UART_BAUDRATE_38400; |
| break; |
| } |
| |
| #ifdef UART_BAUDRATE_56000 |
| case 56000: |
| { |
| br = UART_BAUDRATE_56000; |
| break; |
| } |
| #endif |
| |
| case 57600: |
| { |
| br = UART_BAUDRATE_57600; |
| break; |
| } |
| |
| case 76000: |
| { |
| br = UART_BAUDRATE_76000; |
| break; |
| } |
| |
| case 115200: |
| { |
| br = UART_BAUDRATE_115200; |
| break; |
| } |
| |
| case 230400: |
| { |
| br = UART_BAUDRATE_230400; |
| break; |
| } |
| |
| case 250000: |
| { |
| br = UART_BAUDRATE_250000; |
| break; |
| } |
| |
| case 460800: |
| { |
| br = UART_BAUDRATE_460800; |
| break; |
| } |
| |
| case 921600: |
| { |
| br = UART_BAUDRATE_921600; |
| break; |
| } |
| |
| case 1000000: |
| { |
| br = UART_BAUDRATE_1000000; |
| break; |
| } |
| |
| default: |
| { |
| DEBUGPANIC(); |
| break; |
| } |
| } |
| |
| putreg32(br, base + NRF91_UART_BAUDRATE_OFFSET); |
| } |
| |
| /**************************************************************************** |
| * Name: nrf91_setparity |
| ****************************************************************************/ |
| |
| static void nrf91_setparity(uintptr_t base, |
| const struct uart_config_s *config) |
| { |
| uint32_t regval = 0; |
| |
| regval = getreg32(base + NRF91_UART_CONFIG_OFFSET); |
| |
| if (config->parity == 2) |
| { |
| /* Include even parity */ |
| |
| regval |= UART_CONFIG_PARITY; |
| } |
| else |
| { |
| /* Exclude parity */ |
| |
| regval &= ~UART_CONFIG_PARITY; |
| } |
| |
| putreg32(regval, base + NRF91_UART_CONFIG_OFFSET); |
| } |
| |
| /**************************************************************************** |
| * Name: nrf91_setstops |
| ****************************************************************************/ |
| |
| #ifdef HAVE_UART_STOPBITS |
| static void nrf91_setstops(uintptr_t base, |
| const struct uart_config_s *config) |
| { |
| uint32_t regval = 0; |
| |
| regval = getreg32(base + NRF91_UART_CONFIG_OFFSET); |
| |
| if (config->stopbits2 == true) |
| { |
| regval |= UART_CONFIG_STOP; |
| } |
| else |
| { |
| regval &= ~UART_CONFIG_STOP; |
| } |
| |
| putreg32(regval, base + NRF91_UART_CONFIG_OFFSET); |
| } |
| #endif |
| |
| /**************************************************************************** |
| * Name: nrf91_sethwflow |
| ****************************************************************************/ |
| |
| static void nrf91_sethwflow(uintptr_t base, |
| const struct uart_config_s *config) |
| { |
| /* TODO */ |
| } |
| #endif |
| |
| /**************************************************************************** |
| * Public Functions |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Name: nrf91_lowsetup |
| * |
| * Description: |
| * Called at the very beginning of _start. Performs low level |
| * initialization including setup of the console UART. |
| * This UART initialization is done early so that the serial console is |
| * available for debugging very early in the boot sequence. |
| * |
| ****************************************************************************/ |
| |
| void nrf91_lowsetup(void) |
| { |
| #ifdef HAVE_UART_DEVICE |
| #ifdef HAVE_UART_CONSOLE |
| /* Configure the console UART (if any) */ |
| |
| nrf91_usart_configure(CONSOLE_BASE, &g_console_config); |
| |
| #endif /* HAVE_UART_CONSOLE */ |
| #endif /* HAVE_UART_DEVICE */ |
| } |
| |
| /**************************************************************************** |
| * Name: nrf91_usart_configure |
| * |
| * Description: |
| * Configure a UART for non-interrupt driven operation |
| * |
| ****************************************************************************/ |
| |
| #ifdef HAVE_UART_DEVICE |
| void nrf91_usart_configure(uintptr_t base, |
| const struct uart_config_s *config) |
| { |
| uint32_t pin = 0; |
| uint32_t port = 0; |
| uint32_t regval = 0; |
| |
| putreg32(1, base + NRF91_UART_TASKS_STOPRX_OFFSET); |
| putreg32(1, base + NRF91_UART_TASKS_STOPTX_OFFSET); |
| putreg32(NRF91_UART_ENABLE_DISABLE, base + NRF91_UART_ENABLE_OFFSET); |
| |
| /* Set UART format */ |
| |
| nrf91_usart_setformat(base, config); |
| |
| /* Config GPIO pins for uart */ |
| |
| nrf91_gpio_config(config->txpin); |
| nrf91_gpio_config(config->rxpin); |
| |
| /* Setect TX pins for UART */ |
| |
| pin = GPIO_PIN_DECODE(config->txpin); |
| port = GPIO_PORT_DECODE(config->txpin); |
| |
| regval = (pin << UART_PSELTXD_PIN_SHIFT); |
| regval |= (port << UART_PSELTXD_PORT_SHIFT); |
| putreg32(regval, base + NRF91_UART_PSELTXD_OFFSET); |
| |
| /* Setect RX pins for UART */ |
| |
| pin = GPIO_PIN_DECODE(config->rxpin); |
| port = GPIO_PORT_DECODE(config->rxpin); |
| |
| regval = (pin << UART_PSELRXD_PIN_SHIFT); |
| regval |= (port << UART_PSELRXD_PORT_SHIFT); |
| putreg32(regval, base + NRF91_UART_PSELRXD_OFFSET); |
| |
| /* Enable UART */ |
| |
| putreg32(NRF91_UART_ENABLE_ENABLE, base + NRF91_UART_ENABLE_OFFSET); |
| } |
| |
| /**************************************************************************** |
| * Name: nrf91_usart_disable |
| * |
| * Description: |
| * Disable a UART. it will be necessary to again call |
| * nrf91_usart_configure() in order to use this UART channel again. |
| * |
| ****************************************************************************/ |
| |
| void nrf91_usart_disable(uintptr_t base, const struct uart_config_s *config) |
| { |
| /* Disable interrupts */ |
| |
| /* Disable the UART */ |
| |
| putreg32(1, base + NRF91_UART_TASKS_STOPRX_OFFSET); |
| putreg32(1, base + NRF91_UART_TASKS_STOPTX_OFFSET); |
| putreg32(NRF91_UART_ENABLE_DISABLE, base + NRF91_UART_ENABLE_OFFSET); |
| |
| putreg32(0xffffffff, base + NRF91_UART_PSELTXD_OFFSET); |
| putreg32(0xffffffff, base + NRF91_UART_PSELRXD_OFFSET); |
| |
| /* Unconfigure GPIO */ |
| |
| nrf91_gpio_unconfig(config->rxpin); |
| nrf91_gpio_unconfig(config->txpin); |
| |
| /* Deatach TWI from GPIO */ |
| |
| putreg32(UART_PSELTXD_RESET, base + NRF91_UART_PSELTXD_OFFSET); |
| putreg32(UART_PSELRXD_RESET, base + NRF91_UART_PSELRXD_OFFSET); |
| } |
| |
| /**************************************************************************** |
| * Name: nrf91_usart_setformat |
| * |
| * Description: |
| * Set the USART line format and speed. |
| * |
| ****************************************************************************/ |
| |
| void nrf91_usart_setformat(uintptr_t base, |
| const struct uart_config_s *config) |
| { |
| /* Configure baud */ |
| |
| nrf91_setbaud(base, config); |
| |
| /* Configure polarity */ |
| |
| nrf91_setparity(base, config); |
| |
| #ifdef HAVE_UART_STOPBITS |
| /* Configure STOP bits */ |
| |
| nrf91_setstops(base, config); |
| #endif |
| |
| /* Configure hardware flow control */ |
| |
| nrf91_sethwflow(base, config); |
| } |
| #endif |
| |
| /**************************************************************************** |
| * Name: arm_lowputc |
| * |
| * Description: |
| * Output one byte on the serial console |
| * |
| ****************************************************************************/ |
| |
| void arm_lowputc(char ch) |
| { |
| #ifdef HAVE_UART_CONSOLE |
| putreg32(1, CONSOLE_BASE + NRF91_UART_TASKS_STARTTX_OFFSET); |
| putreg32(0, CONSOLE_BASE + NRF91_UART_EVENTS_TXDRDY_OFFSET); |
| putreg32(ch, CONSOLE_BASE + NRF91_UART_TXD_OFFSET); |
| while (getreg32(CONSOLE_BASE + NRF91_UART_EVENTS_TXDRDY_OFFSET) == 0) |
| { |
| } |
| |
| putreg32(1, CONSOLE_BASE + NRF91_UART_TASKS_STOPTX_OFFSET); |
| #endif |
| } |