Noise on unconnected (floating) serial RX pin, possible to enable internal pull-up?

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys, I have a custom pcb with an ATSAMD21 device, and added the possibility to connect a debug header that allows to communicate with the microcontroller through a serial connection. So a RX, TX and GND pin are broken out.

 

When the header is connected to a serial to USB converter, everything works fine. But when the header is not connected, the device is susceptible to noise and probably receives garbage data (noise). Hard to see what it receives, because the debug header is not connected, also scoping grounds the thing, so the noise is gone.

 

I was wondering if I could solve the problem by enabling an internal pull-up (or down) resistor on the RX pin. I tried these pieces of code:

 

To set a pin to be pulled up (taken from ASF here):

struct system_pinmux_config config_pinmux;
system_pinmux_get_config_defaults(&config_pinmux);
config_pinmux.mux_position = SYSTEM_PINMUX_GPIO;
config_pinmux.direction    = SYSTEM_PINMUX_PIN_DIR_INPUT;
config_pinmux.input_pull   = SYSTEM_PINMUX_PIN_PULL_UP;
system_pinmux_pin_set_config(PIN_PA23, &config_pinmux); // The RX pin

 

To initialize the USART module I use this code:

struct usart_config config_usart;
usart_get_config_defaults(&config_usart);

config_usart.baudrate = baud;
config_usart.mux_setting = USART_RX_1_TX_0_XCK_1;
config_usart.pinmux_pad0 = PINMUX_PA22C_SERCOM3_PAD0; // TX
config_usart.pinmux_pad1 = PINMUX_PA23C_SERCOM3_PAD1; // RX
config_usart.pinmux_pad2 = PINMUX_UNUSED;
config_usart.pinmux_pad3 = PINMUX_UNUSED;

while (usart_init(&usart_instance, SERCOM3, &config_usart) != STATUS_OK);
usart_enable(&usart_instance);

 

When I first do the pin pull up code, the pin is not pulled up and the USART still works. Also, it's still receptable to noise. And when I first do the USART init code, and then the pin pull-up code, the pin is pulled up, but USART does not work anymore...

 

Is it possible to combine the two pieces of code, or to achieve what I want in another way? The USART code references from ASF don't mention anything about pull-up or down resistors. Or is the only option to change the hardware and add a physical pull-up (or down) resistor?

 

Thanks in advance.

This topic has a solution.

Maybe someday I'll have a nice quote here.

Last Edited: Sun. Sep 29, 2019 - 02:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I doubt you can do it with ASF alone but probably by setting up the USART as you have and then just assign the port registers to get the pullup. The internal pullup is possible to combine with the USART function, this is documented:

When the SERCOM is used in USART mode, the SERCOM controls the direction and value of the I/O pins according to the table below. Both PORT control bits PINCFGn.PULLEN and PINCFGn.DRVSTR are still effective.

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey Lars,

 

Thanks, you've pointed me in the right direction. Also I found this topic just now, which has some interesting lines of code:

 

https://www.avrfreaks.net/forum/sercom-uart-and-rx-pull

 

I made it work with these lines:

PORT->Group[0].PINCFG[23].bit.PULLEN = 1; // Enable pull up resistor
PORT->Group[0].OUTSET.reg |= 1 << 8; // Pull up (OUTCLR for pull down)

I put the lines right after initializing the USART. I am not sure if I need both lines. Can you advise?

 

As said, it works now, but I'm not sure if I'm doing it correctly. Thanks again.

Maybe someday I'll have a nice quote here.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need both lines but the 2nd line should set bit 23 (1 << 23). Possibly you have a pull down now (which I guess is equally ok for removing noise problems). BTW, if there is a lot of noise you might still want a real pullup resistor since the builtin ones are weak (documented 20k-60k)

/Lars