#include #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); } }