samples/96b_argonkey: divided test into sensor and microphone
We have now two code samples available for ArgonKey board: 1. sensors sample, fetching data from accel/gyro/mag, barometer, humidity and proximity sensors 2. microphone sample, acquiring 5s audio @16KHz from the on-board microphone. Signed-off-by: Armando Visconti <armando.visconti@st.com>
This commit is contained in:
parent
c4b3583afd
commit
69a3566868
10
samples/boards/96b_argonkey/microphone/CMakeLists.txt
Normal file
10
samples/boards/96b_argonkey/microphone/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2018 STMicroelectronics
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.13.1)
|
||||
|
||||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
project(NONE)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
129
samples/boards/96b_argonkey/microphone/README.rst
Normal file
129
samples/boards/96b_argonkey/microphone/README.rst
Normal file
|
@ -0,0 +1,129 @@
|
|||
.. _ArgonKey_Microphone:
|
||||
|
||||
ArgonKey Board Microphone
|
||||
#########################
|
||||
|
||||
Overview
|
||||
********
|
||||
This sample provides an example of how to acquire audio through
|
||||
the on-board MP34DT05 microphone. The microphone generates a PDM
|
||||
stream which is acquired through I2S. The PDM stream is then
|
||||
converted to PCM using the OpenPDMFilter library, which is available
|
||||
in source code in this sample.
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
This sample requires the ArgonKey board plus a USB to TTL 1V8 serial
|
||||
cable to get the output audio stream. The board can be powered
|
||||
in either one of the following two ways:
|
||||
|
||||
- mezzanine mode, plugging the ArgonKey to HiKey board thru its 96Board
|
||||
low-speed connector
|
||||
- standalone mode, supplying 5V directly on P1 connector
|
||||
|
||||
References
|
||||
**********
|
||||
|
||||
- :ref:`96b_argonkey`
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/boards/96b_argonkey/microphone
|
||||
:host-os: unix
|
||||
:board: 96b_argonkey
|
||||
:goals: run
|
||||
:compact:
|
||||
|
||||
Sample Output
|
||||
=============
|
||||
|
||||
The example acquires 5s of audio and prints out the PCM stream on COM port.
|
||||
A USB to TTL 1V8 serial cable may be attached to the low speed connector on
|
||||
the back of the board on P3.5 (TX) and P3.7 (RX).
|
||||
|
||||
As soon as the acquisition starts the green LED glows. At the end of the
|
||||
acquisition both the green and red LEDs go on and the PCM stream is sent
|
||||
on COM port. When the output is completed the green LED goes off and the red
|
||||
LED stays on. The process can be reiterated by pressing the RST button.
|
||||
|
||||
- audio acquisition starts: GRN on - RED off
|
||||
- audio acquisition ends: GRN on - RED on
|
||||
- audio output ends: GRN off - RED on
|
||||
|
||||
The characteristics of the PCM audio are hardcoded in the example:
|
||||
|
||||
- 16KHz sample rate
|
||||
- 16 bits per sample
|
||||
- 1 channel (mono), as only 1 microphone is available
|
||||
|
||||
Five seconds of acquisition at a 16KHz sampling rate yields 80,000 16-bit samples.
|
||||
The microphone PDM requested clock should lead the MP34DT05 driver to select an
|
||||
oversampling/decimation factor equal to 128, resulting in a 2.048MHz bit clock.
|
||||
|
||||
See pcm and pdm configuration in file :file:`samples/boards/96b_argonkey/microphone/src/main.c`.
|
||||
|
||||
.. note:: It is possible to change the AUDIO_FREQ to 32000 acquiring only 2500 ms. In this
|
||||
case the oversampling/decimation factor will be 64.
|
||||
|
||||
At the end of the acquisition the PCM data will be printed on the terminal
|
||||
emulator in either binary or ASCII format. The output is controlled by
|
||||
following macro, off by default, in :file:`samples/boards/96b_argonkey/microphone/src/main.c`:
|
||||
|
||||
* :c:macro:`PCM_OUTPUT_IN_ASCII`
|
||||
|
||||
Binary PCM Output
|
||||
-----------------
|
||||
|
||||
The ttyUSB0 port must be configured in raw mode to avoid having
|
||||
characters 'cooked' out.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
stty -F /dev/ttyUSB0 115200 raw
|
||||
cat /dev/ttyUSB0 > /tmp/sound.raw
|
||||
|
||||
.. note:: In case the character 0x0a is interpreted as NL and an 0x0d (CR) is added,
|
||||
you may need to remove it::
|
||||
|
||||
dos2unix -f /tmp/sound.raw
|
||||
|
||||
ASCII PCM Output
|
||||
----------------
|
||||
|
||||
It is also possible to recompile and to have PCM output in ASCII, which needs
|
||||
to be converted to binary later on. The output format is the following:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
ArgonKey test!!
|
||||
-- start
|
||||
0xfbe0,
|
||||
0xfbf0,
|
||||
0xfc0c,
|
||||
0xfc24,
|
||||
0xfc3c,
|
||||
0xfc4c,
|
||||
0xfc68,
|
||||
0xfc48,
|
||||
|
||||
[...]
|
||||
|
||||
0xfb98,
|
||||
0xfb98,
|
||||
0xfbb8,
|
||||
0xfbac,
|
||||
0xfbc4,
|
||||
0xfbe8,
|
||||
0xfbf4,
|
||||
-- end
|
||||
|
||||
Play PCM Audio
|
||||
--------------
|
||||
|
||||
Now that we have a binary PCM file (say sound.raw), you can use,
|
||||
for example, the audicity open source editor/player to load and play it.
|
||||
Use the 'Import->Raw Data' menu to load the sound.raw file as
|
||||
signed 16 bit PCM, Little Endian, mono format @16KHz.
|
17
samples/boards/96b_argonkey/microphone/prj.conf
Normal file
17
samples/boards/96b_argonkey/microphone/prj.conf
Normal file
|
@ -0,0 +1,17 @@
|
|||
CONFIG_PRINTK=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2S=y
|
||||
CONFIG_GPIO=y
|
||||
CONFIG_LED=y
|
||||
CONFIG_LP3943=y
|
||||
CONFIG_AUDIO=y
|
||||
CONFIG_AUDIO_DMIC=y
|
||||
CONFIG_AUDIO_MPXXDTYY=y
|
||||
|
||||
# When on-board microphone is used the DMA must run w/o things
|
||||
# that could slow it down. So DMA logging must be completely
|
||||
# disabled and DMA interrupts must run at maximum priority.
|
||||
|
||||
CONFIG_DMA=y
|
||||
CONFIG_DMA_LOG_LEVEL_OFF=y
|
||||
CONFIG_DMA_0_IRQ_PRI=0
|
9
samples/boards/96b_argonkey/microphone/sample.yaml
Normal file
9
samples/boards/96b_argonkey/microphone/sample.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
sample:
|
||||
description: ArgonKey sensor testing
|
||||
name: ArgonKey test
|
||||
tests:
|
||||
test:
|
||||
harness: sensor
|
||||
platform_whitelist: 96b_argonkey
|
||||
tags: sensors
|
||||
depends_on: i2s gpio
|
189
samples/boards/96b_argonkey/microphone/src/main.c
Normal file
189
samples/boards/96b_argonkey/microphone/src/main.c
Normal file
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Copyright (c) 2018 STMicroelectronics
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <zephyr.h>
|
||||
#include <misc/printk.h>
|
||||
|
||||
#include <gpio.h>
|
||||
#include <led.h>
|
||||
|
||||
#include <audio/dmic.h>
|
||||
|
||||
/* uncomment if you want PCM output in ascii */
|
||||
/*#define PCM_OUTPUT_IN_ASCII 1 */
|
||||
|
||||
#define AUDIO_FREQ 16000
|
||||
#define CHAN_SIZE 16
|
||||
#define PCM_BLK_SIZE_MS ((AUDIO_FREQ/1000) * sizeof(s16_t))
|
||||
|
||||
#define NUM_MS 5000
|
||||
|
||||
K_MEM_SLAB_DEFINE(rx_mem_slab, PCM_BLK_SIZE_MS, NUM_MS, 1);
|
||||
|
||||
struct pcm_stream_cfg mic_streams = {
|
||||
.pcm_rate = AUDIO_FREQ,
|
||||
.pcm_width = CHAN_SIZE,
|
||||
.block_size = PCM_BLK_SIZE_MS,
|
||||
.mem_slab = &rx_mem_slab,
|
||||
};
|
||||
|
||||
struct dmic_cfg cfg = {
|
||||
.io = {
|
||||
/* requesting a pdm freq around 2MHz */
|
||||
.min_pdm_clk_freq = 1800000,
|
||||
.max_pdm_clk_freq = 2500000,
|
||||
},
|
||||
.streams = &mic_streams,
|
||||
.channel = {
|
||||
.req_num_chan = 1,
|
||||
},
|
||||
};
|
||||
|
||||
#define NUM_LEDS 12
|
||||
#define DELAY_TIME K_MSEC(25)
|
||||
|
||||
void signal_sampling_started(void)
|
||||
{
|
||||
static struct device *led0, *led1;
|
||||
|
||||
led0 = device_get_binding(LED0_GPIO_CONTROLLER);
|
||||
gpio_pin_configure(led0, LED0_GPIO_PIN, GPIO_DIR_OUT);
|
||||
gpio_pin_write(led0, LED0_GPIO_PIN, 1);
|
||||
|
||||
led1 = device_get_binding(LED1_GPIO_CONTROLLER);
|
||||
gpio_pin_configure(led1, LED1_GPIO_PIN, GPIO_DIR_OUT);
|
||||
gpio_pin_write(led1, LED1_GPIO_PIN, 0);
|
||||
}
|
||||
|
||||
void signal_sampling_stopped(void)
|
||||
{
|
||||
static struct device *led0, *led1;
|
||||
|
||||
led0 = device_get_binding(LED0_GPIO_CONTROLLER);
|
||||
gpio_pin_configure(led0, LED0_GPIO_PIN, GPIO_DIR_OUT);
|
||||
gpio_pin_write(led0, LED0_GPIO_PIN, 1);
|
||||
|
||||
led1 = device_get_binding(LED1_GPIO_CONTROLLER);
|
||||
gpio_pin_configure(led1, LED1_GPIO_PIN, GPIO_DIR_OUT);
|
||||
gpio_pin_write(led1, LED1_GPIO_PIN, 1);
|
||||
}
|
||||
|
||||
void signal_print_stopped(void)
|
||||
{
|
||||
static struct device *led0, *led1;
|
||||
|
||||
led0 = device_get_binding(LED0_GPIO_CONTROLLER);
|
||||
gpio_pin_configure(led0, LED0_GPIO_PIN, GPIO_DIR_OUT);
|
||||
gpio_pin_write(led0, LED0_GPIO_PIN, 0);
|
||||
|
||||
led1 = device_get_binding(LED1_GPIO_CONTROLLER);
|
||||
gpio_pin_configure(led1, LED1_GPIO_PIN, GPIO_DIR_OUT);
|
||||
gpio_pin_write(led1, LED1_GPIO_PIN, 1);
|
||||
}
|
||||
|
||||
void *rx_block[NUM_MS];
|
||||
size_t rx_size = PCM_BLK_SIZE_MS;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int i;
|
||||
u32_t ms;
|
||||
|
||||
#ifdef CONFIG_LP3943
|
||||
static struct device *ledc;
|
||||
|
||||
ledc = device_get_binding(CONFIG_LP3943_DEV_NAME);
|
||||
if (!ledc) {
|
||||
printk("Could not get pointer to %s sensor\n",
|
||||
CONFIG_LP3943_DEV_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
/* turn all leds on */
|
||||
for (i = 0; i < NUM_LEDS; i++) {
|
||||
led_on(ledc, i);
|
||||
k_sleep(DELAY_TIME);
|
||||
}
|
||||
|
||||
/* turn all leds off */
|
||||
for (i = 0; i < NUM_LEDS; i++) {
|
||||
led_off(ledc, i);
|
||||
k_sleep(DELAY_TIME);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
printk("ArgonKey test!!\n");
|
||||
|
||||
int ret;
|
||||
|
||||
struct device *mic_dev = device_get_binding(DT_MPXXDTYY_DEV_NAME);
|
||||
|
||||
if (!mic_dev) {
|
||||
printk("Could not get pointer to %s device\n",
|
||||
DT_MPXXDTYY_DEV_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = dmic_configure(mic_dev, &cfg);
|
||||
if (ret < 0) {
|
||||
printk("microphone configuration error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = dmic_trigger(mic_dev, DMIC_TRIGGER_START);
|
||||
if (ret < 0) {
|
||||
printk("microphone start trigger error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
signal_sampling_started();
|
||||
|
||||
/* Acquire microphone audio */
|
||||
for (ms = 0; ms < NUM_MS; ms++) {
|
||||
dmic_read(mic_dev, 0, &rx_block[ms], &rx_size, 2000);
|
||||
if (ret < 0) {
|
||||
printk("microphone audio read error\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
signal_sampling_stopped();
|
||||
|
||||
/* print PCM stream */
|
||||
#ifdef PCM_OUTPUT_IN_ASCII
|
||||
printk("-- start\n");
|
||||
int j;
|
||||
|
||||
for (i = 0; i < NUM_MS; i++) {
|
||||
u16_t *pcm_out = rx_block[i];
|
||||
|
||||
for (j = 0; j < rx_size/2; j++) {
|
||||
printk("0x%04x,\n", pcm_out[j]);
|
||||
}
|
||||
}
|
||||
printk("-- end\n");
|
||||
#else
|
||||
unsigned char pcm_l, pcm_h;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < NUM_MS; i++) {
|
||||
u16_t *pcm_out = rx_block[i];
|
||||
|
||||
for (j = 0; j < rx_size/2; j++) {
|
||||
pcm_l = (char)(pcm_out[j] & 0xFF);
|
||||
pcm_h = (char)((pcm_out[j] >> 8) & 0xFF);
|
||||
|
||||
_impl_k_str_out(&pcm_l, 1);
|
||||
_impl_k_str_out(&pcm_h, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
signal_print_stopped();
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
cmake_minimum_required(VERSION 3.13.1)
|
||||
# Copyright (c) 2018 STMicroelectronics
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.13.1)
|
||||
|
||||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
project(96b_argonkey)
|
|
@ -1,7 +1,7 @@
|
|||
.. _ArgonKey:
|
||||
.. _ArgonKey_Sensors:
|
||||
|
||||
ArgonKey sensor board
|
||||
#####################
|
||||
ArgonKey Board Sensors
|
||||
######################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
@ -12,15 +12,21 @@ It makes use of both the trigger and poll methods.
|
|||
Requirements
|
||||
************
|
||||
|
||||
This sample just requires the ArgonKey board.
|
||||
This sample just requires the ArgonKey board. The board can be powered
|
||||
in either one of the following two ways:
|
||||
|
||||
- mezzanine mode, plugging the ArgonKey to HiKey board thru its 96Board
|
||||
low-speed connector
|
||||
- standalone mode, supplying 5V directly on P1 connector
|
||||
|
||||
The user may select or unselect the sensors from
|
||||
:file:`samples/boards/96b_argonkey/prj.conf`.
|
||||
:file:`samples/boards/96b_argonkey/sensors/prj.conf`.
|
||||
|
||||
Please note that all sensor related code is conditionally compiled
|
||||
using the `#ifdef` directive, so this sample is supposed to always
|
||||
build correctly. Example:
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
#ifdef CONFIG_HTS221
|
||||
struct device *hum_dev = device_get_binding("HTS221");
|
||||
|
@ -39,8 +45,8 @@ References
|
|||
Building and Running
|
||||
********************
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/boards/96b_argonkey
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/boards/96b_argonkey/sensors
|
||||
:host-os: unix
|
||||
:board: 96b_argonkey
|
||||
:goals: run
|
||||
|
@ -49,27 +55,40 @@ Building and Running
|
|||
Sample Output
|
||||
=============
|
||||
|
||||
A USB to TTL 1V8 serial cable may be attached to the low speed connector on
|
||||
the back of the board on P3.5 (TX) and P3.7 (RX). User may use a simple
|
||||
terminal emulator, such as minicom, to capture the output.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
temp: 24.78 C; press: 101.448535
|
||||
humidity: 43.000000
|
||||
accel (4.121000 -6.859000 -5.384000) m/s2
|
||||
gyro (-0.008000 0.270000 0.161000) dps
|
||||
magn (0.021000 -0.552000 0.271500) gauss
|
||||
- (6) (trig_cnt: 254)
|
||||
proxy: 1 ;
|
||||
distance: 0 m -- 09 cm;
|
||||
temp: 30.35 C; press: 97.466259
|
||||
humidity: 43.500000
|
||||
accel (0.004000 -0.540000 9.757000) m/s2
|
||||
gyro (0.065000 -0.029000 -0.001000) dps
|
||||
magn (0.049500 0.208500 -0.544500) gauss
|
||||
- (6) (trig_cnt: 1878)
|
||||
|
||||
<repeats endlessly every 2s>
|
||||
|
||||
In this example the output is generated polling the sensor every 2 seconds.
|
||||
|
||||
Sensor data is printed in the following order (no data is printed for
|
||||
sensors that are not enabled):
|
||||
|
||||
#. *VL53L0x* proximity
|
||||
#. *LPS22HB* baro/temp
|
||||
#. *HTS221* humidity
|
||||
#. *LSM6DSL* accel
|
||||
#. *LSM6DSL* gyro
|
||||
#. *LIS2MDL* magnetometer (attached to *LSM6DSL*)
|
||||
|
||||
The proximity sensor displays two lines:
|
||||
|
||||
- a flag (proxy) that goes on when the distance is below 10cm
|
||||
- the absolute distance from the obstacle
|
||||
|
||||
The last line displays a counter of how many trigger interrupts
|
||||
has been received. It is possible to display the sensor data
|
||||
read for each trigger by enabling the **ARGONKEY_TEST_LOG** macro.
|
|
@ -278,7 +278,8 @@ void main(void)
|
|||
sensor_channel_get(tof_dev, SENSOR_CHAN_PROX, &prox);
|
||||
printk("proxy: %d ;\n", prox.val1);
|
||||
sensor_channel_get(tof_dev, SENSOR_CHAN_DISTANCE, &prox);
|
||||
printk("distance: %d -- %3d mm;\n", prox.val1, prox.val2);
|
||||
printk("distance: %d m -- %02d cm;\n", prox.val1,
|
||||
prox.val2/10000);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LPS22HB
|
Loading…
Reference in a new issue