crashtest-r0ket/misc/openbeacon/lpc13xx/sound/src/soundtest.c

144 lines
2.6 KiB
C

#include <openbeacon.h>
#define TONES_MAX 32
#define ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0]))
/* 8xLED bar display */
static void
set_led (uint8_t led)
{
led = ~led;
LPC_GPIO2->MASKED_ACCESS[0xF0] = led;
LPC_GPIO3->MASKED_ACCESS[0x0F] = led;
}
static void
beep (double frequency)
{
uint32_t t;
LPC_TMR32B1->TCR = 0;
if (frequency)
{
t = (SystemCoreClock / 2) / frequency;
LPC_TMR32B1->MR0 = LPC_TMR32B1->MR1 = t;
if (LPC_TMR32B1->TC >= t)
LPC_TMR32B1->TC = t;
LPC_TMR32B1->TCR = 1;
}
}
static double
get_frequency_for_tone (uint8_t tone)
{
static const double frequency[] = {
262.63, 293.66, 329.63,
349.23, 392.00, 440.00, 493.88
};
return frequency[tone % ARRAY_COUNT (frequency)] *
(1 << (tone / ARRAY_COUNT (frequency)));
}
static void
tone (uint8_t tone)
{
static uint8_t lasttone = 0;
if (tone != lasttone)
{
lasttone = tone;
beep (tone ? get_frequency_for_tone (tone - 1) : 0);
}
}
int
main (void)
{
volatile int t;
int i, mode, index, start;
/* Get System Clock */
SystemCoreClockUpdate ();
/* Initialize GPIO (sets up clock) */
GPIOInit ();
GPIOSetDir (BUT1_PORT, BUT1_PIN, 0);
GPIOSetDir (BUT2_PORT, BUT2_PIN, 0);
/* Set LED port pin to output */
LPC_GPIO2->DIR |= 0xF0;
LPC_GPIO3->DIR |= 0x0F;
/* Set sound port to PIO1_1 and PIO1_2 */
LPC_GPIO1->DIR |= 0x6;
LPC_IOCON->JTAG_TDO_PIO1_1 = 3;
LPC_IOCON->JTAG_nTRST_PIO1_2 = 3;
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10);
LPC_TMR32B1->TCR = 2;
LPC_TMR32B1->MCR = 1 << 4;
LPC_TMR32B1->EMR = 1 | (0x3 << 4) | (0x3 << 6);
mode = 2;
index = 24;
while (1)
{
/* BUTTON1 press cycles through tones */
if (!GPIOGetValue (BUT1_PORT, BUT1_PIN))
{
mode = (mode + 1) & 0x7;
/* debounce */
for (t = 0; t < 1000000; t++);
}
/* BUTTON2 plays tone */
if (!GPIOGetValue (BUT2_PORT, BUT2_PIN))
{
set_led (0xFF);
/* debounce */
switch (mode)
{
case 0:
index++;
if (index > TONES_MAX)
index = 1;
tone (index);
for (t = 0; t < 2000000; t++);
break;
case 1:
if (index > 1)
index--;
else
index = TONES_MAX;
tone (index);
for (t = 0; t < 2000000; t++);
break;
case 2:
tone (index);
break;
default:
start = get_frequency_for_tone (index) - 500;
for (i = 100; i > 0; i--)
{
beep (start + (i * 10));
for (t = 0; t < (mode * 5000); t++);
}
beep (0);
break;
}
}
else if (mode <= 2)
tone (0);
set_led (1 << mode);
}
}