Arduino Pigweed Target

- New arduino pigweed target that uses gn build args to set arduino
  target board and specific build options.
- Add arduinobuilder.py (includes core installer for Linux/Mac/Windows)
- Working builds for Teensy 4.1, 4.0, 3.6, 3.5, 3.2

Change-Id: Ib751b5f92352ac3ec7fa649f444dc13efd080d12
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/18001
Commit-Queue: Anthony DiGirolamo <tonymd@google.com>
Reviewed-by: Armando Montanez <amontanez@google.com>
diff --git a/pw_sys_io_arduino/BUILD b/pw_sys_io_arduino/BUILD
new file mode 100644
index 0000000..3735a73
--- /dev/null
+++ b/pw_sys_io_arduino/BUILD
@@ -0,0 +1,33 @@
+# Copyright 2019 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+load(
+    "//pw_build:pigweed.bzl",
+    "pw_cc_library",
+)
+
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])  # Apache License 2.0
+
+pw_cc_library(
+    name = "pw_sys_io_arduino",
+    srcs = ["sys_io_arduino.cc"],
+    hdrs = ["public/pw_sys_io_arduino/init.h"],
+    deps = [
+        "//pw_boot_armv7m",
+        "//pw_preprocessor",
+        "//pw_sys_io",
+    ]
+)
diff --git a/pw_sys_io_arduino/BUILD.gn b/pw_sys_io_arduino/BUILD.gn
new file mode 100644
index 0000000..159d7d2
--- /dev/null
+++ b/pw_sys_io_arduino/BUILD.gn
@@ -0,0 +1,42 @@
+# Copyright 2019 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+# gn-format disable
+import("//build_overrides/pigweed.gni")
+
+import("$dir_pw_arduino_build/arduino.gni")
+import("$dir_pw_build/target_types.gni")
+import("$dir_pw_docgen/docs.gni")
+config("default_config") {
+  include_dirs = [ "public" ]
+}
+
+if (dir_pw_third_party_arduino != "") {
+  pw_source_set("pw_sys_io_arduino") {
+    remove_configs = [ "$dir_pw_build:strict_warnings" ]
+    public_configs = [ ":default_config" ]
+    public = [ "public/pw_sys_io_arduino/init.h" ]
+    public_deps = [ "$dir_pw_preprocessor" ]
+    deps = [
+      "$dir_pw_sys_io:default_putget_bytes",
+      "$dir_pw_sys_io:facade",
+      "$dir_pw_third_party_arduino:arduino_core_sources",
+    ]
+    sources = [ "sys_io_arduino.cc" ]
+  }
+}
+
+pw_doc_group("docs") {
+  sources = [ "docs.rst" ]
+}
diff --git a/pw_sys_io_arduino/docs.rst b/pw_sys_io_arduino/docs.rst
new file mode 100644
index 0000000..3c3743c
--- /dev/null
+++ b/pw_sys_io_arduino/docs.rst
@@ -0,0 +1,12 @@
+.. _chapter-pw-sys-io-baremetal-arduino:
+
+.. default-domain:: cpp
+
+.. highlight:: sh
+
+-----------------
+pw_sys_io_arduino
+-----------------
+
+``pw_sys_io_arduino`` implements the ``pw_sys_io`` facade over
+`Arduino's Serial interface <https://www.arduino.cc/reference/en/language/functions/communication/serial/>`_.
diff --git a/pw_sys_io_arduino/public/pw_sys_io_arduino/init.h b/pw_sys_io_arduino/public/pw_sys_io_arduino/init.h
new file mode 100644
index 0000000..d4262c5
--- /dev/null
+++ b/pw_sys_io_arduino/public/pw_sys_io_arduino/init.h
@@ -0,0 +1,23 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+#pragma once
+
+#include "pw_preprocessor/util.h"
+
+PW_EXTERN_C_START
+
+// The actual implement of PreMainInit() in sys_io_BACKEND.
+void pw_sys_io_Init();
+
+PW_EXTERN_C_END
diff --git a/pw_sys_io_arduino/sys_io_arduino.cc b/pw_sys_io_arduino/sys_io_arduino.cc
new file mode 100644
index 0000000..b63e21f
--- /dev/null
+++ b/pw_sys_io_arduino/sys_io_arduino.cc
@@ -0,0 +1,75 @@
+// Copyright 2019 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include <Arduino.h>
+
+#include <cinttypes>
+#include <cstdint>
+
+#include "pw_preprocessor/compiler.h"
+#include "pw_sys_io/sys_io.h"
+
+extern "C" void pw_sys_io_Init() {
+  Serial.begin(115200);
+  // Wait for serial port to be available
+  while (!Serial) {
+  }
+}
+
+namespace pw::sys_io {
+
+// Wait for a byte to read on USART1. This blocks until a byte is read. This is
+// extremely inefficient as it requires the target to burn CPU cycles polling to
+// see if a byte is ready yet.
+
+Status ReadByte(std::byte* dest) {
+  while (true) {
+    if (Serial.available()) {
+      *dest = static_cast<std::byte>(Serial.read());
+      break;
+    }
+  }
+  return Status::OK;
+}
+
+// Send a byte over USART1. Since this blocks on every byte, it's rather
+// inefficient. At the default baud rate of 115200, one byte blocks the CPU for
+// ~87 micro seconds. This means it takes only 10 bytes to block the CPU for
+// 1ms!
+Status WriteByte(std::byte b) {
+  // Wait for TX buffer to be empty. When the buffer is empty, we can write
+  // a value to be dumped out of UART.
+  while (Serial.availableForWrite() < 1) {
+  }
+  Serial.write((uint8_t)b);
+  return Status::OK;
+}
+
+// Writes a string using pw::sys_io, and add newline characters at the end.
+StatusWithSize WriteLine(const std::string_view& s) {
+  size_t chars_written = 0;
+  StatusWithSize result = WriteBytes(std::as_bytes(std::span(s)));
+  if (!result.ok()) {
+    return result;
+  }
+  chars_written += result.size();
+
+  // Write trailing newline.
+  result = WriteBytes(std::as_bytes(std::span("\r\n", 2)));
+  chars_written += result.size();
+
+  return StatusWithSize(result.status(), chars_written);
+}
+
+}  // namespace pw::sys_io