-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsystem_setup.cpp
168 lines (140 loc) · 5.61 KB
/
system_setup.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.
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
http://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 "tensorflow/lite/micro/system_setup.h"
#include <limits>
#include <cstdarg>
#include <cstdint>
#include <cstring>
#include "tensorflow/lite/micro/debug_log.h"
// The preprocessor definition format in Arduino IDE is:
// ARDUINO_<PROCESSOR-DESCRIPTOR>_<BOARDNAME>
// The <PROCESSOR-DESCRIPTOR>_<BOARDNAME> for the installed boards
// can be listed by running in the base Arduino directory, the following command:
// grep board= `find . -name boards.txt` | cut -f2 -d= | sort -u
// E.g. ARDUINO_NANO_RP2040_CONNECT or ARDUINO_SPARKFUN_MICROMOD_RP2040
#if defined(ARDUINO) && !defined(ARDUINO_SPARKFUN_MICROMOD_RP2040) && !defined(ARDUINO_NANO_RP2040_CONNECT)
#define ARDUINO_EXCLUDE_CODE
#endif // defined(ARDUINO) && !defined(ARDUINO_SPARKFUN_MICROMOD_RP2040) && !defined(ARDUINO_NANO_RP2040_CONNECT)
#ifndef ARDUINO_EXCLUDE_CODE
#include <Arduino.h>
#include <api/RingBuffer.h>
// The Arduino DUE uses a different object for the default serial port shown in
// the monitor than most other models, so make sure we pick the right one. See
// https://github.com/arduino/Arduino/issues/3088#issuecomment-406655244
#if defined(__SAM3X8E__)
#define DEBUG_SERIAL_OBJECT (SerialUSB)
#else
#define DEBUG_SERIAL_OBJECT (Serial)
#endif
#ifndef TF_LITE_STRIP_ERROR_STRINGS
#include <stdio.h>
#include "pico/stdlib.h"
#endif // TF_LITE_STRIP_ERROR_STRINGS
namespace tflite {
void InitializeTarget(const int baud) {
#ifndef TF_LITE_STRIP_ERROR_STRINGS
// Not needed. See https://github.com/earlephilhower/arduino-pico/issues/1433#issuecomment-1546783109%22
// stdio_init_all();
DEBUG_SERIAL_OBJECT.begin(baud);
#endif // TF_LITE_STRIP_ERROR_STRINGS
}
} // namespace tflite
extern "C" void DebugLog(const char* format, va_list args) {
#ifndef TF_LITE_STRIP_ERROR_STRINGS
// Reusing TF_LITE_STRIP_ERROR_STRINGS to disable DebugLog completely to get
// maximum reduction in binary size. This is because we have DebugLog calls
// via TF_LITE_CHECK that are not stubbed out by TF_LITE_REPORT_ERROR.
//vfprintf(stderr, format, args);
DEBUG_SERIAL_OBJECT.printf(format, args);
#endif
}
#ifndef TF_LITE_STRIP_ERROR_STRINGS
// Only called from MicroVsnprintf (micro_log.h)
int DebugVsnprintf(char* buffer, size_t buf_size, const char* format,
va_list vlist) {
return vsnprintf(buffer, buf_size, format, vlist);
}
#endif
namespace test_over_serial {
// Change baud rate on default serial port
// void SerialChangeBaudRate(const int baud) {
// DEBUG_SERIAL_OBJECT.begin(baud);
// ulong start_time = millis();
// while (!DEBUG_SERIAL_OBJECT) {
// // allow for Arduino IDE Serial Monitor synchronization
// if (millis() - start_time > tflite::kSerialMaxInitWait) {
// break;
// }
// }
// }
// The RingBufferN class, which is used for buffering incoming serial data, is defined in the ArduinoCore-API.
class _RingBuffer : public RingBufferN<kSerialMaxInputLength + 1> {
public:
bool need_reset = false;
};
static _RingBuffer _ring_buffer;
// SerialReadLine
// Read a set of ASCII characters from the default
// serial port. Data is read up to the first newline ('\\n') character.
// This function uses an internal buffer which is automatically reset.
// The buffer will not contain the newline character.
// The buffer will be zero ('\\0') terminated.
// The <timeout> value is in milliseconds. Any negative value means that
// the wait for data will be forever.
// Returns std::pair<size_t, char*>.
// The first pair element is the number of characters in buffer not including
// the newline character or zero terminator.
// Returns {0, NULL} if the timeout occurs.
std::pair<size_t, char*> SerialReadLine(int timeout) {
if (_ring_buffer.need_reset) {
_ring_buffer.need_reset = false;
_ring_buffer.clear();
}
ulong start_time = millis();
while (true) {
int value = DEBUG_SERIAL_OBJECT.read();
if (value >= 0) {
if (value == '\n') {
// read a newline character
_ring_buffer.store_char('\0');
_ring_buffer.need_reset = true;
break;
} else {
// read other character
_ring_buffer.store_char(value);
if (_ring_buffer.availableForStore() == 1) {
// buffer is full
_ring_buffer.store_char('\0');
_ring_buffer.need_reset = true;
break;
}
}
}
if (timeout < 0) {
// wait forever
continue;
} else if (millis() - start_time >= static_cast<ulong>(timeout)) {
// timeout
return std::make_pair(0UL, reinterpret_cast<char*>(NULL));
}
}
return std::make_pair(static_cast<size_t>(_ring_buffer.available() - 1),
reinterpret_cast<char*>(_ring_buffer._aucBuffer));
}
// SerialWrite
// Write the ASCII characters in <buffer> to the default serial port.
// The <buffer> must be zero terminated.
void SerialWrite(const char* buffer) { DEBUG_SERIAL_OBJECT.print(buffer); }
} // namespace test_over_serial
#else
#error "Unsupported board! Not a RP2040 based board selected!"
#endif // ARDUINO_EXCLUDE_CODE