Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.
0

Grand Central M4 Express, CANNOT implement "Mega" serial por
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Grand Central M4 Express, CANNOT implement "Mega" serial por

by tomjennings on Thu Jul 09, 2020 1:47 pm

It appears to be the case that it is not physically possible to mux SERCOM(s) to "Arduino" pins 14..19 to implement Serial1..Serial4 (in Arduino nomenclature). The mux allows mapping the two free SERCOMs (1, 5) to "Arduino" pins D0, D1, D3, D4, D5, D6, and D10, D11, D12, D13, and I suppose D30, D31, and those in limited combinations.

It is my own fault for not reading between the lines and/or going through the descriptions in the code before I bought, but I think it's misleading to not clearly state such a large and obvious deviation from a very reasonable interpretation of what "Mega pinout" means. (I did install support in the IDE for the board, looked at the table in variants.cpp, saw the comments "// SERIAL3_RX" etc, without looking to see that other functions were assigned to those pins (eg. PWM). Yes it was dumb of me to not read closer.)

I fully realize "Mega" implies an ad hoc collection of work-alikes, and is no standard. The four serials are as important to the implied meaning of "Mega pinout" as the 16 analogs. Implementations vary (different analog resolutions, speeds, ana ref architecture, etc) but some of the essential feature is provided, and major differences noted ("3.3V only", USB connectors, etc). The few compatible boards (Due, etc) provide these.

I could easily adapt my board to use serial ports on other Arduino pins -- but that violates the WHOLE POINT! of pinout compatiblity -- interchangable, multiply-sourced boards. As the Mega 2560 fades with age I (and I assume others) want to move to more modern architectures, and no small factor, buy from Adafruit. A jumper or two I can deal with, but the amount of copper routing to accommodate serials on low pins is too much on an already crowded board.



A simple note on the product page "DOES NOT MEGA SERIAL PORT PINOUT", or anyone responding to any of my multiple posts trying to make those serials go would have saved me a lot of grief.

Sheesh.

tomjennings
 
Posts: 78
Joined: Thu Aug 17, 2006 1:21 am

Re: Grand Central M4 Express, CANNOT implement "Mega" serial

by westfw on Thu Jul 09, 2020 9:15 pm

It should be possible.

Pins 14&15 are SERCOM 5 tx/rx
Pins 16&17 are SERCOM 1 tx/rx
Pins 18&19 are SERCOM 4 tx/rx

I think that all of those are "available" (Serial1 is on SERCOM0, I2C is on SERCOM3, SPI is on SERCOM2. IF I transcribed properly.)
(For completeness, SERCOM6 is on pins 24/25 and SERCOM7 is pins 40/41)

The software support is a bit behind, I guess, or Adafruit has decided to not implement those UART ports for some reason (one possible excuse: leaving them undefined allows an "advanced" programmer to use UART, SPI, or I2C on the pins. Switching Arduino-core "Drivers" after they've been pre-defined for a particular use is more difficult.)

westfw
 
Posts: 1720
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Grand Central M4 Express, CANNOT implement "Mega" serial

by westfw on Fri Jul 10, 2020 5:21 am

Here's a hack that should make things easier. I did SOME testing on a Grand Central, but thorough testing of multiple serial ports is a bit beyond my hardware and patience...
Let us know if there are problems (or if it works.)

/
Code: Select all | TOGGLE FULL SIZE
*
 * sercomlib.h
 * July 2020, by Bill Westfield
 * Released to the public domain.
 *
 * This defines macros to pair up "un-used" sercom interfaces with Arduino driver-level
 *  definitions like UART/HardwareSerial, on SAMD51-based boards.
 * 
 *  Use it like:
 *     sercom_UseSerial(sercomNumber, SerialNumber)
 *  It's all relatively ugly pre-processor magic, and it
 *  assumes that symbols like sercomN, (from variant.cpp)
 *  and PIN_SERIALn_TX, PIN_SERIALn_TX (from variant.h)
 *  are already defined (True for Adafruit's Grand Central Station board,
 *  but not for some others.
 *  SerialN and the SERCOMn_x_Handler() end up being defined.
 *     
 *  At some point, this might get expanded to allow I2C and SPI as well,
 *  and support other chip families.
 */
#include <variant.h>
#define sercom_UseSerial(_sercom, _serialNum) \
  Uart Serial##_serialNum( &sercom##_sercom, PIN_SERIAL##_serialNum##_RX, PIN_SERIAL##_serialNum##_TX, SERCOM_RX_PAD_1, UART_TX_PAD_0 ) ; \
  void SERCOM##_sercom##_0_Handler(void) {  Serial##_serialNum.IrqHandler(); } \
  void SERCOM##_sercom##_1_Handler(void) {  Serial##_serialNum.IrqHandler(); } \
  void SERCOM##_sercom##_2_Handler(void) {  Serial##_serialNum.IrqHandler(); } \
  void SERCOM##_sercom##_3_Handler(void) {  Serial##_serialNum.IrqHandler(); }


And a sample sketch:
Code: Select all | TOGGLE FULL SIZE
#include "sercomlib.h"
/*
 *  July 2020 by Bill Westfield.  Released to the public domain.
 */
/*
 *  Attach the extra SERCOM peripherals to Serial Ports (UART mode.)
 *  Note that for Grand Central, the required PIN_SERIALn_RX/etc defines are already in variant.h
 *  For other boards, it may be necessary to define them.
 */
//              SERCOM#, Serial#
sercom_UseSerial(  4,      2)   // Serial2 - pins 18 and 19
sercom_UseSerial(  1,      3)   // Serial3 - pins 16 and 17
sercom_UseSerial(  5,      4)   // Serial4 - pins 14 and 15


void setup() {
  // Start ports at different speeds to demo their independence.
  Serial.begin(9600);
  Serial1.begin(19200);     // Serial1 (pins 0 and 1) alread defined.
  Serial2.begin(38400);
  Serial3.begin(115200);
  Serial4.begin(9600);
  while (!Serial)           // Wait for USB Serial to finish initialized
    ;
}

void loop() {
  Serial.println("This is Serial");
 
  Serial1.println("This a Serial 1");    // Check Transmit
  while (Serial1.available()) {          // Check receive
    Serial1.print("Serial 1 read ");
    Serial1.println(Serial1.read());
  }
  Serial2.println("This a Serial 2");
  while (Serial2.available()) {
    Serial2.print("Serial 2 read ");
    Serial2.println(Serial2.read());
  }
  Serial3.println("This a Serial 3");
  while (Serial3.available()) {
    Serial3.print("Serial 3 read ");
    Serial3.println(Serial3.read());
  }
  Serial4.println("This a Serial 4");
  while (Serial4.available()) {
    Serial4.print("Serial 4 read ");
    Serial4.println(Serial4.read());
  }
  delay(1000);
}

westfw
 
Posts: 1720
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Grand Central M4 Express, CANNOT implement "Mega" serial

by tomjennings on Fri Jul 10, 2020 1:44 pm

westfw wrote:It should be possible.

Pins 14&15 are SERCOM 5 tx/rx
Pins 16&17 are SERCOM 1 tx/rx
Pins 18&19 are SERCOM 4 tx/rx


Woah! OK! I drew my "can't" conclusion from this Adafruit page:

https://learn.adafruit.com/using-atsamd ... xing-it-up

"Muxing it up", more or less beginning at "Available SERCOMs and pins". (though it's spread out before, and pages after, to include SAMD51), where I got that particular list of usable pins, backed up by the macro defs in variants.cpp, that had PWM-able stuff on Arduino 14, etc.

Not that I want to belabor my error -- I will try your code [next post] and stfu for now.

Thanks so much for the reply and info. NEWS AT 11.

tomjennings
 
Posts: 78
Joined: Thu Aug 17, 2006 1:21 am

Re: Grand Central M4 Express, CANNOT implement "Mega" serial

by tomjennings on Fri Jul 10, 2020 3:33 pm

westfw wrote:Here's a hack that should make things easier.


WORKS! The best thing about it is that it precludes the need for messing with variant.{cpp,h} at all. I backed out the other thread's recommended edits, which approximately performed your configuration.

I re-read the aforementioned pages to see how it read post-enlightenment, and I still see it as stating that the PAD/Pin muxing allows very few combinations, none of them yours. I tried to look (briefly, not intensely) to see if "your" mappings are somehow stepping on other peripherals (eg. Serial2-or-is-it-1, below), but so far so good.

Only one issue: The UART on Arduino pins 18, 19 does Nothing, both pins floating/inputs. Serial port names are slightly confounded by the G.C. M4's new, arbitrary naming:

Code: Select all | TOGGLE FULL SIZE
MEGA             GCM4X         Arduino pins
Serial(0)        Serial1       Main USB serial, 0, 1
Serial1          Serial2       18, 19 not working on GCM4X with your config
Serial2          Serial3       16, 17
Serial3          Serial4       14, 15


But I'll look later at the Serial1/2 issue.

I hacked your example into one of my multi-processor boxes and its working in place just fine (minus one MAX3232 Tx output pin, but it's a newly soldered, new PCB... and the input is there) and messages flow.

I'll spend a little time and work up an example multi-serial sketch that will allow poking a wire between various Tx and Rx pin combos and have it say what it sees. Might take me a day or two.

(Lol, the average idle task time was a few milliseconds on a 16 MHz Mega 2560, which is totally fine; things with mass (motors, pumps) don't move fast. With GCM4X, it's 11 microseconds! But mainly I get all the periphs like SDcard, storage, without addons.)


Thanks so much for this. My macro fu isn't as strong as yours. I would not have worked that out myself. It's a huge relief that GCM4X is working.

tom

tomjennings
 
Posts: 78
Joined: Thu Aug 17, 2006 1:21 am

Re: Grand Central M4 Express, CANNOT implement "Mega" serial

by westfw on Fri Jul 10, 2020 6:23 pm

confounded by the G.C. M4's new, arbitrary naming

It's not quite arbitrary; it's a consequence of having the upload port be "native usb" rather than UART based. This leaves the unfortunate choice of calling the USB path "SerialUSB" (which some boards do) and having "Serial" refer to the first real UART (which breaks expectations of everyone programming something that they expect to communicate back to the PC. Including many of the examples), or the situation you're in where the pins that used to be "Serial" now need to be something different. (I don't think having Serial and Serial0 would be a good idea, either.)

I re-checked pins 18/19 on my GCM4X, and they're working fine with the example code. Did your note imply that "Serial2" is working on some boards but not others? You aren't by any chance using a variants file that you had already modified in your previous attempts to get this working?


The best thing about it is that it precludes the need for messing with variant.{cpp,h} at all.

Yep; I was pleased that it worked out that way.
I'm a bit embarrassed to admit that I've been "designing" a really general way of being able to re-define SERCOM functionality, even at runtime, starting with "if we relocate the vector table to RAM, we can reset the ISR functions for each SERCOM", and it wasn't till I noticed how obnoxious it is to try to do that that I also noticed that it's really unnecessary for the most common use cases :-(

For example, since SPI and I2C usage are controlled by library inclusion, if you DON'T specifically use them, those SERCOMs can also be used for UARTs...

westfw
 
Posts: 1720
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Grand Central M4 Express, CANNOT implement "Mega" serial

by westfw on Sat Jul 11, 2020 8:02 pm

and support other chip families.

hmm. This is also going to require the proper pinDescription entries in the variants file, saying that certain pins belong to a SERCOM
For example, the Metro M0 Express only has the existing Serial1, I2C, SPI, and SPIflash sercoms marked...

westfw
 
Posts: 1720
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Grand Central M4 Express, CANNOT implement "Mega" serial

by tomjennings on Sat Jul 11, 2020 9:18 pm

re: serial port name diff Mega to GCM4X
It's not quite arbitrary; it's a consequence of having the upload port be "native usb" rather than UART based.

You are of course correct. I was being grouchy. They are old name + 1 so predictable.


I re-checked pins 18/19 on my GCM4X, and they're working fine with the example code. Did your note imply that "Serial2" is working on some boards but not others? You aren't by any chance using a variants file that you had already modified in your previous attempts to get this working?

OK great that's good to know. No, I only have the one board, so that was just me communicating badly. Last, I have backed out the edits but when I get to it next (Monday prob) I will find original copies on github/whatever, start again.


I'm a bit embarrassed to admit that I've been "designing" a really general way of being able to re-define SERCOM functionality, even at runtime, starting with "if we relocate the vector table to RAM, we can reset the ISR functions for each SERCOM", and it wasn't till I noticed how obnoxious it is to try to do that that I also noticed that it's really unnecessary for the most common use cases :-(

I'm not certain that working towards broad generality is something to be embarrassed about :-)

For example, since SPI and I2C usage are controlled by library inclusion, if you DON'T specifically use them, those SERCOMs can also be used for UARTs...

That had occurred to me, but it metaphorically feels like playing in traffic. Also I use both (RTC chip, radio).

No matter, once I un-botch my Serial2/18/19 I'll write up an example program and figure out where to post it.

Thanks so much for the succinct work!

tomjennings
 
Posts: 78
Joined: Thu Aug 17, 2006 1:21 am

Re: Grand Central M4 Express, CANNOT implement "Mega" serial

by tomjennings on Sun Jul 12, 2020 9:27 pm

OK your code of course works on all three "Mega" serial ports with the as-shipped variants.{cpp,h} files, I must have hosed something. For temporary posterity, here's a test kludge sketch that I used. The sketch has another tab containing your macros in sercomlib.h.

I used a short jumper to bridge TX to RX. Each TX gets an ASCII digit spit to it that IDs the sender. Prints millis() just to prove it's not dead yet.

Code: Select all | TOGGLE FULL SIZE
#include "sercomlib.h"
/*
 *  July 2020 by Bill Westfield.  Released to the public domain.
 */
/*
 *  Attach the extra SERCOM peripherals to Serial Ports (UART mode.)
 *  Note that for Grand Central, the required PIN_SERIALn_RX/etc defines are already in variant.h
 *  For other boards, it may be necessary to define them.
 */
//              SERCOM#, Serial#

sercom_UseSerial(  4,      2)   // Serial2 - pins 18 and 19
sercom_UseSerial(  1,      3)   // Serial3 - pins 16 and 17
sercom_UseSerial(  5,      4)   // Serial4 - pins 14 and 15


void setup() {

  Serial.begin (115200);
  while (! Serial);
  Serial.println ("This test kludge writes a single character to each \"Mega 2560\" serial port:");
  Serial.println ("   pins 18 (tx), 19 (rx) \"Serial2\"");
  Serial.println ("   pins 16 (tx), 17 (rx), \"Serial3\"");
  Serial.println ("   pins 14 (tx, 15 (rx) \"Serial4\"");
  Serial.println ("once a second. Connect a wire from any tx pin to any rx pin and it will print a message.");
  Serial.println ("(Note floating inputs often generate weird fake data.)\n");

  Serial2.begin (300);     // slow enough to blink an LED sort-of
  Serial3.begin (300);
  Serial4.begin (300);
}


void loop() {

  Serial.print ("millis() says ");
  Serial.println (millis());
  delay (1000);

  // pins 18 (tx), 19 (rx) "Serial2"
  Serial2.write ('2'); if (Serial2.available()) report (2, Serial2.read());

  // pins 16 (tx), 17 (rx), "Serial3"
  Serial3.write ('3'); if (Serial3.available()) report (3, Serial3.read());

  // pins 14 (tx, 15 (rx) "Serial4"
  Serial4.write ('4'); if (Serial4.available()) report (4, Serial4.read());

}

void report (int n, char c) {
char buff [80];

  if ((c >= ' ') && (c <= '~')) {
    sprintf (buff, "Serial%d reads \"%c\"\n", n, c);

  } else {
    sprintf (buff, "Serial%d reads 0x%0x\n", n, c);
  }
  Serial.print (buff);
}

tomjennings
 
Posts: 78
Joined: Thu Aug 17, 2006 1:21 am

Re: Grand Central M4 Express, CANNOT implement "Mega" serial

by westfw on Mon Jul 13, 2020 2:16 am

I'm glad you have it all working.
More macros:

Code: Select all | TOGGLE FULL SIZE
// Use this form to specify the TX and RX pin numbers (Arduino Pin numbers.)
#define sercom_UseSerialPins(_sercom, _ser, _rx, _tx) \
  Uart _ser( &sercom##_sercom, _rx, _tx, SERCOM_RX_PAD_1, UART_TX_PAD_0 ) ; \
  void SERCOM##_sercom##_0_Handler(void) {  _ser.IrqHandler(); } \
  void SERCOM##_sercom##_1_Handler(void) {  _ser.IrqHandler(); } \
  void SERCOM##_sercom##_2_Handler(void) {  _ser.IrqHandler(); } \
  void SERCOM##_sercom##_3_Handler(void) {  _ser.IrqHandler(); }

// Use this form to specify the TX and RX pin numbers AND PAD designators
//  Note that on SAMD51, the TX pad is fixed.
#define sercom_UseSerialPinsPads(_sercom, _serialNum, _rx, _tx, _rxpad, _txpad) \
  Uart _ser( &sercom##_sercom, _rx, _tx, _txpad, _txpad ) ; \
  void SERCOM##_sercom##_0_Handler(void) {  _ser.IrqHandler(); } \
  void SERCOM##_sercom##_1_Handler(void) {  _ser.IrqHandler(); } \
  void SERCOM##_sercom##_2_Handler(void) {  _ser.IrqHandler(); } \
  void SERCOM##_sercom##_3_Handler(void) {  _ser.IrqHandler(); }


So, for example:
Code: Select all | TOGGLE FULL SIZE
sercom_UseSerialPins(3, SerialI2C, 21, 20)  // SerialI2C - I2C pins


sercom_UseSerial(4, 2) is short for sercom_UseSerialPins(4, Serial2, PIN_SERIAL2_RX, PIN_SERIAL2_TX, SERCOM_RX_PAD_1, UART_TX_PAD_0)

I actually like the named version a bit better, because it helps avoid confusion between the Sercom and Serial port numbers, but those pre-defined pin names are ... a lot of typing, and it's not like it will work on arbitrary pins :-(

Maybe I'll clone a branch and submit a pull-request to get this into the Adafruit core.

westfw
 
Posts: 1720
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: Grand Central M4 Express, CANNOT implement "Mega" serial

by tomjennings on Mon Jul 13, 2020 2:00 pm

First, though I now sound all complacent'n'stuff because it's working and serial ports are not inherently interesting to many, I am profoundly appreciative of your macro work here. It's clean and neat and works easily, and breaks nothing.

Both sets of macros are useful, and they don't collide (if used right). The simpler ones (that I will stick with) may be more broadly useful, emulating the old pinout, where the more generalized ones let willing folk exploit hardware feetch, but as you point out, will require knowledge of the SAMDxxx restrictions.

In the Arduino environment, absolute pin numbers are meaningful (for better and worse).

I think the four serials are basic stuff, in spite of crickets in the forum. And certainly making them useful is important.

I agree this should be in the distribution. I don't see how it collides with anything.

Thanks again.

tomjennings
 
Posts: 78
Joined: Thu Aug 17, 2006 1:21 am

Please be positive and constructive with your questions and comments.