/*
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "hardware/address_mapped.h"
#include "hardware/platform_defs.h"
#include "hardware/uart.h"

#include "hardware/structs/uart.h"
#include "hardware/resets.h"
#include "hardware/clocks.h"
#include "hardware/timer.h"

#include "pico/assert.h"
#include "pico.h"

check_hw_layout(uart_hw_t, fr, UART_UARTFR_OFFSET);
check_hw_layout(uart_hw_t, dmacr, UART_UARTDMACR_OFFSET);

#if PICO_UART_ENABLE_CRLF_SUPPORT
short uart_char_to_line_feed[NUM_UARTS];
#endif

/// \tag::uart_reset[]
static inline void uart_reset(uart_inst_t *uart) {
    invalid_params_if(UART, uart != uart0 && uart != uart1);
    reset_block(uart_get_index(uart) ? RESETS_RESET_UART1_BITS : RESETS_RESET_UART0_BITS);
}

static inline void uart_unreset(uart_inst_t *uart) {
    invalid_params_if(UART, uart != uart0 && uart != uart1);
    unreset_block_wait(uart_get_index(uart) ? RESETS_RESET_UART1_BITS : RESETS_RESET_UART0_BITS);
}
/// \end::uart_reset[]

/// \tag::uart_init[]
uint uart_init(uart_inst_t *uart, uint baudrate) {
    invalid_params_if(UART, uart != uart0 && uart != uart1);

    if (clock_get_hz(clk_peri) == 0)
        return 0;

    uart_reset(uart);
    uart_unreset(uart);

#if PICO_UART_ENABLE_CRLF_SUPPORT
    uart_set_translate_crlf(uart, PICO_UART_DEFAULT_CRLF);
#endif

    // Any LCR writes need to take place before enabling the UART
    uint baud = uart_set_baudrate(uart, baudrate);
    uart_set_format(uart, 8, 1, UART_PARITY_NONE);

    // Enable the UART, both TX and RX
    uart_get_hw(uart)->cr = UART_UARTCR_UARTEN_BITS | UART_UARTCR_TXE_BITS | UART_UARTCR_RXE_BITS;
    // Enable FIFOs
    hw_set_bits(&uart_get_hw(uart)->lcr_h, UART_UARTLCR_H_FEN_BITS);
    // Always enable DREQ signals -- no harm in this if DMA is not listening
    uart_get_hw(uart)->dmacr = UART_UARTDMACR_TXDMAE_BITS | UART_UARTDMACR_RXDMAE_BITS;

    return baud;
}
/// \end::uart_init[]

void uart_deinit(uart_inst_t *uart) {
    invalid_params_if(UART, uart != uart0 && uart != uart1);
    uart_reset(uart);
}

/// \tag::uart_set_baudrate[]
uint uart_set_baudrate(uart_inst_t *uart, uint baudrate) {
    invalid_params_if(UART, baudrate == 0);
    uint32_t baud_rate_div = (8 * clock_get_hz(clk_peri) / baudrate);
    uint32_t baud_ibrd = baud_rate_div >> 7;
    uint32_t baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2;
    invalid_params_if(UART, (baud_ibrd > 65535) || (baud_ibrd == 0));

    // Load PL011's baud divisor registers
    uart_get_hw(uart)->ibrd = baud_ibrd;
    if (baud_ibrd == 65535) {
        uart_get_hw(uart)->fbrd = 0;
    } else {
        uart_get_hw(uart)->fbrd = baud_fbrd;
    }

    // PL011 needs a (dummy) line control register write to latch in the
    // divisors. We don't want to actually change LCR contents here.
    hw_set_bits(&uart_get_hw(uart)->lcr_h, 0);

    // See datasheet
    uint baud = (4 * clock_get_hz(clk_peri)) / (64 * baud_ibrd + baud_fbrd);
    return baud;
}
/// \end::uart_set_baudrate[]

void uart_set_translate_crlf(uart_inst_t *uart, bool crlf) {
#if PICO_UART_ENABLE_CRLF_SUPPORT
    uart_char_to_line_feed[uart_get_index(uart)] = crlf ? '\n' : 0x100;
#else
    panic_unsupported();
#endif
}

bool uart_is_readable_within_us(uart_inst_t *uart, uint32_t us) {
    uint32_t t = time_us_32();
    do {
        if (uart_is_readable(uart)) return true;
    } while ((time_us_32() - t) <= us);
    return false;
}
