1 // Copyright 2019 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #include <Arduino.h> 16 17 #include <cinttypes> 18 #include <cstdint> 19 20 #include "pw_preprocessor/compiler.h" 21 #include "pw_sys_io/sys_io.h" 22 pw_sys_io_arduino_Init()23extern "C" void pw_sys_io_arduino_Init() { 24 // On Linux serial output may still not work if the serial monitor is not 25 // connected to ttyACM0 quickly enough after reset. This check forces the 26 // device to wait for a serial connection for up to 3 seconds. 27 // 28 // If you get no serial output, try to connect minicom on the port and then 29 // reboot the chip (reset button). If using Python miniterm, start it right 30 // after pushing the reset switch. 31 while (!Serial && millis() < 3000) { 32 } 33 Serial.begin(115200); 34 } 35 36 namespace pw::sys_io { 37 38 // Wait for a byte to read on USART1. This blocks until a byte is read. This is 39 // extremely inefficient as it requires the target to burn CPU cycles polling to 40 // see if a byte is ready yet. 41 ReadByte(std::byte * dest)42Status ReadByte(std::byte* dest) { 43 while (true) { 44 if (TryReadByte(dest).ok()) { 45 return OkStatus(); 46 } 47 } 48 } 49 TryReadByte(std::byte * dest)50Status TryReadByte(std::byte* dest) { 51 if (!Serial.available()) { 52 return Status::Unavailable(); 53 } 54 *dest = static_cast<std::byte>(Serial.read()); 55 return OkStatus(); 56 } 57 58 // Send a byte over the default Arduino Serial port. WriteByte(std::byte b)59Status WriteByte(std::byte b) { 60 // Serial.write() will block until data can be written. 61 Serial.write((uint8_t)b); 62 return OkStatus(); 63 } 64 65 // Writes a string using pw::sys_io, and add newline characters at the end. WriteLine(std::string_view s)66StatusWithSize WriteLine(std::string_view s) { 67 size_t chars_written = 0; 68 StatusWithSize result = WriteBytes(as_bytes(span(s))); 69 if (!result.ok()) { 70 return result; 71 } 72 chars_written += result.size(); 73 74 // Write trailing newline. 75 result = WriteBytes(as_bytes(span("\r\n", 2))); 76 chars_written += result.size(); 77 78 return StatusWithSize(result.status(), chars_written); 79 } 80 81 } // namespace pw::sys_io 82