Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

valentyusb serial #347

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ ECP_FLASH_OFFSET=0x80000
toplevel=fpga/top-orangecrab0.2.vhdl
litedram_target=orangecrab-85-0.2
soc_extra_v += litesdcard/generated/lattice/litesdcard_core.v
soc_extra_v += valentyusb/generated/orangecrab-85-0.2/gateware/valentyusb.v
dmi_dtm=dmi_dtm_ecp5.vhdl
endif

Expand All @@ -211,7 +212,6 @@ ifneq ($(litedram_target),)
soc_extra_synth += litedram/extras/litedram-wrapper-l2.vhdl \
litedram/generated/$(litedram_target)/litedram-initmem.vhdl
soc_extra_v += litedram/generated/$(litedram_target)/litedram_core.v
LITEDRAM_GHDL_ARG=-gUSE_LITEDRAM=true
endif

GHDL_IMAGE_GENERICS=-gMEMORY_SIZE=$(MEMORY_SIZE) -gRAM_INIT_FILE=$(RAM_INIT_FILE) \
Expand All @@ -232,7 +232,7 @@ fpga_files = fpga/soc_reset.vhdl \

synth_files = $(core_files) $(soc_files) $(soc_extra_synth) $(fpga_files) $(clkgen) $(toplevel) $(dmi_dtm)

microwatt.json: $(synth_files) $(RAM_INIT_FILE)
microwatt.json: $(synth_files) $(RAM_INIT_FILE) $(soc_extra_v)
$(YOSYS) $(GHDLSYNTH) -p "ghdl --std=08 --no-formal $(GHDL_IMAGE_GENERICS) $(synth_files) -e toplevel; read_verilog $(uart_files) $(soc_extra_v); synth_ecp5 -abc9 -nowidelut -json $@ $(SYNTH_ECP5_FLAGS)"

microwatt.v: $(synth_files) $(RAM_INIT_FILE)
Expand Down
12 changes: 12 additions & 0 deletions fpga/top-orangecrab0.2.vhdl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ entity toplevel is
LOG_LENGTH : natural := 0;
UART_IS_16550 : boolean := true;
HAS_UART1 : boolean := false;
HAS_UARTUSB : boolean := true;
USE_LITESDCARD : boolean := true;
ICACHE_NUM_LINES : natural := 64;
NGPIO : natural := 0
Expand All @@ -35,6 +36,11 @@ entity toplevel is
pin_gpio_0 : out std_ulogic;
pin_gpio_1 : in std_ulogic;

-- USB signals:
usb_d_p : in std_ulogic;
usb_d_n : in std_ulogic;
usb_pullup : out std_ulogic;

-- LEDs
led0_b : out std_ulogic;
led0_g : out std_ulogic;
Expand Down Expand Up @@ -186,6 +192,7 @@ begin
LOG_LENGTH => LOG_LENGTH,
UART0_IS_16550 => UART_IS_16550,
HAS_UART1 => HAS_UART1,
HAS_UARTUSB => HAS_UARTUSB,
HAS_SD_CARD => USE_LITESDCARD,
ICACHE_NUM_LINES => ICACHE_NUM_LINES,
HAS_SHORT_MULT => true,
Expand All @@ -194,12 +201,17 @@ begin
port map (
-- System signals
system_clk => system_clk,
clk_48 => ext_clk,
rst => soc_rst,

-- UART signals
uart0_txd => pin_gpio_0,
uart0_rxd => pin_gpio_1,

usb_d_p => usb_d_p,
usb_d_n => usb_d_n,
usb_pullup => usb_pullup,

-- UART1 signals
--uart1_txd => uart_pmod_tx,
--uart1_rxd => uart_pmod_rx,
Expand Down
7 changes: 7 additions & 0 deletions include/liteuart_console.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

int usb_getchar(void);
bool usb_havechar(void);
int usb_putchar(int c);
int usb_puts(const char *str);
void usb_console_init(void);
7 changes: 6 additions & 1 deletion include/microwatt_soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
#define BRAM_BASE 0x80000000 /* Internal BRAM */

#define SYSCON_BASE 0xc0000000 /* System control regs */
#define UART_BASE 0xc0002000 /* UART */
#define UART0_BASE 0xc0002000 /* UART */
#define UART_BASE UART0_BASE
#define UART1_BASE 0xc0003000 /* UART */
#define XICS_ICP_BASE 0xc0004000 /* Interrupt controller */
#define XICS_ICS_BASE 0xc0005000 /* Interrupt controller */
#define SPI_FCTRL_BASE 0xc0006000 /* SPI flash controller registers */
#define UARTUSB_BASE 0xc0008000 /* ValentyUSB UART */
#define DRAM_CTRL_BASE 0xc8000000 /* LiteDRAM control registers */
#define LETH_CSR_BASE 0xc8020000 /* LiteEth CSR registers */
#define LETH_SRAM_BASE 0xc8030000 /* LiteEth MMIO space */
Expand All @@ -26,6 +29,7 @@
*/
#define IRQ_UART0 0
#define IRQ_ETHERNET 1
#define IRQ_UARTUSB 5

/*
* Register definitions for the syscon registers
Expand All @@ -42,6 +46,7 @@
#define SYS_REG_INFO_HAS_UART1 (1ull << 6)
#define SYS_REG_INFO_HAS_ARTB (1ull << 7)
#define SYS_REG_INFO_HAS_LITESDCARD (1ull << 8)
#define SYS_REG_INFO_HAS_UARTUSB (1ull << 9)
#define SYS_REG_BRAMINFO 0x10
#define SYS_REG_BRAMINFO_SIZE_MASK 0xfffffffffffffull
#define SYS_REG_DRAMINFO 0x18
Expand Down
239 changes: 239 additions & 0 deletions lib/liteuart_console.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
#include <stdint.h>
#include <stdbool.h>

#include "console.h"
#include "liteuart_console.h"
#include "microwatt_soc.h"
#include "io.h"

#define UART_BAUDS 115200

static uint64_t uart_base;

/* From Linux liteuart.c */
#define OFF_RXTX 0x00
#define OFF_TXFULL 0x04
#define OFF_RXEMPTY 0x08
#define OFF_EV_STATUS 0x0c
#define OFF_EV_PENDING 0x10
#define OFF_EV_ENABLE 0x14

/* From litex uart.h */
#define UART_EV_TX 0x1
#define UART_EV_RX 0x2

/* Modified version of csr.h */
/* uart */
static inline uint32_t uart_rxtx_read(void) {
return readl(uart_base + OFF_RXTX);
}

static inline void uart_rxtx_write(uint32_t v) {
writel(v, uart_base + OFF_RXTX);
}

static inline uint32_t uart_txfull_read(void) {
return readl(uart_base + OFF_TXFULL);
}

static inline uint32_t uart_rxempty_read(void) {
return readl(uart_base + OFF_RXEMPTY);
}

static inline uint32_t uart_ev_status_read(void) {
return readl(uart_base + OFF_EV_STATUS);
}

// static inline uint32_t uart_ev_status_tx_extract(uint32_t oldword) {
// uint32_t mask = ((1 << 1)-1);
// return ( (oldword >> 0) & mask );
// }
// static inline uint32_t uart_ev_status_tx_read(void) {
// uint32_t word = uart_ev_status_read();
// return uart_ev_status_tx_extract(word);
// }

// static inline uint32_t uart_ev_status_rx_extract(uint32_t oldword) {
// uint32_t mask = ((1 << 1)-1);
// return ( (oldword >> 1) & mask );
// }
// static inline uint32_t uart_ev_status_rx_read(void) {
// uint32_t word = uart_ev_status_read();
// return uart_ev_status_rx_extract(word);
// }

static inline uint32_t uart_ev_pending_read(void) {
return readl(uart_base + OFF_EV_PENDING);
}
static inline void uart_ev_pending_write(uint32_t v) {
writel(v, uart_base + OFF_EV_PENDING);
}

// static inline uint32_t uart_ev_pending_tx_extract(uint32_t oldword) {
// uint32_t mask = ((1 << 1)-1);
// return ( (oldword >> 0) & mask );
// }
// static inline uint32_t uart_ev_pending_tx_read(void) {
// uint32_t word = uart_ev_pending_read();
// return uart_ev_pending_tx_extract(word);
// }
// static inline uint32_t uart_ev_pending_tx_replace(uint32_t oldword, uint32_t plain_value) {
// uint32_t mask = ((1 << 1)-1);
// return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
// }
// static inline void uart_ev_pending_tx_write(uint32_t plain_value) {
// uint32_t oldword = uart_ev_pending_read();
// uint32_t newword = uart_ev_pending_tx_replace(oldword, plain_value);
// uart_ev_pending_write(newword);
// }
// #define CSR_UART_EV_PENDING_RX_OFFSET 1
// #define CSR_UART_EV_PENDING_RX_SIZE 1
// static inline uint32_t uart_ev_pending_rx_extract(uint32_t oldword) {
// uint32_t mask = ((1 << 1)-1);
// return ( (oldword >> 1) & mask );
// }
// static inline uint32_t uart_ev_pending_rx_read(void) {
// uint32_t word = uart_ev_pending_read();
// return uart_ev_pending_rx_extract(word);
// }
// static inline uint32_t uart_ev_pending_rx_replace(uint32_t oldword, uint32_t plain_value) {
// uint32_t mask = ((1 << 1)-1);
// return (oldword & (~(mask << 1))) | (mask & plain_value)<< 1 ;
// }
// static inline void uart_ev_pending_rx_write(uint32_t plain_value) {
// uint32_t oldword = uart_ev_pending_read();
// uint32_t newword = uart_ev_pending_rx_replace(oldword, plain_value);
// uart_ev_pending_write(newword);
// }
// #define CSR_UART_EV_ENABLE_ADDR (CSR_BASE + 0x814L)
// #define CSR_UART_EV_ENABLE_SIZE 1
// static inline uint32_t uart_ev_enable_read(void) {
// return csr_read_simple(CSR_BASE + 0x814L);
// }
static inline void uart_ev_enable_write(uint32_t v) {
writel(v, uart_base + OFF_EV_ENABLE);
}
// #define CSR_UART_EV_ENABLE_TX_OFFSET 0
// #define CSR_UART_EV_ENABLE_TX_SIZE 1
// static inline uint32_t uart_ev_enable_tx_extract(uint32_t oldword) {
// uint32_t mask = ((1 << 1)-1);
// return ( (oldword >> 0) & mask );
// }
// static inline uint32_t uart_ev_enable_tx_read(void) {
// uint32_t word = uart_ev_enable_read();
// return uart_ev_enable_tx_extract(word);
// }
// static inline uint32_t uart_ev_enable_tx_replace(uint32_t oldword, uint32_t plain_value) {
// uint32_t mask = ((1 << 1)-1);
// return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
// }
// static inline void uart_ev_enable_tx_write(uint32_t plain_value) {
// uint32_t oldword = uart_ev_enable_read();
// uint32_t newword = uart_ev_enable_tx_replace(oldword, plain_value);
// uart_ev_enable_write(newword);
// }
// #define CSR_UART_EV_ENABLE_RX_OFFSET 1
// #define CSR_UART_EV_ENABLE_RX_SIZE 1
// static inline uint32_t uart_ev_enable_rx_extract(uint32_t oldword) {
// uint32_t mask = ((1 << 1)-1);
// return ( (oldword >> 1) & mask );
// }
// static inline uint32_t uart_ev_enable_rx_read(void) {
// uint32_t word = uart_ev_enable_read();
// return uart_ev_enable_rx_extract(word);
// }
// static inline uint32_t uart_ev_enable_rx_replace(uint32_t oldword, uint32_t plain_value) {
// uint32_t mask = ((1 << 1)-1);
// return (oldword & (~(mask << 1))) | (mask & plain_value)<< 1 ;
// }
// static inline void uart_ev_enable_rx_write(uint32_t plain_value) {
// uint32_t oldword = uart_ev_enable_read();
// uint32_t newword = uart_ev_enable_rx_replace(oldword, plain_value);
// uart_ev_enable_write(newword);
// }
// #define CSR_UART_TUNING_WORD_ADDR (CSR_BASE + 0x818L)
// #define CSR_UART_TUNING_WORD_SIZE 1
// static inline uint32_t uart_tuning_word_read(void) {
// return csr_read_simple(CSR_BASE + 0x818L);
// }
// static inline void uart_tuning_word_write(uint32_t v) {
// csr_write_simple(v, CSR_BASE + 0x818L);
// }
// #define CSR_UART_CONFIGURED_ADDR (CSR_BASE + 0x81cL)
// #define CSR_UART_CONFIGURED_SIZE 1
// static inline uint32_t uart_configured_read(void) {
// return csr_read_simple(CSR_BASE + 0x81cL);
// }
// static inline void uart_configured_write(uint32_t v) {
// csr_write_simple(v, CSR_BASE + 0x81cL);
// }

// end of csr code

static char uart_read(void)
{
char c;
while (uart_rxempty_read());
c = uart_rxtx_read();
uart_ev_pending_write(UART_EV_RX);
return c;
}

static int uart_read_nonblock(void)
{
return (uart_rxempty_read() == 0);
}

static void uart_write(char c)
{
while (uart_txfull_read());
uart_rxtx_write(c);
uart_ev_pending_write(UART_EV_TX);
}

static void uart_init(void)
{
uart_ev_pending_write(uart_ev_pending_read());
uart_ev_enable_write(UART_EV_TX | UART_EV_RX);
}

// static void uart_sync(void)
// {
// while (uart_txfull_read());
// }

int usb_getchar(void)
{
return uart_read();
}

bool usb_havechar(void)
{
return uart_read_nonblock();
}

int usb_putchar(int c)
{
uart_write(c);
return c;
}

int usb_puts(const char *str)
{
unsigned int i;

for (i = 0; *str; i++) {
char c = *(str++);
if (c == 10)
usb_putchar(13);
usb_putchar(c);
}
return 0;
}

void usb_console_init(void)
{
uart_base = UARTUSB_BASE;
uart_init();
}

Loading