Mercurial > hg > Members > innparusu > xv6_rpi_port
diff source/uart.c @ 0:c450faca55f4
Init
author | Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 22 Oct 2017 18:25:39 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/uart.c Sun Oct 22 18:25:39 2017 +0900 @@ -0,0 +1,135 @@ +/***************************************************************** +* uart.c +* by Zhiyi Huang, hzy@cs.otago.ac.nz +* University of Otago +* +********************************************************************/ + + + +#include "types.h" +#include "defs.h" +#include "memlayout.h" +#include "traps.h" +#include "arm.h" + +#define GPFSEL0 0xFE200000 +#define GPFSEL1 0xFE200004 +#define GPFSEL2 0xFE200008 +#define GPFSEL3 0xFE20000C +#define GPFSEL4 0xFE200010 +#define GPFSEL5 0xFE200014 +#define GPSET0 0xFE20001C +#define GPSET1 0xFE200020 +#define GPCLR0 0xFE200028 +#define GPCLR1 0xFE20002C +#define GPPUD 0xFE200094 +#define GPPUDCLK0 0xFE200098 +#define GPPUDCLK1 0xFE20009C + +#define AUX_IRQ 0xFE215000 +#define AUX_ENABLES 0xFE215004 +#define AUX_MU_IO_REG 0xFE215040 +#define AUX_MU_IER_REG 0xFE215044 +#define AUX_MU_IIR_REG 0xFE215048 +#define AUX_MU_LCR_REG 0xFE21504C +#define AUX_MU_MCR_REG 0xFE215050 +#define AUX_MU_LSR_REG 0xFE215054 +#define AUX_MU_MSR_REG 0xFE215058 +#define AUX_MU_SCRATCH 0xFE21505C +#define AUX_MU_CNTL_REG 0xFE215060 +#define AUX_MU_STAT_REG 0xFE215064 +#define AUX_MU_BAUD_REG 0xFE215068 + +void +setgpioval(uint func, uint val) +{ + uint sel, ssel, rsel; + + if(func > 53) return; + sel = func >> 5; + ssel = GPSET0 + (sel << 2); + rsel = GPCLR0 + (sel << 2); + sel = func & 0x1f; + if(val == 0) outw(rsel, 1<<sel); + else outw(ssel, 1<<sel); +} + + +void +setgpiofunc(uint func, uint alt) +{ + uint sel, data, shift; + + if(func > 53) return; + sel = 0; + while (func > 10) { + func = func - 10; + sel++; + } + sel = (sel << 2) + GPFSEL0; + data = inw(sel); + shift = func + (func << 1); + data &= ~(7 << shift); + data |= alt << shift; + outw(sel, data); +} + + +void +uartputc(uint c) +{ + if(c=='\n') { + while(1) if(inw(AUX_MU_LSR_REG) & 0x20) break; + outw(AUX_MU_IO_REG, 0x0d); // add CR before LF + } + while(1) if(inw(AUX_MU_LSR_REG) & 0x20) break; + outw(AUX_MU_IO_REG, c); +} + +static int +uartgetc(void) +{ + if(inw(AUX_MU_LSR_REG)&0x1) return inw(AUX_MU_IO_REG); + else return -1; +} + +void +enableirqminiuart(void) +{ + intctrlregs *ip; + + ip = (intctrlregs *)INT_REGS_BASE; + ip->gpuenable[0] |= (1 << 29); // enable the miniuart through Aux +} + + +void +miniuartintr(void) +{ + consoleintr(uartgetc); +} + +void +uartinit(void) +{ + outw(AUX_ENABLES, 1); + outw(AUX_MU_CNTL_REG, 0); + outw(AUX_MU_LCR_REG, 0x3); + outw(AUX_MU_MCR_REG, 0); + outw(AUX_MU_IER_REG, 0x1); + outw(AUX_MU_IIR_REG, 0xC7); + outw(AUX_MU_BAUD_REG, 270); // (250,000,000/(115200*8))-1 = 270 + + setgpiofunc(14, 2); // gpio 14, alt 5 + setgpiofunc(15, 2); // gpio 15, alt 5 + + outw(GPPUD, 0); + delay(10); + outw(GPPUDCLK0, (1 << 14) | (1 << 15) ); + delay(10); + outw(GPPUDCLK0, 0); + + outw(AUX_MU_CNTL_REG, 3); + enableirqminiuart(); +}