From 21992cfc5410263750b481044ea77c431adff8d0 Mon Sep 17 00:00:00 2001 From: Vineet K Date: Sun, 21 Apr 2024 17:22:43 -0400 Subject: [PATCH] read and play notes from serial --- notes.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/notes.c b/notes.c index 3f93cc5..7902efe 100644 --- a/notes.c +++ b/notes.c @@ -38,12 +38,12 @@ unsigned short freqs[] = { FREQ(1750), FREQ(2000), - [255] = 0 // used as a 'silent' note + [32] = 0 // used as a 'silent' note }; unsigned char note = 0; // 0 = buttons write note+cycles+\xff to UART // 1 = buttons don't do anything, speaker reads note+cycles+\xff from UART -unsigned char mode = 0; +unsigned char mode = '0'; ISR (PCINT0_vect) { @@ -82,7 +82,7 @@ void usart_init(void) { // 115200 bps, RX/TX enabled - UBRR0 = 8; + UBRR0 = 103; UCSR0B = (1 << RXEN0) | (1 << TXEN0); UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); } @@ -94,6 +94,13 @@ usart_send(unsigned char c) UDR0 = c; } +void +usart_send_str(const char *c) +{ + for (unsigned char i = 0; c[i] != '\0'; i++) + usart_send(c[i]); +} + unsigned char usart_read(void) { @@ -125,9 +132,14 @@ main(void) // Sends Square wave to the Speaker When a Button is Pressed unsigned short cycles = 0; unsigned char tmp = 0; - for (;;) { + for (unsigned char n = 0;; n = (n + 1) % 2) { + if (UCSR0A & (1 << RXC0)) { + mode = UDR0; + PORTD &= ~(1 << P_SPKR); + usart_send(mode); + } // check if any buttons are pressed, otherwise don't play a note - if (((PINB & PCMSK0) | (PINC & PCMSK1) | (PIND & PCMSK2)) == 0) { + if (mode != '1' && ((PINB & PCMSK0) | (PINC & PCMSK1) | (PIND & PCMSK2)) == 0) { // if a button was released, then send note and cycles played if (cycles > 0) { usart_send(tmp); @@ -135,16 +147,11 @@ main(void) usart_send(LOW(cycles)); usart_send(0xff); cycles = 0; - } else { - if (UCSR0A & (1 << RXC0)) { - mode = UDR0; - usart_send(mode); - } } continue; } - if (mode == 0) { + if (mode == '0') { // Prepare Timer/Counter TCNT1 = 1; tmp = note; @@ -159,15 +166,26 @@ main(void) TIFR1 |= 1 << OCF1A; TCCR1B &= ~(1 << CS11); cycles = (cycles + 1) % 0xffff; - } else if (mode == 0xb0) { + } else if (mode == '1') { note = usart_read(); + if (note >= '0') note -= '0'; tmp = usart_read(); cycles = tmp << 8; tmp = usart_read(); cycles |= tmp; - (void)usart_read(); + tmp = usart_read(); + + // reset to default mode when an invalid note is read + if (tmp != 'z' || note > '@') { + mode = '0'; + continue; + } + + for (unsigned short i = 0; i < cycles; i++) { + usart_send(HIGH(cycles)); + usart_send(LOW(cycles)); + usart_send(0); - for (unsigned char i = 0; i < cycles; i++) { TCNT1 = 1; OCR1A = freqs[note]; TCCR1B |= 1 << CS11;