I'm using an Arduino MKR GSM 1400. I know this board uses the Atmel SAMD21 and the SAMD21 supports half-duplex (USART with full-duplex and single-wire half-duplex configuration). My question is, how can I configure one of the SERCOMs to use it as half-duplex (use one pin for rx and tx)?
2 Answers
Up to six Serial Communication Interfaces (SERCOM), each configurable to operate as either:
- USART with full-duplex and single-wire half-duplex configuration
- I2C up to 3.4 MHz
- SPI
- LIN slave
It is an error in the overview of the SAM D21 features in the datasheet. The SERCOM is half-duplex for I2C. USART can't be configured half-duplex.
see Application Note about SERCOM configuration
1 Introduction to Serial Communication Interfaces (USART, I2C, and SPI)
... The exchange of data can be half-duplex or fullduplex depending on the serial module specification. ...
1.1 USART
... It is full-duplex in operation. ...
1.2 I2C
... It is half-duplex in communication. ...
- 103
- 2
- 18,264
- 4
- 31
- 49
You can use USART in half duplex mode.
SERCOMx.PAD0 or SERCOMx.PAD2 are available for this. Refer to document "AT03256: SAM D/R/L/C Serial USART (SERCOM USART) Driver" section "10. SERCOM USART MUX Settings".
Below is a piece of code for ATXMEGA32E5, SERCOM0, PAD0. I am tested - it works:
Pull-up will help keep the line at 1 when the device’s transmitter is turned off and there is no other transmitter on the line, or it has not turned on yet. In the GPIO setup procedure:
// PA08 - SERCOM0/PAD[0]
PORT->Group[0].PINCFG[8].bit.PULLEN=1; // Pull Enable
PORT->Group[0].PINCFG[8].bit.PMUXEN=1; // Peripheral Multiplexer Enable
PORT->Group[0].PMUX [4].bit.PMUXE=0x02; // PMUX function C - SERCOM0/PAD[0]
In the SERCOM setup procedure, configure TX and RX on one pad:
while(SERCOM0->USART.SYNCBUSY.reg & 0x07) { ; }
SERCOM0->USART.CTRLA.bit.TXPO = 0x00; // SERCOM PAD[0] Transmit Data Pinout
while(SERCOM0->USART.SYNCBUSY.reg & 0x07) { ; }
SERCOM0->USART.CTRLA.bit.RXPO = 0x00; // SERCOM PAD[0] is used for data reception
If at the time of your transmission both the receiver and the transmitter are turned on at the same time, you will hear your echo.
When you get up for reception, do not forget to turn off your transmitter so that it does not interfere with reception:
SERCOM0->USART.CTRLB.bit.TXEN=0x00; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; }
SERCOM0->USART.CTRLB.bit.RXEN=0x01; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; }
Before transmitting, do not forget to turn on the transmitter:
SERCOM0->USART.CTRLB.bit.TXEN=0x01; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; }
SERCOM0->USART.CTRLB.bit.RXEN=0x00; while(SERCOM0->USART.SYNCBUSY.bit.CTRLB ) { ; } // If you don't want to receive your own transmission
Hope it helps.
- 21
- 1