aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorardnew <[email protected]>2021-09-11 01:53:30 -0500
committerRon Evans <[email protected]>2021-09-13 09:29:20 +0200
commit1e92e5f6c6e1e56baf4c695032ab275a9bdd7eb4 (patch)
tree6fdcd017a73671b39d1ad8b117923f4e00b21724
parent3eb9dca695254b9d59f30597ea6c409e1b65e7ee (diff)
downloadtinygo-1e92e5f6c6e1e56baf4c695032ab275a9bdd7eb4.tar.gz
tinygo-1e92e5f6c6e1e56baf4c695032ab275a9bdd7eb4.zip
teensy40: enable hardware UART reconfiguration, fix receive watermark interrupt
-rw-r--r--src/device/nxp/mimxrt1062_mpu.go30
-rw-r--r--src/machine/board_teensy40.go24
-rw-r--r--src/machine/machine_mimxrt1062_uart.go92
-rw-r--r--targets/mimxrt1062-teensy40.ld3
4 files changed, 69 insertions, 80 deletions
diff --git a/src/device/nxp/mimxrt1062_mpu.go b/src/device/nxp/mimxrt1062_mpu.go
index 8483b7561..f69dfc3fa 100644
--- a/src/device/nxp/mimxrt1062_mpu.go
+++ b/src/device/nxp/mimxrt1062_mpu.go
@@ -2,6 +2,7 @@
// Type definitions, fields, and constants associated with the MPU peripheral
// of the NXP MIMXRT1062.
+//go:build nxp && mimxrt1062
// +build nxp,mimxrt1062
package nxp
@@ -216,6 +217,12 @@ func enableIcache(enable bool) {
}
}
+var (
+ dcacheCcsidr volatile.Register32
+ dcacheSets volatile.Register32
+ dcacheWays volatile.Register32
+)
+
func enableDcache(enable bool) {
if enable != SystemControl.CCR.HasBits(SCB_CCR_DC_Msk) {
if enable {
@@ -244,11 +251,6 @@ func enableDcache(enable bool) {
isb 0xF
`, nil)
} else {
- var (
- ccsidr volatile.Register32
- sets volatile.Register32
- ways volatile.Register32
- )
SystemControl.CSSELR.Set(0)
arm.AsmFull(`
dsb 0xF
@@ -257,17 +259,17 @@ func enableDcache(enable bool) {
arm.AsmFull(`
dsb 0xF
`, nil)
- ccsidr.Set(SystemControl.CCSIDR.Get())
- sets.Set((ccsidr.Get() & SCB_CCSIDR_NUMSETS_Msk) >> SCB_CCSIDR_NUMSETS_Pos)
- for sets.Get() != 0 {
- ways.Set((ccsidr.Get() & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
- for ways.Get() != 0 {
+ dcacheCcsidr.Set(SystemControl.CCSIDR.Get())
+ dcacheSets.Set((dcacheCcsidr.Get() & SCB_CCSIDR_NUMSETS_Msk) >> SCB_CCSIDR_NUMSETS_Pos)
+ for dcacheSets.Get() != 0 {
+ dcacheWays.Set((dcacheCcsidr.Get() & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
+ for dcacheWays.Get() != 0 {
SystemControl.DCCISW.Set(
- ((sets.Get() << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
- ((ways.Get() << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk))
- ways.Set(ways.Get() - 1)
+ ((dcacheSets.Get() << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
+ ((dcacheWays.Get() << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk))
+ dcacheWays.Set(dcacheWays.Get() - 1)
}
- sets.Set(sets.Get() - 1)
+ dcacheSets.Set(dcacheSets.Get() - 1)
}
arm.AsmFull(`
dsb 0xF
diff --git a/src/machine/board_teensy40.go b/src/machine/board_teensy40.go
index 289edadd8..f96f63de7 100644
--- a/src/machine/board_teensy40.go
+++ b/src/machine/board_teensy40.go
@@ -88,15 +88,20 @@ const (
I2C_SCL_PIN = I2C1_SCL_PIN // D19/A5
)
+// Default peripherals
+var (
+ DefaultUART = UART1
+)
+
func init() {
// register any interrupt handlers for this board's peripherals
- UART1.Interrupt = interrupt.New(nxp.IRQ_LPUART6, _UART1.handleInterrupt)
- UART2.Interrupt = interrupt.New(nxp.IRQ_LPUART4, _UART2.handleInterrupt)
- UART3.Interrupt = interrupt.New(nxp.IRQ_LPUART2, _UART3.handleInterrupt)
- UART4.Interrupt = interrupt.New(nxp.IRQ_LPUART3, _UART4.handleInterrupt)
- UART5.Interrupt = interrupt.New(nxp.IRQ_LPUART8, _UART5.handleInterrupt)
- UART6.Interrupt = interrupt.New(nxp.IRQ_LPUART1, _UART6.handleInterrupt)
- UART7.Interrupt = interrupt.New(nxp.IRQ_LPUART7, _UART7.handleInterrupt)
+ _UART1.Interrupt = interrupt.New(nxp.IRQ_LPUART6, _UART1.handleInterrupt)
+ _UART2.Interrupt = interrupt.New(nxp.IRQ_LPUART4, _UART2.handleInterrupt)
+ _UART3.Interrupt = interrupt.New(nxp.IRQ_LPUART2, _UART3.handleInterrupt)
+ _UART4.Interrupt = interrupt.New(nxp.IRQ_LPUART3, _UART4.handleInterrupt)
+ _UART5.Interrupt = interrupt.New(nxp.IRQ_LPUART8, _UART5.handleInterrupt)
+ _UART6.Interrupt = interrupt.New(nxp.IRQ_LPUART1, _UART6.handleInterrupt)
+ _UART7.Interrupt = interrupt.New(nxp.IRQ_LPUART7, _UART7.handleInterrupt)
}
// #=====================================================#
@@ -136,9 +141,8 @@ const (
)
var (
- DefaultUART = UART1
- UART1 = &_UART1
- _UART1 = UART{
+ UART1 = &_UART1
+ _UART1 = UART{
Bus: nxp.LPUART6,
Buffer: NewRingBuffer(),
txBuffer: NewRingBuffer(),
diff --git a/src/machine/machine_mimxrt1062_uart.go b/src/machine/machine_mimxrt1062_uart.go
index ade7c1706..bb43f4be5 100644
--- a/src/machine/machine_mimxrt1062_uart.go
+++ b/src/machine/machine_mimxrt1062_uart.go
@@ -33,7 +33,6 @@ type UART struct {
// auxiliary state data used internally
configured bool
- msbFirst bool
transmitting volatile.Register32
}
@@ -46,6 +45,11 @@ func (uart *UART) resetTransmitting() {
uart.Bus.GLOBAL.ClearBits(nxp.LPUART_GLOBAL_RST)
}
+func (uart *UART) usesConfig(c UARTConfig) bool {
+ return uart.configured && uart.baud == c.BaudRate &&
+ uart.rx == c.RX && uart.tx == c.TX
+}
+
// Configure initializes a UART with the given UARTConfig and other default
// settings.
func (uart *UART) Configure(config UARTConfig) {
@@ -56,13 +60,19 @@ func (uart *UART) Configure(config UARTConfig) {
if config.BaudRate == 0 {
config.BaudRate = defaultUartFreq
}
- uart.baud = config.BaudRate
// use default UART pins if not specified
if config.RX == 0 && config.TX == 0 {
config.RX = UART_RX_PIN
config.TX = UART_TX_PIN
}
+
+ // Do not reconfigure pins and device buffers if duplicate config provided.
+ if uart.usesConfig(config) {
+ return
+ }
+
+ uart.baud = config.BaudRate
uart.rx = config.RX
uart.tx = config.TX
@@ -77,84 +87,58 @@ func (uart *UART) Configure(config UARTConfig) {
// reset all internal logic and registers
uart.resetTransmitting()
+ // disable until we have finished configuring registers
+ uart.Bus.CTRL.Set(0)
+
// determine the baud rate and over-sample divisors
sbr, osr := uart.getBaudRateDivisor(uart.baud)
- // for now we assume some configuration. in particular:
- // Data bits -> 8-bit
- // Parity bit -> None (parity bit generation disabled)
- // Stop bits -> 1 stop bit
- // MSB first -> false
- // RX idle type -> idle count starts after start bit
- // RX idle config -> 1 idle character
- // RX RTS enabled -> false
- // TX CTS enabled -> false
-
// set the baud rate, over-sample configuration, stop bits
baudBits := (((osr - 1) << nxp.LPUART_BAUD_OSR_Pos) & nxp.LPUART_BAUD_OSR_Msk) |
- ((sbr << nxp.LPUART_BAUD_SBR_Pos) & nxp.LPUART_BAUD_SBR_Msk) |
- ((nxp.LPUART_BAUD_SBNS_SBNS_0 << nxp.LPUART_BAUD_SBNS_Pos) & nxp.LPUART_BAUD_SBNS_Msk)
+ ((sbr << nxp.LPUART_BAUD_SBR_Pos) & nxp.LPUART_BAUD_SBR_Msk)
if osr <= 8 {
// if OSR less than or equal to 8, we must enable sampling on both edges
baudBits |= nxp.LPUART_BAUD_BOTHEDGE
}
uart.Bus.BAUD.Set(baudBits)
-
uart.Bus.PINCFG.Set(0) // disable triggers
- // use 8 data bits, disable parity, use 1 idle char, and idle count starts
- // after start bit
- ctrlBits := uint32(((nxp.LPUART_CTRL_M_M_0 << nxp.LPUART_CTRL_M_Pos) & nxp.LPUART_CTRL_M_Msk) |
- ((nxp.LPUART_CTRL_PE_PE_0 << nxp.LPUART_CTRL_PE_Pos) & nxp.LPUART_CTRL_PE_Msk) |
- ((nxp.LPUART_CTRL_ILT_ILT_0 << nxp.LPUART_CTRL_ILT_Pos) & nxp.LPUART_CTRL_ILT_Msk) |
- ((nxp.LPUART_CTRL_IDLECFG_IDLECFG_0 << nxp.LPUART_CTRL_IDLECFG_Pos) & nxp.LPUART_CTRL_IDLECFG_Msk))
- uart.Bus.CTRL.Set(ctrlBits)
-
+ // configure watermarks, flush and enable TX/RX FIFOs
rxSize, txSize := uart.getFIFOSize()
-
rxWater := rxSize >> 1
if rxWater > uint32(nxp.LPUART_FIFO_RXFIFOSIZE_Msk>>nxp.LPUART_FIFO_RXFIFOSIZE_Pos) {
rxWater = uint32(nxp.LPUART_FIFO_RXFIFOSIZE_Msk >> nxp.LPUART_FIFO_RXFIFOSIZE_Pos)
}
-
txWater := txSize >> 1
if txWater > uint32(nxp.LPUART_FIFO_TXFIFOSIZE_Msk>>nxp.LPUART_FIFO_TXFIFOSIZE_Pos) {
txWater = uint32(nxp.LPUART_FIFO_TXFIFOSIZE_Msk >> nxp.LPUART_FIFO_TXFIFOSIZE_Pos)
}
-
uart.Bus.WATER.Set(
((rxWater << nxp.LPUART_WATER_RXWATER_Pos) & nxp.LPUART_WATER_RXWATER_Msk) |
((txWater << nxp.LPUART_WATER_TXWATER_Pos) & nxp.LPUART_WATER_TXWATER_Msk))
+ uart.Bus.FIFO.SetBits(nxp.LPUART_FIFO_RXFE | nxp.LPUART_FIFO_TXFE |
+ nxp.LPUART_FIFO_RXFLUSH | nxp.LPUART_FIFO_TXFLUSH)
- // enable TX/RX FIFOs
- uart.Bus.FIFO.SetBits(nxp.LPUART_FIFO_RXFE | nxp.LPUART_FIFO_TXFE)
-
- // flush TX/RX FIFOs
- uart.Bus.FIFO.SetBits(nxp.LPUART_FIFO_RXFLUSH | nxp.LPUART_FIFO_TXFLUSH)
+ // for now we assume some configuration. in particular:
+ // Data bits -> 8-bit
+ // Parity bit -> None (parity bit generation disabled)
+ // Stop bits -> 1 stop bit
+ // MSB first -> false
+ // RX idle type -> idle count starts after start bit
+ // RX idle config -> 1 idle character
+ // RX RTS enabled -> false
+ // TX CTS enabled -> false
- uart.Bus.MODIR.SetBits( // set the CTS configuration/TX CTS source
- ((nxp.LPUART_MODIR_TXCTSC_TXCTSC_0 << nxp.LPUART_MODIR_TXCTSC_Pos) & nxp.LPUART_MODIR_TXCTSC_Msk) |
- ((nxp.LPUART_MODIR_TXCTSSRC_TXCTSSRC_0 << nxp.LPUART_MODIR_TXCTSSRC_Pos) & nxp.LPUART_MODIR_TXCTSSRC_Msk))
+ // enable transmitter, receiver functions
+ uart.Bus.CTRL.Set(nxp.LPUART_CTRL_TE | nxp.LPUART_CTRL_RE |
+ // enable receiver, idle line interrupts
+ nxp.LPUART_CTRL_RIE | nxp.LPUART_CTRL_ILIE)
// clear all status flags
- stat := uint32(nxp.LPUART_STAT_RXEDGIF_Msk | nxp.LPUART_STAT_IDLE_Msk | nxp.LPUART_STAT_OR_Msk |
- nxp.LPUART_STAT_NF_Msk | nxp.LPUART_STAT_FE_Msk | nxp.LPUART_STAT_PF_Msk |
- nxp.LPUART_STAT_LBKDIF_Msk | nxp.LPUART_STAT_MA1F_Msk | nxp.LPUART_STAT_MA2F_Msk)
-
- // set data bits order
- if uart.msbFirst {
- stat |= nxp.LPUART_STAT_MSBF
- } else {
- stat &^= nxp.LPUART_STAT_MSBF
- }
-
- uart.Bus.STAT.SetBits(stat)
-
- // enable RX/TX functions
- uart.Bus.CTRL.SetBits(nxp.LPUART_CTRL_TE | nxp.LPUART_CTRL_RE)
+ uart.Bus.STAT.Set(uart.Bus.STAT.Get())
- // enable RX IRQ
- uart.Interrupt.SetPriority(0xc0)
+ // enable RX interrupt
+ uart.Interrupt.SetPriority(0xC0)
uart.Interrupt.Enable()
uart.configured = true
@@ -211,13 +195,13 @@ func (uart *UART) WriteByte(c byte) error {
// corresponding baud rate divisor (1..8191) that best partition a given baud
// rate into equal intervals.
//
-// This is an integral (i.e. non-floating point) port of the logic at the
+// This is an integral (non-floating point) translation of the logic at the
// beginning of:
// void HardwareSerial::begin(uint32_t baud, uint16_t format)
// (from Teensyduino: `cores/teensy4/HardwareSerial.cpp`)
//
-// We don't want to risk using floating point here in the machine package in
-// case it gets called before the FPU or interrupts are ready (e.g., init()).
+// We don't want to use floating point here in case it gets called from an ISR
+// or very early during system init.
func (uart *UART) getBaudRateDivisor(baudRate uint32) (sbr uint32, osr uint32) {
const clock = 24000000 // UART is muxed to 24 MHz OSC
err := uint32(0xFFFFFFFF)
diff --git a/targets/mimxrt1062-teensy40.ld b/targets/mimxrt1062-teensy40.ld
index 312b1078c..70a717b72 100644
--- a/targets/mimxrt1062-teensy40.ld
+++ b/targets/mimxrt1062-teensy40.ld
@@ -8,8 +8,7 @@ MEMORY
ENTRY(Reset_Handler);
-_stack_size = 128K;
-_heap_size = 512K;
+_stack_size = 4K;
SECTIONS
{