Add a speaker

This commit is contained in:
NIIBE Yutaka
2015-08-06 11:01:49 +09:00
parent 218102c5c4
commit 1bbbaabe0d
5 changed files with 193 additions and 25 deletions

View File

@@ -31,13 +31,12 @@
#define RCC_ENR_IOP_EN (RCC_AHBENR_IOPAEN | RCC_AHBENR_IOPFEN)
#define RCC_RSTR_IOP_RST (RCC_AHBRSTR_IOPARST | RCC_AHBRSTR_IOPFRST)
/* ??? NeuG settings for ADC2 is default (PA0: Analog IN0, PA1: Analog IN1). */
/*
* Port F setup.
* PF0 - USER Button
* PF1 - SPEAKER
*/
#define VAL_GPIO_OTHER_MODER 0x00000000 /* Input Pin0 */
#define VAL_GPIO_OTHER_OTYPER 0x00000000
#define VAL_GPIO_OTHER_MODER 0x00000004 /* Input Pin0, Output Pin1 */
#define VAL_GPIO_OTHER_OTYPER 0x00000000 /* Push-Pull Pin1 */
#define VAL_GPIO_OTHER_OSPEEDR 0x00000000
#define VAL_GPIO_OTHER_PUPDR 0x00000001 /* Pull-up Pin0 */
#define VAL_GPIO_OTHER_PUPDR 0x00000009 /* Pull-up Pin0, Pull-down Pin1 */

View File

@@ -4,7 +4,7 @@ PROJECT = hacker-emblem
CHOPSTX = ..
LDSCRIPT= hacker-emblem.ld
CSRC = sys.c hacker-emblem.c
CSRC = sys.c hiroshi-ayumi.c # hacker-emblem.c
###################################
CROSS = arm-none-eabi-

View File

@@ -6,7 +6,7 @@ Display. Please see the product page:
The file stlink-v2.cfg can be used for ST-Link/V2 with OpenOCD. You
can flash by typing:
$ openocd -f ./stlink-v2.cfg -c "program build/hacker-emblem.elf"
$ openocd -f ./stlink-v2.cfg -c "program build/hacker-emblem.elf; reset run; shutdown"
Thanks to Kiwamu Okabe who kindly tested OpenOCD and wrote the
configuration.

View File

@@ -1,5 +1,6 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <chopstx.h>
#include "board.h"
@@ -32,11 +33,13 @@ struct GPIO {
#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400)
#define GPIOF ((struct GPIO *) GPIOF_BASE)
#define GPIO_SPEAKER_PIN 1
static struct GPIO *const GPIO_LED = ((struct GPIO *const) GPIO_LED_BASE);
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
static chopstx_mutex_t mtx;
static chopstx_cond_t cnd0;
static chopstx_cond_t cnd;
static uint8_t
user_button (void)
@@ -82,13 +85,21 @@ led_enable_column (uint8_t col)
GPIO_LED->BRR = (1 << col);
}
#define PRIO_LED 3
extern uint8_t __process1_stack_base__, __process1_stack_size__;
const uint32_t stackaddr_led = (uint32_t)&__process1_stack_base__;
const size_t stacksize_led = (size_t)&__process1_stack_size__;
static void *
led (void *arg)
{
(void)arg;
chopstx_mutex_lock (&mtx);
chopstx_cond_wait (&cnd0, &mtx);
chopstx_cond_wait (&cnd, &mtx);
chopstx_mutex_unlock (&mtx);
while (1)
@@ -106,12 +117,168 @@ led (void *arg)
return NULL;
}
#define PRIO_LED 3
extern uint8_t __process1_stack_base__, __process1_stack_size__;
#define PRIO_SPK 4
extern uint8_t __process2_stack_base__, __process2_stack_size__;
const uint32_t stackaddr_spk = (uint32_t)&__process2_stack_base__;
const size_t stacksize_spk = (size_t)&__process2_stack_size__;
static chopstx_mutex_t spk_mtx;
static chopstx_cond_t spk_cnd;
static chopstx_cond_t spk_cnd_no_tone;
static uint8_t tone;
#define NO_TONE 255
static uint16_t tone_table[] = {
568, /* a = 880Hz */
/* 536, */
506, /* b */
478, /* c */
/* 451, */
426, /* d */
/* 402, */
379, /* e */
358, /* f*/
/* 338, */
319, /* g */
/* 301, */
284, /* A = 1760Hz */
/* 268 */
253, /* B */
239, /* C */
};
static void
change_tone (uint8_t t)
{
chopstx_mutex_lock (&spk_mtx);
tone = t;
chopstx_cond_signal (&spk_cnd_no_tone);
chopstx_cond_wait (&spk_cnd, &spk_mtx);
chopstx_mutex_unlock (&spk_mtx);
}
static void *
spk (void *arg)
{
(void)arg;
while (1)
{
uint8_t t;
uint16_t w;
chopstx_mutex_lock (&spk_mtx);
t = tone;
chopstx_cond_signal (&spk_cnd);
if (t == NO_TONE)
{
chopstx_cond_wait (&spk_cnd_no_tone, &spk_mtx);
t = tone;
}
chopstx_mutex_unlock (&spk_mtx);
w = tone_table[t];
GPIO_OTHER->BSRR = (1 << GPIO_SPEAKER_PIN);
wait_for (w);
GPIO_OTHER->BRR = (1 << GPIO_SPEAKER_PIN);
wait_for (w);
}
return NULL;
}
#define PRIO_MUSIC 2
extern uint8_t __process3_stack_base__, __process3_stack_size__;
const uint32_t stackaddr_music = (uint32_t)&__process3_stack_base__;
const size_t stacksize_music = (size_t)&__process3_stack_size__;
#define C 0
#define D 1
#define E 2
#define F 3
#define G 4
#define A 5
#define B 6
#if 0 /* twinkle stars */
static const char *musical_score =
"c4c4g4g4A4A4g2f4f4e4e4d4d4c2"
"g4g4f4f4e4e4d2g4g4f4f4e4e4d2"
"c4c4g4g4A4A4g2f4f4e4e4d4d4c2";
#else /* tulip */
static const char *musical_score =
"c4d4e2c4d4e2g4e4d4c4d4e4d2"
"c4d4e2c4d4e2g4e4d4c4d4e4c2"
"g4g4e4g4a4a4g2e4e4d4d4c2";
#endif
static int get_t_and_l (char *tp, char *lp)
{
static unsigned int i = 0;
char tl, ll;
tl = musical_score[i++];
ll = musical_score[i++];
if (tl >= 'a')
*tp = tl - 'a';
else
*tp = tl - 'A' + 7;
*lp = ll - '0';
if (i >= strlen (musical_score))
{
i = 0;
return 0;
}
else
return 1;
}
#define WAIT_FOR_NO_TONE (1000*20)
#define WAIT_FOR_TONE (1000000*3/2)
static void *
music (void *arg)
{
(void)arg;
chopstx_mutex_init (&spk_mtx);
chopstx_cond_init (&spk_cnd);
chopstx_cond_init (&spk_cnd_no_tone);
chopstx_create (PRIO_SPK, stackaddr_spk, stacksize_spk, spk, NULL);
while (1)
{
char t, l;
int r;
r = get_t_and_l (&t, &l);
change_tone (NO_TONE);
wait_for (WAIT_FOR_NO_TONE);
change_tone (t);
wait_for (WAIT_FOR_TONE / l);
if (!r)
{
change_tone (NO_TONE);
wait_for (WAIT_FOR_TONE * 3);
}
}
return NULL;
}
const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__;
const size_t __stacksize_led = (size_t)&__process1_stack_size__;
#define DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0)
#define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
@@ -181,14 +348,15 @@ main (int argc, const char *argv[])
(void)argv;
chopstx_mutex_init (&mtx);
chopstx_cond_init (&cnd0);
chopstx_cond_init (&cnd);
chopstx_create (PRIO_LED, __stackaddr_led, __stacksize_led, led, NULL);
chopstx_create (PRIO_LED, stackaddr_led, stacksize_led, led, NULL);
chopstx_create (PRIO_MUSIC, stackaddr_music, stacksize_music, music, NULL);
chopstx_usec_wait (200*1000);
chopstx_mutex_lock (&mtx);
chopstx_cond_signal (&cnd0);
chopstx_cond_signal (&cnd);
chopstx_mutex_unlock (&mtx);
while (1)
@@ -196,21 +364,21 @@ main (int argc, const char *argv[])
unsigned int i;
if (state)
for (i = 0; i < SIZE55 (image0); i++)
{
if (user_button ())
state = 0;
set_led_display (image0[i]);
wait_for (200*1000);
}
else
for (i = 0; i < SIZE55 (image1); i++)
{
if (user_button ())
state = 1;
state = 0;
set_led_display (image1[i]);
wait_for (200*1000);
}
else
for (i = 0; i < SIZE55 (image0); i++)
{
if (user_button ())
state = 1;
set_led_display (image0[i]);
wait_for (200*1000);
}
}
return 0;

View File

@@ -9,3 +9,4 @@ set WORKAREASIZE 0x1000
source [find target/stm32f0x.cfg]
# use hardware reset, connect under reset
reset_config srst_only srst_nogate connect_assert_srst