@@ -627,90 +627,75 @@ func (a ADC) getADCChannel() uint8 {
627627type UART struct {
628628 Buffer * RingBuffer
629629 Bus * sam.SERCOM_USART_INT_Type
630- Mode PinMode
630+ SERCOM uint8
631631}
632632
633633var (
634634 // UART0 is actually a USB CDC interface.
635635 UART0 = USBCDC {Buffer : NewRingBuffer ()}
636636
637637 // The first hardware serial port on the SAMD51. Uses the SERCOM3 interface.
638- UART1 = UART {Bus : sam . SERCOM3_USART_INT ,
638+ UART1 = UART {
639639 Buffer : NewRingBuffer (),
640- Mode : PinSERCOMAlt ,
640+ Bus : sam .SERCOM3_USART_INT ,
641+ SERCOM : 3 ,
641642 }
642643
643644 // The second hardware serial port on the SAMD51. Uses the SERCOM0 interface.
644645 UART2 = UART {
645646 Buffer : NewRingBuffer (),
646647 Bus : sam .SERCOM0_USART_INT ,
647- Mode : PinSERCOMAlt ,
648+ SERCOM : 0 ,
648649 }
649650)
650651
651652const (
652- sampleRate16X = 16
653- lsbFirst = 1
654- sercomRXPad0 = 0
655- sercomRXPad1 = 1
656- sercomRXPad2 = 2
657- sercomRXPad3 = 3
658- sercomTXPad0 = 0 // Only for UART
659- sercomTXPad2 = 1 // Only for UART
660- sercomTXPad023 = 2 // Only for UART with TX on PAD0, RTS on PAD2 and CTS on PAD3
653+ sampleRate16X = 16
654+ lsbFirst = 1
661655)
662656
663657// Configure the UART.
664- func (uart UART ) Configure (config UARTConfig ) {
658+ func (uart UART ) Configure (config UARTConfig ) error {
665659 // Default baud rate to 115200.
666660 if config .BaudRate == 0 {
667661 config .BaudRate = 115200
668662 }
669663
670664 // determine pins
671- if config .TX == 0 {
665+ if config .TX == 0 && config . RX == 0 {
672666 // use default pins
673667 config .TX = UART_TX_PIN
674668 config .RX = UART_RX_PIN
675669 }
676670
677- // determine pads
678- var txpad , rxpad int
679- switch config . TX {
680- case PA04 :
681- txpad = sercomTXPad0
682- case PA10 :
683- txpad = sercomTXPad2
684- case PA18 :
685- txpad = sercomTXPad2
686- case PA16 :
687- txpad = sercomTXPad0
671+ // Determine transmit pinout.
672+ txPinMode , txPad , ok := findPinPadMapping ( uart . SERCOM , config . TX )
673+ if ! ok {
674+ return ErrInvalidOutputPin
675+ }
676+ var txPinOut uint32
677+ // See CTRLA.RXPO bits of the SERCOM USART peripheral (page 945-946) for how
678+ // pads are mapped to pinout values.
679+ switch txPad {
680+ case 0 :
681+ txPinOut = 0
688682 default :
689- panic ("Invalid TX pin for UART" )
683+ // TODO: flow control (RTS/CTS)
684+ return ErrInvalidOutputPin
690685 }
691686
692- switch config .RX {
693- case PA06 :
694- rxpad = sercomRXPad2
695- case PA07 :
696- rxpad = sercomRXPad3
697- case PA11 :
698- rxpad = sercomRXPad3
699- case PA18 :
700- rxpad = sercomRXPad2
701- case PA16 :
702- rxpad = sercomRXPad0
703- case PA19 :
704- rxpad = sercomRXPad3
705- case PA17 :
706- rxpad = sercomRXPad1
707- default :
708- panic ("Invalid RX pin for UART" )
687+ // Determine receive pinout.
688+ rxPinMode , rxPad , ok := findPinPadMapping (uart .SERCOM , config .RX )
689+ if ! ok {
690+ return ErrInvalidInputPin
709691 }
692+ // As you can see in the CTRLA.RXPO bits of the SERCOM USART peripheral
693+ // (page 945), input pins are mapped directly.
694+ rxPinOut := rxPad
710695
711696 // configure pins
712- config .TX .Configure (PinConfig {Mode : uart . Mode })
713- config .RX .Configure (PinConfig {Mode : uart . Mode })
697+ config .TX .Configure (PinConfig {Mode : txPinMode })
698+ config .RX .Configure (PinConfig {Mode : rxPinMode })
714699
715700 // reset SERCOM0
716701 uart .Bus .CTRLA .SetBits (sam .SERCOM_USART_INT_CTRLA_SWRST )
@@ -745,8 +730,8 @@ func (uart UART) Configure(config UARTConfig) {
745730 // set UART pads. This is not same as pins...
746731 // SERCOM_USART_CTRLA_TXPO(txPad) |
747732 // SERCOM_USART_CTRLA_RXPO(rxPad);
748- uart .Bus .CTRLA .SetBits (uint32 (( txpad << sam .SERCOM_USART_INT_CTRLA_TXPO_Pos ) |
749- (rxpad << sam .SERCOM_USART_INT_CTRLA_RXPO_Pos ) ))
733+ uart .Bus .CTRLA .SetBits (( txPinOut << sam .SERCOM_USART_INT_CTRLA_TXPO_Pos ) |
734+ (rxPinOut << sam .SERCOM_USART_INT_CTRLA_RXPO_Pos ))
750735
751736 // Enable Transceiver and Receiver
752737 //sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_RXEN ;
@@ -762,8 +747,8 @@ func (uart UART) Configure(config UARTConfig) {
762747 uart .Bus .INTENSET .Set (sam .SERCOM_USART_INT_INTENSET_RXC )
763748
764749 // Enable RX IRQ.
765- switch uart .Bus {
766- case sam . SERCOM0_USART_INT :
750+ switch uart .SERCOM {
751+ case 0 :
767752 arm .EnableIRQ (sam .IRQ_SERCOM0_0 )
768753 arm .EnableIRQ (sam .IRQ_SERCOM0_1 )
769754 arm .EnableIRQ (sam .IRQ_SERCOM0_2 )
@@ -775,6 +760,8 @@ func (uart UART) Configure(config UARTConfig) {
775760 arm .EnableIRQ (sam .IRQ_SERCOM3_2 )
776761 arm .EnableIRQ (sam .IRQ_SERCOM3_OTHER )
777762 }
763+
764+ return nil
778765}
779766
780767// SetBaudRate sets the communication speed for the UART.
0 commit comments