Merge pull request #24182 from snease-abq:master

PiperOrigin-RevId: 227080754
This commit is contained in:
TensorFlower Gardener 2018-12-27 17:56:41 -08:00
commit 770b26ea08
33 changed files with 1738 additions and 221 deletions

View File

@ -187,5 +187,53 @@ You should see the following log with the magic string `~~~ALL TEST PASSED~~~`:
02:25:22.4253 [DEBUG] uart0: [+0.16ms host +0s virt 0.28s virt from start] Progam has exited with code:0x00000000
```
## Building for Apollo3
Follow these steps to get the pushbutton yes/no example working on Apollo 3:
1. Make sure to run the "Getting Started" section before performing the
following steps
2. Download Apollo3-SDK-2018.08.13 and place in
`tensorflow/lite/experimental/micro/tools/make/downloads`. This is not yet
publicly released, but you can contact ashah@ambiqmicro.com to request a
copy.
3. Compile the project with the following command: make -f
tensorflow/lite/experimental/micro/tools/make/Makefile TARGET=apollo3evb
pushbutton_cmsis_speech_test_bin
4. Install [Segger JLink tools](https://www.segger.com/downloads/jlink/)
5. Connect the Apollo3 EVB (with mic shield) to the computer and power it on
6. Start the GDB server in a new terminal with the following command:
JLinkGDBServer -select USB -device AMA3B1KK-KBR -endian little -if SWD
-speed 1000 -noir -noLocalhostOnly
1. The command has run successfully if you see the message "Waiting for GDB
connection"
7. Back in the original terminal, run the program via the debugger
1. Navigate to
tensorflow/lite/experimental/micro/examples/micro_speech/apollo3
2. Start gdb by entering the following command: arm-none-eabi-gdb
3. Run the command script by entering the following command: source
pushbutton_cmsis_scores.cmd. This script does the following:
1. Load the binary created in step 6
2. Set a breakpoint after inference scores have been computed
3. Tell the debugger what variables should be printed out at this
breakpoint
4. Begin program execution
5. Press Ctrl+c to exit
4. Press BTN2. An LED will flash for 1 second. Speak your utterance during
this one second
5. The debugger will print out four numbers. They are the probabilites for
1) no speech, 2) unknown speech, 3) yes, 4) no
6. The EVB LEDs will indicate detection.
1. LED0 (rightmost LED) - ON when capturing 1sec of audio
2. LED1 - ON when detecting silence
3. LED2 - ON when detecting UNKNOWN utterance
4. LED3 - ON when detecting YES utterance
5. LED4 (leftmost LED) - ON when detecting NO utterance
### Additional Apollo3 Instructions
To flash a part with JFlash Lite, do the following: 1. At the command line:
JFlashLiteExe 2. Device = AMA3B1KK-KBR 3. Interface = SWD at 1000 kHz 4. Data
file =
tensorflow/lite/experimental/micro/tools/make/gen/apollo3evb_cortex-m4/bin/pushbutton_cmsis_speech_test.bin
5. Prog Addr = 0x0000C000

View File

@ -0,0 +1 @@
*.wav

View File

@ -0,0 +1,23 @@
# Description of files
* **create_constants.py**: Python file used to create hanning.cc, hanning.h,
sin_1k.cc, and sin_1k.h
* **hanning.cc**: Precomputed
[Hann window](https://en.wikipedia.org/wiki/Hann_function) for use in the
preprocessor. This file is created in ../create_constants.py
* **hanning.h**: Header file fro hanning.cc
* **preprocessor.cc**: CMSIS version of the preprocessor
* **sin_1k.cc**: A 1 kHZ sinusoid used for comparing the CMSIS preprocessor
with the Micro-Lite fixed_point preprocessor
* **sin_1k.h**: Header file for sin_1k.cc
# Description of externally downloaded files in ../CMSIS_ext
* **arm_cmplx_mag_squared_q10p6.c**: Modified version of the ARM CMSIS
function
[arm_cmplx_mag_squared.c](http://arm-software.github.io/CMSIS_5/DSP/html/group__cmplx__mag__squared.html#ga45537f576102d960d467eb722b8431f2).
The modification is that we have changed the amount of right-shift to make
sure our data is in the correct range. We redistribute because the original
content was created with the Apache 2.0 license.
* **arm_cmplx_mag_squared_q10p6.h**: Header file for
arm_cmplx_mag_squared_q10p6.c

View File

@ -0,0 +1,75 @@
# Copyright 2018 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.
# ==============================================================================
"""Outputs tables used for fast calculations at runtime."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
# import soundfile as sf
import numpy as np
def to_cc(x, varname, directory='', scale_factor=1):
"""Writes table values to a C++ source file."""
x = (x / np.max(np.abs(x))) * 32768 * scale_factor
x[x > 32767] = 32767
x[x < -32768] = -32768
x = x.astype(int)
x = [str(v) if i % 10 != 0 else '\n ' + str(v) for i, v in enumerate(x)]
cmsis_path = 'tensorflow/lite/experimental/micro/examples/micro_speech/CMSIS'
xstr = '#include "{}/{}.h"\n\n'.format(cmsis_path, varname)
xstr += 'const int g_{}_size = {};\n'.format(varname, len(x))
xstr += 'const int16_t g_{}[{}] = {{{}}};\n'.format(varname, len(x),
', '.join(x))
with open(directory + varname + '.cc', 'w') as f:
f.write(xstr)
def to_h(_, varname, directory=''):
"""Writes a header file for the table values."""
tf_prepend = 'TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_MICRO_SPEECH_'
xstr = '#ifndef {}{}_H_\n'.format(tf_prepend, varname.upper())
xstr += '#define {}{}_H_\n\n'.format(tf_prepend, varname.upper())
xstr += '#include <cstdint>\n\n'
xstr += 'extern const int g_{}_size;\n'.format(varname)
xstr += 'extern const int16_t g_{}[];\n\n'.format(varname)
xstr += '#endif'
with open(directory + varname + '.h', 'w') as f:
f.write(xstr)
# x = sf.read('yes_f2e59fea_nohash_1.wav')[0]
# to_cc(x, 'yes_waveform')
# to_h(x, 'yes_waveform')
#
# x = sf.read('no_f9643d42_nohash_4.wav')[0]
# to_cc(x, 'no_waveform')
# to_h(x, 'no_waveform')
# 30ms of data @ 16 kHz = 480 samples
hann = np.hanning(int(16000 * 0.03)) # Window 30ms of data
to_cc(hann, 'hanning', directory='./')
to_h(hann, 'hanning', directory='./')
t = np.arange(16000. * 0.03) / 16000.
sin1k = np.sin(
2 * np.pi * 1000 *
t) # Factor of 10 because micro preprocessing overflows otherwise
to_cc(sin1k, 'sin_1k', directory='./', scale_factor=0.1)
to_h(sin1k, 'sin_1k', directory='./')

View File

@ -0,0 +1,63 @@
/* Copyright 2018 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/experimental/micro/examples/micro_speech/CMSIS/hanning.h"
const int g_hanning_size = 480;
const int16_t g_hanning[480] = {
0, 1, 5, 12, 22, 35, 50, 69, 90, 114, 140,
170, 202, 237, 275, 316, 359, 405, 454, 506, 560, 617,
677, 740, 805, 873, 943, 1016, 1092, 1171, 1252, 1336, 1422,
1511, 1602, 1696, 1793, 1892, 1993, 2097, 2204, 2312, 2424, 2537,
2653, 2772, 2893, 3016, 3141, 3269, 3399, 3531, 3665, 3802, 3941,
4082, 4225, 4370, 4517, 4666, 4817, 4971, 5126, 5283, 5442, 5603,
5765, 5930, 6096, 6265, 6435, 6606, 6779, 6954, 7131, 7309, 7489,
7670, 7853, 8037, 8223, 8410, 8598, 8788, 8979, 9171, 9365, 9560,
9756, 9953, 10151, 10350, 10551, 10752, 10954, 11157, 11362, 11567, 11772,
11979, 12186, 12395, 12603, 12813, 13023, 13233, 13445, 13656, 13868, 14081,
14294, 14507, 14721, 14935, 15149, 15363, 15578, 15793, 16008, 16222, 16437,
16652, 16867, 17082, 17297, 17511, 17725, 17939, 18153, 18367, 18580, 18793,
19005, 19217, 19428, 19639, 19850, 20059, 20269, 20477, 20685, 20892, 21098,
21303, 21508, 21712, 21914, 22116, 22317, 22517, 22716, 22913, 23110, 23305,
23499, 23692, 23884, 24075, 24264, 24451, 24638, 24823, 25006, 25188, 25369,
25548, 25725, 25901, 26075, 26247, 26418, 26587, 26754, 26920, 27083, 27245,
27405, 27563, 27719, 27874, 28026, 28176, 28324, 28470, 28614, 28756, 28896,
29034, 29169, 29303, 29434, 29563, 29689, 29813, 29935, 30055, 30172, 30287,
30400, 30510, 30617, 30723, 30825, 30926, 31023, 31119, 31211, 31301, 31389,
31474, 31556, 31636, 31713, 31788, 31860, 31929, 31996, 32059, 32121, 32179,
32235, 32288, 32338, 32386, 32430, 32472, 32512, 32548, 32582, 32613, 32641,
32666, 32689, 32708, 32725, 32739, 32751, 32759, 32765, 32767, 32767, 32765,
32759, 32751, 32739, 32725, 32708, 32689, 32666, 32641, 32613, 32582, 32548,
32512, 32472, 32430, 32386, 32338, 32288, 32235, 32179, 32121, 32059, 31996,
31929, 31860, 31788, 31713, 31636, 31556, 31474, 31389, 31301, 31211, 31119,
31023, 30926, 30825, 30723, 30617, 30510, 30400, 30287, 30172, 30055, 29935,
29813, 29689, 29563, 29434, 29303, 29169, 29034, 28896, 28756, 28614, 28470,
28324, 28176, 28026, 27874, 27719, 27563, 27405, 27245, 27083, 26920, 26754,
26587, 26418, 26247, 26075, 25901, 25725, 25548, 25369, 25188, 25006, 24823,
24638, 24451, 24264, 24075, 23884, 23692, 23499, 23305, 23110, 22913, 22716,
22517, 22317, 22116, 21914, 21712, 21508, 21303, 21098, 20892, 20685, 20477,
20269, 20059, 19850, 19639, 19428, 19217, 19005, 18793, 18580, 18367, 18153,
17939, 17725, 17511, 17297, 17082, 16867, 16652, 16437, 16222, 16008, 15793,
15578, 15363, 15149, 14935, 14721, 14507, 14294, 14081, 13868, 13656, 13445,
13233, 13023, 12813, 12603, 12395, 12186, 11979, 11772, 11567, 11362, 11157,
10954, 10752, 10551, 10350, 10151, 9953, 9756, 9560, 9365, 9171, 8979,
8788, 8598, 8410, 8223, 8037, 7853, 7670, 7489, 7309, 7131, 6954,
6779, 6606, 6435, 6265, 6096, 5930, 5765, 5603, 5442, 5283, 5126,
4971, 4817, 4666, 4517, 4370, 4225, 4082, 3941, 3802, 3665, 3531,
3399, 3269, 3141, 3016, 2893, 2772, 2653, 2537, 2424, 2312, 2204,
2097, 1993, 1892, 1793, 1696, 1602, 1511, 1422, 1336, 1252, 1171,
1092, 1016, 943, 873, 805, 740, 677, 617, 560, 506, 454,
405, 359, 316, 275, 237, 202, 170, 140, 114, 90, 69,
50, 35, 22, 12, 5, 1, 0};

View File

@ -0,0 +1,24 @@
/* Copyright 2018 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.
==============================================================================*/
#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_MICRO_SPEECH_HANNING_H_
#define TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_MICRO_SPEECH_HANNING_H_
#include <cstdint>
extern const int g_hanning_size;
extern const int16_t g_hanning[];
#endif

View File

@ -0,0 +1,105 @@
/* Copyright 2018 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.
==============================================================================*/
extern "C" {
#define ARM_MATH_CM4
#define IFFT_FLAG_R 0
#define BIT_REVERSE_FLAG 1
#define FFT_SIZE 512
#define FFT_SIZE_DIV2 256
#include <arm_math.h>
#include "arm_cmplx_mag_squared_q10p6.h"
#include "tensorflow/lite/experimental/micro/examples/micro_speech/CMSIS/hanning.h"
}
#include "tensorflow/lite/experimental/micro/examples/micro_speech/preprocessor.h"
void quantize(q15_t* bufA, q15_t* bufB, uint8_t* output);
q15_t bufA[FFT_SIZE];
q15_t bufB[FFT_SIZE];
arm_rfft_instance_q15 S_arm_fft;
arm_status arm_math_status;
namespace {
// These constants allow us to allocate fixed-sized arrays on the stack for our
// working memory.
constexpr int kInputSize = 512;
constexpr int kAverageWindowSize = 6;
constexpr int kOutputSize =
((kInputSize / 2) + (kAverageWindowSize - 1)) / kAverageWindowSize;
} // namespace
TfLiteStatus Preprocess(tflite::ErrorReporter* error_reporter,
const int16_t* input, int input_size, int output_size,
uint8_t* output) {
if (input_size > kInputSize) {
error_reporter->Report("Input size %d larger than %d", input_size,
kInputSize);
return kTfLiteError;
}
if (output_size != kOutputSize) {
error_reporter->Report("Requested output size %d doesn't match %d",
output_size, kOutputSize);
return kTfLiteError;
}
// 30ms at 16 kHz = 480 samples
// We want to pad the rest of the 512-sample buffer with zeros
arm_mult_q15((q15_t*)input, g_hanning, bufB, 480);
int i;
for (i = 480; i < 512; i++) {
bufB[i] = 0;
}
// Should move init code outside of Preprocess() function
arm_math_status =
arm_rfft_init_q15(&S_arm_fft, FFT_SIZE, IFFT_FLAG_R, BIT_REVERSE_FLAG);
arm_rfft_q15(&S_arm_fft, bufB, bufA);
// The rfft function packs data as follows:
// {real[0], real[N/2], real[1], imag[1], ..., real[N/2-1], imag[N/2-1]}
// Below we pack as follows:
// {real[0], 0, real[1], imag[1], ..., real[N/2-1], imag[N/2-1, real[N/2], 0}
bufA[FFT_SIZE_DIV2] = bufA[1];
bufA[FFT_SIZE_DIV2 + 1] = 0;
bufA[1] = 0;
arm_cmplx_mag_squared_q10p6(bufA, bufB, FFT_SIZE_DIV2 + 1);
quantize(bufA, bufB, output);
return kTfLiteOk;
}
void quantize(q15_t* bufA, q15_t* bufB, uint8_t* output) {
int i;
for (i = 0; i < 42; i++) {
arm_mean_q15(bufB + 6 * i, 6, bufA + i);
}
arm_mean_q15(bufB + 252, 5, bufA + 42);
for (i = 0; i < 43; i++) {
output[i] = (uint8_t)(bufA[i] >> 5);
}
}
TfLiteStatus Preprocess_1sec(tflite::ErrorReporter* error_reporter,
const int16_t* input, uint8_t* output) {
int i;
for (i = 0; i < 49; i++) {
Preprocess(error_reporter, input + i * 320, 480, 43, output + i * 43);
}
return kTfLiteOk;
}

View File

@ -0,0 +1,63 @@
/* Copyright 2018 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/experimental/micro/examples/micro_speech/CMSIS/sin_1k.h"
const int g_sin_1k_size = 480;
const int16_t g_sin_1k[480] = {
0, 1253, 2317, 3027, 3276, 3027, 2317, 1253, 0, -1253, -2317,
-3027, -3276, -3027, -2317, -1253, 0, 1253, 2317, 3027, 3276, 3027,
2317, 1253, 0, -1253, -2317, -3027, -3276, -3027, -2317, -1253, 0,
1253, 2317, 3027, 3276, 3027, 2317, 1253, 0, -1253, -2317, -3027,
-3276, -3027, -2317, -1253, 0, 1253, 2317, 3027, 3276, 3027, 2317,
1253, 0, -1253, -2317, -3027, -3276, -3027, -2317, -1253, 0, 1253,
2317, 3027, 3276, 3027, 2317, 1253, 0, -1253, -2317, -3027, -3276,
-3027, -2317, -1253, 0, 1253, 2317, 3027, 3276, 3027, 2317, 1253,
0, -1253, -2317, -3027, -3276, -3027, -2317, -1253, 0, 1253, 2317,
3027, 3276, 3027, 2317, 1253, 0, -1253, -2317, -3027, -3276, -3027,
-2317, -1253, 0, 1253, 2317, 3027, 3276, 3027, 2317, 1253, 0,
-1253, -2317, -3027, -3276, -3027, -2317, -1253, 0, 1253, 2317, 3027,
3276, 3027, 2317, 1253, 0, -1253, -2317, -3027, -3276, -3027, -2317,
-1253, 0, 1253, 2317, 3027, 3276, 3027, 2317, 1253, 0, -1253,
-2317, -3027, -3276, -3027, -2317, -1253, 0, 1253, 2317, 3027, 3276,
3027, 2317, 1253, 0, -1253, -2317, -3027, -3276, -3027, -2317, -1253,
0, 1253, 2317, 3027, 3276, 3027, 2317, 1253, 0, -1253, -2317,
-3027, -3276, -3027, -2317, -1253, 0, 1253, 2317, 3027, 3276, 3027,
2317, 1253, 0, -1253, -2317, -3027, -3276, -3027, -2317, -1253, 0,
1253, 2317, 3027, 3276, 3027, 2317, 1253, 0, -1253, -2317, -3027,
-3276, -3027, -2317, -1253, 0, 1253, 2317, 3027, 3276, 3027, 2317,
1253, 0, -1253, -2317, -3027, -3276, -3027, -2317, -1253, 0, 1253,
2317, 3027, 3276, 3027, 2317, 1253, 0, -1253, -2317, -3027, -3276,
-3027, -2317, -1253, 0, 1253, 2317, 3027, 3276, 3027, 2317, 1253,
0, -1253, -2317, -3027, -3276, -3027, -2317, -1253, 0, 1253, 2317,
3027, 3276, 3027, 2317, 1253, 0, -1253, -2317, -3027, -3276, -3027,
-2317, -1253, 0, 1253, 2317, 3027, 3276, 3027, 2317, 1253, 0,
-1253, -2317, -3027, -3276, -3027, -2317, -1253, 0, 1253, 2317, 3027,
3276, 3027, 2317, 1253, 0, -1253, -2317, -3027, -3276, -3027, -2317,
-1253, 0, 1253, 2317, 3027, 3276, 3027, 2317, 1253, 0, -1253,
-2317, -3027, -3276, -3027, -2317, -1253, 0, 1253, 2317, 3027, 3276,
3027, 2317, 1253, 0, -1253, -2317, -3027, -3276, -3027, -2317, -1253,
0, 1253, 2317, 3027, 3276, 3027, 2317, 1253, 0, -1253, -2317,
-3027, -3276, -3027, -2317, -1253, 0, 1253, 2317, 3027, 3276, 3027,
2317, 1253, 0, -1253, -2317, -3027, -3276, -3027, -2317, -1253, 0,
1253, 2317, 3027, 3276, 3027, 2317, 1253, 0, -1253, -2317, -3027,
-3276, -3027, -2317, -1253, 0, 1253, 2317, 3027, 3276, 3027, 2317,
1253, 0, -1253, -2317, -3027, -3276, -3027, -2317, -1253, 0, 1253,
2317, 3027, 3276, 3027, 2317, 1253, 0, -1253, -2317, -3027, -3276,
-3027, -2317, -1253, 0, 1253, 2317, 3027, 3276, 3027, 2317, 1253,
0, -1253, -2317, -3027, -3276, -3027, -2317, -1253, 0, 1253, 2317,
3027, 3276, 3027, 2317, 1253, 0, -1253, -2317, -3027, -3276, -3027,
-2317, -1253, 0, 1253, 2317, 3027, 3276, 3027, 2317, 1253, 0,
-1253, -2317, -3027, -3276, -3027, -2317, -1253};

View File

@ -0,0 +1,24 @@
/* Copyright 2018 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.
==============================================================================*/
#ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_MICRO_SPEECH_SIN_1K_H_
#define TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_MICRO_SPEECH_SIN_1K_H_
#include <cstdint>
extern const int g_sin_1k_size;
extern const int16_t g_sin_1k[];
#endif

View File

@ -171,3 +171,6 @@ $(MICRO_SPEECH_BINARY): $(MICRO_SPEECH_OBJS) $(MICROLITE_LIB_PATH)
$(LIBFLAGS) $(MICROLITE_LIB_PATH) $(LDFLAGS) $(MICROLITE_LIBS)
micro_speech: $(MICRO_SPEECH_BINARY)
micro_speech_bin: $(MICRO_SPEECH_BINARY).bin
# Find any platform-specific rules for this example.
include $(wildcard tensorflow/lite/experimental/micro/examples/micro_speech/*/Makefile.inc)

View File

@ -0,0 +1,4 @@
captured_data.txt
captured_data.wav
cmsis_*.txt
micro_*.txt

View File

@ -0,0 +1,100 @@
# Settings for apollo3 evb platforms.
ifeq ($(TARGET), apollo3evb)
PUSHBUTTON_MICRO_SPEECH_TEST_SRCS := \
$(AP3_MICRO_DIR)/../preprocessor.cc \
$(AP3_MICRO_DIR)/pushbutton_main.c \
$(AP3_MICRO_DIR)/pushbutton_test.cc \
$(AP3_MICRO_DIR)/../tiny_conv_model_data.cc \
$(APOLLO3_SDK)/devices/am_devices_led.c
ALL_SRCS += $(PUSHBUTTON_MICRO_SPEECH_TEST_SRCS)
PUSHBUTTON_MICRO_SPEECH_TEST_OBJS := $(addprefix $(OBJDIR), \
$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(PUSHBUTTON_MICRO_SPEECH_TEST_SRCS))))
PUSHBUTTON_MICRO_SPEECH_TEST_BINARY := $(BINDIR)pushbutton_micro_speech_test
$(PUSHBUTTON_MICRO_SPEECH_TEST_BINARY): $(PUSHBUTTON_MICRO_SPEECH_TEST_OBJS) $(MICROLITE_LIB_PATH)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(INCLUDES) \
-o $(PUSHBUTTON_MICRO_SPEECH_TEST_BINARY) $(PUSHBUTTON_MICRO_SPEECH_TEST_OBJS) \
$(LIBFLAGS) $(MICROLITE_LIB_PATH) $(LDFLAGS) $(MICROLITE_LIBS)
pushbutton_micro_speech_test: $(PUSHBUTTON_MICRO_SPEECH_TEST_BINARY)
pushbutton_micro_speech_test_bin: $(PUSHBUTTON_MICRO_SPEECH_TEST_BINARY).bin
test_pushbutton_micro_speech: $(PUSHBUTTON_MICRO_SPEECH_TEST_BINARY)
$(TEST_SCRIPT) $(PUSHBUTTON_MICRO_SPEECH_TEST_BINARY) '~~~ALL TESTS PASSED~~~'
PUSHBUTTON_CMSIS_SPEECH_TEST_SRCS := \
$(AP3_MICRO_DIR)/pushbutton_main.c \
$(AP3_MICRO_DIR)/pushbutton_test.cc \
$(AP3_MICRO_DIR)/../tiny_conv_model_data.cc \
$(CMSIS_DIR)/preprocessor.cc \
$(CMSIS_EXT_DIR)/arm_cmplx_mag_squared_q10p6.c \
$(CMSIS_DIR)/hanning.c \
$(APOLLO3_SDK)/devices/am_devices_led.c \
$(CMSIS_SRCS)
ALL_SRCS += $(PUSHBUTTON_CMSIS_SPEECH_TEST_SRCS)
PUSHBUTTON_CMSIS_SPEECH_TEST_OBJS := $(addprefix $(OBJDIR), \
$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(PUSHBUTTON_CMSIS_SPEECH_TEST_SRCS))) \
arm_bitreversal2.o)
PUSHBUTTON_CMSIS_SPEECH_TEST_BINARY := $(BINDIR)pushbutton_cmsis_speech_test
$(PUSHBUTTON_CMSIS_SPEECH_TEST_BINARY): $(PUSHBUTTON_CMSIS_SPEECH_TEST_OBJS) $(MICROLITE_LIB_PATH)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(INCLUDES) \
-o $(PUSHBUTTON_CMSIS_SPEECH_TEST_BINARY) $(PUSHBUTTON_CMSIS_SPEECH_TEST_OBJS) \
$(LIBFLAGS) $(MICROLITE_LIB_PATH) $(LDFLAGS) $(MICROLITE_LIBS)
pushbutton_cmsis_speech_test: $(PUSHBUTTON_CMSIS_SPEECH_TEST_BINARY)
pushbutton_cmsis_speech_test_bin: $(PUSHBUTTON_CMSIS_SPEECH_TEST_BINARY).bin
test_pushbutton_cmsis_speech: $(PUSHBUTTON_CMSIS_SPEECH_TEST_BINARY)
$(TEST_SCRIPT) $(PUSHBUTTON_CMSIS_SPEECH_TEST_BINARY) '~~~ALL TESTS PASSED~~~'
PREPROCESSOR_1K_SRCS := \
tensorflow/lite/experimental/micro/examples/micro_speech/apollo3/preprocessor_1k.cc \
tensorflow/lite/experimental/micro/examples/micro_speech/CMSIS/sin_1k.cc
PREPROCESSOR_1K_MICRO_TEST_SRCS := \
$(PREPROCESSOR_1K_SRCS) \
$(AP3_MICRO_DIR)/../fixed_point/preprocessor.cc \
$(AP3_EXT_MICRO_DIR)/system_apollo3.c \
$(AP3_MICRO_DIR)/_main.c
ALL_SRCS += $(PREPROCESSOR_1K_MICRO_TEST_SRCS)
PREPROCESSOR_1K_MICRO_TEST_OBJS := $(addprefix $(OBJDIR), \
$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(PREPROCESSOR_1K_MICRO_TEST_SRCS))))
PREPROCESSOR_1K_MICRO_TEST_BINARY := $(BINDIR)preprocessor_1k_micro_test
$(PREPROCESSOR_1K_MICRO_TEST_BINARY): $(PREPROCESSOR_1K_MICRO_TEST_OBJS) $(MICROLITE_LIB_PATH)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(INCLUDES) \
-o $(PREPROCESSOR_1K_MICRO_TEST_BINARY) $(PREPROCESSOR_1K_MICRO_TEST_OBJS) \
$(LIBFLAGS) $(MICROLITE_LIB_PATH) $(LDFLAGS) $(MICROLITE_LIBS)
preprocessor_1k_micro_test: $(PREPROCESSOR_1K_MICRO_TEST_BINARY)
preprocessor_1k_micro_test_bin: $(PREPROCESSOR_1K_MICRO_TEST_BINARY).bin
test_preprocessor_1k_micro: $(PREPROCESSOR_1K_MICRO_TEST_BINARY)
$(TEST_SCRIPT) $(PREPROCESSOR_1K_MICRO_TEST_BINARY) '~~~ALL TESTS PASSED~~~'
PREPROCESSOR_1K_CMSIS_TEST_SRCS := \
$(PREPROCESSOR_1K_SRCS) \
$(CMSIS_DIR)/preprocessor.cc \
$(CMSIS_EXT_DIR)/arm_cmplx_mag_squared_q10p6.c \
$(CMSIS_DIR)/hanning.c \
$(AP3_EXT_MICRO_DIR)/system_apollo3.c \
$(AP3_MICRO_DIR)/_main.c \
$(CMSIS_SRCS)
ALL_SRCS += $(PREPROCESSOR_1K_CMSIS_TEST_SRCS)
PREPROCESSOR_1K_CMSIS_TEST_BINARY := $(BINDIR)preprocessor_1k_cmsis_test
PREPROCESSOR_1K_CMSIS_TEST_OBJS := $(addprefix $(OBJDIR), \
$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(PREPROCESSOR_1K_CMSIS_TEST_SRCS)))\
arm_bitreversal2.o)
$(PREPROCESSOR_1K_CMSIS_TEST_BINARY): $(PREPROCESSOR_1K_CMSIS_TEST_OBJS) $(MICROLITE_LIB_PATH)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(INCLUDES) \
-o $(PREPROCESSOR_1K_CMSIS_TEST_BINARY) $(PREPROCESSOR_1K_CMSIS_TEST_OBJS) \
$(LIBFLAGS) $(MICROLITE_LIB_PATH) $(LDFLAGS) $(MICROLITE_LIBS)
preprocessor_1k_cmsis_test: $(PREPROCESSOR_1K_CMSIS_TEST_BINARY)
preprocessor_1k_cmsis_test_bin: $(PREPROCESSOR_1K_CMSIS_TEST_BINARY).bin
test_preprocessor_1k_cmsis: $(PREPROCESSOR_1K_CMSIS_TEST_BINARY)
$(TEST_SCRIPT) $(PREPROCESSOR_1K_CMSIS_TEST_BINARY) '~~~ALL TESTS PASSED~~~'
PREPROCESSOR_TEST_SRCS += \
$(AP3_MICRO_DIR)/_main.c
$(OBJDIR)arm_bitreversal2.o:
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $(CMSIS_SRC_DIR)/TransformFunctions/arm_bitreversal2.S -o $(OBJDIR)arm_bitreversal2.o
endif

View File

@ -0,0 +1,129 @@
# Description of Apollo3 Makefile targets
* **pushbutton_cmsis_speech_test_bin**:
* When users press BTN2 on the Apollo3 EVK, 1 second of audio is captured.
* Then the audio is sent to the CMSIS version of the preprocessor and into
the neural net
* To print out the neural net's inference scores, run GDB and source
pushbutton\_cmsis\_scores.cmd
* To save the captured audio to a text file (captured\_data.txt), run GDB
and source pushbutton\_cmsis\_voice.cmd
* Setup python
* sudo apt install python-pip
* sudo apt install python-tk
* pip install numpy
* pip install matplotlib
* pip install pysoundfile
* python captured_data_to_wav.py
* captured\_data.txt can be turned into a \*.wav file using
captured\_data\_to\_wav.py by executing "python
captured\_data\_to\_wav.py"
* **preprocessor_1k_cmsis_test_bin**:
* Sends a 1 kHz sine wave to the CMSIS fixed\_point version of the
preprocessor
* **This test should be compiled with the -O0 option.** Otherwise, the
breakpoints will not be reached
* In
tensorflow/lite/experimental/micro/tools/make/targets/apollo3evb_makefile.inc
change "-O3" to "-O0" on line 47
* **DO NOT FORGET TO REVERT CHANGE AFTER EXPERIMENT**
* In future, enhance scripts to handle automatically, NOT manually!
* Clean project by running "make -f
tensorflow/lite/experimental/micro/tools/make/Makefile clean"
* Compile BIN by running "make -f
tensorflow/lite/experimental/micro/tools/make/Makefile TARGET=apollo3evb
preprocessor_1k_cmsis_test_bin"
* Run with the preprocessor\_1k\_cmsis\_test.cmd GDB command file
* Produces four text files corresponding to outputs from the CMSIS
fixed\_point version of this algorithm:
* cmsis_windowed_input.txt: the sinusoid after multiplying elementwise
with a Hann window
* cmsis_dft.txt: the DFT of the windowed sinusoid
* cmsis_power.txt: the magnitude squared of the DFT
* cmsis_power_avg.txt: the 6-bin average of the magnitude squared of
the DFT
* Run both verisons of the 1KHz pre-processor test and then compare.
* These files can be plotted with "python compare\_1k.py"
* Also prints out the number of cycles the code took to execute (using the
DWT->CYCCNT register)
* **preprocessor_1k_micro_test_bin**
* Sends a 1 kHz sine wave to the Micro-Lite fixed\_point version of the
preprocessor
* **This test should be compiled with the -O0 option.** Otherwise, the
breakpoints will not be reached
* Run with the preprocessor\_1k\_micro\_test.cmd GDB command file
* Produces four text files corresponding to outputs from the Micro-Lite
version of this algorithm:
* micro_windowed_input.txt: the sinusoid after multiplying elementwise
with a Hann window
* micro_dft.txt: the DFT of the windowed sinusoid
* micro_power.txt: the magnitude squared of the DFT
* micro_power_avg.txt: the 6-bin average of the magnitude squared of
the DFT
* Run both verisons of the 1KHz pre-processor test and then compare.
* These files can be plotted with "python compare\_1k.py"
* Also prints out the number of cycles the code took to execute (using the
DWT->CYCCNT register)
# Description of files
* **.gitignore**: Git should ignore \*.txt and \*.wav files that result from
experiments run in this directory
* **captured\_data\_to\_wav.py**: Python script that parses a text file
containing data dumped from GDB (specifically the verilog format) and
creates a \*.wav file using
[PySoundFile](https://pysoundfile.readthedocs.io/en/0.9.0/).
* **compare\_1k.py**: This script compares the intermediate variables and
final outputs of the micro-lite fixed-point preprocessor function and the
CMSIS version of this function. The stimulus provided to each preprocessor
is the same: a 1 kHz sinusoid.
* **get\_yesno\_data.cmd**: A GDB command file that runs preprocessor_test
(where TARGET=apollo3evb) and dumps the calculated data for the "yes" and
"no" input wavfeorms to text files
* **\_main.c**: Point of entry for the micro_speech test
* **preprocessor_1k.cc**: A version of preprocessor.cc where a 1 kHz sinusoid
is provided as input to the preprocessor
* **preprocessor_1k_cmsis_test.cmd**: GDB command file for the CMSIS
preprocessor 1 kHz test
* **preprocessor_1k_micro_test.cmd**: GDB command file for the Micro-Lite
preprocessor 1 kHz test
* **preprocessor_test.cmd**: GDB command file for the preprocessor test
* **pushbutton_cmsis_scores.cmd**: GDB command file that runs
pushbutton_cmsis_speech_test_bin. It adds a breakpoint immediately after the
scores are reported and prints out each score. Then it continues code
execution.
* **pushbutton_cmsis_voice.cmd**: GDB command file that runs
pushbutton_cmsis_speech_test_bin. Dumps the recorded 1 second of audio to
captured_data.txt, which can then be processed by the python file
captured_data_to_wav.py.
* **pushbutton_main.c**: Source file containing program point of entry
\_main() for the pushbutton\_\* tests. Contains Interrupt Service Routines
for PDM data capture and pushbuttons. Calls the main() function of
pushbutton_test.cc
* **pushbutton_test.cc**: Source file containing main() function for the
pushbutton\_\* tests. main() calls the preprocessor function and the neural
net inference function.
# Description of externally downloaded files in ../apollo3_ext
* **apollo3.h**: Apollo 3 version of the
[CMSIS Device Header File (device.h)](https://www.keil.com/pack/doc/CMSIS/Core/html/device_h_pg.html).
Available in the
[Ambiq Keil Pack](http://s3.ambiqmicro.com/pack/AmbiqMicro.Apollo_DFP.1.1.0.pack).
* **system_apollo3.c**: Apollo 3 version of the
[CMSIS System Configuration File system\_\<device\>.c](https://www.keil.com/pack/doc/CMSIS/Core/html/system_c_pg.html).
Available in the
[Ambiq Keil Pack](http://s3.ambiqmicro.com/pack/AmbiqMicro.Apollo_DFP.1.1.0.pack).
* **system_apollo3.h**: Apollo 3 version of the
[CMSIS System Configuration File system\_\<device\>.h](https://www.keil.com/pack/doc/CMSIS/Core/html/system_c_pg.html).
Available in the
[Ambiq Keil Pack](http://s3.ambiqmicro.com/pack/AmbiqMicro.Apollo_DFP.1.1.0.pack).
# FFT scaling
See https://github.com/ARM-software/CMSIS_5/issues/220
> And as @xizhizhang pointed, I think there may be an error on the internal
> downscaling, or at least on the documentation. It looks like during the fft
> computation, the downscaling factor reach 2**-9 for a 512 rfft operation,
> being the output in Q10.22, instead the documented 2**-8 and Q9.23.

View File

@ -0,0 +1,117 @@
/* Copyright 2018 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 <stdint.h>
#include "am_bsp.h"
#include "am_mcu_apollo.h" // Defines AM_CMSIS_REGS
#include "am_util.h"
//*****************************************************************************
//
// The entry point for the application.
//
//*****************************************************************************
extern int main(int argc, char** argv);
void DebugLog(const char* s) { am_util_stdio_printf("%s", s); }
void DebugLogInt32(int32_t i) { am_util_stdio_printf("%d", i); }
void DebugLogUInt32(uint32_t i) { am_util_stdio_printf("%d", i); }
void DebugLogHex(uint32_t i) { am_util_stdio_printf("0x%8x", i); }
void DebugLogFloat(float i) { am_util_stdio_printf("%f", i); }
int _main(void) {
am_util_id_t sIdDevice;
uint32_t ui32StrBuf;
//
// Set the clock frequency.
//
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
//
// Set the default cache configuration
//
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
//
// Configure the board for low power operation.
//
am_bsp_low_power_init();
//
// Initialize the printf interface for UART output
//
am_bsp_uart_printf_enable();
//
// Print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("Hello World!\n\n");
//
// Print the device info.
//
am_util_id_device(&sIdDevice);
am_util_stdio_printf("Vendor Name: %s\n", sIdDevice.pui8VendorName);
am_util_stdio_printf("Device type: %s\n", sIdDevice.pui8DeviceName);
am_util_stdio_printf("Qualified: %s\n",
sIdDevice.sMcuCtrlDevice.ui32Qualified ? "Yes" : "No");
am_util_stdio_printf(
"Device Info:\n"
"\tPart number: 0x%08X\n"
"\tChip ID0: 0x%08X\n"
"\tChip ID1: 0x%08X\n"
"\tRevision: 0x%08X (Rev%c%c)\n",
sIdDevice.sMcuCtrlDevice.ui32ChipPN, sIdDevice.sMcuCtrlDevice.ui32ChipID0,
sIdDevice.sMcuCtrlDevice.ui32ChipID1,
sIdDevice.sMcuCtrlDevice.ui32ChipRev, sIdDevice.ui8ChipRevMaj,
sIdDevice.ui8ChipRevMin);
//
// If not a multiple of 1024 bytes, append a plus sign to the KB.
//
ui32StrBuf = (sIdDevice.sMcuCtrlDevice.ui32FlashSize % 1024) ? '+' : 0;
am_util_stdio_printf(
"\tFlash size: %7d (%d KB%s)\n", sIdDevice.sMcuCtrlDevice.ui32FlashSize,
sIdDevice.sMcuCtrlDevice.ui32FlashSize / 1024, &ui32StrBuf);
ui32StrBuf = (sIdDevice.sMcuCtrlDevice.ui32SRAMSize % 1024) ? '+' : 0;
am_util_stdio_printf(
"\tSRAM size: %7d (%d KB%s)\n\n", sIdDevice.sMcuCtrlDevice.ui32SRAMSize,
sIdDevice.sMcuCtrlDevice.ui32SRAMSize / 1024, &ui32StrBuf);
//
// Print the compiler version.
//
am_util_stdio_printf("App Compiler: %s\n", COMPILER_VERSION);
#ifdef AM_PART_APOLLO3
am_util_stdio_printf("HAL Compiler: %s\n", g_ui8HALcompiler);
am_util_stdio_printf("HAL SDK version: %d.%d.%d\n", g_ui32HALversion.s.Major,
g_ui32HALversion.s.Minor, g_ui32HALversion.s.Revision);
am_util_stdio_printf("HAL compiled with %s-style registers\n",
g_ui32HALversion.s.bAMREGS ? "AM_REG" : "CMSIS");
am_util_stdio_printf("&sIdDevice: 0x%x, &ui32StrBuf: 0x%x\n", &sIdDevice,
&ui32StrBuf);
am_hal_security_info_t secInfo;
char sINFO[32];
uint32_t ui32Status;
#endif // AM_PART_APOLLO3
main(0, NULL);
}

View File

@ -0,0 +1,46 @@
# Copyright 2018 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.
# ==============================================================================
"""Converts values pulled from the microcontroller into audio files."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import struct
# import matplotlib.pyplot as plt
import numpy as np
import soundfile as sf
def new_data_to_array(fn):
vals = []
with open(fn) as f:
for n, line in enumerate(f):
if n is not 0:
vals.extend([int(v, 16) for v in line.split()])
b = ''.join(map(chr, vals))
y = struct.unpack('<' + 'h' * int(len(b) / 2), b)
return y
data = 'captured_data.txt'
values = np.array(new_data_to_array(data)).astype(float)
# plt.plot(values, 'o-')
# plt.show(block=False)
wav = values / np.max(np.abs(values))
sf.write('captured_data.wav', wav, 16000)

View File

@ -0,0 +1,167 @@
# Copyright 2018 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.
# ==============================================================================
"""Debugging script for checking calculation values."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import struct
import matplotlib.pyplot as plt
import numpy as np
# import soundfile as sf
def new_data_to_array(fn, datatype='int16'):
"""Converts file information to an in-memory array."""
vals = []
with open(fn) as f:
for n, line in enumerate(f):
if n is not 0:
vals.extend([int(v, 16) for v in line.split()])
b = ''.join(map(chr, vals))
if datatype == 'int8':
typestr = 'b'
arraylen = int(len(b))
elif datatype == 'int16':
typestr = 'h'
arraylen = int(len(b) // 2)
elif datatype == 'int32':
typestr = 'i'
arraylen = int(len(b) // 4)
if datatype == 'uint8':
typestr = 'B'
arraylen = int(len(b))
elif datatype == 'uint16':
typestr = 'H'
arraylen = int(len(b) // 2)
elif datatype == 'uint32':
typestr = 'I'
arraylen = int(len(b) // 4)
y = np.array(struct.unpack('<' + typestr * arraylen, b))
return y
# x is the fixed-point input in Qm.n format
def to_float(x, n):
return x.astype(float) * 2**(-n)
micro_windowed_input = new_data_to_array(
'micro_windowed_input.txt', datatype='int32')
cmsis_windowed_input = new_data_to_array(
'cmsis_windowed_input.txt', datatype='int16')
micro_dft = new_data_to_array('micro_dft.txt', datatype='int32')
cmsis_dft = new_data_to_array('cmsis_dft.txt', datatype='int16')
py_dft = np.fft.rfft(to_float(cmsis_windowed_input, 15), n=512)
py_result = np.empty((2 * py_dft.size), dtype=np.float)
py_result[0::2] = np.real(py_dft)
py_result[1::2] = np.imag(py_dft)
micro_power = new_data_to_array('micro_power.txt', datatype='int32')
cmsis_power = new_data_to_array('cmsis_power.txt', datatype='int16')
py_power = np.square(np.abs(py_dft))
micro_power_avg = new_data_to_array('micro_power_avg.txt', datatype='uint8')
cmsis_power_avg = new_data_to_array('cmsis_power_avg.txt', datatype='uint8')
plt.figure(1)
plt.subplot(311)
plt.plot(micro_windowed_input, label='Micro fixed')
plt.legend()
plt.subplot(312)
plt.plot(cmsis_windowed_input, label='CMSIS fixed')
plt.legend()
plt.subplot(313)
plt.plot(to_float(micro_windowed_input, 30), label='Micro to float')
plt.plot(to_float(cmsis_windowed_input, 15), label='CMSIS to float')
plt.legend()
plt.figure(2)
plt.subplot(311)
plt.plot(micro_dft, label='Micro fixed')
plt.legend()
plt.subplot(312)
plt.plot(cmsis_dft, label='CMSIS fixed')
plt.legend()
plt.subplot(313)
plt.plot(to_float(micro_dft, 22), label='Micro to float')
# CMSIS result has 6 fractionanl bits (not 7) due to documentation error (see
# README.md)
plt.plot(to_float(cmsis_dft, 6), label='CMSIS to float')
plt.plot(py_result, label='Python result')
plt.legend()
plt.figure(3)
plt.subplot(311)
plt.plot(micro_power, label='Micro fixed')
plt.legend()
plt.subplot(312)
plt.plot(cmsis_power[0:256], label='CMSIS fixed')
plt.legend()
plt.subplot(313)
plt.plot(to_float(micro_power, 22), label='Micro to float')
plt.plot(to_float(cmsis_power[0:256], 6), label='CMSIS to float')
plt.plot(py_power, label='Python result')
plt.legend()
plt.figure(4)
plt.plot(micro_power_avg, label='Micro fixed')
plt.plot(cmsis_power_avg, label='CMSIS fixed')
plt.legend()
plt.show()
# t = np.arange(16000.*0.03)/16000.
# # Factor of 10 because micro preprocessing overflows otherwise
# sin1k = 0.1*np.sin(2*np.pi*1000*t)
#
# plt.figure(1)
# plt.subplot(511)
# plt.plot(sin1k)
# plt.title('Input sine')
#
# plt.subplot(512)
# plt.plot(to_float(micro_windowed_input, 30), label='Micro-Lite')
# plt.plot(to_float(cmsis_windowed_input, 15), label='CMSIS')
# plt.title('Windowed sine')
# plt.legend(loc='center right')
#
# plt.subplot(513)
# plt.plot(to_float(micro_dft, 22), label='Micro-Lite')
# plt.plot(to_float(cmsis_dft, 6), label='CMSIS')
# plt.title('FFT')
# plt.legend(loc='center')
#
# plt.subplot(514)
# plt.plot(to_float(micro_power, 22), label='Micro-Lite')
# plt.plot(to_float(cmsis_power[0:256], 6), label='CMSIS')
# plt.title('|FFT|^2')
# plt.legend(loc='center right')
#
# plt.subplot(515)
# plt.plot(micro_power_avg, label='Micro-Lite')
# plt.plot(cmsis_power_avg, label='CMSIS')
# plt.title('Averaged |FFT|^2')
# plt.legend(loc='center right')
#
# plt.tight_layout(pad=0, w_pad=0.2, h_pad=0.2)
#
# plt.show()
#

View File

@ -0,0 +1,53 @@
/* Copyright 2018 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.
==============================================================================*/
/* This file is a modification of the Tensorflow Micro Lite file preprocessor.cc
*/
#include "tensorflow/lite/c/c_api_internal.h"
#include "tensorflow/lite/experimental/micro/examples/micro_speech/CMSIS/sin_1k.h"
#include "tensorflow/lite/experimental/micro/micro_error_reporter.h"
#include "tensorflow/lite/experimental/micro/testing/micro_test.h"
extern "C" {
#include "apollo3.h"
#include "system_apollo3.h"
}
#define output_data_size 43
int count;
extern TfLiteStatus Preprocess(tflite::ErrorReporter* error_reporter,
const int16_t* input, int input_size,
int output_size, uint8_t* output);
TF_LITE_MICRO_TESTS_BEGIN
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
// DWT->LAR = 0xC5ACCE55;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
TF_LITE_MICRO_TEST(TestPreprocessor) {
tflite::MicroErrorReporter micro_error_reporter;
tflite::ErrorReporter* error_reporter = &micro_error_reporter;
uint8_t calculated_data[output_data_size];
TfLiteStatus yes_status = Preprocess(error_reporter, g_sin_1k, g_sin_1k_size,
output_data_size, calculated_data);
count = DWT->CYCCNT;
TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, yes_status);
}
TF_LITE_MICRO_TESTS_END

View File

@ -0,0 +1,37 @@
# 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.
# ==============================================================================
# Needs to be compiled with -O0
file ../../../tools/make/gen/apollo3evb_cortex-m4/bin/preprocessor_1k_cmsis_test
target remote localhost:2331
load ../../../tools/make/gen/apollo3evb_cortex-m4/bin/preprocessor_1k_cmsis_test
monitor reset
break preprocessor.cc:68
commands
dump verilog value cmsis_windowed_input.txt bufB
c
end
break preprocessor.cc:76
commands
dump verilog value cmsis_dft.txt bufA
c
end
break preprocessor.cc:81
commands
dump verilog value cmsis_power.txt bufB
c
end
break preprocessor.cc:83
commands
dump verilog memory cmsis_power_avg.txt output output+42
c
end
break preprocessor_1k.cc:50
commands
print count
end
c

View File

@ -0,0 +1,25 @@
# 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.
# ==============================================================================
# Needs to be run when compiled with -O0
file ../../../tools/make/gen/apollo3evb_cortex-m4/bin/preprocessor_1k_micro_test
target remote localhost:2331
load ../../../tools/make/gen/apollo3evb_cortex-m4/bin/preprocessor_1k_micro_test
monitor reset
break preprocessor.cc:211
commands
dump verilog value micro_windowed_input.txt fixed_input
dump verilog value micro_dft.txt fourier_values
dump verilog value micro_power.txt power_spectrum
dump verilog memory micro_power_avg.txt output output+42
c
end
break preprocessor_1k.cc:50
commands
print count
end
c

View File

@ -0,0 +1,11 @@
# 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.
# ==============================================================================
file ../../gen/apollo3evb_cortex-m4/bin/preprocessor_test
target remote localhost:2331
load ../../gen/apollo3evb_cortex-m4/bin/preprocessor_test
monitor reset

View File

@ -0,0 +1,26 @@
# 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.
# ==============================================================================
file ../../../tools/make/gen/apollo3evb_cortex-m4/bin/pushbutton_cmsis_speech_test
target remote localhost:2331
load ../../../tools/make/gen/apollo3evb_cortex-m4/bin/pushbutton_cmsis_speech_test
monitor reset
break pushbutton_main.c:307
commands
printf "Silence score: %d\n", g_silence_score
printf "Unknown score: %d\n", g_unknown_score
printf "Yes score: %d\n", g_yes_score
printf "No score: %d\n", g_no_score
printf "g_scores[0]: %d\n", g_scores[0]
printf "g_scores[1]: %d\n", g_scores[1]
printf "g_scores[2]: %d\n", g_scores[2]
printf "g_scores[3]: %d\n", g_scores[3]
printf "max_score: %d\n", max_score
printf "max_score_index: %d\n", max_score_index
c
end
c

View File

@ -0,0 +1,25 @@
# Copyright 2018 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.
# ==============================================================================
file ../../../tools/make/gen/apollo3evb_cortex-m4/bin/pushbutton_cmsis_speech_test
target remote localhost:2331
load ../../../tools/make/gen/apollo3evb_cortex-m4/bin/pushbutton_cmsis_speech_test
monitor reset
break pushbutton_main.c:296
commands
dump verilog value captured_data.txt captured_data
c
end
c

View File

@ -0,0 +1,322 @@
/* Copyright 2018 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.
==============================================================================*/
/* This file is a modification of the Tensorflow Micro Lite file _main.c */
#include <stdint.h>
#include "am_bsp.h"
#include "am_mcu_apollo.h" // Defines AM_CMSIS_REGS
#include "am_util.h"
#define ARM_MATH_CM4
#include <arm_math.h>
//*****************************************************************************
// Parameters
//
// Total number of bytes transferred = 320*50*2 = 32000
//*****************************************************************************
#define FRAME_SIZE 320 // Capture one 320-sample (20-ms) frame at a time
#define NUM_FRAMES 50 // Number of frames in 1 second
//*****************************************************************************
// GLOBALS
//*****************************************************************************
volatile int16_t g_numFramesCaptured = 0;
volatile bool g_bPDMDataReady = false;
int16_t
captured_data[FRAME_SIZE * NUM_FRAMES]; // Location of 1-second data buffer
extern uint8_t g_silence_score;
extern uint8_t g_unknown_score;
extern uint8_t g_yes_score;
extern uint8_t g_no_score;
q7_t g_scores[4] = {0};
//*****************************************************************************
// The entry point for the application.
//*****************************************************************************
extern int main(int argc, char** argv);
void DebugLog(const char* s) { am_util_stdio_printf("%s", s); }
void DebugLogInt32(int32_t i) { am_util_stdio_printf("%d", i); }
void DebugLogUInt32(uint32_t i) { am_util_stdio_printf("%d", i); }
void DebugLogHex(uint32_t i) { am_util_stdio_printf("0x%8x", i); }
void DebugLogFloat(float i) { am_util_stdio_printf("%f", i); }
//*****************************************************************************
// PDM configuration information.
//*****************************************************************************
void* PDMHandle;
am_hal_pdm_config_t g_sPdmConfig = {
.eClkDivider = AM_HAL_PDM_MCLKDIV_1,
.eLeftGain = AM_HAL_PDM_GAIN_P225DB,
.eRightGain = AM_HAL_PDM_GAIN_P225DB,
.ui32DecimationRate =
48, // OSR = 1500/16 = 96 = 2*SINCRATE --> SINC_RATE = 48
.bHighPassEnable = 0,
.ui32HighPassCutoff = 0xB,
.ePDMClkSpeed = AM_HAL_PDM_CLK_1_5MHZ,
.bInvertI2SBCLK = 0,
.ePDMClkSource = AM_HAL_PDM_INTERNAL_CLK,
.bPDMSampleDelay = 0,
.bDataPacking = 1,
.ePCMChannels = AM_HAL_PDM_CHANNEL_RIGHT,
.bLRSwap = 0,
};
//*****************************************************************************
// BUTTON0 pin configuration settings.
//*****************************************************************************
const am_hal_gpio_pincfg_t g_deepsleep_button0 = {
.uFuncSel = 3,
.eIntDir = AM_HAL_GPIO_PIN_INTDIR_LO2HI,
.eGPInput = AM_HAL_GPIO_PIN_INPUT_ENABLE,
};
//*****************************************************************************
// PDM initialization.
//*****************************************************************************
void pdm_init(void) {
//
// Initialize, power-up, and configure the PDM.
//
am_hal_pdm_initialize(0, &PDMHandle);
am_hal_pdm_power_control(PDMHandle, AM_HAL_PDM_POWER_ON, false);
am_hal_pdm_configure(PDMHandle, &g_sPdmConfig);
am_hal_pdm_enable(PDMHandle);
//
// Configure the necessary pins.
//
am_hal_gpio_pincfg_t sPinCfg = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// ARPIT 181019
// sPinCfg.uFuncSel = AM_HAL_PIN_10_PDMCLK;
// am_hal_gpio_pinconfig(10, sPinCfg);
sPinCfg.uFuncSel = AM_HAL_PIN_12_PDMCLK;
am_hal_gpio_pinconfig(12, sPinCfg);
sPinCfg.uFuncSel = AM_HAL_PIN_11_PDMDATA;
am_hal_gpio_pinconfig(11, sPinCfg);
// am_hal_gpio_state_write(14, AM_HAL_GPIO_OUTPUT_CLEAR);
// am_hal_gpio_pinconfig(14, g_AM_HAL_GPIO_OUTPUT);
//
// Configure and enable PDM interrupts (set up to trigger on DMA
// completion).
//
am_hal_pdm_interrupt_enable(PDMHandle,
(AM_HAL_PDM_INT_DERR | AM_HAL_PDM_INT_DCMP |
AM_HAL_PDM_INT_UNDFL | AM_HAL_PDM_INT_OVF));
#if AM_CMSIS_REGS
NVIC_EnableIRQ(PDM_IRQn);
#else
am_hal_interrupt_enable(AM_HAL_INTERRUPT_PDM);
#endif
}
//*****************************************************************************
//
// Start a transaction to get some number of bytes from the PDM interface.
//
//*****************************************************************************
void pdm_data_get(void) {
//
// Configure DMA and target address.
//
am_hal_pdm_transfer_t sTransfer;
sTransfer.ui32TargetAddr =
(uint32_t)(&captured_data[FRAME_SIZE * g_numFramesCaptured]);
sTransfer.ui32TotalCount = 2 * FRAME_SIZE; // Each sample is 2 bytes
//
// Start the data transfer.
//
am_hal_pdm_dma_start(PDMHandle, &sTransfer);
}
//*****************************************************************************
//
// PDM interrupt handler.
//
//*****************************************************************************
void am_pdm_isr(void) {
uint32_t ui32Status;
//
// Read the interrupt status.
//
am_hal_pdm_interrupt_status_get(PDMHandle, &ui32Status, true);
am_hal_pdm_interrupt_clear(PDMHandle, ui32Status);
//
// Once our DMA transaction completes, send a flag to the main routine
//
if (ui32Status & AM_HAL_PDM_INT_DCMP) g_bPDMDataReady = true;
}
//*****************************************************************************
// GPIO ISR
// Will enable the PDM, set number of frames transferred to 0, and turn on LED
//*****************************************************************************
void am_gpio_isr(void) {
//
// Delay for debounce.
//
am_util_delay_ms(200);
//
// Clear the GPIO Interrupt (write to clear).
//
am_hal_gpio_interrupt_clear(AM_HAL_GPIO_BIT(AM_BSP_GPIO_BUTTON0));
// Start audio transfer
am_hal_pdm_fifo_flush(PDMHandle);
pdm_data_get();
am_hal_pdm_enable(PDMHandle);
//
// Turn on LED 0
//
am_devices_led_on(am_bsp_psLEDs, 0);
}
int _main(void) {
am_util_id_t sIdDevice;
uint32_t ui32StrBuf;
//
// Set the clock frequency.
//
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
//
// Set the default cache configuration
//
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
//
// Configure the board for low power operation.
//
am_bsp_low_power_init();
#if defined(AM_BSP_NUM_BUTTONS) && defined(AM_BSP_NUM_LEDS)
//
// Configure the button pin.
//
am_hal_gpio_pinconfig(AM_BSP_GPIO_BUTTON0, g_deepsleep_button0);
//
// Clear the GPIO Interrupt (write to clear).
//
am_hal_gpio_interrupt_clear(AM_HAL_GPIO_BIT(AM_BSP_GPIO_BUTTON0));
//
// Enable the GPIO/button interrupt.
//
am_hal_gpio_interrupt_enable(AM_HAL_GPIO_BIT(AM_BSP_GPIO_BUTTON0));
//
// Configure the LEDs.
//
am_devices_led_array_init(am_bsp_psLEDs, AM_BSP_NUM_LEDS);
//
// Turn the LEDs off
//
for (int ix = 0; ix < AM_BSP_NUM_LEDS; ix++) {
am_devices_led_off(am_bsp_psLEDs, ix);
}
// am_devices_led_on(am_bsp_psLEDs, 1);
#endif // defined(AM_BSP_NUM_BUTTONS) && defined(AM_BSP_NUM_LEDS)
#if AM_CMSIS_REGS
NVIC_EnableIRQ(GPIO_IRQn);
#else // AM_CMSIS_REGS
am_hal_interrupt_enable(AM_HAL_INTERRUPT_GPIO);
#endif // AM_CMSIS_REGS
//
// Enable interrupts to the core.
//
am_hal_interrupt_master_enable();
// Turn on PDM
pdm_init();
//
// Initialize the printf interface for UART output
//
am_bsp_uart_printf_enable();
//
// Print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("Starting streaming test\n\n");
// Score variables
q7_t max_score = 0;
uint32_t max_score_index = 0;
while (1) {
am_hal_interrupt_master_disable();
if (g_bPDMDataReady) {
g_bPDMDataReady = false;
g_numFramesCaptured++;
if (g_numFramesCaptured < NUM_FRAMES) {
pdm_data_get(); // Start converting the next set of PCM samples.
}
else {
g_numFramesCaptured = 0;
// am_hal_pdm_disable(PDMHandle);
am_devices_led_off(am_bsp_psLEDs, 0);
main(0, NULL);
g_scores[0] = (q7_t)g_silence_score - 128;
g_scores[1] = (q7_t)g_unknown_score - 128;
g_scores[2] = (q7_t)g_yes_score - 128;
g_scores[3] = (q7_t)g_no_score - 128;
am_devices_led_off(
am_bsp_psLEDs,
max_score_index + 1); // Turn off LED for previous max score
arm_max_q7(g_scores, 4, &max_score, &max_score_index);
am_devices_led_on(
am_bsp_psLEDs,
max_score_index + 1); // Turn on LED for new max score
}
}
//
// Go to Deep Sleep.
//
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
am_hal_interrupt_master_enable();
}
// main(0, NULL);
}

View File

@ -0,0 +1,116 @@
/* Copyright 2018 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.
==============================================================================*/
/* This file is a modification of the Tensorflow Micro Lite file
* micro_speech_test.cc */
#include "tensorflow/lite/c/c_api_internal.h"
#include "tensorflow/lite/experimental/micro/examples/micro_speech/preprocessor.h"
#include "tensorflow/lite/experimental/micro/examples/micro_speech/tiny_conv_model_data.h"
#include "tensorflow/lite/experimental/micro/kernels/all_ops_resolver.h"
#include "tensorflow/lite/experimental/micro/micro_error_reporter.h"
#include "tensorflow/lite/experimental/micro/micro_interpreter.h"
#include "tensorflow/lite/experimental/micro/testing/micro_test.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "tensorflow/lite/version.h"
extern int16_t captured_data[16000];
uint8_t g_silence_score = 0;
uint8_t g_unknown_score = 0;
uint8_t g_yes_score = 0;
uint8_t g_no_score = 0;
TF_LITE_MICRO_TESTS_BEGIN
TF_LITE_MICRO_TEST(TestPreprocessor) {
tflite::MicroErrorReporter micro_error_reporter;
tflite::ErrorReporter* error_reporter = &micro_error_reporter;
uint8_t preprocessed_data[43 * 49];
TfLiteStatus preprocess_1sec_status =
Preprocess_1sec(error_reporter, captured_data, preprocessed_data);
TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, preprocess_1sec_status);
// Map the model into a usable data structure. This doesn't involve any
// copying or parsing, it's a very lightweight operation.
const tflite::Model* model = ::tflite::GetModel(g_tiny_conv_model_data);
if (model->version() != TFLITE_SCHEMA_VERSION) {
error_reporter->Report(
"Model provided is schema version %d not equal "
"to supported version %d.\n",
model->version(), TFLITE_SCHEMA_VERSION);
}
// This pulls in all the operation implementations we need.
tflite::ops::micro::AllOpsResolver resolver;
// Create an area of memory to use for input, output, and intermediate arrays.
const int tensor_arena_size = 10 * 1024;
uint8_t tensor_arena[tensor_arena_size];
tflite::SimpleTensorAllocator tensor_allocator(tensor_arena,
tensor_arena_size);
// Build an interpreter to run the model with.
tflite::MicroInterpreter interpreter(model, resolver, &tensor_allocator,
error_reporter);
// Get information about the memory area to use for the model's input.
TfLiteTensor* input = interpreter.input(0);
// Make sure the input has the properties we expect.
TF_LITE_MICRO_EXPECT_NE(nullptr, input);
TF_LITE_MICRO_EXPECT_EQ(4, input->dims->size);
TF_LITE_MICRO_EXPECT_EQ(1, input->dims->data[0]);
TF_LITE_MICRO_EXPECT_EQ(49, input->dims->data[1]);
TF_LITE_MICRO_EXPECT_EQ(43, input->dims->data[2]);
TF_LITE_MICRO_EXPECT_EQ(kTfLiteUInt8, input->type);
// Copy a spectrogram created from a .wav audio file of someone saying "Yes",
// into the memory area used for the input.
for (int i = 0; i < input->bytes; ++i) {
input->data.uint8[i] = preprocessed_data[i];
}
// Run the model on this input and make sure it succeeds.
TfLiteStatus invoke_status = interpreter.Invoke();
if (invoke_status != kTfLiteOk) {
error_reporter->Report("Invoke failed\n");
}
TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, invoke_status);
// Get the output from the model, and make sure it's the expected size and
// type.
TfLiteTensor* output = interpreter.output(0);
TF_LITE_MICRO_EXPECT_EQ(2, output->dims->size);
TF_LITE_MICRO_EXPECT_EQ(1, output->dims->data[0]);
TF_LITE_MICRO_EXPECT_EQ(4, output->dims->data[1]);
TF_LITE_MICRO_EXPECT_EQ(kTfLiteUInt8, output->type);
// There are four possible classes in the output, each with a score.
const int kSilenceIndex = 0;
const int kUnknownIndex = 1;
const int kYesIndex = 2;
const int kNoIndex = 3;
// Make sure that the expected "Yes" score is higher than the other classes.
g_silence_score = output->data.uint8[kSilenceIndex];
g_unknown_score = output->data.uint8[kUnknownIndex];
g_yes_score = output->data.uint8[kYesIndex];
g_no_score = output->data.uint8[kNoIndex];
error_reporter->Report("Ran successfully\n");
}
TF_LITE_MICRO_TESTS_END

View File

@ -143,3 +143,12 @@ TfLiteStatus Preprocess(tflite::ErrorReporter* error_reporter,
}
return kTfLiteOk;
}
TfLiteStatus Preprocess_1sec(tflite::ErrorReporter* error_reporter,
const int16_t* input, uint8_t* output) {
int i;
for (i = 0; i < 49; i++) {
Preprocess(error_reporter, input + i * 320, 480, 43, output + i * 43);
}
return kTfLiteOk;
}

View File

@ -28,4 +28,7 @@ TfLiteStatus Preprocess(tflite::ErrorReporter* error_reporter,
const int16_t* input, int input_size, int output_size,
uint8_t* output);
TfLiteStatus Preprocess_1sec(tflite::ErrorReporter* error_reporter,
const int16_t* input, uint8_t* output);
#endif // TENSORFLOW_LITE_EXPERIMENTAL_MICRO_EXAMPLES_MICRO_SPEECH_PREPROCESSOR_H_

View File

@ -0,0 +1,2 @@
downloads
gen

View File

@ -53,29 +53,6 @@ CC_PREFIX :=
# runtime that can be linked in to other programs.
MICROLITE_LIB_NAME := libtensorflow-microlite.a
# Test binary for the microcontroller speech model.
MICRO_SPEECH_TEST_SRCS := \
tensorflow/lite/experimental/micro/examples/micro_speech/micro_speech_test.cc \
tensorflow/lite/experimental/micro/examples/micro_speech/tiny_conv_model_data.cc \
tensorflow/lite/experimental/micro/examples/micro_speech/no_features_data.cc \
tensorflow/lite/experimental/micro/examples/micro_speech/yes_features_data.cc
# Test binary for the microcontroller speech model.
PREPROCESSOR_TEST_SRCS := \
tensorflow/lite/experimental/micro/examples/micro_speech/preprocessor_test.cc \
tensorflow/lite/experimental/micro/examples/micro_speech/no_30ms_sample_data.cc \
tensorflow/lite/experimental/micro/examples/micro_speech/yes_30ms_sample_data.cc \
tensorflow/lite/experimental/micro/examples/micro_speech/no_power_spectrum_data.cc \
tensorflow/lite/experimental/micro/examples/micro_speech/yes_power_spectrum_data.cc
PREPROCESSOR_REFERENCE_TEST_SRCS = \
$(PREPROCESSOR_TEST_SRCS) \
tensorflow/lite/experimental/micro/examples/micro_speech/preprocessor.cc
PREPROCESSOR_FIXED_TEST_SRCS += \
$(PREPROCESSOR_TEST_SRCS) \
tensorflow/lite/experimental/micro/examples/micro_speech/fixed_point/preprocessor.cc
MICROLITE_TEST_SRCS := \
$(wildcard tensorflow/lite/experimental/micro/*test.cc) \
$(wildcard tensorflow/lite/experimental/micro/kernels/*test.cc)
@ -98,9 +75,6 @@ MICROLITE_CC_SRCS := $(filter-out $(MICROLITE_TEST_SRCS), $(MICROLITE_CC_BASE_SR
include $(wildcard $(MAKEFILE_DIR)/targets/*_makefile.inc)
ALL_SRCS := \
$(MICRO_SPEECH_TEST_SRCS) \
$(PREPROCESSOR_REFERENCE_TEST_SRCS) \
$(PREPROCESSOR_FIXED_TEST_SRCS) \
$(MICROLITE_CC_SRCS) \
$(MICROLITE_TEST_SRCS)
@ -112,22 +86,12 @@ LIBDIR := $(GENDIR)lib/
MICROLITE_LIB_PATH := $(LIBDIR)$(MICROLITE_LIB_NAME)
MICRO_SPEECH_TEST_BINARY := $(BINDIR)micro_speech_test
PREPROCESSOR_REFERENCE_TEST_BINARY := $(BINDIR)preprocessor_reference_test
PREPROCESSOR_FIXED_TEST_BINARY := $(BINDIR)preprocessor_fixed_test
CXX := $(CC_PREFIX)${TARGET_TOOLCHAIN_PREFIX}g++
CC := $(CC_PREFIX)${TARGET_TOOLCHAIN_PREFIX}gcc
AR := $(CC_PREFIX)${TARGET_TOOLCHAIN_PREFIX}ar
MICRO_SPEECH_TEST_OBJS := $(addprefix $(OBJDIR), \
$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(patsubst %.S,%.o,$(MICRO_SPEECH_TEST_SRCS)))))
PREPROCESSOR_REFERENCE_TEST_OBJS := $(addprefix $(OBJDIR), \
$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(PREPROCESSOR_REFERENCE_TEST_SRCS))))
PREPROCESSOR_FIXED_TEST_OBJS := $(addprefix $(OBJDIR), \
$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(PREPROCESSOR_FIXED_TEST_SRCS))))
# Load the examples.
include $(wildcard tensorflow/lite/experimental/micro/examples/*/Makefile.inc)
MICROLITE_LIB_OBJS := $(addprefix $(OBJDIR), \
$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(MICROLITE_CC_SRCS))))
@ -164,42 +128,6 @@ $(MICROLITE_LIB_PATH): tensorflow/lite/schema/schema_generated.h $(MICROLITE_LIB
@mkdir -p $(dir $@)
$(AR) $(ARFLAGS) $(MICROLITE_LIB_PATH) $(MICROLITE_LIB_OBJS)
$(MICRO_SPEECH_TEST_BINARY): $(MICRO_SPEECH_TEST_OBJS) $(MICROLITE_LIB_PATH)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(INCLUDES) \
-o $(MICRO_SPEECH_TEST_BINARY) $(MICRO_SPEECH_TEST_OBJS) \
$(LIBFLAGS) $(MICROLITE_LIB_PATH) $(LDFLAGS) $(MICROLITE_LIBS)
micro_speech_test: $(MICRO_SPEECH_TEST_BINARY)
micro_speech_test_bin: $(MICRO_SPEECH_TEST_BINARY).bin
test_micro_speech: $(MICRO_SPEECH_TEST_BINARY)
$(TEST_SCRIPT) $(MICRO_SPEECH_TEST_BINARY) '~~~ALL TESTS PASSED~~~'
$(PREPROCESSOR_REFERENCE_TEST_BINARY): $(PREPROCESSOR_REFERENCE_TEST_OBJS) $(MICROLITE_LIB_PATH)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(INCLUDES) \
-o $(PREPROCESSOR_REFERENCE_TEST_BINARY) $(PREPROCESSOR_REFERENCE_TEST_OBJS) \
$(LIBFLAGS) $(MICROLITE_LIB_PATH) $(LDFLAGS) $(MICROLITE_LIBS)
preprocessor_reference_test: $(PREPROCESSOR_REFERENCE_TEST_BINARY)
preprocessor_reference_test_bin: $(PREPROCESSOR_REFERENCE_TEST_BINARY).bin
test_preprocessor_reference: $(PREPROCESSOR_REFERENCE_TEST_BINARY)
$(TEST_SCRIPT) $(PREPROCESSOR_REFERENCE_TEST_BINARY) '~~~ALL TESTS PASSED~~~'
$(PREPROCESSOR_FIXED_TEST_BINARY): $(PREPROCESSOR_FIXED_TEST_OBJS) $(MICROLITE_LIB_PATH)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(INCLUDES) \
-o $(PREPROCESSOR_FIXED_TEST_BINARY) $(PREPROCESSOR_FIXED_TEST_OBJS) \
$(LIBFLAGS) $(MICROLITE_LIB_PATH) $(LDFLAGS) $(MICROLITE_LIBS)
preprocessor_fixed_test: $(PREPROCESSOR_FIXED_TEST_BINARY)
preprocessor_fixed_test_bin: $(PREPROCESSOR_FIXED_TEST_BINARY).bin
test_preprocessor_fixed: $(PREPROCESSOR_FIXED_TEST_BINARY)
$(TEST_SCRIPT) $(PREPROCESSOR_FIXED_TEST_BINARY) '~~~ALL TESTS PASSED~~~'
$(BINDIR)%_test : $(OBJDIR)%_test.o $(MICROLITE_LIB_PATH)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(INCLUDES) \
@ -209,7 +137,13 @@ $(BINDIR)%_test : $(OBJDIR)%_test.o $(MICROLITE_LIB_PATH)
$(BINDIR)%.test_target: $(BINDIR)%_test
$(TEST_SCRIPT) $< '~~~ALL TESTS PASSED~~~'
$(info $(MICROLITE_TEST_TARGETS))
# snease: Add %.bin rule here since BINDIR is now defined
# These are microcontroller-specific rules for converting the ELF output
# of the linker into a binary image that can be loaded directly.
OBJCOPY := $(TARGET_TOOLCHAIN_PREFIX)objcopy
$(BINDIR)%.bin: $(BINDIR)%
@mkdir -p $(dir $@)
$(OBJCOPY) $< $@ -O binary
test: test_micro_speech $(MICROLITE_TEST_TARGETS)

View File

@ -35,6 +35,9 @@ CMSIS_URL="https://github.com/ARM-software/CMSIS_5/archive/5.4.0.zip"
STM32_BARE_LIB_URL="https://github.com/google/stm32_bare_lib/archive/c07d611fb0af58450c5a3e0ab4d52b47f99bc82d.zip"
SIFIVE_FE310_LIB_URL="https://github.com/sifive/freedom-e-sdk/archive/baeeb8fd497a99b3c141d7494309ec2e64f19bdf.zip"
RISCV_TOOLCHAIN_URL="https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-20181030-x86_64-linux-ubuntu14.tar.gz"
AP3_URL="https://github.com/AmbiqMicro/TFLiteMicro_Apollo3/archive/dfbcef9a57276c087d95aab7cb234f1d4c9eaaba.zip"
CUST_CMSIS_URL="https://github.com/AmbiqMicro/TFLiteMicro_CustCMSIS/archive/8f63966c5692e6a3a83956efd2e4aed77c4c9949.zip"
GCC_EMBEDDED_URL="https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2018q2/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2"
download_and_extract() {
local usage="Usage: download_and_extract URL DIR"
@ -44,6 +47,8 @@ download_and_extract() {
mkdir -p "${dir}"
if [[ "${url}" == *gz ]]; then
curl -Ls "${url}" | tar -C "${dir}" --strip-components=1 -xz
elif [[ "${url}" == *bz2 ]]; then
curl -Ls "${url}" | tar -C "${dir}" --strip-components=1 -xj
elif [[ "${url}" == *zip ]]; then
tempdir=$(mktemp -d)
tempdir2=$(mktemp -d)
@ -67,11 +72,37 @@ download_and_extract() {
find "${dir}" -type f -name '*BUILD' -delete
}
patch_apollo3_sdk() {
local ap3_dir="${1}"
if [ ! -f ${ap3_dir}/VERSION.txt ]; then
echo "Could not find ${ap3_dir}, skipping Apollo3 SDK";
return;
fi
local src_dir=${ap3_dir}/boards/apollo3_evb/examples/hello_world/gcc
local dest_dir=${ap3_dir}/boards/apollo3_evb/examples/hello_world/gcc_patched
rm -rf ${dest_dir}
mkdir ${dest_dir}
cp "${src_dir}/startup_gcc.c" "${dest_dir}/startup_gcc.c"
cp "${src_dir}/hello_world.ld" "${dest_dir}/apollo3evb.ld"
sed -i -e '131s/1024/1024\*20/g' "${dest_dir}/startup_gcc.c"
sed -i -e 's/main/_main/g' "${dest_dir}/startup_gcc.c"
sed -i -e '3s/hello_world.ld/apollo3evb.ld/g' "${dest_dir}/apollo3evb.ld"
sed -i -e '3s/startup_gnu/startup_gcc/g' "${dest_dir}/apollo3evb.ld"
sed -i -e '6s/am_reset_isr/Reset_Handler/g' "${dest_dir}/apollo3evb.ld"
sed -i -e '22s/\*(.text\*)/\*(.text\*)\n\n\t\/\* These are the C++ global constructors. Stick them all here and\n\t \* then walk through the array in main() calling them all.\n\t \*\/\n\t_init_array_start = .;\n\tKEEP (\*(SORT(.init_array\*)))\n\t_init_array_end = .;\n\n\t\/\* XXX Currently not doing anything for global destructors. \*\/\n/g' "${dest_dir}/apollo3evb.ld"
sed -i -e "70s/} > SRAM/} > SRAM\n \/\* Add this to satisfy reference to symbol 'end' from libnosys.a(sbrk.o)\n \* to denote the HEAP start.\n \*\/\n end = .;/g" "${dest_dir}/apollo3evb.ld"
echo "Finished preparing Apollo3 files"
}
download_and_extract "${GEMMLOWP_URL}" "${DOWNLOADS_DIR}/gemmlowp"
download_and_extract "${FLATBUFFERS_URL}" "${DOWNLOADS_DIR}/flatbuffers"
download_and_extract "${CMSIS_URL}" "${DOWNLOADS_DIR}/cmsis"
download_and_extract "${STM32_BARE_LIB_URL}" "${DOWNLOADS_DIR}/stm32_bare_lib"
download_and_extract "${SIFIVE_FE310_LIB_URL}" "${DOWNLOADS_DIR}/sifive_fe310_lib"
download_and_extract "${RISCV_TOOLCHAIN_URL}" "${DOWNLOADS_DIR}/riscv_toolchain"
download_and_extract "${AP3_URL}" "${DOWNLOADS_DIR}/apollo3_ext"
patch_apollo3_sdk "${DOWNLOADS_DIR}/Apollo3-SDK-2018.08.13"
download_and_extract "${CUST_CMSIS_URL}" "${DOWNLOADS_DIR}/CMSIS_ext"
download_and_extract "${GCC_EMBEDDED_URL}" "${DOWNLOADS_DIR}/gcc_embedded"
echo "download_dependencies.sh completed successfully." >&2

View File

@ -0,0 +1,4 @@
startup_gcc.c
am_*.c
libam*.a

View File

@ -1,123 +0,0 @@
/* Copyright 2018 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 <stdint.h>
#include "am_mcu_apollo.h" // Defines AM_CMSIS_REGS
#include "am_bsp.h"
#include "am_util.h"
//*****************************************************************************
//
// The entry point for the application.
//
//*****************************************************************************
extern int main(int argc, char**argv);
void DebugLog(const char* s) { am_util_stdio_printf( "%s", s); }
void DebugLogInt32(int32_t i) { am_util_stdio_printf( "%d", i); }
void DebugLogUInt32(uint32_t i) { am_util_stdio_printf( "%d", i); }
void DebugLogHex(uint32_t i) { am_util_stdio_printf( "0x%8x", i); }
void DebugLogFloat(float i) { am_util_stdio_printf( "%f", i); }
int _main(void)
{
am_util_id_t sIdDevice;
uint32_t ui32StrBuf;
//
// Set the clock frequency.
//
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
//
// Set the default cache configuration
//
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
//
// Configure the board for low power operation.
//
am_bsp_low_power_init();
//
// Initialize the printf interface for UART output
//
am_bsp_uart_printf_enable();
//
// Print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("Hello World!\n\n");
//
// Print the device info.
//
am_util_id_device(&sIdDevice);
am_util_stdio_printf("Vendor Name: %s\n", sIdDevice.pui8VendorName);
am_util_stdio_printf("Device type: %s\n", sIdDevice.pui8DeviceName);
am_util_stdio_printf("Qualified: %s\n",
sIdDevice.sMcuCtrlDevice.ui32Qualified ?
"Yes" : "No");
am_util_stdio_printf("Device Info:\n"
"\tPart number: 0x%08X\n"
"\tChip ID0: 0x%08X\n"
"\tChip ID1: 0x%08X\n"
"\tRevision: 0x%08X (Rev%c%c)\n",
sIdDevice.sMcuCtrlDevice.ui32ChipPN,
sIdDevice.sMcuCtrlDevice.ui32ChipID0,
sIdDevice.sMcuCtrlDevice.ui32ChipID1,
sIdDevice.sMcuCtrlDevice.ui32ChipRev,
sIdDevice.ui8ChipRevMaj, sIdDevice.ui8ChipRevMin );
//
// If not a multiple of 1024 bytes, append a plus sign to the KB.
//
ui32StrBuf = ( sIdDevice.sMcuCtrlDevice.ui32FlashSize % 1024 ) ? '+' : 0;
am_util_stdio_printf("\tFlash size: %7d (%d KB%s)\n",
sIdDevice.sMcuCtrlDevice.ui32FlashSize,
sIdDevice.sMcuCtrlDevice.ui32FlashSize / 1024,
&ui32StrBuf);
ui32StrBuf = ( sIdDevice.sMcuCtrlDevice.ui32SRAMSize % 1024 ) ? '+' : 0;
am_util_stdio_printf("\tSRAM size: %7d (%d KB%s)\n\n",
sIdDevice.sMcuCtrlDevice.ui32SRAMSize,
sIdDevice.sMcuCtrlDevice.ui32SRAMSize / 1024,
&ui32StrBuf);
//
// Print the compiler version.
//
am_util_stdio_printf("App Compiler: %s\n", COMPILER_VERSION);
#ifdef AM_PART_APOLLO3
am_util_stdio_printf("HAL Compiler: %s\n", g_ui8HALcompiler);
am_util_stdio_printf("HAL SDK version: %d.%d.%d\n",
g_ui32HALversion.s.Major,
g_ui32HALversion.s.Minor,
g_ui32HALversion.s.Revision);
am_util_stdio_printf("HAL compiled with %s-style registers\n",
g_ui32HALversion.s.bAMREGS ? "AM_REG" : "CMSIS");
am_util_stdio_printf("&sIdDevice: 0x%x, &ui32StrBuf: 0x%x\n", &sIdDevice, &ui32StrBuf);
am_hal_security_info_t secInfo;
char sINFO[32];
uint32_t ui32Status;
#endif // AM_PART_APOLLO3
main(0, NULL);
}

View File

@ -0,0 +1,35 @@
#!/bin/bash
# Copyright 2017 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.
# ==============================================================================
AP3_DIR="tensorflow/lite/experimental/micro/tools/make/downloads/Apollo3-SDK-2018.08.13"
if [ ! -d $AP3_DIR ]; then
echo "Apollo 3 SDK does not exist"
echo "Either the SDK has not been downloaded, or this script is not being run from the root of the repository"
else
DEST_DIR="tensorflow/lite/experimental/micro/tools/make/targets/apollo3evb"
cp "$AP3_DIR/boards/apollo3_evb/examples/hello_world/gcc/startup_gcc.c" "$DEST_DIR"
cp "$AP3_DIR/boards/apollo3_evb/examples/hello_world/gcc/hello_world.ld" "$DEST_DIR/apollo3evb.ld"
sed -i -e '131s/1024/1024\*20/g' "$DEST_DIR/startup_gcc.c"
sed -i -e 's/main/_main/g' "$DEST_DIR/startup_gcc.c"
sed -i -e '3s/hello_world.ld/apollo3evb.ld/g' "$DEST_DIR/apollo3evb.ld"
sed -i -e '3s/startup_gnu/startup_gcc/g' "$DEST_DIR/apollo3evb.ld"
sed -i -e '6s/am_reset_isr/Reset_Handler/g' "$DEST_DIR/apollo3evb.ld"
sed -i -e '22s/\*(.text\*)/\*(.text\*)\n\n\t\/\* These are the C++ global constructors. Stick them all here and\n\t \* then walk through the array in main() calling them all.\n\t \*\/\n\t_init_array_start = .;\n\tKEEP (\*(SORT(.init_array\*)))\n\t_init_array_end = .;\n\n\t\/\* XXX Currently not doing anything for global destructors. \*\/\n/g' "$DEST_DIR/apollo3evb.ld"
sed -i -e "70s/} > SRAM/} > SRAM\n \/\* Add this to satisfy reference to symbol 'end' from libnosys.a(sbrk.o)\n \* to denote the HEAP start.\n \*\/\n end = .;/g" "$DEST_DIR/apollo3evb.ld"
echo "Finished preparing Apollo3 files"
fi

View File

@ -1,13 +1,14 @@
# Settings for apollo3 evb platforms.
ifeq ($(TARGET), apollo3evb)
export PATH := $(MAKEFILE_DIR)/downloads/gcc_embedded/bin/:$(PATH)
TARGET_ARCH := cortex-m4
TARGET_TOOLCHAIN_PREFIX := arm-none-eabi-
# Download the Ambiq Apollo3 SDK and set this variable to find the header
# files:
APOLLO3_SDK := /ssd/ambiq/AmbiqSuite\ SDK\ for\ Apollo3/Apollo3-SDK-2018.08.13/
APOLLO3_SDK := $(MAKEFILE_DIR)/downloads/Apollo3-SDK-2018.08.13
# Need a pointer to the GNU ARM toolchain for crtbegin.o for the fp functions
# with the softfp interfaces.
GCC_ARM := /ssd/gnu_arm_toolchain/gcc-arm-none-eabi-7-2018-q2-update/
GCC_ARM := $(MAKEFILE_DIR)/downloads/gcc_embedded/
PLATFORM_FLAGS = \
-DPART_apollo3 \
@ -16,6 +17,8 @@ ifeq ($(TARGET), apollo3evb)
-DGEMMLOWP_ALLOW_SLOW_SCALAR_FALLBACK \
-DTF_LITE_STATIC_MEMORY \
-DTF_LITE_MCU_DEBUG_LOG \
-D __FPU_PRESENT=1 \
-DARM_MATH_CM4 \
-fno-rtti \
-fmessage-length=0 \
-fno-exceptions \
@ -41,8 +44,8 @@ ifeq ($(TARGET), apollo3evb)
-fomit-frame-pointer \
-fpermissive \
-nostdlib \
-g \
-Os
-ggdb \
-O3
CXXFLAGS += $(PLATFORM_FLAGS)
CCFLAGS += $(PLATFORM_FLAGS)
LDFLAGS += \
@ -52,17 +55,18 @@ ifeq ($(TARGET), apollo3evb)
-Wl,--start-group -lm -lc -lgcc -Wl,--end-group \
-fno-exceptions \
-nostdlib --specs=nano.specs -t -lstdc++ -lc -lnosys -lm \
-Wl,-T,$(MAKEFILE_DIR)/targets/apollo3evb/apollo3evb.ld \
-Wl,-T,$(APOLLO3_SDK)/boards/apollo3_evb/examples/hello_world/gcc_patched/apollo3evb.ld \
-Wl,-Map=$(MAKEFILE_DIR)/gen/$(TARGET).map,--cref
BUILD_TYPE := micro
# The apollo3evb libs should be copied from the SDK after building them.
MICROLITE_LIBS := \
$(MAKEFILE_DIR)/targets/apollo3evb/libam_bsp.a \
$(MAKEFILE_DIR)/targets/apollo3evb/libam_hal.a \
$(APOLLO3_SDK)/boards/apollo3_evb/bsp/gcc/bin/libam_bsp.a \
$(APOLLO3_SDK)/mcu/apollo3/hal/gcc/bin/libam_hal.a \
$(GCC_ARM)/lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/fpv4-sp/softfp/crtbegin.o \
-lm
INCLUDES += \
-isystem$(MAKEFILE_DIR)/downloads/cmsis/CMSIS/Core/Include/ \
-isystem$(MAKEFILE_DIR)/downloads/cmsis/CMSIS/DSP/Include/ \
-I$(MAKEFILE_DIR)/downloads/CMSIS_ext/ \
-I$(GCC_ARM)/arm-none-eabi/ \
-I$(APOLLO3_SDK)/mcu/apollo3/ \
-I$(APOLLO3_SDK)/CMSIS/AmbiqMicro/Include/ \
@ -79,26 +83,37 @@ ifeq ($(TARGET), apollo3evb)
# setting clock speed, default uart setups, etc. and an implementation
# of the DebugLog interfaces.
MICROLITE_CC_SRCS += \
$(MAKEFILE_DIR)/targets/apollo3evb/startup_gcc.c \
$(MAKEFILE_DIR)/targets/apollo3evb/_main.c \
$(MAKEFILE_DIR)/targets/apollo3evb/am_util_delay.c \
$(MAKEFILE_DIR)/targets/apollo3evb/am_util_faultisr.c \
$(MAKEFILE_DIR)/targets/apollo3evb/am_util_id.c \
$(MAKEFILE_DIR)/targets/apollo3evb/am_util_stdio.c
$(APOLLO3_SDK)/boards/apollo3_evb/examples/hello_world/gcc_patched/startup_gcc.c \
$(APOLLO3_SDK)/utils/am_util_delay.c \
$(APOLLO3_SDK)/utils/am_util_faultisr.c \
$(APOLLO3_SDK)/utils/am_util_id.c \
$(APOLLO3_SDK)/utils/am_util_stdio.c
CMSIS_SRC_DIR := tensorflow/lite/experimental/micro/tools/make/downloads/cmsis/CMSIS/DSP/Source
CMSIS_SRCS := \
$(CMSIS_SRC_DIR)/BasicMathFunctions/arm_mult_q15.c \
$(CMSIS_SRC_DIR)/TransformFunctions/arm_rfft_init_q15.c \
$(CMSIS_SRC_DIR)/TransformFunctions/arm_rfft_q15.c \
$(CMSIS_SRC_DIR)/TransformFunctions/arm_cfft_q15.c \
$(CMSIS_SRC_DIR)/TransformFunctions/arm_cfft_radix4_q15.c \
$(CMSIS_SRC_DIR)/CommonTables/arm_const_structs.c \
$(CMSIS_SRC_DIR)/CommonTables/arm_common_tables.c \
$(CMSIS_SRC_DIR)/StatisticsFunctions/arm_mean_q15.c \
$(CMSIS_SRC_DIR)/StatisticsFunctions/arm_max_q7.c
AP3_EXT_MICRO_DIR := $(MAKEFILE_DIR)/downloads/apollo3_ext
AP3_MICRO_DIR := tensorflow/lite/experimental/micro/examples/micro_speech/apollo3
CMSIS_DIR := tensorflow/lite/experimental/micro/examples/micro_speech/CMSIS
CMSIS_EXT_DIR := $(MAKEFILE_DIR)/downloads/CMSIS_ext
MICRO_SPEECH_TEST_SRCS += \
$(AP3_MICRO_DIR)/_main.c
TEST_SCRIPT := tensorflow/lite/experimental/log_test/test_apollo3evb_binary.sh
# These are tests that don't currently work on the blue pill.
# These are tests that don't currently work on the Apollo3 board.
EXCLUDED_TESTS := \
tensorflow/lite/experimental/micro/micro_interpreter_test.cc \
tensorflow/lite/experimental/micro/simple_tensor_allocator_test.cc
MICROLITE_TEST_SRCS := $(filter-out $(EXCLUDED_TESTS), $(MICROLITE_TEST_SRCS))
# These are microcontroller-specific rules for converting the ELF output
# of the linker into a binary image that can be loaded directly.
OBJCOPY := $(TARGET_TOOLCHAIN_PREFIX)objcopy
$(BINDIR)/%.bin: $(BINDIR)/%
@mkdir -p $(dir $@)
$(OBJCOPY) $< $@ -O binary
endif