samples: microbit/pong: Add basic sound support

Add beeps whenever the ball hits the walls or the paddle. Requires a
piezo buzzer connected to pin 0.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2017-05-23 07:34:45 -07:00 committed by Anas Nashif
commit 9e2fb2f3ad
2 changed files with 48 additions and 0 deletions

View file

@ -6,3 +6,5 @@ CONFIG_BLUETOOTH_GATT_DYNAMIC_DB=y
CONFIG_BLUETOOTH_DEVICE_NAME="Zephyr Pong"
CONFIG_GPIO=y
CONFIG_MICROBIT_DISPLAY=y
CONFIG_PWM=y
CONFIG_PWM_NRF5_SW=y

View file

@ -10,6 +10,7 @@
#include <gpio.h>
#include <device.h>
#include <string.h>
#include <pwm.h>
#include <display/mb_display.h>
@ -103,6 +104,40 @@ static struct x_y ball_vel = { 0, 0 };
static s64_t a_timestamp;
static s64_t b_timestamp;
#define SOUND_PIN EXT_P0_GPIO_PIN
#define SOUND_PERIOD_PADDLE 200
#define SOUND_PERIOD_WALL 1000
static struct device *pwm;
static enum sound_state {
SOUND_IDLE, /* No sound */
SOUND_PADDLE, /* Ball has hit the paddle */
SOUND_WALL, /* Ball has hit a wall */
} sound_state;
static inline void beep(int period)
{
pwm_pin_set_usec(pwm, SOUND_PIN, period, period / 2);
}
static void sound_set(enum sound_state state)
{
switch (state) {
case SOUND_IDLE:
beep(0);
break;
case SOUND_PADDLE:
beep(SOUND_PERIOD_PADDLE);
break;
case SOUND_WALL:
beep(SOUND_PERIOD_WALL);
break;
}
sound_state = state;
}
static void pong_select(const struct pong_selection *sel)
{
struct mb_display *disp = mb_display_get();
@ -260,6 +295,10 @@ static void game_ended(bool won)
static void game_refresh(struct k_work *work)
{
if (sound_state != SOUND_IDLE) {
sound_set(SOUND_IDLE);
}
if (ended) {
game_init(state == SINGLE || remote_lost);
k_sem_give(&disp_update);
@ -274,6 +313,7 @@ static void game_refresh(struct k_work *work)
if (state == SINGLE) {
ball_pos.y = -ball_pos.y;
ball_vel.y = -ball_vel.y;
sound_set(SOUND_WALL);
} else {
ble_send_ball(BALL_POS_X_MAX - ball_pos.x, ball_pos.y,
-ball_vel.x, -ball_vel.y);
@ -286,9 +326,11 @@ static void game_refresh(struct k_work *work)
if (ball_pos.x < BALL_POS_X_MIN) {
ball_pos.x = -ball_pos.x;
ball_vel.x = -ball_vel.x;
sound_set(SOUND_WALL);
} else if (ball_pos.x > BALL_POS_X_MAX) {
ball_pos.x = (2 * BALL_POS_X_MAX) - ball_pos.x;
ball_vel.x = -ball_vel.x;
sound_set(SOUND_WALL);
}
/* Ball approaching paddle */
@ -310,6 +352,8 @@ static void game_refresh(struct k_work *work)
}
ball_vel.y = -ball_vel.y;
sound_set(SOUND_PADDLE);
}
k_delayed_work_submit(&refresh, GAME_REFRESH);
@ -438,6 +482,8 @@ void main(void)
k_delayed_work_init(&refresh, game_refresh);
pwm = device_get_binding(CONFIG_PWM_NRF5_SW_0_DEV_NAME);
ble_init();
pong_select(&mode_selection);