aboutsummaryrefslogtreecommitdiff
path: root/src/io.c
blob: f259514c93e8125192fdd54bc1962bb525db2eb4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "io.h"

#include <stdint.h>
#include <stdio.h>

#include "ch573/gpio.h"
#include "ch573/uart.h"
#include "clock.h"

#ifndef DEBUG_UART
#define DEBUG_UART UART1
#endif

#define UART1 ch573_uart__uart1
#define UART CH573_UART__UART_T_INTF

#define GPIO_PORT_A ch573_gpio__gpio_port_a
#define GPIO_PORT CH573_GPIO__GPIO_PORT_T_INTF

#define gpio_usart1_tx_pin 9

static int uart1_FILE_put(char ch, FILE* unused)
{
  if (ch == '\n') {
    uart1_FILE_put('\r', unused);
  }

  while (!UART.lsr.thr_empty.get(UART1));
  UART.thr.set(UART1, ch);
  while (!UART.lsr.thr_empty.get(UART1));

  return 1;
}

int uart1_FILE_get(FILE* unused)
{
  while (!UART.rfc.get(UART1));
  return UART.rbr.get(UART1);
}

static int uart1_FILE_flush(FILE* f)
{
  return 0;
}

FILE _uart1_FILE = (FILE){
    .put = uart1_FILE_put,
    .get = uart1_FILE_get,
    .flush = uart1_FILE_flush,
    .flags = __SWR | __SRD,
};

FILE* const stdout = &_uart1_FILE;
FILE* const stdin = &_uart1_FILE;

static int uart1_init_for_stdout = 0;

void init_uart1_for_stdout(void)
{
  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);
  UART.fcr.fifo_en.set(UART1, 1);

  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);


  volatile uint32_t dl = (10 * 6400000 / 8 / BAUD_RATE + 5) / 10;
  UART.dl.set(UART1, dl);
  uart1_init_for_stdout = 1;
}

/* When the system clock changes, we need to update the UART baud rate. */
on_system_clock_changed(uart_clock_change)(const clock_cfg_t* cfg)
{
  if (uart1_init_for_stdout) {
    clock_cfg_t c;

    if (get_system_clock(&c)) {
      return;
    }

    uint32_t freq = get_clock_freq(&c);

    uint32_t dl = (10 * freq / 8 / BAUD_RATE + 5) / 10;
    UART.dl.set(UART1, dl);
  }
}