samples/boards/microbit: Add sound sample
Add a sample demonstrating sound output using PWM to a piezo buzzer connected to the external edge connector port P0. Change-Id: I8c0902fd935f2eb3b9979476a7540e7a0216ca63 Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
eea12f6f14
commit
191cb2d0fc
|
@ -0,0 +1,4 @@
|
|||
BOARD ?= bbc_microbit
|
||||
CONF_FILE = prj.conf
|
||||
|
||||
include ${ZEPHYR_BASE}/Makefile.test
|
|
@ -0,0 +1,32 @@
|
|||
.. _microbit_sound:
|
||||
|
||||
BBC micro:bit sound
|
||||
###################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
This is simple example demonstrating how to use a piezo buzzer connected
|
||||
to port P0 on the edge connector of the BBC micro:bit board. Note that
|
||||
the buzzer is not part of the main micro:bit board, rather it it needs
|
||||
to be separately acquired and connected. A well working example is the
|
||||
MI:Power board that has a piezo buzzer in addition to a coin-cell
|
||||
battery. Resellers of this board can be fairly easily found using online
|
||||
search.
|
||||
|
||||
Building
|
||||
********
|
||||
|
||||
The sample can be built as follows:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd samples/boards/microbit/sound
|
||||
$ make
|
||||
|
||||
Sample Output
|
||||
=============
|
||||
|
||||
This sample outputs sounds through a connected piezo buzzer based on
|
||||
button presses of the two main buttons. For each press the current
|
||||
output frequency will be printed on the 5x5 LED display.
|
|
@ -0,0 +1,4 @@
|
|||
CONFIG_GPIO=y
|
||||
CONFIG_MICROBIT_DISPLAY=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_NRF5_SW=y
|
|
@ -0,0 +1 @@
|
|||
obj-y = main.o
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <misc/printk.h>
|
||||
#include <board.h>
|
||||
#include <gpio.h>
|
||||
#include <pwm.h>
|
||||
#include <device.h>
|
||||
|
||||
#include <display/mb_display.h>
|
||||
|
||||
#define BUZZER_PIN EXT_P0_GPIO_PIN
|
||||
|
||||
#define PERIOD_MIN 50
|
||||
#define PERIOD_MAX 3900
|
||||
#define PERIOD_INIT 1500
|
||||
|
||||
#define BEEP_DURATION K_MSEC(60)
|
||||
|
||||
#define US_TO_HZ(_us) (USEC_PER_SEC / (_us))
|
||||
|
||||
static struct device *pwm;
|
||||
static struct device *gpio;
|
||||
static uint32_t period = PERIOD_INIT;
|
||||
static struct k_work beep_work;
|
||||
static volatile bool beep_active;
|
||||
|
||||
static void beep(struct k_work *work)
|
||||
{
|
||||
/* The "period / 2" pulse duration gives 50% duty cycle, which
|
||||
* should result in the maximum sound volume.
|
||||
*/
|
||||
pwm_pin_set_usec(pwm, BUZZER_PIN, period, period / 2);
|
||||
k_sleep(BEEP_DURATION);
|
||||
|
||||
/* Disable the PWM */
|
||||
pwm_pin_set_usec(pwm, BUZZER_PIN, 0, 0);
|
||||
|
||||
/* Ensure there's a clear silent period between two tones */
|
||||
k_sleep(K_MSEC(50));
|
||||
beep_active = false;
|
||||
}
|
||||
|
||||
static void button_pressed(struct device *dev, struct gpio_callback *cb,
|
||||
uint32_t pins)
|
||||
{
|
||||
struct mb_display *disp;
|
||||
|
||||
if (beep_active) {
|
||||
printk("Button press while beeping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
beep_active = true;
|
||||
|
||||
if (pins & BIT(SW0_GPIO_PIN)) {
|
||||
printk("A pressed\n");
|
||||
if (period < PERIOD_MAX) {
|
||||
period += 50;
|
||||
}
|
||||
} else {
|
||||
printk("B pressed\n");
|
||||
if (period > PERIOD_MIN) {
|
||||
period -= 50;
|
||||
}
|
||||
}
|
||||
|
||||
printk("Period is %u us (%u Hz)\n", period, US_TO_HZ(period));
|
||||
|
||||
disp = mb_display_get();
|
||||
mb_display_print(disp, MB_DISPLAY_MODE_DEFAULT, K_MSEC(500), "%uHz",
|
||||
US_TO_HZ(period));
|
||||
|
||||
k_work_submit(&beep_work);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
static struct gpio_callback button_cb;
|
||||
|
||||
gpio = device_get_binding(SW0_GPIO_NAME);
|
||||
|
||||
gpio_pin_configure(gpio, SW0_GPIO_PIN,
|
||||
(GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
|
||||
GPIO_INT_ACTIVE_LOW));
|
||||
gpio_pin_configure(gpio, SW1_GPIO_PIN,
|
||||
(GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
|
||||
GPIO_INT_ACTIVE_LOW));
|
||||
gpio_init_callback(&button_cb, button_pressed,
|
||||
BIT(SW0_GPIO_PIN) | BIT(SW1_GPIO_PIN));
|
||||
gpio_add_callback(gpio, &button_cb);
|
||||
|
||||
pwm = device_get_binding(CONFIG_PWM_NRF5_SW_0_DEV_NAME);
|
||||
|
||||
k_work_init(&beep_work, beep);
|
||||
/* Notify with a beep that we've started */
|
||||
k_work_submit(&beep_work);
|
||||
|
||||
gpio_pin_enable_callback(gpio, SW0_GPIO_PIN);
|
||||
gpio_pin_enable_callback(gpio, SW1_GPIO_PIN);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
[test]
|
||||
build_only = true
|
||||
tags = samples
|
||||
platform_whitelist = bbc_microbit
|
Loading…
Reference in New Issue