PDA

View Full Version : Teensyduino 1.38 Beta #2



Paul
07-03-2017, 09:44 PM
Here is a second beta test for Teensyduino 1.38.


Old beta download links removed. Please use the latest version:
https://www.pjrc.com/teensy/td_download.html


Changes since Teensyduino 1.38-beta1 (https://forum.pjrc.com/threads/44978-Teensyduino-1-37-Released-and-1-38-beta1-(C-14-support)):

Fix C++14 delete and link with -lstdc++
Add pure code choices in Tools > Optimization
Fix Wire lib with fastest optimize and >120 MHz CPU speed
Wire emulate AVR twi_writeTo - for Adafruit compatibility
Wire1 support for pins on SD socket (if not using SD card)
Fix install problem on Arduino 1.0.6
Fix analogReadAveraging with ADC1
Allow more memory for audio library on Teensy 3.5 & 3.6
Fix audio library delay effect on Teensy 3.5 & 3.6
Audio I2S uses 64 bit frame, improve compatibility with I2S mics
Fix OctoWS2811 seldom-used color conversion options
USBHost_t36 improved handling of error & pipe stall

mjs513
07-03-2017, 11:34 PM
Downloaded and installed no issues. Ran it through several of the same sketches as for beta1 and everything compiled. Ran a modified Onehorse's PropShield sensor sketch with fastest-mpure the "sketch uses 58260 bytes (11%) of program storage space" with fastest only the "Sketch uses 53220 bytes (10%) of program storage space". Not much of a difference. Haven't tested speed but will give it a try later and update.

PaulStoffregen
07-04-2017, 07:47 AM
Thanks for testing! It's a huge help. :)

mjs513
07-05-2017, 02:32 AM
My pleasure. If there is anything else I can do I will. With all that you do its the least that I can do. Been using the c14 version now non-stop since you released it and haven't had any issue. :o

Jantje
07-07-2017, 09:44 PM
I just tested on windows 10 installed on top of the arduino ide 1.8.2.
Compiled and uploaded blink ( on a teesy3.1 ) from arduino IDE and Sloeber.
All went as smooth as can be.
Jantje

Jantje
07-08-2017, 05:08 PM
A test run in sloeber just finished compiling all arduino examples on all teensy boards. That makes 560 compiles.
No problems whatsoever so the toolchain is fine.
Top quality as usual.
Best regards
Jantje

Theremingenieur
07-08-2017, 10:17 PM
That's why I use Teensyduino with Sloeber :)

fiveangle
07-13-2017, 06:48 AM
latest Mac OS and AIDE 1.8.3, compiles for Teensy2.0++ various flavors of Marlin that run correctly w/o issue.

danixdj
07-15-2017, 07:04 PM
Audio I2S uses 64 bit frame

What's this?

WMXZ
07-15-2017, 08:03 PM
What's this?

one stereo frame (left/right word) of a I2S sample consists of 64 bits (2 x 32 bit)
this was changed by Paul from 32 bit (2 x 16 bit)
The driver has also been modified to allow proper 16 bit access for audio library

danixdj
07-15-2017, 09:32 PM
one stereo frame (left/right word) of a I2S sample consists of 64 bits (2 x 32 bit)
this was changed by Paul from 32 bit (2 x 16 bit)
The driver has also been modified to allow proper 16 bit access for audio library

So the sample is more accurate?

This feature need a sketch modification?

WMXZ
07-16-2017, 04:34 AM
So the sample is more accurate?

This feature need a sketch modification?

No, if the ADC has only 16 bit resolution the I2S interface will not increase resolution,
The Audio library is also fixed a 16 bit resolution.
Standard sketches do not need to be modified, only recompiled.

The modification was only introduced to allow the use of 24 or 32 bit I2S-ADC's to be used with Audio library.
For this to work, all data are stored MSB first by the I2S interface and the upper 16 bit are extracted.

The Audio library still will work with 16 bit resolution.
To use the Audio library with 32 bit resolution, ALL routines may need rewriting, as they are hard coded to 44100 Hz AND 16 bit resolution.

mjs513
07-16-2017, 02:12 PM
Been playing around with the Prop Shield IMU code and the only different warning I have been getting that I have not seen before is:

warning: argument to 'sizeof' in 'void* memset(void*, int, size_t)' call is the same
expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess]

memset(_ar, 0.0, sizeof(_ar));

Haven't gone back to give it a try in 1.37 though.

tni
07-16-2017, 03:36 PM
Been playing around with the Prop Shield IMU code and the only different warning I have been getting that I have not seen before is:

warning: argument to 'sizeof' in 'void* memset(void*, int, size_t)' call is the same
expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess]

memset(_ar, 0.0, sizeof(_ar));
Chances are 99% that it's a valid warning and the code in question buggy (wherever it may be from).

MichaelMeissner
07-17-2017, 07:48 PM
Been playing around with the Prop Shield IMU code and the only different warning I have been getting that I have not seen before is:

warning: argument to 'sizeof' in 'void* memset(void*, int, size_t)' call is the same
expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess]

memset(_ar, 0.0, sizeof(_ar));

Haven't gone back to give it a try in 1.37 though.

Note, you do not want to use 0.0 as an argument to memset, instead:



memset(_ar, 0, sizeof(_ar));


However, what it is likely warning you about is the variable _ar is likely a pointer, and not an array. Note, in C/C++, arrays are second class objects. If you pass an array to a function, the compiler converts the declaration within the function to be a pointer to the element, and it passes the pointer, instead of copying the entire array to a temporary on the stack.

So for example:



void clear (char foo[])
{
memset (foo, 0, sizeof (foo));
}

void bar (void)
{
char foo[100];
clear (foo);
// ...
}


is actually implemented as:



void clear (char *foo)
{
memset (foo, 0, sizeof (foo)); // sizeof char * is 4
}

void bar (void)
{
char foo[100];
clear (&foo[0]);
// only the first 4 bytes are cleared
// ...
}


What you should do is pass the length as a separate argument:



void clear (char *foo, size_t len)
{
memset (foo, 0, len);
}

void bar (void)
{
char foo[100];
clear (foo, sizeof (foo));
// ...
}

mjs513
07-17-2017, 09:56 PM
Thanks Michael for the explanation. I was wondering what the warning really meant, never saw that one before. Saw one piece but didn't dive into the library that is calling it yet.

Appreciate it.
Mike

PaulStoffregen
07-17-2017, 10:09 PM
Been playing around with the Prop Shield IMU code and the only different warning I have been getting that I have not seen before is:


Is this from code in one of the libraries or any of the examples?

I tried compiling all 5 of the Arduino examples with the NXPMotionSense library. None give this warning. The MadgwickAHRS and MahonyAHRS do give a couple [-Wstrict-aliasing] warnings, but I couldn't find any example that gives the [-Wsizeof-pointer-memaccess] warning you reported.

If this problem is in any of the libraries or published examples, please point me to the right code so I can fix it.

mjs513
07-18-2017, 01:04 AM
Hi Paul. Not in any of the Teensy libraries or examples. It came from a modified version of an APM library that contained several types of filters that can be used. I added a couple more and the issue is with the RunningAverage. Here is the offending code for reference:

//
// FILE: RunningAverage.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.04
// PURPOSE: RunningAverage library for Arduino
//
// The library stores the last N individual values in a circular buffer,
// to calculate the running average.
//
// HISTORY:
// 0.1.00 - 2011-01-30 initial version
// 0.1.01 - 2011-02-28 fixed missing destructor in .h
// 0.2.00 - 2012-??-?? Yuval Naveh added trimValue (found on web)
// http://stromputer.googlecode.com/svn-history/r74/trunk/Arduino/Libraries/RunningAverage/RunningAverage.cpp
// 0.2.01 - 2012-11-21 refactored
// 0.2.02 - 2012-12-30 refactored trimValue -> fillValue
// 0.2.03 - 2013-11-31 getElement
// 0.2.04 - 2014-07-03 added memory protection
//
// Released to the public domain
//

#include "RunningAverage.h"
#include <stdlib.h>

RunningAverage::RunningAverage(int n)
{
_size = n;
_ar = (float*) malloc(_size * sizeof(float));
if (_ar == NULL) _size = 0;
clear();
}

RunningAverage::~RunningAverage()
{
if (_ar != NULL) free(_ar);
}

// resets all counters
void RunningAverage::clear()
{
_cnt = 0;
_idx = 0;
_sum = 0.0;
//for (int i = 0; i< _size; i++) _ar[i] = 0.0; // needed to keep addValue simple
memset(_ar, 0.0, sizeof(_ar));
}

// adds a new value to the data-set
void RunningAverage::addValue(float f)
{
if (_ar == NULL) return;
_sum -= _ar[_idx];
_ar[_idx] = f;
_sum += _ar[_idx];
_idx++;
if (_idx == _size) _idx = 0; // faster than %
if (_cnt < _size) _cnt++;
}

// returns the average of the data-set added sofar
float RunningAverage::getAverage()
{
if (_cnt == 0) return NAN;
return _sum / _cnt;
}

// returns the value of an element if exist, 0 otherwise
float RunningAverage::getElement(uint8_t idx)
{
if (idx >=_cnt ) return NAN;
return _ar[idx];
}

// fill the average with a value
// the param number determines how often value is added (weight)
// number should preferably be between 1 and size
void RunningAverage::fillValue(float value, int number)
{
clear();
for (int i = 0; i < number; i++)
{
addValue(value);
}
}
// END OF FILE

PaulStoffregen
07-18-2017, 01:49 AM
That's definitely a bug in the RunningAverage library.

It should have been:

memset(_ar, 0, _size * sizeof(float));

This is a common occurrence, where newer versions of the toolchain are able to detect more problems. Long established bugs become more apparent.

mjs513
07-18-2017, 12:44 PM
Thank you for the solution. Seems so obvious :). Thought that what was happening, with the new toolchain I was seeing things that I didn't see before. Think its good for newbies to toolchains to understand that.

gfvalvo
07-20-2017, 03:52 PM
Per this post (https://forum.pjrc.com/threads/45394-SPDIF-Input-and-Output?p=148645&viewfull=1#post148645), I think you need to update the AudioControlSGTL5000::enable() method to select BCLK = 64 * Fs. I say "think" because I've only looked at the code, haven't actually tested it.

mjs513
07-20-2017, 05:56 PM
@Paul. Is this a good time to start talking about additional libraries to be included with the Teenys loader?

PaulStoffregen
07-20-2017, 06:15 PM
Yes, or sometime next week. I'm actually taking this weekend off... but will try to catch up to forum messages when I get back Monday.

Frank B
07-20-2017, 06:20 PM
The ADC Library misses the documentation doxygen-folder

mjs513
07-20-2017, 06:47 PM
Good for you Paul. :) Enjoy they weekend.

Fyod
07-21-2017, 09:13 AM
Wire1 support for pins on SD socket (if not using SD card)

Hi Paul,
any chance you could map PTE0-5 including both UARTs alternates, I2C and SPI as, say, pins 58-63?

KurtE
07-21-2017, 12:21 PM
They already are as far as I know. I added that support awhile ago. I have run SPI display using an adapter I plug into the SD card slot.
They are pins 58-62, and I verified code in Serial2 and Serial4.

Likewise I verified pins 58 and 59 are in table for Wire1.

tni
07-21-2017, 12:44 PM
The SD socket pins are there:
https://github.com/PaulStoffregen/cores/commit/db1e687b18dfcdd0373d666d70ba0dbd668a2f26

Port E0 - E5 (https://www.pjrc.com/teensy/schematic.html) is mapped to 58 - 63 (core_pins.h):
#define CORE_PIN58_BIT 0
#define CORE_PIN59_BIT 1
#define CORE_PIN60_BIT 2
#define CORE_PIN61_BIT 3
#define CORE_PIN62_BIT 4
#define CORE_PIN63_BIT 5

Fyod
07-21-2017, 03:43 PM
I had no idea about that, thanks guys. SPI makes sense (brain fart), but is I2C on pte0,1 mapped too?
Edit: "I2C1: SCL/SDA" awesome

mjs513
07-22-2017, 11:31 AM
I would recommend TeensyThreads as well as NeoGPS. Both work great with the Teensy. NeoGPS is already downloadable the lib manager in Arduino IDE.

Thanks
Mike

mjs513
07-23-2017, 10:57 AM
More of question on the compiler than an issue. I am getting warnings during compile that variables are declared but not used. However, when I go into the code to check the variables are used but are used in "if-else" statements. Is there a way to fix this? I did try compiling with different options (not all of them) but got the same error.

Thanks
Mike

WMXZ
07-23-2017, 01:25 PM
More of question on the compiler than an issue. I am getting warnings during compile that variables are declared but not used. However, when I go into the code to check the variables are used but are used in "if-else" statements. Is there a way to fix this? I did try compiling with different options (not all of them) but got the same error.

Thanks
Mike

That is typical for situations where not all cases are covered by (if,if-else,else)
I found this warning useful to verify the logic behind the program.
Fix: cover all cases

MichaelMeissner
07-23-2017, 02:35 PM
More of question on the compiler than an issue. I am getting warnings during compile that variables are declared but not used. However, when I go into the code to check the variables are used but are used in "if-else" statements. Is there a way to fix this? I did try compiling with different options (not all of them) but got the same error.

Thanks
Mike

This is a feature, not a bug. If the only place where you set a variable is inside of the then part of an if-then-else statement, but you use it outside of the if-then-else statement, then the value is unset if the else condition was set.

So if your code is the following, a could be 0, -53, or any value depending what previous functions left in that stack location, or in the register chosen:



void foo (void)
{
int a;

if (condition ()) {
a = 1;
// ..
} else {
// ...
}

// ...
if (a) { ... }
}


Now, one way to solve this is to initialize the variable when it is declared.



void foo (void)
{
int a = 0;

if (condition ()) {
a = 1;
// ...
} else {
// ...
}

// ...
if (a) {
// ...
}
}


Or in the else statement, you can provide a value:



void foo (void)
{
int a;

if (condition ()) {
a = 1;
// ...
} else {
a = 0;
// ...
}

// ...
if (a) {
// ...
}
}

Another way is to move the scope of a into the if-then-else:



void foo (void)
{

if (condition ()) {
int a = 1;

// ..

if (a) {
// ...
}
} else {
// ...
}
}

mjs513
07-23-2017, 03:00 PM
Thanks Michael. Figure Option 2 would resolve the warning but was trying to understand the compiler warnings. Didn't think it was a bug. Because of what I am doing I will probably go with this option (just initializing the variable at the beginning of the function). I did check the logic and all cases were covered as wmxz suggested.

If anyone is using the Adafruit Motor Shield library, they are going to be seeing a lot of these warnings. The library covers the shields ability to use dc motors, steppers and servos. So if you use just the dc motor option the stepper functions throw a lot of these warnings. Probably should post it on GitHub.

Thanks again.

EDIT: Interesting. Did that then I get another warning about the variables being set but not used. Have to do a double check but they are defined within if-then-else statements. Have to rethink the logic I guess.

PaulStoffregen
07-24-2017, 05:06 PM
Per this post (https://forum.pjrc.com/threads/45394-SPDIF-Input-and-Output?p=148645&viewfull=1#post148645), I think you need to update the AudioControlSGTL5000::enable() method to select BCLK = 64 * Fs. I say "think" because I've only looked at the code, haven't actually tested it.

I tested. It works fine.

KurtE
07-24-2017, 05:41 PM
@Paul - Any progress on the adding storage for Serial buffer design/code? I know it was talked about on the Arduino mailing list maybe 2+ months ago.
Also you mentioned it up on the forum thread: https://forum.pjrc.com/threads/44540-C-Teaching-old-dog-new-tricks?p=146849&viewfull=1#post146849

Is this something you wish to get into this release?

If so, do you see it at least currently stay with C code for each UART or do you see it converting over to maybe something like we did to Wire and SPI objects, where one class, with hardware data structure passed in for each instance?

My assumption is you do not wish to have the class allocate (malloc, new, ...) the buffer, but instead wish to pass in pointer, size (or helper class). Do we do it on new method(s) like:

Serial.addStorageForRead(void *buffer, size_t length);
Serial.addStorageForWrite(void *buffer, size_t length);

Or the other way of having additional begin methods where you can pass them in?

And if yes to any of this do you want some help on it?

PaulStoffregen
07-24-2017, 10:54 PM
@Paul - Any progress on the adding storage for Serial buffer design/code?

Nope, but it's on my todo list...



Is this something you wish to get into this release?

And if yes to any of this do you want some help on it?

Yes, if you'd like to work on this, I've love to merge it. We're going to need quite a bit of time for testing, so now's probably a pretty good time since Arduino 1.8.4 seems quite a long way off. But if they do release unexpectedly, we'll need to revert to the old code and push this to a future version...



If so, do you see it at least currently stay with C code for each UART or do you see it converting over to maybe something like we did to Wire and SPI objects, where one class, with hardware data structure passed in for each instance?


Converting the serial code to the same single-class approach with const tables for the hardware details has also been on my wish list.

Honestly, I'm a little nervous about doing both at the same time.



Or the other way of having additional begin methods where you can pass them in?


I know at one point I talked about an addMemoryForReceive() function, but after thinking about this more, I believe it's cleaner to do it by overloading begin(). Still not sure if we should do with with C++ wrapper classes as Martino proposed, or just pointers and size.

KurtE
07-30-2017, 10:01 PM
Hi Paul (and others),

I am playing around with merging all of the Hardware Serial code into one call implementation. Still a WIP.

I have it all as one class, where you pass in const hardware structure. This is with the exception of Serial6 on T3.6 which is LPUART class, where currently I am doing this as a sub-class...

Still want to clean this up. Things like I currently have 3 different ISR implementations. One for Serial1/2 with FIFO queues, one for the non fifo queues and third for LPUART... I had the first two as one earlier, with an if test to know if this queue is FIFO or not and branch around code... But also wondering if I can combine as currently the worker class code is marked as inline...

That is currently I have:

void uart0_status_isr(void) {
#ifdef HAS_KINETISK_UART0_FIFO
Serial1.status_isr_fifo();
#else
Serial1.status_isr();
#endif
}
Where the code for status_isr and status_isr_FIFO are marked as inline. Wondering if it would work if I did something like:

void uart0_status_isr(void) {
#define UART_FIFO
Serial1.status_isr();
}
And have the implementation of status_isr, check #ifdef UART_FIFO and do the fifo stuff and if not defined not do fifo stuff... Will have to try it out.

Again WIP, so far tested on T3.6 with simple app, probably similar to what Defragster did earlier in beta code. that I output a string to Serial1, and I have a jumper for Serial1.TX to Serial2.RX, and have code that when Serial2 receives data, it sends it back out on Serial2.TX... When the last Serial port if I jumper is TX back to Serial1's RX it echoes everything it receives back in terminal window.

uint32_t current_baud = 38400;
void setup() {
while (!Serial && (millis() < 3000)) ;
Serial.begin(38400);
Serial.println("Test Serial ports");
Serial1.begin(current_baud);
Serial2.begin(current_baud);
Serial3.begin(current_baud);
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
Serial4.begin(current_baud);
Serial5.begin(current_baud);
Serial6.begin(current_baud);
#endif
}

void loop() {
Serial.printf("Output to all Serial ports at Baud %d\n", current_baud);
Serial1.println("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX YZ0123456789");
delay(200); // give time for it to happen

Serial.println("Enter new baud or hit enter to continue using previous baud");

// See if the user
char szTemp[10];

uint32_t new_baud = 0;
int ch;
while ((ch = Serial.read()) != '\n') {
if ((ch >= '0') && (ch <= '9'))
new_baud = new_baud * 10 + ( ch - '0');
}
if (new_baud && (new_baud != current_baud)) {
current_baud = new_baud;
Serial1.end();
Serial2.end();
Serial3.end();
Serial1.begin(current_baud);
Serial2.begin(current_baud);
Serial3.begin(current_baud);
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
Serial4.end();
Serial5.end();
Serial6.end();
Serial4.begin(current_baud);
Serial5.begin(current_baud);
Serial6.begin(current_baud);
#endif

}
}

void serialEvent1() {
uint8_t buffer[80];
uint8_t cb = min (min(sizeof(buffer), Serial1.available()), Serial.availableForWrite());
Serial1.readBytes(buffer, cb);
Serial.write(buffer, cb);
}

void serialEvent2() {
uint8_t buffer[80];
uint8_t cb = min (min(sizeof(buffer), Serial2.available()), Serial2.availableForWrite());
Serial2.readBytes(buffer, cb);
Serial2.write(buffer, cb);
}
void serialEvent3() {
uint8_t buffer[80];
uint8_t cb = min (min(sizeof(buffer), Serial3.available()), Serial3.availableForWrite());
Serial3.readBytes(buffer, cb);
Serial3.write(buffer, cb);
}
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
void serialEvent4() {
uint8_t buffer[80];
uint8_t cb = min (min(sizeof(buffer), Serial4.available()), Serial4.availableForWrite());
Serial4.readBytes(buffer, cb);
Serial4.write(buffer, cb);

}
void serialEvent5() {
uint8_t buffer[80];
uint8_t cb = min (min(sizeof(buffer), Serial5.available()), Serial5.availableForWrite());
Serial5.readBytes(buffer, cb);
Serial5.write(buffer, cb);
}
void serialEvent6() {
uint8_t buffer[80];
uint8_t cb = min (min(sizeof(buffer), Serial6.available()), Serial6.availableForWrite());
Serial6.readBytes(buffer, cb);
Serial6.write(buffer, cb);

}
#endif
I also added code that after it sends out the string, it waits for the user to enter something. Simple CR will send same string. If you enter a number it uses this as a new BAUD rate for all of the Serial ports...
So I tried this code out at 38400, 1000000, 2000000, 2500000 and they all appeared to work.
On my T3.6 have jumpers (1-9)(10-7)(8-31)(32-34)(33-47)(48-0)

Again WIP - Currently up at https://github.com/KurtE/cores/tree/unified-serial
I have the code that if I set a #define in HardwareSerial.h it removes the code from Serial1.c... Serial6.c HardwareSerial1.cpp... Once happy with this can remove these files and probably rename the new stuff

Also once I think this is working well, then will add in ability for addMemory... I personally am on fence on if this should be API or begin.

mjs513
07-30-2017, 11:38 PM
Reminds me of Processing's SerialEvent(Serial p). One question I do have is if the isr is really interrupt controlled, I looked at the code but don't really understand enough of the port manipulation/registers (still a long way off :( ). The concern I have is will this conflict with any other libraries using interrupts? Also, no sure if this would be available if I am using the TeensyThreads library where they kind of frown on using an interrupt within a thread, I am probably wrong on this. Tonton81 and tni knows a lot more about the way it works than I do. But that aside I like the approach. Is there a way to define not to use a ISR?

Thanks
Mike

KurtE
07-31-2017, 12:54 PM
Hi Mike,

Actually I have rarely used serialEvent in my programs, but for a test program, I thought I would put it in to make sure I did not bust things, with my reworking of all of the Serial objects. The Serial Event calls are not called during the ISR of the actual Serial code, but are called from yield(). And yield is called after each call to loop() as well as in some code that do delay loops, like delay()...

As for the Serial code using Interrupts, yes there is an ISR that is serviced for each of the Serial objects, which is the same as it is currently. I have thought of maybe changing this to not installing the ISR for all of the objects, but instead have the begin method do an attachInterruptVector, but not sure how much that would gain.

As for threads, will need to see. At some point I should play more with them and see what the state of things are. It will be interesting if Paul adds the TeensyThreads library to the install package, or waits to see where Arduino is headed with some form of threading...

mjs513
07-31-2017, 01:55 PM
Hi KurtE. Thanks for the explanation. Most of the time I do Serial from the main thread when using the thread library so for me its probably won't be a big impact for me - at least for now. Should try a few more things with it - another thing for the todo list.

If I wanted to play around with your fork do I have to install the whole thing? I did notice that the new stuff is from a few days to a few hours. Can I just copy them to the my current install? Maybe better I just do a clean copy with a new IDE.

Not sure Arduino folks will ever implement threading unless its for the Curie or Due type boards or other 32 bit boards. Most of what I've seen out there are really scheduling type libraries. Think that would be covered with Paul's event library which will probably be better by 10 fold.

KurtE
07-31-2017, 11:34 PM
@Paul - The version I have up on github (https://github.com/KurtE/cores/tree/unified-serial) -
I added methods to the class at least to test with,
Just tested on T3.5 with:
Where each of these buffers is 100 bytes long.

Serial1.addStorageForRead(rxBuffer1, sizeof(rxBuffer1));
Serial1.addStorageForWrite(txBuffer1, sizeof(txBuffer1));
Serial2.addStorageForRead(rxBuffer2, sizeof(rxBuffer2));
Serial2.addStorageForWrite(txBuffer2, sizeof(txBuffer2));


in slightly modified version of test app


uint32_t current_baud = 38400;
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
// Optionally setup alternate pins
#define T356_ALTPINS
#endif

uint8_t rxBuffer1[100];
uint8_t txBuffer1[100];
uint8_t rxBuffer2[100];
uint8_t txBuffer2[100];

void setup() {
pinMode(2, OUTPUT);
digitalWrite(2, LOW);
while (!Serial && (millis() < 3000)) ;
Serial.begin(38400);
Serial.println("Test Serial ports");
#ifdef T356_ALTPINS
Serial.println("Set Alt pins for T3.5/3.6");
Serial1.setRX(21);
Serial1.setTX(5);
#ifdef TEST_SDCARD_PINS
Serial2.setRX(59);
Serial2.setTX(58);
Serial4.setRX(63);
Serial4.setTX(62);
#endif
#endif
Serial1.addStorageForRead(rxBuffer1, sizeof(rxBuffer1));
Serial1.addStorageForWrite(txBuffer1, sizeof(txBuffer1));
Serial2.addStorageForRead(rxBuffer2, sizeof(rxBuffer2));
Serial2.addStorageForWrite(txBuffer2, sizeof(txBuffer2));
Serial.println("Test Serial ports");
Serial1.begin(current_baud);
Serial2.begin(current_baud);
Serial3.begin(current_baud);
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
Serial4.begin(current_baud);
Serial5.begin(current_baud);
Serial6.begin(current_baud);
#endif
}

void loop() {
Serial.printf("Output to all Serial ports at Baud %d\n", current_baud);
digitalWriteFast(2, HIGH);
Serial1.println("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX YZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL MNOPQRSTUVWXYZ0123456789");
digitalWriteFast(2, LOW);
delay(200); // give time for it to happen

Serial.println("Enter new baud or hit enter to continue using previous baud");

uint32_t new_baud = 0;
int ch;
while ((ch = Serial.read()) != '\n') {
if ((ch >= '0') && (ch <= '9'))
new_baud = new_baud * 10 + ( ch - '0');
}
if (new_baud && (new_baud != current_baud)) {
current_baud = new_baud;
Serial1.end();
Serial2.end();
Serial3.end();
Serial1.begin(current_baud);
Serial2.begin(current_baud);
Serial3.begin(current_baud);
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
Serial4.end();
Serial5.end();
Serial6.end();
Serial4.begin(current_baud);
Serial5.begin(current_baud);
Serial6.begin(current_baud);
#endif

}
}

void serialEvent1() {
uint8_t buffer[80];
uint8_t cb = min (min((int)sizeof(buffer), Serial1.available()), Serial.availableForWrite());
Serial1.readBytes(buffer, cb);
Serial.write(buffer, cb);
}

void serialEvent2() {
uint8_t buffer[80];
uint8_t cb = min (min((int)sizeof(buffer), Serial2.available()), Serial2.availableForWrite());
Serial2.readBytes(buffer, cb);
Serial2.write(buffer, cb);
}
void serialEvent3() {
uint8_t buffer[80];
uint8_t cb = min (min((int)sizeof(buffer), Serial3.available()), Serial3.availableForWrite());
Serial3.readBytes(buffer, cb);
Serial3.write(buffer, cb);
}
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
void serialEvent4() {
uint8_t buffer[80];
uint8_t cb = min (min((int)sizeof(buffer), Serial4.available()), Serial4.availableForWrite());
Serial4.readBytes(buffer, cb);
Serial4.write(buffer, cb);

}
void serialEvent5() {
uint8_t buffer[80];
uint8_t cb = min (min((int)sizeof(buffer), Serial5.available()), Serial5.availableForWrite());
Serial5.readBytes(buffer, cb);
Serial5.write(buffer, cb);
}
void serialEvent6() {
uint8_t buffer[80];
uint8_t cb = min (min((int)sizeof(buffer), Serial6.available()), Serial6.availableForWrite());
Serial6.readBytes(buffer, cb);
Serial6.write(buffer, cb);

}
#endif

Again the code does one Serial1.println at the beginning of loop, and then I have jumpers from Serial1->Serial2->Serial3->...->Serial6->Serial1->(writes data to )Serial I verified that the data looks correct. I also checked that the baud rates were correct...

In this test I put a set of digitalWriteFast calls around the starting println call which outputs something like 126 bytes. Without adding storage this write would wait for space to be available in the output queue to get the last bytes into it.... I then added the buffer calls and the write completes at about the time the first or second character is actually output.

Currently the main RX/TX buffers and sizes are passed into the Serial objects when they are created as to allow different sizes for each one, like before. The code would probably be slightly faster if we had one fixed size for all RX and likewise for TX, in which case the buffer could be part of the class, and then the code again compare index versus a constant instead of an instance variable, like is done in peek:

int HardwareSerial::peek(void)
{
uint32_t head, tail;

head = rx_buffer_head_;
tail = rx_buffer_tail_;
if (head == tail) return -1;
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < rx_buffer_size_) {
return rx_buffer_[tail];
} else {
return rx_buffer_storage_[tail-rx_buffer_size_];
}
}


Edit: So far I have done testing on T3.6, 3.5 and TLC... Still need to run it on T3.2 and maybe 3.0

Edit2: I have now also tested on T3.2 and T3.0 which required a fix.

@mjs513 - Yes you can simply copy in the new files into your arduino installation directory, which in the case mine is at: D:\arduino-1.8.3\hardware\teensy\avr\cores\teensy3
I am actually doing all of the editing there and then I copy the changed files back into my github cores project directory.
You currently need my NHardwareSerial.(h cpp) files as well as the HardwareSerial.* files and Serial.* files.

Once I am happy and if Paul likes some of this, I will probably remove those older files and rename mine to HardwareSerial.*... But have it such that hopefully you can simply redefine one #define in the current HardwareSerial.h file and build it to use existing released code, else use the new stuff...

defragster
08-05-2017, 06:52 AM
Paul: Saw a TeensyLoader 'file too large' warning trying to upload FrankB's Teensy64 HEX. It is a simple thing - TeensyLoader doesn't know the active MCU because it plugged in running - but complains on loading anyhow - perhaps based on last Teensy seen? Not critical if you follow through - but some folks seeing the RED FLASH of DOOM - might be put off.

I said OPEN got TOO LARGE then hit the Button and it actually talked to the Teensy and then revised its GOOD estimate – and gave the same 32% then when I said OPEN again. Here is the SPEW I got before actually flashing:
00:17:19.895: Open File event
00:18:07.564: File "c64.ino.3Aug.hex". 333472 bytes, 127% used
00:18:07.564: File contains data beyond chip size, yikes!
00:18:13.763: Verbose Info event
00:18:44.229: Device came online, code_size = 1048576
00:18:44.237: Board is: Teensy 3.6 (MK66FX1M0), version 1.03
00:18:44.316: File "c64.ino.3Aug.hex". 333472 bytes, 32% used
00:18:44.321: set background IMG_ONLINE
00:18:44.473: HID/win32: HidD_GetPreparsedData ok, device still online :-)
00:19:05.016: Open File event
00:19:08.004: File "c64.ino.3Aug.hex". 333472 bytes, 32% used

Frank B
08-05-2017, 10:23 AM
Paul, any chance you could add a "MTP + Serial" usb mode to the next beta ?
I'd happy to test it.. and I can add it to my current project.

https://forum.pjrc.com/threads/44569-Switching-USB-device-type-in-software?p=145192&viewfull=1#post145192

EDIT: oops... there is no code in the library?
usb_mtp.c :


void usb_mtp_update(void)
{
serial_print("test\n");

// TODO: a lot of work here....



}


What do I have to add to be able to test it ? Is there an example anywhere ?





(https://forum.pjrc.com/threads/44569-Switching-USB-device-type-in-software?p=145192&viewfull=1#post145192)

mjs513
08-12-2017, 08:23 PM
@KurtE Took me awhile to get to this (working another project) but I just downloaded your unified Serial branch and gave your example in your last post a shot but didn't get the string you pass to Serial1 output to serial at the end. It does ask me to change baudrates and returns and confirms it. I did notice that you changed the lib around a bit. Does the sketch above still apply?

EDIT: My issue here. Forgot I didn't solder backside pins on so I didn't have a Serial. That's what I get for assuming. Had another issue. For some reason Rx1 was not working (didn't receive anything) so I used setRX(27) for the T3.5 and reran the your sketch and everything worked as advertised. :) I will use this branch in the future. Sorry for the confusion.

Mike

KurtE
08-13-2017, 03:31 PM
Thanks Mike,

You are saying that doing Serial1.setRX(1) did not work? That would be expected. Pin 1 is TX pin for Serial1, Pin 0 is default RX pin for Serial1

mjs513
08-13-2017, 05:00 PM
No. After my first failure I did a serial pass through test on Serial1 by connecting pin 0 and 1 by transmitting a by Serial1.write and tried reading it back on Serial1 and it failed. All other Serial ports read, except 6 of course since it wasn't connected to begin with. To get around it I set Serail1.setRx(27) and ran the same test and it passed. In your example you had the following lines for T356:

#ifdef T356_ALTPINS
Serial.println("Set Alt pins for T3.5/3.6");
Serial1.setRX(21);
Serial1.setTX(5);

I commented out setTX of course since pin1 for TX seemed to work fine (must have a bad connection some place on my breakout board), but anyway, pin 21 for the T35 didn't work so I checked the card and it showed the alternate pin for the T35/6 on pin 27 not 21. 21 didn't work for me for some reason = again have to check the connection before I say anything else.

Mike

KurtE
08-13-2017, 08:05 PM
Thanks Mike,
I will check up on some of these pins on some of my boards and make sure they work... It is always possible I screwed up a table of which pins are valid and the proper MUX setting...

KurtE
08-13-2017, 11:08 PM
I tried some of the different pins on a T3.6 and so far the Serial1 ones work:
Simple Test program:

#define XSERIAL Serial1
#define TXPIN 26 //5
#define RXPIN 27 //21
void setup() {
// put your setup code here, to run once:
while (!Serial && (millis() < 3000)) ;
Serial.begin(9600);

#ifdef TXPIN
XSERIAL.setTX(TXPIN);
#endif

#ifdef RXPIN
XSERIAL.setRX(RXPIN);
#endif

XSERIAL.begin(115200);

}
uint32_t last_output;

void loop() {
// put your main code here, to run repeatedly:
if ((millis() - last_output) >= 1000) {
XSERIAL.println("Test String");
last_output = millis();
}

int ch;
while ((ch = XSERIAL.read()) != -1)
Serial.write(ch);

}
I tried it with defines for RX and TX not set so 0-1 worked, then tried 5-21, and tried 26-27.

mjs513
08-13-2017, 11:14 PM
KurtE. I am sure it was my set up - may have a bad solder joint based on the continuity checks. Not sure 1 and 21 didn't work though. Will be checking tonight. Working my new rover right now.

EDIT: Must have been me last night and getting wires crossed but I did test your combos as well as rx=21 and tx =1 and it all worked. I still have a problem with rx on pin 0 but that is me - 100% sure on that one.

PaulStoffregen
08-18-2017, 01:25 PM
I would recommend TeensyThreads as well as NeoGPS.

I'm willing to include it, if it's open source with MIT or a MIT-like license. I opened an issue to ask...

https://github.com/ftrias/TeensyThreads/issues/3



NeoGPS is already downloadable the lib manager in Arduino IDE.


Maybe best to just use the lib manager?

mjs513
08-18-2017, 04:18 PM
Thanks Paul. I saw that fritas added the MIT license and you are probably right since the lib manager already takes care of NeoGPS.

Respectfully
Mike