aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2024-11-15 02:48:27 -0700
committerJosh Rahm <joshuarahm@gmail.com>2024-11-15 02:48:27 -0700
commitede9bee7f22fd5d0e1bacb7689f1cac23992b70b (patch)
tree904d8d80063aa415b9e407f6ec73aa874483ebcd
parent63054d2fdf9a0ae3e9dcdd0d20eb8714671a010b (diff)
downloadch573-ede9bee7f22fd5d0e1bacb7689f1cac23992b70b.tar.gz
ch573-ede9bee7f22fd5d0e1bacb7689f1cac23992b70b.tar.bz2
ch573-ede9bee7f22fd5d0e1bacb7689f1cac23992b70b.zip
UART is working.
-rw-r--r--fdl/ch573/gpio.fdl10
-rw-r--r--fdl/ch573/pwr.fdl28
-rw-r--r--fdl/ch573/uart.fdl11
-rw-r--r--include/isr_vector.h2
-rw-r--r--linker/ls.ld2
-rw-r--r--src/init.c12
-rw-r--r--src/isr.s5
-rw-r--r--src/main.c (renamed from src/blinky.c)59
8 files changed, 101 insertions, 28 deletions
diff --git a/fdl/ch573/gpio.fdl b/fdl/ch573/gpio.fdl
index c54d956..bab481a 100644
--- a/fdl/ch573/gpio.fdl
+++ b/fdl/ch573/gpio.fdl
@@ -34,7 +34,10 @@ package ch573.gpio {
};
/** Pin input register. */
- reg pin(32);
+ reg pin(32) : struct {
+ in : bit_t[16];
+ reserved(16);
+ };
/** Pin output register. */
reg (32) : struct {
@@ -46,7 +49,10 @@ package ch573.gpio {
reg clr(32);
/** Pull-up resistor configuration. */
- reg pu(32);
+ reg (32) : struct {
+ pu : enable_t[16];
+ reserved(16);
+ };
/** pull-down/drive configuration register. */
reg (32) : struct {
diff --git a/fdl/ch573/pwr.fdl b/fdl/ch573/pwr.fdl
new file mode 100644
index 0000000..65f2dbb
--- /dev/null
+++ b/fdl/ch573/pwr.fdl
@@ -0,0 +1,28 @@
+import "ch573/common.fdl";
+
+/** Package for the system power control registers. */
+package ch573.pwr {
+ location pwr_base = 0x4000100C;
+
+ bits clock_source_status_t : enum(1) {
+ [[ c: unqualified ]]
+ CLK_SOURCE_ENABLED = 0,
+ [[ c: unqualified ]]
+ CLK_SOURCE_DISABLED = 1,
+ };
+
+ type pwr_mgmt_t : struct {
+ reg slp_clk_off_0(8) : struct {
+ tmr0 : clock_source_status_t;
+ tmr1 : clock_source_status_t;
+ tmr2 : clock_source_status_t;
+ tmr3 : clock_source_status_t;
+ uart0 : clock_source_status_t;
+ uart1 : clock_source_status_t;
+ uart2 : clock_source_status_t;
+ uart3 : clock_source_status_t;
+ };
+ };
+
+ instance pwr_mgmt at pwr_base : pwr_mgmt_t;
+};
diff --git a/fdl/ch573/uart.fdl b/fdl/ch573/uart.fdl
index bc2df2d..9a4f0c5 100644
--- a/fdl/ch573/uart.fdl
+++ b/fdl/ch573/uart.fdl
@@ -70,7 +70,16 @@ package ch573.uart {
/** Line Control Register */
reg lcr(8) : struct {
/** UART word size (5-8 bits) */
- word_sz : (2);
+ word_sz : enum(2) {
+ [[ c: unqualified ]]
+ WORD_SZ_5_BITS = 0b00,
+ [[ c: unqualified ]]
+ WORD_SZ_6_BITS = 0b01,
+ [[ c: unqualified ]]
+ WORD_SZ_7_BITS = 0b10,
+ [[ c: unqualified ]]
+ WORD_SZ_8_BITS = 0b11,
+ };
/** Stop bit setting */
stop_bit : bit_t;
/** Parity bit enable */
diff --git a/include/isr_vector.h b/include/isr_vector.h
index 65359a5..6059875 100644
--- a/include/isr_vector.h
+++ b/include/isr_vector.h
@@ -46,7 +46,7 @@ void irq_on_wdog_bat(void);
* long jump). This stub is compiled and linked promimal to the ISR vector. \
*/ \
void __attribute__((interrupt)) \
- __attribute__((__section__(".isr_vector"))) irq_on_##name(void) \
+ __attribute__((__section__(".isr_vector.routines"))) irq_on_##name(void) \
{ \
_real__irq_on_##name(); \
} \
diff --git a/linker/ls.ld b/linker/ls.ld
index 18ee181..916438b 100644
--- a/linker/ls.ld
+++ b/linker/ls.ld
@@ -10,6 +10,7 @@ SECTIONS
.text : ALIGN(0x04) {
*(.sinit);
+ *(.sinit.1);
/* The ch573 starts execution at address 0x0000, so we have to make sure the
* on_reset function is put at the beginning of the flash. */
@@ -23,6 +24,7 @@ SECTIONS
.isr_vector : ALIGN(0x04) {
ISR_VECTOR_START = .;
*(.isr_vector);
+ *(.isr_vector.routines);
ISR_VECTOR_STOP = .;
} >sram AT>flash
diff --git a/src/init.c b/src/init.c
index 30e2c6d..5753a13 100644
--- a/src/init.c
+++ b/src/init.c
@@ -5,7 +5,7 @@
void on_reset(void);
-void __attribute__((weak, interrupt, __section__(".isr_vector")))
+void __attribute__((weak, interrupt, __section__(".isr_vector.routines")))
default_irq_handler(void)
{
return;
@@ -13,7 +13,7 @@ default_irq_handler(void)
#define WEAK_IRQ(irq) \
void __attribute__(( \
- weak, alias("default_irq_handler"), __section__(".isr_vector"))) \
+ weak, alias("default_irq_handler"), __section__(".isr_vector.routines"))) \
irq(void)
WEAK_IRQ(irq_on_reset);
@@ -60,7 +60,9 @@ extern uint32_t BSS_STOP;
static inline void set_mtvec(void* vector_table)
{
- asm volatile("csrw mtvec, %0" : : "r"(vector_table));
+ uint32_t mtvec = (uint32_t) vector_table;
+ mtvec |= 1; // Set interrupt table mode to "VECTORED"
+ asm volatile("csrw mtvec, %0" : : "r"(mtvec));
}
/*
@@ -99,7 +101,7 @@ extern void main(void);
/* Start function. Responsible for initializing the system and jumping to the
* main function. */
-static void start(void)
+static __attribute((__section__(".sinit.1"))) void start(void)
{
/* Initialize the data segments. */
init_data_segments();
@@ -113,7 +115,7 @@ static void start(void)
* The reset callback.This has to be a naked function because the stack pointer
* may not be initialized!!.
*/
-__attribute((naked, __section__(".isr_routines.on_reset"))) void on_reset(void)
+__attribute((naked, __section__(".sinit"))) void _begin(void)
{
// Set up the stack pointer to point to the end of SRAM.
asm volatile(
diff --git a/src/isr.s b/src/isr.s
index 065450d..04d66d1 100644
--- a/src/isr.s
+++ b/src/isr.s
@@ -1,8 +1,3 @@
-
-.section .sinit
-_start:
-j on_reset /* first instruction. Should jump directly to on_reset */
-
.section .isr_vector
.global isr_vector
isr_vector:
diff --git a/src/blinky.c b/src/main.c
index 355b479..3066123 100644
--- a/src/blinky.c
+++ b/src/main.c
@@ -1,11 +1,20 @@
#include <stdint.h>
-#include "isr_vector.h"
#include "ch573/gpio.h"
+#include "ch573/uart.h"
+#include "ch573/pwr.h"
+
+#include "isr_vector.h"
#define GPIO_PORT_A ch573_gpio__gpio_port_a
#define GPIO_PORT CH573_GPIO__GPIO_PORT_T_INTF
+#define UART1 ch573_uart__uart1
+#define UART CH573_UART__UART_T_INTF
+
+#define PWR1 ch573_pwr__pwr_mgmt
+#define PWR CH573_PWR__PWR_MGMT_T_INTF
+
/*
* Function which delays for a bit.
*/
@@ -57,29 +66,51 @@ extern uint32_t DATA_VALUES_IN_FLASH;
extern uint32_t DATA_SEGMENT_START;
extern uint32_t DATA_SEGMENT_STOP;
+#define gpio_usart1_tx_pin 9
+#define gpio_usart1_rx_pin 8
+
+const char* hello_world = "Hello, World!\r\n";
+
+#define BAUD_RATE 115200
+
/* Main routine. This is called on_reset once everything else has been set up.
*/
void main(void)
{
- GPIO_PORT.dir.set(GPIO_PORT_A, DIR_OUT, 8);
- GPIO_PORT.pd_drv.set(GPIO_PORT_A, PD_DRV_OPEN_DRAIN, 8);
+ GPIO_PORT.dir.set(GPIO_PORT_A, DIR_OUT, gpio_usart1_tx_pin);
+ GPIO_PORT.pd_drv.set(GPIO_PORT_A, 0, gpio_usart1_tx_pin);
+
+ UART.div.set(UART1, 1);
+ UART.fcr.set(UART1, 0x07);
+ UART.ier.txd_en.set(UART1, ON);
+ UART.lcr.word_sz.set(UART1, WORD_SZ_8_BITS);
+
+ uint32_t dl = (10 * 6400000 / 8 / BAUD_RATE + 5) / 10;
+ UART.dl.set(UART1, dl);
+
+ // PWR.slp_clk_off_0.uart1.set(PWR1, CLK_SOURCE_ENABLED);
+
+ const char* ptr = hello_world;
- for (;;) {
- if (deadbeef == 0xdeadbeef) {
- GPIO_PORT.out.set(GPIO_PORT_A, ON, 8);
+ while (1) {
+ if (*ptr == 0) {
+ ptr = hello_world;
}
- delay();
- delay();
- delay();
- GPIO_PORT.out.set(GPIO_PORT_A, OFF, 8);
- delay();
+
+ while (!UART.lsr.thr_empty.get(UART1));
+ UART.thr.set(UART1, *(ptr++));
}
}
-IRQ(systick) {
+IRQ(systick)
+{
collatz(5);
}
-IRQ(exc) {}
+IRQ(exc)
+{
+}
-IRQ(nmi) {}
+IRQ(nmi)
+{
+}