Skip to content

Add USB examples #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Feb 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ jobs:
cd work
mbed config root .
mbed update
mbed add https://github.com/c1728p9/AudioPlayer
mbed test --compile -m K64F -t GCC_ARM -n sinppet-* --app-config=sinppet/TESTS/test.json -v

8 changes: 8 additions & 0 deletions APIs_USB/USBAudio_loopback_example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## USBAudio loopback example

The example loops input audio to the Mbed board back to the host PC, so that you may record the audio or listen to it through headphones or speakers.

1. Flash the board, and ensure the target's auxiliary USB is plugged into the PC.
2. Select "Mbed Audio" as your PC's default speaker and microphone devices.
3. Play some sound (YouTube, audio file, etc.) on your PC.
4. The audio that is playing on your PC will be recorded by Audacity via USB loopback.
16 changes: 16 additions & 0 deletions APIs_USB/USBAudio_loopback_example/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "mbed.h"
#include "USBAudio.h"

int main()
{
USBAudio audio(true, 44100, 2, 44100, 2);

printf("Looping audio\r\n");
static uint8_t buf[128];
while (true) {
if (!audio.read(buf, sizeof(buf))) {
memset(buf, 0, sizeof(buf));
}
audio.write(buf, sizeof(buf));
}
}
10 changes: 10 additions & 0 deletions APIs_USB/USBAudio_play_sound/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## USBAudio play sound example

The example loads raw audio data to your board's flash and then plays on the host PC over USB.

1. Flash the board, and ensure the target's auxiliary USB is plugged into the PC.
2. Open a program like Audacity, select microphone(Mbed audio) as an audio source and record sample.
3. Play the the recorded sound.

**Note:** This example should work whitout any modifications on the `NXP FRDM-K64F`, which has `1 MB` of flash memory.
**Note:** If you are using a board that has less than `1 MB` of flash memory, delete data from the end of the `data` array, and set `NUM_ELEMENTS` accordingly until the program size is small enough to flash without exceeding storage.
9,390 changes: 9,390 additions & 0 deletions APIs_USB/USBAudio_play_sound/main.cpp

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions APIs_USB/USBAudio_square_wave/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## USBAudio square wave example

The example outputs an audio square wave over USB.

1. Flash the board, and ensure the target's auxiliary USB is plugged into the PC.
2. Open a program like Audacity, select microphone(Mbed audio) as an audio source and record sample.
3. Zoom in the recorded sound and you should see a square wave.

**Note:** You can also route microphone(Mbed audio) to the output device and you should hear a buzz.
30 changes: 30 additions & 0 deletions APIs_USB/USBAudio_square_wave/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "mbed.h"
#include "USBAudio.h"
#include <math.h>

int16_t square_wave(uint32_t freq_hz, uint16_t amplitude, float time_s)
{
float period = (float)1 / freq_hz;
if (fmod(time_s, period) > period / 2) {
return amplitude / 2;
} else {
return -(amplitude / 2);
}
}

int main()
{
uint32_t tx_freq = 16000;
USBAudio audio(true, 8000, 2, tx_freq, 1, 10, 0x7bb8, 0x1112, 0x0100);
float cur_time = 0;
while (true) {
uint16_t samples[64];
for (int i = 0; i < 64; i++) {
samples[i] = square_wave(100, 5000, cur_time);
cur_time += 1.0 / tx_freq;
}
if (!audio.write((uint8_t *)&samples, sizeof(samples))) {
audio.write_wait_ready();
}
}
}
Binary file not shown.
12 changes: 12 additions & 0 deletions APIs_USB/USBAudio_wav_audio_player/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## USBAudio wav audio player example

The example plays the wav audio file from the target's SD card on the host PC over USB.

1. Flash the board, and ensure the target's auxiliary USB is plugged into the PC.
2. Store example audio file on the SD card in the following location: `songs/Bach-minuet-in-g.wav`.
3. Insert SD-card to the targte's SD-card slot.
4. Open a program like Audacity, select microphone(Mbed audio) as an audio source and record sample.
5. Play the recorded sound.

**Note:** This example should work whitout any modifications on the `NXP FRDM-K64F` with SD card connected.
**Note:** You can also route microphone(Mbed audio) to the output device and you should hear the music.
48 changes: 48 additions & 0 deletions APIs_USB/USBAudio_wav_audio_player/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "mbed.h"
#include "USBAudio.h"
#include "SDBlockDevice.h"
#include "FATFileSystem.h"
#include "AudioPlayer.h"
#include "WaveAudioStream.h"

#define BUFFER_SIZE 512
#define FREQ_25_MHZ 25000000

// Connection for SD card
SDBlockDevice sd(PTE3, PTE1, PTE2, PTE4);//MOSI, MISO, SCLK, CS
FATFileSystem fs("sd", &sd);

int main()
{
// Set the maximum speed so it can keep up with audio
sd.frequency(FREQ_25_MHZ);
// Load WAV file from SD card
// WAV file must be PCM signed 16-bit little endian
File file;
if (file.open(&fs, "songs/Bach-minuet-in-g.wav") != 0) {
error("Could not open 'songs/Bach-minuet-in-g.wav'\r\n");
}
WaveAudioStream song(&file);//"song" is the audio data object
// Check to see if file is a valid WAV file
if (song.get_valid() == 0) {
error("ERROR: not valid WAV file\r\n");
}
// WAV file must be 16-bit
if (song.get_bytes_per_sample() != 2) {
error("ERROR: WAV file not 2 bytes per sample (16-bit)\r\n");
}
USBAudio audio(true, 8000, song.get_channels(), song.get_sample_rate(), song.get_channels());
uint8_t buffer[BUFFER_SIZE];
int num_bytes_read;
printf("Playing Audio\r\n");
// Reads and plays data from WAV file over USB until song is over
while (1) {
num_bytes_read = song.read(buffer, BUFFER_SIZE);
if (num_bytes_read == -1) {
printf("Song Over\r\n");
break;
}
audio.write(buffer, num_bytes_read);
}
song.close();//Close the WAV file
}
11 changes: 11 additions & 0 deletions APIs_USB/USBCDC/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## USBCDC example

The example sends string in the loop using an emulated serial port over USB.

1. Flash the board, and ensure the target's auxiliary USB is plugged into the PC.
2. Open serial console (select associated COM port, transmission speed: 9600 bps).
3. Reset the target.
4. "Hello world" string should appear in the loop on the serial console in the 1-second delays.

**Note:** On Windows you can check the associated COM port in the Device Manager (USB Serial Device).
**Note:** If you want printf functionality, please see the USBSerial class.
14 changes: 14 additions & 0 deletions APIs_USB/USBCDC/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "mbed.h"
#include "USBCDC.h"

USBCDC cdc;

int main(void)
{

while (1) {
char msg[] = "Hello world\r\n";
cdc.send((uint8_t *)msg, strlen(msg));
ThisThread::sleep_for(1000);
}
}
12 changes: 7 additions & 5 deletions APIs_USB/USBCDC_ECM/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
The example sends an Ethernet frame that carries "Hello world" payload with a custom EtherType to the host PC. You can capture the frame by using a program called "Wireshark":

1. Flash the board, and ensure the target's USB is plugged into the PC.
2. Open Wireshark.
3. Click **Capture > Options** to select the correct capture interface.
4. Click **Capture > Start**.
5. Click captured packet from source address 12:34:56:78:9a:bc to see the "Hello world" payload.
2. Use `dmesg -w` linux command to determine address of the USB CDC Ethernet device.
3. Use `ifconfig` linux command to determine interface related to the the USB CDC Ethernet device.
4. Open Wireshark.
5. Click **Capture > Options** to select the correct capture interface.
6. Click **Capture > Start**.
7. Click captured packet from source address 12:34:56:78:9a:bc to see the "Hello world" payload.

**Note:** Because Windows doesn't provide native support for the USB CDC-ECM model, you must use third party drivers to use this class on Windows.
**Note:** Because Windows doesn't provide native support for the USB CDC-ECM model, you must use third party drivers to use this class on Windows. It is suggested to run this example on Linux.
22 changes: 5 additions & 17 deletions APIs_USB/USBCDC_ECM/main.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
/*
* Copyright (c) 2019 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* 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 "mbed.h"
#include "USBCDC_ECM.h"

Expand All @@ -36,8 +20,12 @@ USBCDC_ECM ecm;

int main()
{
// Let the USB device to setup
ThisThread::sleep_for(10);

// Send "Hello world" packets in loop
while (true) {
ecm.send((uint8_t *)&packet, sizeof(packet));
wait(1.0);
ThisThread::sleep_for(1000);
}
}
12 changes: 12 additions & 0 deletions APIs_USB/USBHID/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## USBHID example

This example turns the Mbed board into the HID (Human Interface Device) that can send and receive messages over USB.

1. Flash the board, and ensure the target's auxiliary USB is plugged into the PC.
2. Open serial console (select Mbed COM port, transmission speed: 9600 bps).
3. Reset the target.
4. Run the attached Python script.
5. The script will send 8 bytes of data (1 2 3 4 5 6 7 8) to the Mbed board and will read and print the data sent to the host computer by the Mbed board.
6. You should see "1 2 3 4 5 6 7 8" on the console and LED1 on the target device should change its state to the opposite.

**Note:** You can check the Mbed COM port using "mbedls" command.
31 changes: 31 additions & 0 deletions APIs_USB/USBHID/USBHID.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from pywinusb import hid

# Whenever the host computer receives data from the
# Mbed board, the received data is printed
def on_data(data):
print(f"Got message {data}")

'''
Gets all HIDs currently connected to host computer,
and sets the first device with string "mbed" in its
vendor name equal to variable mbed. This variable
will be used to send data to the Mbed board.
'''
all_hid_devices = hid.find_all_hid_devices()
mbed_devices = [d for d in all_hid_devices if "mbed" in d.vendor_name]

if mbed_devices is None:
raise ValueError("No HID devices found")

# A buffer of bytes representing the values 1-8
# The first byte is the report ID which must be 0
buffer = [0, 1, 2, 3, 4, 5, 6, 7, 8]

mbed_devices[0].open()
# Set custom raw data handler
mbed_devices[0].set_raw_data_handler(on_data)

# Send the message to the Mbed board
out_report = mbed_devices[0].find_output_reports()
out_report[0].set_raw_data(buffer)
out_report[0].send()
40 changes: 40 additions & 0 deletions APIs_USB/USBHID/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <stdio.h>
#include "mbed.h"
#include "drivers/USBHID.h"

// Declare a USBHID device
USBHID HID(8, 8, 0x1234, 0x0006, 0x0001, true);

HID_REPORT output_report = {
.length = 8,
.data = {0}
};
HID_REPORT input_report = {
.length = 0,
.data = {0}
};

DigitalOut led_out(LED1);

int main(void)
{
while (1) {

// Fill the report
for (int i = 0; i < output_report.length; i++) {
output_report.data[i] = rand() & UINT8_MAX;
}

// Send the report
HID.send(&output_report);

// Try to read a msg
if (HID.read_nb(&input_report)) {
led_out = !led_out;
for (int i = 0; i < input_report.length; i++) {
printf("%d ", input_report.data[i]);
}
printf("\r\n");
}
}
}
7 changes: 7 additions & 0 deletions APIs_USB/USBKeyboard/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## USBKeyboard example

The example emulates keyboard over USB port.

1. Flash the board, and ensure the target's auxiliary USB is plugged into the PC.
2. Reset the target.
3. "Hello World" sequence should be typed by the virtual keyboard in loop with 1 sec delays.
12 changes: 12 additions & 0 deletions APIs_USB/USBKeyboard/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "mbed.h"
#include "USBKeyboard.h"

USBKeyboard key;

int main(void)
{
while (1) {
key.printf("Hello World\r\n");
ThisThread::sleep_for(1000);
}
}
9 changes: 9 additions & 0 deletions APIs_USB/USBMIDI/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## USBMIDI example

The example sends a series of MIDI notes to the host PC

1. Flash the board, and ensure the target's auxiliary USB is plugged into the PC.
2. Open Anvil Studio.
3. Click View > Synthesizers, MIDI + Audio Devices.
4. Uncheck Synth is too slow to echo incoming events.
5. Click View > Composer (Staff Editor) to see notes from the board being mapped to the sheet music.
16 changes: 16 additions & 0 deletions APIs_USB/USBMIDI/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "mbed.h"
#include "USBMIDI.h"

USBMIDI midi;

int main()
{
while (1) {
for (int i = 48; i < 83; i++) { // send some messages!
midi.write(MIDIMessage::NoteOn(i));
ThisThread::sleep_for(250);
midi.write(MIDIMessage::NoteOff(i));
ThisThread::sleep_for(500);
}
}
}
9 changes: 9 additions & 0 deletions APIs_USB/USBMIDI_Take_Me_Out_to_the_Ball_Game/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## USBMIDI "Take Me Out to the Ball Game" example

The example plays an entire song, not just a series of notes. "Take Me Out to the Ball Game" is a popular song in the public domain.

1. Flash the board, and ensure the target's auxiliary USB is plugged into the PC.
2. Open Anvil Studio.
3. Click View > Synthesizers, MIDI + Audio Devices.
4. Uncheck Synth is too slow to echo incoming events.
5. Click View > Composer (Staff Editor) to see notes from the board being mapped to the sheet music.
Loading