Mercurial > hg > Members > mitsuki > xv6_rpi2_port
diff source/uart.c @ 0:ed10291ff195
first commit
author | mir3636 |
---|---|
date | Sun, 06 Jan 2019 19:27:03 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/uart.c Sun Jan 06 19:27:03 2019 +0900 @@ -0,0 +1,137 @@ +/***************************************************************** +* 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 (MMIO_VA+0x200000) +#define GPFSEL1 (MMIO_VA+0x200004) +#define GPFSEL2 (MMIO_VA+0x200008) +#define GPFSEL3 (MMIO_VA+0x20000C) +#define GPFSEL4 (MMIO_VA+0x200010) +#define GPFSEL5 (MMIO_VA+0x200014) +#define GPSET0 (MMIO_VA+0x20001C) +#define GPSET1 (MMIO_VA+0x200020) +#define GPCLR0 (MMIO_VA+0x200028) +#define GPCLR1 (MMIO_VA+0x20002C) +#define GPPUD (MMIO_VA+0x200094) +#define GPPUDCLK0 (MMIO_VA+0x200098) +#define GPPUDCLK1 (MMIO_VA+0x20009C) + +#define AUX_IRQ (MMIO_VA+0x215000) +#define AUX_ENABLES (MMIO_VA+0x215004) +#define AUX_MU_IO_REG (MMIO_VA+0x215040) +#define AUX_MU_IER_REG (MMIO_VA+0x215044) +#define AUX_MU_IIR_REG (MMIO_VA+0x215048) +#define AUX_MU_LCR_REG (MMIO_VA+0x21504C) +#define AUX_MU_MCR_REG (MMIO_VA+0x215050) +#define AUX_MU_LSR_REG (MMIO_VA+0x215054) +#define AUX_MU_MSR_REG (MMIO_VA+0x215058) +#define AUX_MU_SCRATCH (MMIO_VA+0x21505C) +#define AUX_MU_CNTL_REG (MMIO_VA+0x215060) +#define AUX_MU_STAT_REG (MMIO_VA+0x215064) +#define AUX_MU_BAUD_REG (MMIO_VA+0x215068) + +void +setgpioval(uint pin, uint val) +{ + uint sel, ssel, rsel, shift; + + if(pin > 53) return; + if(pin >= 32) sel = 1; else sel = 0; + ssel = GPSET0 + (sel << 2); + rsel = GPCLR0 + (sel << 2); + if(sel) shift = (pin - 32) & 0x1f; + else shift = pin & 0x1f; + if(val == 0) outw(rsel, 1<<shift); + else outw(ssel, 1<<shift); +} + + +void +setgpiofunc(uint pin, uint func) +{ + uint sel, data, shift; + + if(pin > 53) return; + sel = 0; + while (pin > 10) { + pin = pin - 10; + sel++; + } + sel = (sel << 2) + GPFSEL0; + data = inw(sel); + shift = pin + (pin << 1); + data &= ~(7 << shift); + outw(sel, data); + data |= func << 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(); +}