I just started playing with a new GIGA, and thought I would start off simple and try out some of the basic things, like GPIO, UARTS, SPI and the like.
One of the Serial tests, I like to try is to daisy chain one serial port to the next to see how well they work together. Which I expected that would work as the cheat sheet shows:
This not only means that you may print different values to different ports and monitor them separately, which is useful enough in and of itself, but that you may also communicate with 4 different serial enabled devices simultaneously.
Here is a modified version of one of my normal tests, that I updated from the UNO R4 version, that I have/had working with an update to the UART code (PR pending)
l2 TX -> Serial3 RX, Serial3 TX -> Serial4 RX....
#define SPD 115200
int loop_count = 0;
#define BUFFER_SIZE 80
class BufferInfoClass {
public:
BufferInfoClass() {
clear();
}
char buffer[BUFFER_SIZE];
uint8_t cb_buffer;
uint8_t cb_copy[BUFFER_SIZE];
uint8_t cb_copy_cnt;
void clear() {
cb_buffer = 0;
cb_copy_cnt = 0;
}
};
BufferInfoClass buffers[5];
uint32_t millis_last_input = 0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
while (!Serial && millis() < 4000)
;
Serial.begin(115200);
delay(800);
Serial.println("Test all Serials");
Serial.print("Baud rate: ");
Serial.println(SPD, DEC);
Serial1.begin(SPD);
Serial2.begin(SPD);
Serial3.begin(SPD);
Serial4.begin(SPD);
}
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
void CopyFromTo(Stream &SerialF, Stream &SerialT, uint8_t buffer_index) {
int available;
int available_for_write;
int cb;
BufferInfoClass *buf = &buffers[buffer_index];
if ((available = SerialF.available()) != 0) {
Serial.print(buffer_index, DEC);
Serial.print(":Avail: ");
Serial.print(available, DEC);
available_for_write = SerialT.availableForWrite();
Serial.print(" ");
Serial.println(available_for_write, DEC);
cb = MIN(MIN(available, available_for_write), BUFFER_SIZE);
if (cb) {
SerialF.readBytes(&buf->buffer[buf->cb_buffer], cb);
SerialT.write(&buf->buffer[buf->cb_buffer], cb);
buf->cb_buffer += cb;
buf->cb_copy[buf->cb_copy_cnt] = cb;
buf->cb_copy_cnt++;
millis_last_input = millis();
}
}
}
void memory_dump(const char *pb, uint8_t cb) {
const char *pbA = pb;
uint8_t cbA = cb;
Serial.print("\t");
for (uint8_t i = 0; i < cb; i++) {
if (*pb < 0x10) Serial.write('0');
Serial.print(*pb, HEX);
Serial.print(" ");
pb++;
}
Serial.print("\n\t ");
for (uint8_t i = 0; i < cbA; i++) {
if (*pbA >= ' ') Serial.write(*pbA);
else Serial.write(' ');
Serial.print(" ");
pbA++;
}
Serial.println();
}
void print_buffer_header(uint8_t index) {
BufferInfoClass *buf = &buffers[index];
Serial.print(" ");
Serial.print(buf->cb_buffer, DEC);
Serial.print(" (");
for (uint8_t i = 0; i < buf->cb_copy_cnt; i++) {
if (i != 0) Serial.print(",");
Serial.print(buf->cb_copy[i], DEC);
}
Serial.print(")");
}
void CompareBuffers(uint8_t index1, uint8_t index2) {
if (buffers[index1].cb_buffer == buffers[index2].cb_buffer) {
if (memcmp(buffers[index1].buffer, buffers[index2].buffer, buffers[index1].cb_buffer) == 0) {
Serial.println(" ** Match **");
return;
} else {
Serial.println(" ** different **");
}
} else {
Serial.println(" ** counts different **");
}
memory_dump(buffers[index1].buffer, buffers[index1].cb_buffer);
memory_dump(buffers[index2].buffer, buffers[index2].cb_buffer);
}
void loop() {
CopyFromTo(Serial, Serial1, 0);
CopyFromTo(Serial1, Serial, 1);
CopyFromTo(Serial2, Serial2, 2);
CopyFromTo(Serial3, Serial3, 3);
CopyFromTo(Serial4, Serial4, 4);
// now see if we should compare the data yet or not
if (buffers[0].cb_buffer && ((millis() - millis_last_input) > 100)) {
Serial.println("Check buffers: ");
print_buffer_header(0);
Serial.println();
for (uint8_t i = 1; i < 5; i++) {
print_buffer_header(i);
CompareBuffers(0, i);
}
for (uint8_t i = 0; i < 5; i++) buffers[i].clear();
}
digitalWrite(LED_BUILTIN, HIGH);
delayMicroseconds(100); // give time form things to propagate
digitalWrite(LED_BUILTIN, LOW);
}
I added some debug prints in the code, which confirmed what I expected.
The call Serial1.availableForWrite() will always return 0.
Digging some into the code base, I see that the Serial objects are using the
UnbufferedSerial class internally. I am not sure where the actual unbuffered write code is, as the UnbufferedSerial.h file shows the write methods as overwrite...
SerialX.flush() does not appear to work either:
That is my expectations is that it will not return, until the Serial transfer has been completed.
Simple sketch:
void setup() {
Serial1.begin(115200);
pinMode(2, OUTPUT);
}
void loop() {
digitalWrite(2, HIGH);
Serial1.print("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
Serial1.flush();
digitalWrite(2, LOW);
delay(1);
digitalWrite(2, HIGH);
for (char ch = 'a'; ch <= 'z'; ch++) Serial1.write(ch);
Serial1.flush();
digitalWrite(2, LOW);
delay(1000);
}
My expectations are that the pin 2 should not go low, until the last bits are sent.
Now back to more playing




