mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-12 23:13:40 +00:00
all: use less magic in memory-mapped IO
Don't store addresses in the values of registers, this leads to problems with char arrays (among others). Instead, do it like it's done in C with raw addresses cast to struct pointers. This commit also splits gen-device.py, as AVR and ARM have very different ideas of what a register is. It's easier to just keep them separate.
This commit is contained in:
+8
-13
@@ -29,6 +29,10 @@
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
package arm
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type __reg uint32
|
||||
type RegValue = __reg
|
||||
|
||||
@@ -42,22 +46,13 @@ const (
|
||||
)
|
||||
|
||||
// Nested Vectored Interrupt Controller (NVIC).
|
||||
var NVIC = struct {
|
||||
type NVIC_Type struct {
|
||||
ISER [8]__reg
|
||||
}{
|
||||
ISER: [8]__reg{
|
||||
NVIC_BASE + 0x000,
|
||||
NVIC_BASE + 0x004,
|
||||
NVIC_BASE + 0x008,
|
||||
NVIC_BASE + 0x00C,
|
||||
NVIC_BASE + 0x010,
|
||||
NVIC_BASE + 0x014,
|
||||
NVIC_BASE + 0x018,
|
||||
NVIC_BASE + 0x01C,
|
||||
},
|
||||
}
|
||||
|
||||
var NVIC = (*NVIC_Type)(unsafe.Pointer(uintptr(NVIC_BASE)))
|
||||
|
||||
// Enable the given interrupt number.
|
||||
func EnableIRQ(irq uint32) {
|
||||
NVIC.ISER[irq >> 5] = 1 << (irq & 0x1F)
|
||||
NVIC.ISER[irq>>5] = 1 << (irq & 0x1F)
|
||||
}
|
||||
|
||||
@@ -19,15 +19,15 @@ const LED = 13
|
||||
func (p GPIO) Configure(config GPIOConfig) {
|
||||
if config.Mode == GPIO_OUTPUT { // set output bit
|
||||
if p.Pin < 8 {
|
||||
avr.PORT.DDRD |= 1 << p.Pin
|
||||
*avr.DDRD |= 1 << p.Pin
|
||||
} else {
|
||||
avr.PORT.DDRB |= 1 << (p.Pin - 8)
|
||||
*avr.DDRB |= 1 << (p.Pin - 8)
|
||||
}
|
||||
} else { // configure input: clear output bit
|
||||
if p.Pin < 8 {
|
||||
avr.PORT.DDRD &^= 1 << p.Pin
|
||||
*avr.DDRD &^= 1 << p.Pin
|
||||
} else {
|
||||
avr.PORT.DDRB &^= 1 << (p.Pin - 8)
|
||||
*avr.DDRB &^= 1 << (p.Pin - 8)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,15 +35,15 @@ func (p GPIO) Configure(config GPIOConfig) {
|
||||
func (p GPIO) Set(value bool) {
|
||||
if value { // set bits
|
||||
if p.Pin < 8 {
|
||||
avr.PORT.PORTD |= 1 << p.Pin
|
||||
*avr.PORTD |= 1 << p.Pin
|
||||
} else {
|
||||
avr.PORT.PORTB |= 1 << (p.Pin - 8)
|
||||
*avr.PORTB |= 1 << (p.Pin - 8)
|
||||
}
|
||||
} else { // clear bits
|
||||
if p.Pin < 8 {
|
||||
avr.PORT.PORTB &^= 1 << p.Pin
|
||||
*avr.PORTB &^= 1 << p.Pin
|
||||
} else {
|
||||
avr.PORT.PORTB &^= 1 << (p.Pin - 8)
|
||||
*avr.PORTB &^= 1 << (p.Pin - 8)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -36,17 +36,17 @@ func init() {
|
||||
|
||||
func initUART() {
|
||||
// Initialize UART at 115200 baud when running at 16MHz.
|
||||
avr.USART.UBRR0H = 0
|
||||
avr.USART.UBRR0L = 8
|
||||
avr.USART.UCSR0B = avr.UCSR0B_RXEN0 | avr.UCSR0B_TXEN0 // enable RX and TX
|
||||
avr.USART.UCSR0C = avr.UCSR0C_UCSZ0 // 8-bits data
|
||||
*avr.UBRR0H = 0
|
||||
*avr.UBRR0L = 8
|
||||
*avr.UCSR0B = avr.UCSR0B_RXEN0 | avr.UCSR0B_TXEN0 // enable RX and TX
|
||||
*avr.UCSR0C = avr.UCSR0C_UCSZ0 // 8-bits data
|
||||
}
|
||||
|
||||
func putchar(c byte) {
|
||||
for (avr.USART.UCSR0A & avr.UCSR0A_UDRE0) == 0 {
|
||||
for (*avr.UCSR0A & avr.UCSR0A_UDRE0) == 0 {
|
||||
// Wait until previous char has been sent.
|
||||
}
|
||||
avr.USART.UDR0 = avr.RegValue(c) // send char
|
||||
*avr.UDR0 = avr.RegValue(c) // send char
|
||||
}
|
||||
|
||||
// Sleep by the given amount.
|
||||
@@ -73,21 +73,21 @@ func sleepWDT(period uint8) {
|
||||
avr.Asm("cli")
|
||||
avr.Asm("wdr")
|
||||
// Start timed sequence.
|
||||
avr.WDT.WDTCSR |= avr.WDTCSR_WDCE | avr.WDTCSR_WDE
|
||||
*avr.WDTCSR |= avr.WDTCSR_WDCE | avr.WDTCSR_WDE
|
||||
// Enable WDT and set new timeout (0.5s)
|
||||
avr.WDT.WDTCSR = avr.WDTCSR_WDIE | avr.RegValue(period)
|
||||
*avr.WDTCSR = avr.WDTCSR_WDIE | avr.RegValue(period)
|
||||
avr.Asm("sei")
|
||||
|
||||
// Set sleep mode to idle and enable sleep mode.
|
||||
// Note: when using something other than idle, the UART won't work
|
||||
// correctly. This needs to be fixed, though, so we can truly sleep.
|
||||
avr.CPU.SMCR = (0 << 1) | avr.SMCR_SE
|
||||
*avr.SMCR = (0 << 1) | avr.SMCR_SE
|
||||
|
||||
// go to sleep
|
||||
avr.Asm("sleep")
|
||||
|
||||
// disable sleep
|
||||
avr.CPU.SMCR = 0
|
||||
*avr.SMCR = 0
|
||||
}
|
||||
|
||||
func monotime() uint64 {
|
||||
|
||||
Reference in New Issue
Block a user