machine/samd21: switch UART to use new pin configuration

This allows all possible UART pin configurations to be used and avoids
some tricky configuration.
Этот коммит содержится в:
Ayke van Laethem 2019-09-30 16:44:21 +02:00 коммит произвёл Ron Evans
родитель 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 (
@ -376,64 +375,52 @@ 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.