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_ENR_IOP_EN (RCC_AHBENR_IOPAEN | RCC_AHBENR_IOPFEN)
|
||||||
#define RCC_RSTR_IOP_RST (RCC_AHBRSTR_IOPARST | RCC_AHBRSTR_IOPFRST)
|
#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.
|
* Port F setup.
|
||||||
* PF0 - USER Button
|
* PF0 - USER Button
|
||||||
|
* PF1 - SPEAKER
|
||||||
*/
|
*/
|
||||||
#define VAL_GPIO_OTHER_MODER 0x00000000 /* Input Pin0 */
|
#define VAL_GPIO_OTHER_MODER 0x00000004 /* Input Pin0, Output Pin1 */
|
||||||
#define VAL_GPIO_OTHER_OTYPER 0x00000000
|
#define VAL_GPIO_OTHER_OTYPER 0x00000000 /* Push-Pull Pin1 */
|
||||||
#define VAL_GPIO_OTHER_OSPEEDR 0x00000000
|
#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 = ..
|
CHOPSTX = ..
|
||||||
LDSCRIPT= hacker-emblem.ld
|
LDSCRIPT= hacker-emblem.ld
|
||||||
CSRC = sys.c hacker-emblem.c
|
CSRC = sys.c hiroshi-ayumi.c # hacker-emblem.c
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
CROSS = arm-none-eabi-
|
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
|
The file stlink-v2.cfg can be used for ST-Link/V2 with OpenOCD. You
|
||||||
can flash by typing:
|
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
|
Thanks to Kiwamu Okabe who kindly tested OpenOCD and wrote the
|
||||||
configuration.
|
configuration.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <chopstx.h>
|
#include <chopstx.h>
|
||||||
|
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
@@ -32,11 +33,13 @@ struct GPIO {
|
|||||||
#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400)
|
#define GPIOF_BASE (AHB2PERIPH_BASE + 0x1400)
|
||||||
#define GPIOF ((struct GPIO *) GPIOF_BASE)
|
#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_LED = ((struct GPIO *const) GPIO_LED_BASE);
|
||||||
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
|
static struct GPIO *const GPIO_OTHER = ((struct GPIO *const) GPIO_OTHER_BASE);
|
||||||
|
|
||||||
static chopstx_mutex_t mtx;
|
static chopstx_mutex_t mtx;
|
||||||
static chopstx_cond_t cnd0;
|
static chopstx_cond_t cnd;
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
user_button (void)
|
user_button (void)
|
||||||
@@ -82,13 +85,21 @@ led_enable_column (uint8_t col)
|
|||||||
GPIO_LED->BRR = (1 << 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 *
|
static void *
|
||||||
led (void *arg)
|
led (void *arg)
|
||||||
{
|
{
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
|
||||||
chopstx_mutex_lock (&mtx);
|
chopstx_mutex_lock (&mtx);
|
||||||
chopstx_cond_wait (&cnd0, &mtx);
|
chopstx_cond_wait (&cnd, &mtx);
|
||||||
chopstx_mutex_unlock (&mtx);
|
chopstx_mutex_unlock (&mtx);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@@ -106,12 +117,168 @@ led (void *arg)
|
|||||||
return NULL;
|
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 DATA55(x0,x1,x2,x3,x4) (x0<<20)|(x1<<15)|(x2<<10)|(x3<< 5)|(x4<< 0)
|
||||||
#define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
|
#define SIZE55(img) (sizeof (img) / sizeof (uint32_t))
|
||||||
@@ -181,14 +348,15 @@ main (int argc, const char *argv[])
|
|||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
chopstx_mutex_init (&mtx);
|
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_usec_wait (200*1000);
|
||||||
|
|
||||||
chopstx_mutex_lock (&mtx);
|
chopstx_mutex_lock (&mtx);
|
||||||
chopstx_cond_signal (&cnd0);
|
chopstx_cond_signal (&cnd);
|
||||||
chopstx_mutex_unlock (&mtx);
|
chopstx_mutex_unlock (&mtx);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@@ -196,21 +364,21 @@ main (int argc, const char *argv[])
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (state)
|
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++)
|
for (i = 0; i < SIZE55 (image1); i++)
|
||||||
{
|
{
|
||||||
if (user_button ())
|
if (user_button ())
|
||||||
state = 1;
|
state = 0;
|
||||||
set_led_display (image1[i]);
|
set_led_display (image1[i]);
|
||||||
wait_for (200*1000);
|
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;
|
return 0;
|
||||||
|
|||||||
@@ -9,3 +9,4 @@ set WORKAREASIZE 0x1000
|
|||||||
source [find target/stm32f0x.cfg]
|
source [find target/stm32f0x.cfg]
|
||||||
|
|
||||||
# use hardware reset, connect under reset
|
# use hardware reset, connect under reset
|
||||||
|
reset_config srst_only srst_nogate connect_assert_srst
|
||||||
|
|||||||
Reference in New Issue
Block a user