github.com/f-secure-foundry/tamago@v0.0.0-20220307101044-d73fcdd7f11b/soc/bcm2835/miniuart.go (about) 1 // BCM2835 mini-UART driver 2 // https://github.com/f-secure-foundry/tamago 3 // 4 // Copyright (c) the bcm2835 package authors 5 // 6 // Use of this source code is governed by the license 7 // that can be found in the LICENSE file. 8 // 9 // This mini-UART is specifically intended for use as a 10 // console. See BCM2835-ARM-Peripherals.pdf that is 11 // widely available. 12 // 13 14 package bcm2835 15 16 import ( 17 "github.com/f-secure-foundry/tamago/arm" 18 "github.com/f-secure-foundry/tamago/internal/reg" 19 ) 20 21 const ( 22 AUX_ENABLES = 0x215004 23 AUX_MU_IO_REG = 0x215040 24 AUX_MU_IER_REG = 0x215044 25 AUX_MU_IIR_REG = 0x215048 26 AUX_MU_LCR_REG = 0x21504C 27 AUX_MU_MCR_REG = 0x215050 28 AUX_MU_LSR_REG = 0x215054 29 AUX_MU_MSR_REG = 0x215058 30 AUX_MU_SCRATCH = 0x21505C 31 AUX_MU_CNTL_REG = 0x215060 32 AUX_MU_STAT_REG = 0x215064 33 AUX_MU_BAUD_REG = 0x215068 34 ) 35 36 type miniUART struct { 37 lsr uint32 38 io uint32 39 } 40 41 // MiniUART is a secondary low throughput UART intended to be 42 // used as a console. 43 var MiniUART = &miniUART{} 44 45 // Init initializes the MiniUART. 46 func (hw *miniUART) Init() { 47 reg.Write(PeripheralAddress(AUX_ENABLES), 1) 48 reg.Write(PeripheralAddress(AUX_MU_IER_REG), 0) 49 reg.Write(PeripheralAddress(AUX_MU_CNTL_REG), 0) 50 reg.Write(PeripheralAddress(AUX_MU_LCR_REG), 3) 51 reg.Write(PeripheralAddress(AUX_MU_MCR_REG), 0) 52 reg.Write(PeripheralAddress(AUX_MU_IER_REG), 0) 53 reg.Write(PeripheralAddress(AUX_MU_IIR_REG), 0xc6) 54 reg.Write(PeripheralAddress(AUX_MU_BAUD_REG), 270) 55 56 // Not using GPIO abstraction here because at the point 57 // we initialize mini-UART during initialization, to 58 // provide 'console', calling Lock on sync.Mutex fails. 59 ra := reg.Read(PeripheralAddress(GPFSEL1)) 60 ra &= ^(uint32(7) << 12) // gpio14 61 ra |= 2 << 12 // alt5 62 ra &= ^(uint32(7) << 15) // gpio15 63 ra |= 2 << 15 // alt5 64 reg.Write(PeripheralAddress(GPFSEL1), ra) 65 66 reg.Write(PeripheralAddress(GPPUD), 0) 67 arm.Busyloop(150) 68 69 reg.Write(PeripheralAddress(GPPUDCLK0), (1<<14)|(1<<15)) 70 arm.Busyloop(150) 71 72 reg.Write(PeripheralAddress(GPPUDCLK0), 0) 73 reg.Write(PeripheralAddress(AUX_MU_CNTL_REG), 3) 74 75 hw.lsr = PeripheralAddress(AUX_MU_LSR_REG) 76 hw.io = PeripheralAddress(AUX_MU_IO_REG) 77 } 78 79 // TX transmits a single character to the serial port. 80 func (hw *miniUART) Tx(c byte) { 81 for { 82 if reg.Read(hw.lsr)&0x20 != 0 { 83 break 84 } 85 } 86 87 reg.Write(hw.io, uint32(c)) 88 } 89 90 // Write data from buffer to serial port. 91 func (hw *miniUART) Write(buf []byte) { 92 for i := 0; i < len(buf); i++ { 93 hw.Tx(buf[i]) 94 } 95 }