diff --git a/samples/boards/microbit/sound/Makefile b/samples/boards/microbit/sound/Makefile new file mode 100644 index 00000000000..20ad981a51f --- /dev/null +++ b/samples/boards/microbit/sound/Makefile @@ -0,0 +1,4 @@ +BOARD ?= bbc_microbit +CONF_FILE = prj.conf + +include ${ZEPHYR_BASE}/Makefile.test diff --git a/samples/boards/microbit/sound/README.rst b/samples/boards/microbit/sound/README.rst new file mode 100644 index 00000000000..14d377b31a7 --- /dev/null +++ b/samples/boards/microbit/sound/README.rst @@ -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. diff --git a/samples/boards/microbit/sound/prj.conf b/samples/boards/microbit/sound/prj.conf new file mode 100644 index 00000000000..bf1d0352122 --- /dev/null +++ b/samples/boards/microbit/sound/prj.conf @@ -0,0 +1,4 @@ +CONFIG_GPIO=y +CONFIG_MICROBIT_DISPLAY=y +CONFIG_PWM=y +CONFIG_PWM_NRF5_SW=y diff --git a/samples/boards/microbit/sound/src/Makefile b/samples/boards/microbit/sound/src/Makefile new file mode 100644 index 00000000000..00066e15678 --- /dev/null +++ b/samples/boards/microbit/sound/src/Makefile @@ -0,0 +1 @@ +obj-y = main.o diff --git a/samples/boards/microbit/sound/src/main.c b/samples/boards/microbit/sound/src/main.c new file mode 100644 index 00000000000..7c767a58459 --- /dev/null +++ b/samples/boards/microbit/sound/src/main.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include + +#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); +} diff --git a/samples/boards/microbit/sound/testcase.ini b/samples/boards/microbit/sound/testcase.ini new file mode 100644 index 00000000000..0763266506b --- /dev/null +++ b/samples/boards/microbit/sound/testcase.ini @@ -0,0 +1,4 @@ +[test] +build_only = true +tags = samples +platform_whitelist = bbc_microbit