summaryrefslogtreecommitdiffstats
path: root/uart/uart.c
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2017-05-18 19:31:00 +0100
committerTomasz Kramkowski <tk@the-tk.com>2017-05-18 19:31:00 +0100
commit98f075af24dc60a5179511db7b84dbb62d8d80a1 (patch)
tree56f62b18f928b27086b07535576d7ae2d0b3c058 /uart/uart.c
parentfee379e0042b8232ca1b106fd02134ce4451953e (diff)
downloadfmk-98f075af24dc60a5179511db7b84dbb62d8d80a1.tar.gz
fmk-98f075af24dc60a5179511db7b84dbb62d8d80a1.tar.xz
fmk-98f075af24dc60a5179511db7b84dbb62d8d80a1.zip
move uart implementation out of subdirectory
Diffstat (limited to 'uart/uart.c')
-rw-r--r--uart/uart.c238
1 files changed, 0 insertions, 238 deletions
diff --git a/uart/uart.c b/uart/uart.c
deleted file mode 100644
index 3ead880..0000000
--- a/uart/uart.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * uart/uart.c -- hardware UART interface
- *
- * Copyright (C) 2016-2017 Tomasz Kramkowski <tk@the-tk.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <asm.h>
-#include <cm4.h>
-#include <reg/gpio.h>
-#include <reg/port.h>
-#include <reg/sim.h>
-#include <reg/uart.h>
-#include <stdarg.h>
-#include <stddef.h>
-
-#include "uart.h"
-
-enum {
- SBR_VAL = 39,
- BRFA_VAL = 2,
- SRBSZ = 2048,
- FIFOSZ = 8,
-};
-
-static struct {
- unsigned char buf[SRBSZ];
- int start, end;
-} send_rb = { .start = 0, .end = 0 };
-
-static inline size_t rb_store(void *_data, size_t size)
-{
- unsigned char *data = _data;
- size_t avail;
- int start, end;
-
- start = send_rb.start;
- end = send_rb.end;
- avail = (start + sizeof send_rb.buf - end) % sizeof send_rb.buf - 1;
-
- if (size > avail) {
- GPIOC_PSOR = BV(5);
- size = avail;
- }
-
- for (size_t i = 0; i < size; i++)
- send_rb.buf[(end + i) % sizeof send_rb.buf] = data[i];
- send_rb.end = (end + size) % sizeof send_rb.buf;
-
- /* Enable Transmission Interrupt */
- CLI();
- SET_BIT(UART0_C2, C2_TIE);
- STI();
-
- return size;
-}
-
-void uart_setup(void)
-{
- /* Clock gating for UART0 */
- SET_BIT(SIM_SCGC4, SCGC4_UART0);
- /* Disable TX and RX */
- SET_MASKED(UART0_C2, BV(C2_TE) | BV(C2_RE), 0);
- /* Default settings */
- UART0_C1 = 0;
- /* SBR and BRFA for baud rate */
- SET_MASKED(UART0_BDH, BDH_SBR_M, ((SBR_VAL & 0x1f00) >> 8) << BDH_SBR);
- SET_MASKED(UART0_BDL, BDL_SBR_M, (SBR_VAL & 0xff) << BDL_SBR);
- SET_MASKED(UART0_C4, C4_BRFA_M, BRFA_VAL << C4_BRFA);
- /* flush and enable TX FIFO */
- UART0_CFIFO |= BV(CFIFO_TXFLUSH);
- UART0_PFIFO |= BV(PFIFO_TXFE);
- /* set watermark at 1 entry */
- SET_MASKED(UART0_TWFIFO, TWFIFO_TXWATER_M, 1 << TWFIFO_TXWATER);
- /* NVIC enable interrupt */
- ISR_CLRPEND(45);
- INTPRI(45) = 0xf0;
- ISR_SETENA(45);
- /* enable correct ALT MUX on TX pin */
- PORTB_PCR(17) = 3 << PCR_MUX;
- /* enable TX */
- SET_MASKED(UART0_C2, BV(C2_TE), BV(C2_TE));
-}
-
-void uart_putchar(int c)
-{
- static unsigned char buf[128];
- static size_t size = 0;
-
- if (c == '\n')
- uart_putchar('\r');
-
- buf[size++] = c;
-
- if (size >= sizeof buf || c == '\n') {
- rb_store(buf, size);
- size = 0;
- }
-}
-
-void uart_puts(const char *s)
-{
- for (size_t i = 0; s[i]; i++)
- uart_putchar(s[i]);
- uart_putchar('\n');
-}
-
-static inline void putul(unsigned long n, int base)
-{
- static const char *digits = "0123456789abcdef";
- int i;
- char tmp[64];
-
- if (base < 2 || base > 16)
- return;
-
- if (n == 0) {
- uart_putchar('0');
- return;
- }
- for (i = 0; n; i++) {
- int res = n % base;
- n = n / base;
- tmp[i] = digits[res];
- }
-
- for (i -= 1; i >= 0; i--)
- uart_putchar(tmp[i]);
-}
-
-static inline void putl(long n)
-{
- int i;
- char tmp[64];
-
- if (n < 0) {
- uart_putchar('-');
- n *= -1;
- }
-
- if (n == 0) {
- uart_putchar('0');
- return;
- }
-
- for (i = 0; n; i++) {
- int res = n % 10;
- n = n / 10;
- tmp[i] = '0' + res;
- }
-
- for (i -= 1; i >= 0; i--)
- uart_putchar(tmp[i]);
-}
-
-void uart_printf(const char *fmt, ...)
-{
- va_list ap;
- const char *p;
- int ival;
- unsigned uival;
- long lival;
- unsigned long ulival;
-
- va_start(ap, fmt);
- for (p = fmt; *p; p++) {
- if (*p != '%') {
- uart_putchar(*p);
- continue;
- }
- switch (*++p) {
- case 'd': case 'i':
- ival = va_arg(ap, int);
- putl(ival);
- break;
- case 'o': case 'u': case 'x':
- uival = va_arg(ap, unsigned);
- switch (*p) {
- case 'o': putul(uival, 8); break;
- case 'u': putul(uival, 10); break;
- case 'x': putul(uival, 16); break;
- }
- break;
- case 'l':
- switch (*++p) {
- case 'd': case 'i':
- lival = va_arg(ap, long);
- putl(lival);
- break;
- case 'o': case 'u': case 'x':
- ulival = va_arg(ap, unsigned long);
- switch (*p) {
- case 'o': putul(ulival, 8); break;
- case 'u': putul(ulival, 10); break;
- case 'x': putul(ulival, 16); break;
- }
- break;
- }
- }
- }
- va_end(ap);
-}
-
-void uart0_isr(void)
-{
- int avail, start, end, tosend;
-
- if (!GET_BIT(UART0_S1, S1_TDRE))
- return;
-
- avail = FIFOSZ - UART0_TCFIFO;
- CLI();
- start = send_rb.start;
- end = send_rb.end;
- tosend = (end + sizeof send_rb.buf - start) % sizeof send_rb.buf;
- if (tosend == 0)
- UNSET_BIT(UART0_C2, C2_TIE);
- STI();
-
- if (tosend > avail)
- tosend = avail;
-
- for (int i = 0; i < tosend; i++)
- UART0_D = send_rb.buf[(start + i) % sizeof send_rb.buf];
-
- send_rb.start = (start + tosend) % sizeof send_rb.buf;
-}