machine/samd21: switch UART to use new pin configuration
This allows all possible UART pin configurations to be used and avoids some tricky configuration.
Этот коммит содержится в:
родитель
d266e44bc5
коммит
4397152108
6 изменённых файлов: 56 добавлений и 64 удалений
|
@ -68,10 +68,10 @@ const (
|
||||||
|
|
||||||
// UART1 on the Arduino Nano 33 connects to the onboard NINA-W102 WiFi chip.
|
// UART1 on the Arduino Nano 33 connects to the onboard NINA-W102 WiFi chip.
|
||||||
var (
|
var (
|
||||||
UART1 = UART{Bus: sam.SERCOM5_USART,
|
UART1 = UART{
|
||||||
Buffer: NewRingBuffer(),
|
Buffer: NewRingBuffer(),
|
||||||
Mode: PinSERCOMAlt,
|
Bus: sam.SERCOM5_USART,
|
||||||
IRQVal: sam.IRQ_SERCOM5,
|
SERCOM: 5,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -88,10 +88,10 @@ func handleUART1() {
|
||||||
|
|
||||||
// UART2 on the Arduino Nano 33 connects to the normal TX/RX pins.
|
// UART2 on the Arduino Nano 33 connects to the normal TX/RX pins.
|
||||||
var (
|
var (
|
||||||
UART2 = UART{Bus: sam.SERCOM3_USART,
|
UART2 = UART{
|
||||||
Buffer: NewRingBuffer(),
|
Buffer: NewRingBuffer(),
|
||||||
Mode: PinSERCOMAlt,
|
Bus: sam.SERCOM3_USART,
|
||||||
IRQVal: sam.IRQ_SERCOM3,
|
SERCOM: 3,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -70,10 +70,10 @@ const (
|
||||||
|
|
||||||
// UART1 on the Circuit Playground Express.
|
// UART1 on the Circuit Playground Express.
|
||||||
var (
|
var (
|
||||||
UART1 = UART{Bus: sam.SERCOM1_USART,
|
UART1 = UART{
|
||||||
Buffer: NewRingBuffer(),
|
Buffer: NewRingBuffer(),
|
||||||
Mode: PinSERCOM,
|
Bus: sam.SERCOM4_USART,
|
||||||
IRQVal: sam.IRQ_SERCOM1,
|
SERCOM: 4,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,10 @@ const (
|
||||||
|
|
||||||
// UART1 on the Feather M0.
|
// UART1 on the Feather M0.
|
||||||
var (
|
var (
|
||||||
UART1 = UART{Bus: sam.SERCOM1_USART,
|
UART1 = UART{
|
||||||
Buffer: NewRingBuffer(),
|
Buffer: NewRingBuffer(),
|
||||||
Mode: PinSERCOM,
|
Bus: sam.SERCOM1_USART,
|
||||||
IRQVal: sam.IRQ_SERCOM1,
|
SERCOM: 1,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -55,10 +55,10 @@ const (
|
||||||
|
|
||||||
// UART1 on the ItsyBitsy M0.
|
// UART1 on the ItsyBitsy M0.
|
||||||
var (
|
var (
|
||||||
UART1 = UART{Bus: sam.SERCOM1_USART,
|
UART1 = UART{
|
||||||
Buffer: NewRingBuffer(),
|
Buffer: NewRingBuffer(),
|
||||||
Mode: PinSERCOM,
|
Bus: sam.SERCOM1_USART,
|
||||||
IRQVal: sam.IRQ_SERCOM1,
|
SERCOM: 1,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -44,10 +44,10 @@ const (
|
||||||
|
|
||||||
// UART1 on the Trinket M0.
|
// UART1 on the Trinket M0.
|
||||||
var (
|
var (
|
||||||
UART1 = UART{Bus: sam.SERCOM1_USART,
|
UART1 = UART{
|
||||||
Buffer: NewRingBuffer(),
|
Buffer: NewRingBuffer(),
|
||||||
Mode: PinSERCOM,
|
Bus: sam.SERCOM0_USART,
|
||||||
IRQVal: sam.IRQ_SERCOM1,
|
SERCOM: 0,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -364,8 +364,7 @@ func waitADCSync() {
|
||||||
type UART struct {
|
type UART struct {
|
||||||
Buffer *RingBuffer
|
Buffer *RingBuffer
|
||||||
Bus *sam.SERCOM_USART_Type
|
Bus *sam.SERCOM_USART_Type
|
||||||
Mode PinMode
|
SERCOM uint8
|
||||||
IRQVal uint32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -374,66 +373,54 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sampleRate16X = 16
|
sampleRate16X = 16
|
||||||
lsbFirst = 1
|
lsbFirst = 1
|
||||||
sercomRXPad0 = 0
|
|
||||||
sercomRXPad1 = 1
|
|
||||||
sercomRXPad2 = 2
|
|
||||||
sercomRXPad3 = 3
|
|
||||||
sercomTXPad0 = 0 // Only for UART
|
|
||||||
sercomTXPad2 = 1 // Only for UART
|
|
||||||
sercomTXPad023 = 2 // Only for UART with TX on PAD0, RTS on PAD2 and CTS on PAD3
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Configure the UART.
|
// Configure the UART.
|
||||||
func (uart UART) Configure(config UARTConfig) {
|
func (uart UART) Configure(config UARTConfig) error {
|
||||||
// Default baud rate to 115200.
|
// Default baud rate to 115200.
|
||||||
if config.BaudRate == 0 {
|
if config.BaudRate == 0 {
|
||||||
config.BaudRate = 115200
|
config.BaudRate = 115200
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine pins
|
// Use default pins if pins are not set.
|
||||||
if config.TX == 0 {
|
if config.TX == 0 && config.RX == 0 {
|
||||||
// use default pins
|
// use default pins
|
||||||
config.TX = UART_TX_PIN
|
config.TX = UART_TX_PIN
|
||||||
config.RX = UART_RX_PIN
|
config.RX = UART_RX_PIN
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine pads
|
// Determine transmit pinout.
|
||||||
var txpad, rxpad int
|
txPinMode, txPad, ok := findPinPadMapping(uart.SERCOM, config.TX)
|
||||||
switch config.TX {
|
if !ok {
|
||||||
case PA10:
|
return ErrInvalidOutputPin
|
||||||
txpad = sercomTXPad2
|
}
|
||||||
case PA18:
|
var txPinOut uint32
|
||||||
txpad = sercomTXPad2
|
// See table 25-9 of the datasheet (page 459) for how pads are mapped to
|
||||||
case PA16:
|
// pinout values.
|
||||||
txpad = sercomTXPad0
|
switch txPad {
|
||||||
case PA22:
|
case 0:
|
||||||
txpad = sercomTXPad0
|
txPinOut = 0
|
||||||
|
case 2:
|
||||||
|
txPinOut = 1
|
||||||
default:
|
default:
|
||||||
panic("Invalid TX pin for UART")
|
// TODO: flow control (RTS/CTS)
|
||||||
|
return ErrInvalidOutputPin
|
||||||
}
|
}
|
||||||
|
|
||||||
switch config.RX {
|
// Determine receive pinout.
|
||||||
case PA11:
|
rxPinMode, rxPad, ok := findPinPadMapping(uart.SERCOM, config.RX)
|
||||||
rxpad = sercomRXPad3
|
if !ok {
|
||||||
case PA18:
|
return ErrInvalidInputPin
|
||||||
rxpad = sercomRXPad2
|
|
||||||
case PA16:
|
|
||||||
rxpad = sercomRXPad0
|
|
||||||
case PA19:
|
|
||||||
rxpad = sercomRXPad3
|
|
||||||
case PA17:
|
|
||||||
rxpad = sercomRXPad1
|
|
||||||
case PA23:
|
|
||||||
rxpad = sercomRXPad1
|
|
||||||
default:
|
|
||||||
panic("Invalid RX pin for UART")
|
|
||||||
}
|
}
|
||||||
|
// As you can see in table 25-8 on page 459 of the datasheet, input pins
|
||||||
|
// are mapped directly.
|
||||||
|
rxPinOut := rxPad
|
||||||
|
|
||||||
// configure pins
|
// configure pins
|
||||||
config.TX.Configure(PinConfig{Mode: uart.Mode})
|
config.TX.Configure(PinConfig{Mode: txPinMode})
|
||||||
config.RX.Configure(PinConfig{Mode: uart.Mode})
|
config.RX.Configure(PinConfig{Mode: rxPinMode})
|
||||||
|
|
||||||
// reset SERCOM0
|
// reset SERCOM0
|
||||||
uart.Bus.CTRLA.SetBits(sam.SERCOM_USART_CTRLA_SWRST)
|
uart.Bus.CTRLA.SetBits(sam.SERCOM_USART_CTRLA_SWRST)
|
||||||
|
@ -467,8 +454,8 @@ func (uart UART) Configure(config UARTConfig) {
|
||||||
// set UART pads. This is not same as pins...
|
// set UART pads. This is not same as pins...
|
||||||
// SERCOM_USART_CTRLA_TXPO(txPad) |
|
// SERCOM_USART_CTRLA_TXPO(txPad) |
|
||||||
// SERCOM_USART_CTRLA_RXPO(rxPad);
|
// SERCOM_USART_CTRLA_RXPO(rxPad);
|
||||||
uart.Bus.CTRLA.SetBits(uint32((txpad << sam.SERCOM_USART_CTRLA_TXPO_Pos) |
|
uart.Bus.CTRLA.SetBits((txPinOut << sam.SERCOM_USART_CTRLA_TXPO_Pos) |
|
||||||
(rxpad << sam.SERCOM_USART_CTRLA_RXPO_Pos)))
|
(rxPinOut << sam.SERCOM_USART_CTRLA_RXPO_Pos))
|
||||||
|
|
||||||
// Enable Transceiver and Receiver
|
// Enable Transceiver and Receiver
|
||||||
//sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_RXEN ;
|
//sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_RXEN ;
|
||||||
|
@ -484,7 +471,12 @@ func (uart UART) Configure(config UARTConfig) {
|
||||||
uart.Bus.INTENSET.Set(sam.SERCOM_USART_INTENSET_RXC)
|
uart.Bus.INTENSET.Set(sam.SERCOM_USART_INTENSET_RXC)
|
||||||
|
|
||||||
// Enable RX IRQ.
|
// Enable RX IRQ.
|
||||||
arm.EnableIRQ(uart.IRQVal)
|
// IRQ lines are in the same order as SERCOM instance numbers on SAMD21
|
||||||
|
// chips, so the IRQ number can be trivially determined from the SERCOM
|
||||||
|
// number.
|
||||||
|
arm.EnableIRQ(sam.IRQ_SERCOM0 + uint32(uart.SERCOM))
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBaudRate sets the communication speed for the UART.
|
// SetBaudRate sets the communication speed for the UART.
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче