SAME51 - Problems muxing a SERCOM

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

Hey all, 

 

I am driving myself insane trying to figure this out, I could use another set of eyes. I have several UARTs muxed in my current project, but I am having a heap of trouble using SERCOM3.. I am configuring it all using START, and it doesn't seem to be working.. Also, I found some discrepancies between what START generates, and what the Datasheet states.

 

uC PN#: ATSAME51J20A (TQFP)

 

Problem: When creating a UART on SERCOM3 using Atmel START, I set TX to PA20, and RX to PA21. Using the "driver_example.c", I execute the UART example function, but see no data out on TX. The module is functioning, and I see the TX COMP callback fire using the debugger, however, nothing comes out the pin. It seems like a muxing problem.

 

Discrepancies: Datasheet states, that within a SERCOM, you must use pins within the same IOSET (Section 6.2.8). If you look at table 6-13, you can see that the pins I am using are both within IOSET 2. However, take note of the pads that they say are being used. PA21 -> Pad3 and PA20 -> Pad2.. However, when you look at the configuration that START generates, it places PA21 -> Pad3, BUT it places PA20 -> Pad1...

 

So, all that being said, I have tried to update the config and set the PA20 pin to the Pad specified in the datasheet (Pad2), but it seems that no matter what I set it to, I never properly the SERCOM module to my pin (PA20 or uC pin 41)..

 

Any ideas guys? It seems like a problem with ASF, but I honestly really hope I am overlooking something simple and it's my fault.. Also, placing my current config for you all to review.

 

#ifndef CONF_SERCOM_3_USART_ENABLE
#define CONF_SERCOM_3_USART_ENABLE 1
#endif

// <h> Basic Configuration

// <q> Receive buffer enable
// <i> Enable input buffer in SERCOM module
// <id> usart_rx_enable
#ifndef CONF_SERCOM_3_USART_RXEN
#define CONF_SERCOM_3_USART_RXEN 1
#endif

// <q> Transmitt buffer enable
// <i> Enable output buffer in SERCOM module
// <id> usart_tx_enable
#ifndef CONF_SERCOM_3_USART_TXEN
#define CONF_SERCOM_3_USART_TXEN 1
#endif

// <o> Frame parity
// <0x0=>No parity
// <0x1=>Even parity
// <0x2=>Odd parity
// <i> Parity bit mode for USART frame
// <id> usart_parity
#ifndef CONF_SERCOM_3_USART_PARITY
#define CONF_SERCOM_3_USART_PARITY 0x0
#endif

// <o> Character Size
// <0x0=>8 bits
// <0x1=>9 bits
// <0x5=>5 bits
// <0x6=>6 bits
// <0x7=>7 bits
// <i> Data character size in USART frame
// <id> usart_character_size
#ifndef CONF_SERCOM_3_USART_CHSIZE
#define CONF_SERCOM_3_USART_CHSIZE 0x0
#endif

// <o> Stop Bit
// <0=>One stop bit
// <1=>Two stop bits
// <i> Number of stop bits in USART frame
// <id> usart_stop_bit
#ifndef CONF_SERCOM_3_USART_SBMODE
#define CONF_SERCOM_3_USART_SBMODE 0
#endif

// <o> Baud rate <1-3000000>
// <i> USART baud rate setting
// <id> usart_baud_rate
#ifndef CONF_SERCOM_3_USART_BAUD
#define CONF_SERCOM_3_USART_BAUD 115200
#endif

// </h>

// <e> Advanced configuration
// <id> usart_advanced
#ifndef CONF_SERCOM_3_USART_ADVANCED_CONFIG
#define CONF_SERCOM_3_USART_ADVANCED_CONFIG 0
#endif

// <q> Run in stand-by
// <i> Keep the module running in standby sleep mode
// <id> usart_arch_runstdby
#ifndef CONF_SERCOM_3_USART_RUNSTDBY
#define CONF_SERCOM_3_USART_RUNSTDBY 0
#endif

// <q> Immediate Buffer Overflow Notification
// <i> Controls when the BUFOVF status bit is asserted
// <id> usart_arch_ibon
#ifndef CONF_SERCOM_3_USART_IBON
#define CONF_SERCOM_3_USART_IBON 0
#endif

// <q> Start of Frame Detection Enable
// <i> Will wake the device from any sleep mode if usart_init and usart_enable was run priort to going to sleep. (receive buffer must be enabled)
// <id> usart_arch_sfde
#ifndef CONF_SERCOM_3_USART_SFDE
#define CONF_SERCOM_3_USART_SFDE 0
#endif

// <q> Collision Detection Enable
// <i> Collision detection enable
// <id> usart_arch_cloden
#ifndef CONF_SERCOM_3_USART_CLODEN
#define CONF_SERCOM_3_USART_CLODEN 0
#endif

// <o> Operating Mode
// <0x0=>USART with external clock
// <0x1=>USART with internal clock
// <i> Drive the shift register by an internal clock generated by the baud rate generator or an external clock supplied on the XCK pin.
// <id> usart_arch_clock_mode
#ifndef CONF_SERCOM_3_USART_MODE
#define CONF_SERCOM_3_USART_MODE 0x1
#endif

// <o> Sample Rate
// <0x0=>16x arithmetic
// <0x1=>16x fractional
// <0x2=>8x arithmetic
// <0x3=>8x fractional
// <0x3=>3x
// <i> How many over-sampling bits used when samling data state
// <id> usart_arch_sampr
#ifndef CONF_SERCOM_3_USART_SAMPR
#define CONF_SERCOM_3_USART_SAMPR 0x0
#endif

// <o> Sample Adjustment
// <0x0=>7-8-9 (3-4-5 8-bit over-sampling)
// <0x1=>9-10-11 (4-5-6 8-bit over-sampling)
// <0x2=>11-12-13 (5-6-7 8-bit over-sampling)
// <0x3=>13-14-15 (6-7-8 8-bit over-sampling)
// <i> Adjust which samples to use for data sampling in asynchronous mode
// <id> usart_arch_sampa
#ifndef CONF_SERCOM_3_USART_SAMPA
#define CONF_SERCOM_3_USART_SAMPA 0x0
#endif

// <o> Fractional Part <0-7>
// <i> Fractional part of the baud rate if baud rate generator is in fractional mode
// <id> usart_arch_fractional
#ifndef CONF_SERCOM_3_USART_FRACTIONAL
#define CONF_SERCOM_3_USART_FRACTIONAL 0x0
#endif

// <o> Data Order
// <0=>MSB is transmitted first
// <1=>LSB is transmitted first
// <i> Data order of the data bits in the frame
// <id> usart_arch_dord
#ifndef CONF_SERCOM_3_USART_DORD
#define CONF_SERCOM_3_USART_DORD 1
#endif

// Does not do anything in UART mode
#define CONF_SERCOM_3_USART_CPOL 0

// <o> Encoding Format
// <0=>No encoding
// <1=>IrDA encoded
// <id> usart_arch_enc
#ifndef CONF_SERCOM_3_USART_ENC
#define CONF_SERCOM_3_USART_ENC 0
#endif

// <o> LIN Slave Enable
// <i> Break Character Detection and Auto-Baud/LIN Slave Enable.
// <i> Additional setting needed: 16x sample rate using fractional baud rate generation (CTRLA.SAMPR = 1).
// <0=>Disable
// <1=>Enable
// <id> usart_arch_lin_slave_enable
#ifndef CONF_SERCOM_3_USART_LIN_SLAVE_ENABLE
#define CONF_SERCOM_3_USART_LIN_SLAVE_ENABLE 0
#endif

// <o> Debug Stop Mode
// <i> Behavior of the baud-rate generator when CPU is halted by external debugger.
// <0=>Keep running
// <1=>Halt
// <id> usart_arch_dbgstop
#ifndef CONF_SERCOM_3_USART_DEBUG_STOP_MODE
#define CONF_SERCOM_3_USART_DEBUG_STOP_MODE 0
#endif

// </e>

#ifndef CONF_SERCOM_3_USART_INACK
#define CONF_SERCOM_3_USART_INACK 0x0
#endif

#ifndef CONF_SERCOM_3_USART_DSNACK
#define CONF_SERCOM_3_USART_DSNACK 0x0
#endif

#ifndef CONF_SERCOM_3_USART_MAXITER
#define CONF_SERCOM_3_USART_MAXITER 0x7
#endif

#ifndef CONF_SERCOM_3_USART_GTIME
#define CONF_SERCOM_3_USART_GTIME 0x2
#endif

#define CONF_SERCOM_3_USART_RXINV 0x0
#define CONF_SERCOM_3_USART_TXINV 0x0

#ifndef CONF_SERCOM_3_USART_CMODE
#define CONF_SERCOM_3_USART_CMODE 0
#endif

#ifndef CONF_SERCOM_3_USART_RXPO
#define CONF_SERCOM_3_USART_RXPO 3 /* RX is on PIN_PA21 */
#endif

#ifndef CONF_SERCOM_3_USART_TXPO
#define CONF_SERCOM_3_USART_TXPO 1 /* TX is on PIN_PA20 */
#endif

/* Set correct parity settings in register interface based on PARITY setting */
#if CONF_SERCOM_3_USART_LIN_SLAVE_ENABLE == 1
#if CONF_SERCOM_3_USART_PARITY == 0
#define CONF_SERCOM_3_USART_PMODE 0
#define CONF_SERCOM_3_USART_FORM 4
#else
#define CONF_SERCOM_3_USART_PMODE CONF_SERCOM_3_USART_PARITY - 1
#define CONF_SERCOM_3_USART_FORM 5
#endif
#else /* #if CONF_SERCOM_3_USART_LIN_SLAVE_ENABLE == 0 */
#if CONF_SERCOM_3_USART_PARITY == 0
#define CONF_SERCOM_3_USART_PMODE 0
#define CONF_SERCOM_3_USART_FORM 0
#else
#define CONF_SERCOM_3_USART_PMODE CONF_SERCOM_3_USART_PARITY - 1
#define CONF_SERCOM_3_USART_FORM 1
#endif
#endif

// Calculate BAUD register value in UART mode
#if CONF_SERCOM_3_USART_SAMPR == 0
#ifndef CONF_SERCOM_3_USART_BAUD_RATE
#define CONF_SERCOM_3_USART_BAUD_RATE                                                                                  \
	65536 - ((65536 * 16.0f * CONF_SERCOM_3_USART_BAUD) / CONF_GCLK_SERCOM3_CORE_FREQUENCY)
#endif
#ifndef CONF_SERCOM_3_USART_RECEIVE_PULSE_LENGTH
#define CONF_SERCOM_3_USART_RECEIVE_PULSE_LENGTH 0
#endif
#elif CONF_SERCOM_3_USART_SAMPR == 1
#ifndef CONF_SERCOM_3_USART_BAUD_RATE
#define CONF_SERCOM_3_USART_BAUD_RATE                                                                                  \
	((CONF_GCLK_SERCOM3_CORE_FREQUENCY) / (CONF_SERCOM_3_USART_BAUD * 16)) - (CONF_SERCOM_3_USART_FRACTIONAL / 8)
#endif
#ifndef CONF_SERCOM_3_USART_RECEIVE_PULSE_LENGTH
#define CONF_SERCOM_3_USART_RECEIVE_PULSE_LENGTH 0
#endif
#elif CONF_SERCOM_3_USART_SAMPR == 2
#ifndef CONF_SERCOM_3_USART_BAUD_RATE
#define CONF_SERCOM_3_USART_BAUD_RATE                                                                                  \
	65536 - ((65536 * 8.0f * CONF_SERCOM_3_USART_BAUD) / CONF_GCLK_SERCOM3_CORE_FREQUENCY)
#endif
#ifndef CONF_SERCOM_3_USART_RECEIVE_PULSE_LENGTH
#define CONF_SERCOM_3_USART_RECEIVE_PULSE_LENGTH 0
#endif
#elif CONF_SERCOM_3_USART_SAMPR == 3
#ifndef CONF_SERCOM_3_USART_BAUD_RATE
#define CONF_SERCOM_3_USART_BAUD_RATE                                                                                  \
	((CONF_GCLK_SERCOM3_CORE_FREQUENCY) / (CONF_SERCOM_3_USART_BAUD * 8)) - (CONF_SERCOM_3_USART_FRACTIONAL / 8)
#endif
#ifndef CONF_SERCOM_3_USART_RECEIVE_PULSE_LENGTH
#define CONF_SERCOM_3_USART_RECEIVE_PULSE_LENGTH 0
#endif
#elif CONF_SERCOM_3_USART_SAMPR == 4
#ifndef CONF_SERCOM_3_USART_BAUD_RATE
#define CONF_SERCOM_3_USART_BAUD_RATE                                                                                  \
	65536 - ((65536 * 3.0f * CONF_SERCOM_3_USART_BAUD) / CONF_GCLK_SERCOM3_CORE_FREQUENCY)
#endif
#ifndef CONF_SERCOM_3_USART_RECEIVE_PULSE_LENGTH
#define CONF_SERCOM_3_USART_RECEIVE_PULSE_LENGTH 0
#endif
#endif

 

This topic has a solution.

murph

Debugging - Being a detective in a crime movie where you are also the murderer.

Last Edited: Wed. Jul 25, 2018 - 03:48 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, START thinks that is OK, but it has let me do impossible things (since the chip wouldn't, read that as respin).

RXPO = 0x3 should allow RX on pad 3 (PA21).  BUT - and this is what killed my first ATSAMD51 board - TXPO only allows TXD on pad0.  (PA17, PA22 with a group C RX) 

jeff

Last Edited: Sat. Jul 21, 2018 - 06:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well that is a bummer.. It seems to be the case for the E51 then as well, since my other working UART TX pins are on Pad0... I doubt I can get a fly wire on a Pad0 pin for SERCOM3 using my setup at home. I'll take it to work with me on Monday and then test Monday evening..

 

How did you come about discovering this? Just stumbling on it when having the same type of problem? Or is there documented ERRATA?

 

Looks like I will have a Rev C then... :(

 

Once again, thanks Jeff. yes

 

 

//I'm confident that Jeff provided the solution, but I will wait until Monday when I get confirmation on my board, before marking as Solution.

murph

Debugging - Being a detective in a crime movie where you are also the murderer.

Last Edited: Sat. Jul 21, 2018 - 06:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have done it... on the qfn even.  flux the pin, solder-wet the wire, tough then and tape the wire steady, then heat.

jeff

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

I might give it a try. I don't think I have the patience to wait until Monday.. Unfortunately because of the pin usage and what's left available on my chip, I'm going to have to move both the RX and TX to a different SERCOM entirely. Putting two next to each other.. With the size of my wire and the steadiness of my hand, I bet I have a hard time soldering one, without de-soldering the other.. I'll give it a shot though. laugh

murph

Debugging - Being a detective in a crime movie where you are also the murderer.

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

I was looking at the chip (48 pin qfn) for a couple uses - one with several serial ports.  I just used START to find suitable pin assignments and assumed i could read the details while I waited for boards...  I was able to "make" start take TX and RX in different sets and with TX not on pad0, and I had no reason to doubt it.  The error made it into two boards before it was figured out.

 

Why do they need to be next to each other?  They are not a diff pair and they don't need to have matched delays...

jeff

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

It just happens to work out that way with leftover pins.. Plus, most of the IOSETs on the SERCOMS seem to just be setup that way anyways (Putting pins next to each other)

murph

Debugging - Being a detective in a crime movie where you are also the murderer.