From 9e2fb2f3adfbf2e3362b81f79e12d8e15d309320 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 23 May 2017 07:34:45 -0700 Subject: [PATCH] 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 --- samples/boards/microbit/pong/prj.conf | 2 ++ samples/boards/microbit/pong/src/main.c | 46 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/samples/boards/microbit/pong/prj.conf b/samples/boards/microbit/pong/prj.conf index 4079abc5b31..4744d12b231 100644 --- a/samples/boards/microbit/pong/prj.conf +++ b/samples/boards/microbit/pong/prj.conf @@ -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 diff --git a/samples/boards/microbit/pong/src/main.c b/samples/boards/microbit/pong/src/main.c index 8c643b820e6..54970d13e6e 100644 --- a/samples/boards/microbit/pong/src/main.c +++ b/samples/boards/microbit/pong/src/main.c @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -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);