Add a speaker
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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-
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user