11
#include <drivers/common/memory.h>
13
#include <drivers/amba_pnp.h>
15
#include <hal/system.h>
16
#include <kernel/irq.h>
18
#include <drivers/diag.h>
19
#include <drivers/serial/uart_dev.h>
20
#include <drivers/serial/diag_serial.h>
22
#include <embox/unit.h>
24
#include <kernel/printk.h>
27
OPTION_GET(NUMBER, baud_rate)
29
#define UART_SCALER_VAL \
30
(((SYS_CLOCK * 10) / (BAUD_RATE * 8) - 5) / 10)
33
#define UART_STAT_DR (1u << 0)
34
#define UART_STAT_TS (1u << 1)
35
#define UART_STAT_TE (1u << 2)
36
#define UART_STAT_BR (1u << 3)
37
#define UART_STAT_OV (1u << 4)
38
#define UART_STAT_PE (1u << 5)
39
#define UART_STAT_FE (1u << 6)
40
#define UART_STAT_TH (1u << 7)
41
#define UART_STAT_RH (1u << 8)
42
#define UART_STAT_TF (1u << 9)
43
#define UART_STAT_RF (1u << 10)
46
#define UART_CTRL_RE (1u << 0)
47
#define UART_CTRL_TE (1u << 1)
48
#define UART_CTRL_RI (1u << 2)
49
#define UART_CTRL_TI (1u << 3)
50
#define UART_CTRL_PS (1u << 4)
51
#define UART_CTRL_PE (1u << 5)
52
#define UART_CTRL_FL (1u << 6)
53
#define UART_CTRL_LB (1u << 7)
54
#define UART_CTRL_EC (1u << 8)
55
#define UART_CTRL_TF (1u << 9)
56
#define UART_CTRL_RF (1u << 10)
57
#define UART_CTRL_DB (1u << 11)
58
#define UART_CTRL_OE (1u << 12)
59
#define UART_CTRL_FA (1u << 31)
60
#define UART_DISABLE_ALL 0
85
static volatile struct apbuart_regs *dev_regs;
87
static int dev_regs_init(void);
89
EMBOX_UNIT_INIT(uart_init);
91
static int apbuart_setup(struct uart *dev, const struct uart_params *params) {
94
if (NULL == dev_regs && 0 != (res = dev_regs_init())) {
98
assert(NULL != dev_regs);
100
REG_STORE(&dev_regs->ctrl, UART_DISABLE_ALL);
101
REG_STORE(&dev_regs->scaler, UART_SCALER_VAL);
102
if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
103
REG_STORE(&dev_regs->ctrl, UART_CTRL_TE | UART_CTRL_RE | UART_CTRL_RI);
105
REG_STORE(&dev_regs->ctrl, UART_CTRL_TE | UART_CTRL_RE);
111
static int apbuart_irq_en(struct uart *dev, const struct uart_params *params) {
113
if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
114
REG_STORE(&dev_regs->ctrl, UART_CTRL_TE | UART_CTRL_RE | UART_CTRL_RI);
120
static int apbuart_irq_dis(struct uart *dev, const struct uart_params *params) {
121
if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
122
REG_STORE(&dev_regs->ctrl, UART_CTRL_TE | UART_CTRL_RE);
128
static int apbuart_putc(struct uart *dev, int ch) {
129
while (!(UART_STAT_TE & REG_LOAD(&dev_regs->status))) {
131
REG_STORE(&dev_regs->data, (uint32_t) ch);
136
static int apbuart_has_symbol(struct uart *dev) {
137
return (UART_STAT_DR & REG_LOAD(&dev_regs->status));
140
static int apbuart_getc(struct uart *dev) {
141
return REG_LOAD(&dev_regs->data);
146
static int dev_regs_init() {
148
if (-1 == capture_amba_dev(&amba_dev, AMBAPP_VENDOR_GAISLER,
149
AMBAPP_DEVICE_GAISLER_APBUART, false, false)) {
150
printk("can't capture apb dev venID=0x%X, devID=0x%X\n",
151
AMBAPP_VENDOR_GAISLER, AMBAPP_DEVICE_GAISLER_APBUART);
154
dev_regs = (volatile struct apbuart_regs *) amba_dev.bar[0].start;
157
#elif OPTION_DEFINED(NUMBER,apbuart_base)
159
PERIPH_MEMORY_DEFINE(apbuart, OPTION_GET(NUMBER,apbuart_base), sizeof(struct apbuart_regs));
161
static int dev_regs_init() {
162
dev_regs = (volatile struct apbuart_regs *) OPTION_GET(NUMBER,apbuart_base);
166
# error "Either DRIVER_AMBAPP or apbuart_base option must be defined"
169
static const struct uart_ops uart_ops = {
170
.uart_getc = apbuart_getc,
171
.uart_putc = apbuart_putc,
172
.uart_hasrx = apbuart_has_symbol,
173
.uart_setup = apbuart_setup,
174
.uart_irq_en = apbuart_irq_en,
175
.uart_irq_dis = apbuart_irq_dis,
178
static struct uart uart0 = {
179
.irq_num = OPTION_GET(NUMBER,irq_num),
180
.base_addr = OPTION_GET(NUMBER,apbuart_base),
181
.uart_ops = &uart_ops,
184
static const struct uart_params uart_defparams = {
185
.baud_rate = OPTION_GET(NUMBER,baud_rate),
186
.uart_param_flags = UART_PARAM_FLAGS_8BIT_WORD | UART_PARAM_FLAGS_USE_IRQ,
189
static const struct uart_params uart_diag_params = {
190
.baud_rate = OPTION_GET(NUMBER,baud_rate),
191
.uart_param_flags = UART_PARAM_FLAGS_8BIT_WORD,
194
DIAG_SERIAL_DEF(&uart0, &uart_diag_params);
196
static int uart_init(void) {
197
return uart_register(&uart0, &uart_defparams);