teensy40: add UART support
Этот коммит содержится в:
родитель
9ca0e3f2d1
коммит
9aa50853b8
4 изменённых файлов: 425 добавлений и 4 удалений
|
@ -2,6 +2,11 @@
|
|||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/nxp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// Digital pins
|
||||
const (
|
||||
// = Pin // [Pad]: Alt Func 0 Alt Func 1 Alt Func 2 Alt Func 3 Alt Func 4 Alt Func 5 Alt Func 6 Alt Func 7 Alt Func 8 Alt Func 9
|
||||
|
@ -83,6 +88,17 @@ const (
|
|||
I2C_SCL_PIN = I2C1_SCL_PIN // D19/A5
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// #=====================================================#
|
||||
// | UART |
|
||||
// #===========#===========#=============#===============#
|
||||
|
@ -119,8 +135,88 @@ const (
|
|||
UART7_TX_PIN = D29
|
||||
)
|
||||
|
||||
// #==================================================================#
|
||||
// | SPI |
|
||||
var (
|
||||
UART1 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: nxp.LPUART6,
|
||||
muxRX: muxSelect{ // D0 (PA3 [AD_B0_03])
|
||||
mux: nxp.IOMUXC_LPUART6_RX_SELECT_INPUT_DAISY_GPIO_AD_B0_03_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART6_RX_SELECT_INPUT,
|
||||
},
|
||||
muxTX: muxSelect{ // D1 (PA2 [AD_B0_02])
|
||||
mux: nxp.IOMUXC_LPUART6_TX_SELECT_INPUT_DAISY_GPIO_AD_B0_02_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART6_TX_SELECT_INPUT,
|
||||
},
|
||||
}
|
||||
UART2 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: nxp.LPUART4,
|
||||
muxRX: muxSelect{ // D7 (PB17 [B1_01])
|
||||
mux: nxp.IOMUXC_LPUART4_RX_SELECT_INPUT_DAISY_GPIO_B1_01_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART4_RX_SELECT_INPUT,
|
||||
},
|
||||
muxTX: muxSelect{ // D8 (PB16 [B1_00])
|
||||
mux: nxp.IOMUXC_LPUART4_TX_SELECT_INPUT_DAISY_GPIO_B1_00_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART4_TX_SELECT_INPUT,
|
||||
},
|
||||
}
|
||||
UART3 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: nxp.LPUART2,
|
||||
muxRX: muxSelect{ // D15 (PA19 [AD_B1_03])
|
||||
mux: nxp.IOMUXC_LPUART2_RX_SELECT_INPUT_DAISY_GPIO_AD_B1_03_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART2_RX_SELECT_INPUT,
|
||||
},
|
||||
muxTX: muxSelect{ // D14 (PA18 [AD_B1_02])
|
||||
mux: nxp.IOMUXC_LPUART2_TX_SELECT_INPUT_DAISY_GPIO_AD_B1_02_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART2_TX_SELECT_INPUT,
|
||||
},
|
||||
}
|
||||
UART4 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: nxp.LPUART3,
|
||||
muxRX: muxSelect{ // D16 (PA23 [AD_B1_07])
|
||||
mux: nxp.IOMUXC_LPUART3_RX_SELECT_INPUT_DAISY_GPIO_AD_B1_07_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART3_RX_SELECT_INPUT,
|
||||
},
|
||||
muxTX: muxSelect{ // D17 (PA22 [AD_B1_06])
|
||||
mux: nxp.IOMUXC_LPUART3_TX_SELECT_INPUT_DAISY_GPIO_AD_B1_06_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART3_TX_SELECT_INPUT,
|
||||
},
|
||||
}
|
||||
UART5 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: nxp.LPUART8,
|
||||
muxRX: muxSelect{ // D21 (PA27 [AD_B1_11])
|
||||
mux: nxp.IOMUXC_LPUART8_RX_SELECT_INPUT_DAISY_GPIO_AD_B1_11_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART8_RX_SELECT_INPUT,
|
||||
},
|
||||
muxTX: muxSelect{ // D20 (PA26 [AD_B1_10])
|
||||
mux: nxp.IOMUXC_LPUART8_TX_SELECT_INPUT_DAISY_GPIO_AD_B1_10_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART8_TX_SELECT_INPUT,
|
||||
},
|
||||
}
|
||||
UART6 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: nxp.LPUART1,
|
||||
// LPUART1 not connected via IOMUXC
|
||||
// RX: D24 (PA12 [AD_B0_12])
|
||||
// TX: D25 (PA13 [AD_B0_13])
|
||||
}
|
||||
UART7 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: nxp.LPUART7,
|
||||
muxRX: muxSelect{ // D28 (PC18 [EMC_32])
|
||||
mux: nxp.IOMUXC_LPUART7_RX_SELECT_INPUT_DAISY_GPIO_EMC_32_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART7_RX_SELECT_INPUT,
|
||||
},
|
||||
muxTX: muxSelect{ // D29 (PD31 [EMC_31])
|
||||
mux: nxp.IOMUXC_LPUART7_TX_SELECT_INPUT_DAISY_GPIO_EMC_31_ALT2,
|
||||
sel: &nxp.IOMUXC.LPUART7_TX_SELECT_INPUT,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// #===========#==========#===============#===========================#
|
||||
// | Interface | Hardware | Clock(Freq) | SDI/SDO/SCK/CS : Alt |
|
||||
// #===========#==========#===============#=================-=========#
|
||||
|
|
317
src/machine/machine_mimxrt1062_uart.go
Обычный файл
317
src/machine/machine_mimxrt1062_uart.go
Обычный файл
|
@ -0,0 +1,317 @@
|
|||
// +build mimxrt1062
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/nxp"
|
||||
"runtime/interrupt"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
// UART peripheral abstraction layer for the MIMXRT1062
|
||||
|
||||
type UART struct {
|
||||
Bus *nxp.LPUART_Type
|
||||
Buffer *RingBuffer
|
||||
Interrupt interrupt.Interrupt
|
||||
|
||||
// these hold the input selector ("daisy chain") values that select which pins
|
||||
// are connected to the LPUART device, and should be defined where the UART
|
||||
// instance is declared. see the godoc comments on type muxSelect for more
|
||||
// details.
|
||||
muxRX, muxTX muxSelect
|
||||
|
||||
// these are copied from UARTConfig, during (*UART).Configure(UARTConfig), and
|
||||
// should be considered read-only for internal reference (i.e., modifying them
|
||||
// will have no desirable effect).
|
||||
rx, tx Pin
|
||||
baud uint32
|
||||
|
||||
// auxiliary state data used internally
|
||||
configured bool
|
||||
msbFirst bool
|
||||
transmitting volatile.Register32
|
||||
txBuffer *RingBuffer
|
||||
}
|
||||
|
||||
func (uart *UART) isTransmitting() bool { return uart.transmitting.Get() != 0 }
|
||||
func (uart *UART) startTransmitting() { uart.transmitting.Set(1) }
|
||||
func (uart *UART) stopTransmitting() { uart.transmitting.Set(0) }
|
||||
func (uart *UART) resetTransmitting() {
|
||||
uart.stopTransmitting()
|
||||
uart.Bus.GLOBAL.SetBits(nxp.LPUART_GLOBAL_RST)
|
||||
uart.Bus.GLOBAL.ClearBits(nxp.LPUART_GLOBAL_RST)
|
||||
}
|
||||
|
||||
// Configure initializes a UART with the given UARTConfig and other default
|
||||
// settings.
|
||||
func (uart *UART) Configure(config UARTConfig) {
|
||||
|
||||
const defaultUartFreq = 115200
|
||||
|
||||
// use default baud rate if not specified
|
||||
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
|
||||
}
|
||||
uart.rx = config.RX
|
||||
uart.tx = config.TX
|
||||
|
||||
// configure the mux and pad control registers
|
||||
uart.rx.Configure(PinConfig{Mode: PinModeUARTRX})
|
||||
uart.tx.Configure(PinConfig{Mode: PinModeUARTTX})
|
||||
|
||||
// configure the mux input selector
|
||||
uart.muxRX.connect()
|
||||
uart.muxTX.connect()
|
||||
|
||||
// reset all internal logic and registers
|
||||
uart.resetTransmitting()
|
||||
|
||||
// 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)
|
||||
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)
|
||||
|
||||
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))
|
||||
|
||||
// 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)
|
||||
|
||||
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))
|
||||
|
||||
// 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)
|
||||
|
||||
// enable RX IRQ
|
||||
uart.Interrupt.SetPriority(0xc0)
|
||||
uart.Interrupt.Enable()
|
||||
|
||||
uart.configured = true
|
||||
}
|
||||
|
||||
func (uart *UART) Disable() {
|
||||
|
||||
// first ensure the device is enabled
|
||||
if uart.configured {
|
||||
|
||||
// wait for any buffered data to send
|
||||
uart.Flush()
|
||||
|
||||
// stop trapping RX interrupts
|
||||
uart.Interrupt.Disable()
|
||||
|
||||
// reset all internal registers
|
||||
uart.resetTransmitting()
|
||||
|
||||
// disable RX/TX functions
|
||||
uart.Bus.CTRL.ClearBits(nxp.LPUART_CTRL_TE | nxp.LPUART_CTRL_RE)
|
||||
|
||||
// put pins back into GPIO mode
|
||||
uart.rx.Configure(PinConfig{Mode: PinInputPullUp})
|
||||
uart.tx.Configure(PinConfig{Mode: PinInputPullUp})
|
||||
}
|
||||
uart.configured = false
|
||||
}
|
||||
|
||||
// Flush blocks the calling goroutine until all data in the output buffer has
|
||||
// been written out.
|
||||
func (uart *UART) Flush() {
|
||||
for uart.isTransmitting() {
|
||||
}
|
||||
}
|
||||
|
||||
func (uart *UART) WriteByte(c byte) error {
|
||||
if nil == uart.txBuffer {
|
||||
uart.txBuffer = NewRingBuffer()
|
||||
}
|
||||
uart.startTransmitting()
|
||||
for !uart.txBuffer.Put(c) {
|
||||
}
|
||||
uart.Bus.CTRL.SetBits(nxp.LPUART_CTRL_TIE)
|
||||
return nil
|
||||
}
|
||||
|
||||
// getBaudRateDivisor finds the greatest over-sampling factor (4..32) and
|
||||
// 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
|
||||
// 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()).
|
||||
func (uart *UART) getBaudRateDivisor(baudRate uint32) (sbr uint32, osr uint32) {
|
||||
const clock = 24000000 // UART is muxed to 24 MHz OSC
|
||||
err := uint32(0xFFFFFFFF)
|
||||
sbr, osr = 0, 0
|
||||
for o := uint32(4); o <= 32; o++ {
|
||||
s := ((clock*10)/(baudRate*o) + 5) / 10
|
||||
if s == 0 {
|
||||
s = 1
|
||||
}
|
||||
b := clock / (s * o)
|
||||
var e uint32
|
||||
if b > baudRate {
|
||||
e = b - baudRate
|
||||
} else {
|
||||
e = baudRate - b
|
||||
}
|
||||
if e <= err {
|
||||
err = e
|
||||
osr = o
|
||||
sbr = s
|
||||
}
|
||||
}
|
||||
return sbr, osr
|
||||
}
|
||||
|
||||
func (uart *UART) getFIFOSize() (rx, tx uint32) {
|
||||
fifo := uart.Bus.FIFO.Get()
|
||||
rx = uint32(1) << ((fifo & nxp.LPUART_FIFO_RXFIFOSIZE_Msk) >> nxp.LPUART_FIFO_RXFIFOSIZE_Pos)
|
||||
if rx > 1 {
|
||||
rx <<= 1
|
||||
}
|
||||
tx = uint32(1) << ((fifo & nxp.LPUART_FIFO_TXFIFOSIZE_Msk) >> nxp.LPUART_FIFO_TXFIFOSIZE_Pos)
|
||||
if tx > 1 {
|
||||
tx <<= 1
|
||||
}
|
||||
return rx, tx
|
||||
}
|
||||
|
||||
func (uart *UART) getStatus() uint32 {
|
||||
return uart.Bus.STAT.Get() |
|
||||
((uart.Bus.FIFO.Get() & uint32(nxp.LPUART_FIFO_TXEMPT_Msk|nxp.LPUART_FIFO_RXEMPT_Msk|
|
||||
nxp.LPUART_FIFO_TXOF_Msk|nxp.LPUART_FIFO_RXUF_Msk)) >> 16)
|
||||
}
|
||||
|
||||
func (uart *UART) getEnabledInterrupts() uint32 {
|
||||
return ((uart.Bus.BAUD.Get() & uint32(nxp.LPUART_BAUD_LBKDIE_Msk|nxp.LPUART_BAUD_RXEDGIE_Msk)) >> 8) |
|
||||
((uart.Bus.FIFO.Get() & uint32(nxp.LPUART_FIFO_TXOFE_Msk|nxp.LPUART_FIFO_RXUFE_Msk)) >> 8) |
|
||||
(uart.Bus.CTRL.Get() & uint32(0xFF0C000))
|
||||
}
|
||||
|
||||
func (uart *UART) disableInterrupts(mask uint32) {
|
||||
uart.Bus.BAUD.ClearBits((mask << 8) & uint32(nxp.LPUART_BAUD_LBKDIE_Msk|nxp.LPUART_BAUD_RXEDGIE_Msk))
|
||||
uart.Bus.FIFO.Set((uart.Bus.FIFO.Get() & ^uint32(nxp.LPUART_FIFO_TXOF_Msk|nxp.LPUART_FIFO_RXUF_Msk)) &
|
||||
^uint32((mask<<8)&(nxp.LPUART_FIFO_TXOFE_Msk|nxp.LPUART_FIFO_RXUFE_Msk)))
|
||||
mask &= uint32(0xFFFFFF00)
|
||||
uart.Bus.CTRL.ClearBits(mask)
|
||||
}
|
||||
|
||||
func (uart *UART) handleInterrupt(interrupt.Interrupt) {
|
||||
|
||||
stat := uart.getStatus()
|
||||
inte := uart.getEnabledInterrupts()
|
||||
|
||||
_, txSize := uart.getFIFOSize()
|
||||
|
||||
// check for and clear overrun, otherwise RX will not work
|
||||
if (stat & uint32(nxp.LPUART_STAT_OR)) != 0 {
|
||||
uart.Bus.STAT.Set((uart.Bus.STAT.Get() & uint32(0x3FE00000)) | nxp.LPUART_STAT_OR)
|
||||
}
|
||||
|
||||
// idle or receive data register is full
|
||||
if (stat & uint32(nxp.LPUART_STAT_RDRF|nxp.LPUART_STAT_IDLE)) != 0 {
|
||||
count := (uart.Bus.WATER.Get() & uint32(nxp.LPUART_WATER_RXCOUNT_Msk)) >> nxp.LPUART_WATER_RXCOUNT_Pos
|
||||
for ; count > 0; count-- {
|
||||
// read up to 8 bits of data at a time
|
||||
// TODO: 7, 9, and 10-bit support?
|
||||
uart.Buffer.Put(uint8(uart.Bus.DATA.Get() & uint32(0xFF)))
|
||||
}
|
||||
// if it was an IDLE status, clear the flag
|
||||
if (stat & uint32(nxp.LPUART_STAT_IDLE)) != 0 {
|
||||
uart.Bus.STAT.SetBits(nxp.LPUART_STAT_IDLE)
|
||||
}
|
||||
// disable idle line interrupts
|
||||
uart.disableInterrupts(nxp.LPUART_CTRL_RIE | nxp.LPUART_CTRL_ORIE)
|
||||
}
|
||||
|
||||
// check if we have data to write
|
||||
if ((inte & nxp.LPUART_CTRL_TIE) != 0) && ((stat & nxp.LPUART_STAT_TDRE) != 0) {
|
||||
for ((uart.Bus.WATER.Get() & uint32(nxp.LPUART_WATER_TXCOUNT_Msk)) >> nxp.LPUART_WATER_TXCOUNT_Pos) < txSize {
|
||||
if b, ok := uart.txBuffer.Get(); ok {
|
||||
uart.Bus.DATA.Set(uint32(b))
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if uart.Bus.STAT.HasBits(nxp.LPUART_STAT_TDRE) {
|
||||
uart.Bus.CTRL.Set((uart.Bus.CTRL.Get() & ^uint32(nxp.LPUART_CTRL_TIE)) | nxp.LPUART_CTRL_TCIE)
|
||||
}
|
||||
}
|
||||
|
||||
if ((inte & nxp.LPUART_CTRL_TCIE) != 0) && ((stat & nxp.LPUART_STAT_TC) != 0) {
|
||||
uart.stopTransmitting()
|
||||
uart.Bus.CTRL.ClearBits(nxp.LPUART_CTRL_TCIE)
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build avr esp nrf sam sifive stm32 k210 nxpmk66f18
|
||||
// +build avr esp nrf sam sifive stm32 k210 nxp
|
||||
|
||||
package machine
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ package runtime
|
|||
import (
|
||||
"device/arm"
|
||||
"device/nxp"
|
||||
"machine"
|
||||
"math/bits"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -114,6 +115,7 @@ func initPeripherals() {
|
|||
initPins() // configure GPIO
|
||||
|
||||
enablePeripheralClocks() // activate peripheral clock gates
|
||||
initUART() // configure UART (initialized first for debugging)
|
||||
}
|
||||
|
||||
func initPins() {
|
||||
|
@ -124,7 +126,13 @@ func initPins() {
|
|||
nxp.IOMUXC_GPR.GPR29.Set(0xFFFFFFFF)
|
||||
}
|
||||
|
||||
func putchar(c byte) {}
|
||||
func initUART() {
|
||||
machine.UART1.Configure(machine.UARTConfig{})
|
||||
}
|
||||
|
||||
func putchar(c byte) {
|
||||
machine.UART1.WriteByte(c)
|
||||
}
|
||||
|
||||
func abort() {
|
||||
for {
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче