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

Configurable UART #57

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
1 change: 0 additions & 1 deletion sw/c/common/demo_system.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,3 @@ void simple_exc_handler(void) {

while(1);
}

2 changes: 1 addition & 1 deletion sw/c/common/demo_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,4 @@ uint32_t get_mcycle(void);
void reset_mcycle(void);


#endif
#endif
76 changes: 76 additions & 0 deletions sw/c/common/link.ld
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you copying this from sw/common/?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a copy bug, I had a version without the c/rust update and it resulted to this when I copied the folder.

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* Copyright lowRISC contributors.
Licensed under the Apache License, Version 2.0, see LICENSE for details.
SPDX-License-Identifier: Apache-2.0 */

OUTPUT_ARCH(riscv)

MEMORY
{
/* 60 KiB should be enough for anybody... */
ram : ORIGIN = 0x00100000, LENGTH = 0xE000 /* 56 KiB */
stack : ORIGIN = 0x0010E000, LENGTH = 0x2000 /* 4 KiB */
}

/* Stack information variables */
_min_stack = 0x1000; /* 4K - minimum stack space to reserve */
_stack_len = LENGTH(stack);
_stack_start = ORIGIN(stack) + LENGTH(stack);

_entry_point = _vectors_start + 0x80;
ENTRY(_entry_point)

SECTIONS
{
.text : {
. = ALIGN(4);
_vectors_start = .;
KEEP(*(.vectors))
_vectors_end = .;
*(.text)
*(.text.*)
. = ALIGN(4);
} > ram

.rodata : {
. = ALIGN(4);
/* Small RO data before large RO data */
*(.srodata)
*(.srodata.*)
*(.rodata);
*(.rodata.*)
. = ALIGN(4);
} > ram

.data : {
. = ALIGN(4);
/* Small data before large data */
*(.sdata)
*(.sdata.*)
*(.data);
*(.data.*)
. = ALIGN(4);
} > ram

.bss :
{
. = ALIGN(4);
_bss_start = .;
/* Small BSS before large BSS */
*(.sbss)
*(.sbss.*)
*(.bss)
*(.bss.*)
*(COMMON)
_bss_end = .;
. = ALIGN(4);
} > ram

/* ensure there is enough room for stack */
.stack (NOLOAD): {
. = ALIGN(4);
. = . + _min_stack ;
. = ALIGN(4);
stack = . ;
_stack = . ;
} > stack
}
19 changes: 15 additions & 4 deletions sw/c/common/uart.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "uart.h"
#include "dev_access.h"
#include "demo_system.h"
Expand All @@ -26,3 +22,18 @@ void uart_out(uart_t uart, char c) {

DEV_WRITE(uart + UART_TX_REG, c);
}

void uart_enable(uart_t uart, char en) {

DEV_WRITE(uart + UART_ENABLE_REG, en);
}

void uart_disable(uart_t uart) {

DEV_WRITE(uart + UART_ENABLE_REG, 0x00);
}

void uart_setup(uart_t uart, char parameters) {

DEV_WRITE(uart + UART_PARAMETERS_REG, parameters);
}
39 changes: 31 additions & 8 deletions sw/c/common/uart.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#ifndef UART_H__
#define UART_H__

#define UART_RX_REG 0
#define UART_TX_REG 4
#define UART_STATUS_REG 8
#include <stdint.h>

#define UART_RX_REG 0x00
#define UART_TX_REG 0x04
#define UART_STATUS_REG 0x08
#define UART_ENABLE_REG 0x0C
#define UART_PARAMETERS_REG 0x10

#define UART_STATUS_RX_EMPTY 1
#define UART_STATUS_TX_FULL 2
Expand All @@ -18,9 +18,32 @@ typedef void* uart_t;

#define UART_FROM_BASE_ADDR(addr)((uart_t)(addr))

#define DATA_SIZE_6 0x00
#define DATA_SIZE_7 0x01
#define DATA_SIZE_8 0x02
#define DATA_SIZE_9 0x03

#define PARITY_NONE 0x00
#define PARITY_EVEN 0x04
#define PARITY_ODD 0x0C

#define STOP_BITS_ONE 0x00
#define STOP_BITS_TWO 0x10

#define BAUD_RATE_4800 0x00
#define BAUD_RATE_9600 0x20
#define BAUD_RATE_57600 0x40
#define BAUD_RATE_115200 0x60

#define UART_RX_EN 0x01
#define UART_TX_EN 0x02

void uart_enable_rx_int(void);
int uart_in(uart_t uart);
void uart_out(uart_t uart, char c);

#endif // UART_H__
void uart_enable(uart_t uart, char en);
void uart_disable(uart_t uart);
void uart_setup(uart_t uart, char parameters);

#endif
50 changes: 17 additions & 33 deletions sw/c/demo/hello_world/main.c
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "uart.h"
#include "demo_system.h"
#include "timer.h"
#include "gpio.h"
#include "pwm.h"
#include <stdbool.h>
#include <stdint.h>

#define USE_GPIO_SHIFT_REG 0

void test_uart_irq_handler(void) __attribute__((interrupt));

void test_uart_irq_handler(void) {
int uart_in_char;

while ((uart_in_char = uart_in(DEFAULT_UART)) != -1) {
uart_out(DEFAULT_UART, uart_in_char);
uart_out(DEFAULT_UART, '\r');
uart_out(DEFAULT_UART, '\n');
}
unsigned char u;
u = getchar();
putchar(u);
}

int main(void) {
install_exception_handler(UART_IRQ_NUM, &test_uart_irq_handler);
uart_enable_rx_int();

uart_enable(DEFAULT_UART, UART_RX_EN | UART_TX_EN);
uart_setup(DEFAULT_UART, DATA_SIZE_8 | PARITY_NONE | STOP_BITS_ONE | BAUD_RATE_115200);

// This indicates how often the timer gets updated.
timer_init();
Expand All @@ -41,37 +41,21 @@ int main(void) {
bool ascending = true;
// The three least significant bits correspond to RGB, where B is the leas significant.
uint8_t color = 7;


const char str[] = " Hello World ";
uint32_t c = 0;
while(1) {
uint64_t cur_time = get_elapsed_time();

if (cur_time != last_elapsed_time) {
last_elapsed_time = cur_time;

// Disable interrupts whilst outputting to prevent output for RX IRQ
// happening in the middle

set_global_interrupt_enable(0);

// Print this to UART (use the screen command to see it).
puts("Hello World! ");
puthex(last_elapsed_time);
puts(" Input Value: ");
uint32_t in_val = read_gpio(GPIO_IN_DBNC);
puthex(in_val);
putchar('\n');

// Re-enable interrupts with output complete
puts(str);
puthex(c++);
puts("\r\n");
set_global_interrupt_enable(1);

// Cycling through green LEDs when BTN0 is pressed
if (USE_GPIO_SHIFT_REG) {
set_outputs(GPIO_OUT_SHIFT, in_val);
} else {
uint32_t out_val = read_gpio(GPIO_OUT);
out_val = ((out_val << 1) & GPIO_OUT_MASK) | (in_val & 0x1);
set_outputs(GPIO_OUT, out_val);
}


// Going from bright to dim on PWM
for(int i = 0; i < NUM_PWM_MODULES; i++) {
set_pwm(PWM_FROM_ADDR_AND_INDEX(PWM_BASE, i),
Expand All @@ -94,8 +78,8 @@ int main(void) {
}
}
}

}

asm volatile ("wfi");
}
}