From 36d3b2f73522b5f0ff727d7eadfced2f3ca858c7 Mon Sep 17 00:00:00 2001 From: Wolfgang Hottgenroth Date: Wed, 17 Apr 2024 15:30:45 +0200 Subject: [PATCH] sound works --- game-ctrl/buttons.c | 16 ++--- game-ctrl/game.c | 13 ++-- game-ctrl/sound.c | 5 +- game-ctrl/sound.h | 26 ++------ sound-driver/Makefile | 11 +++- sound-driver/main.c | 2 + sound-driver/melody_tetris.c | 3 +- sound-driver/melody_tusch1.c | 3 +- sound-driver/scheduler.h | 2 +- sound-driver/sequencer.c | 13 +++- sound-driver/sequencer.h | 3 +- sound-driver/soundCodes.h | 14 +++++ sound-driver/spi.S | 70 +++++++++++++++++++++ sound-driver/spi.c | 118 ----------------------------------- sound-driver/spi.h | 2 +- sound-driver/spi_init.c | 31 +++++++++ 16 files changed, 165 insertions(+), 167 deletions(-) create mode 100644 sound-driver/soundCodes.h create mode 100644 sound-driver/spi.S delete mode 100644 sound-driver/spi.c create mode 100644 sound-driver/spi_init.c diff --git a/game-ctrl/buttons.c b/game-ctrl/buttons.c index 2c21d12..88e796f 100644 --- a/game-ctrl/buttons.c +++ b/game-ctrl/buttons.c @@ -49,7 +49,7 @@ static uint8_t buttonsMoveDownPressed() { void buttonsExec(void *handle) { static uint32_t unmuteTimestamp; uint32_t currentTimestamp = getSeconds(); - static bool unmuteFlag = false; + static bool unmuteFlag = true; if (! stoneIsValid()) { @@ -61,27 +61,27 @@ void buttonsExec(void *handle) { if (buttonsMoveLeftPressed()) { stoneMoveLeft(); - soundCtrl(e_SOUND_STONE_MOVE_LEFT); + soundCtrl(SOUND_MOTION); buttonPressed = 1; } if (buttonsMoveRightPressed()) { stoneMoveRight(); - soundCtrl(e_SOUND_STONE_MOVE_RIGHT); + soundCtrl(SOUND_MOTION); buttonPressed = 1; } if (buttonsRotateLeftPressed()) { stoneRotateLeft(); - soundCtrl(e_SOUND_STONE_ROTATE_LEFT); + soundCtrl(SOUND_MOTION); buttonPressed = 1; } if (buttonsRotateRightPressed()) { stoneRotateRight(); - soundCtrl(e_SOUND_STONE_ROTATE_RIGHT); + soundCtrl(SOUND_MOTION); buttonPressed = 1; } if (buttonsMoveDownPressed()) { stoneMoveDown(); - soundCtrl(e_SOUND_STONE_MOVE_DOWN); + soundCtrl(SOUND_MOTION); buttonPressed = 1; } @@ -89,14 +89,14 @@ void buttonsExec(void *handle) { canvasShow(); if (! unmuteFlag) { - soundCtrl(e_SOUND_UNMUTE); + soundCtrl(SOUND_UNMUTE); unmuteFlag = true; } unmuteTimestamp = currentTimestamp; } if (unmuteFlag && (unmuteTimestamp + MUTE_DELAY < currentTimestamp)) { - soundCtrl(e_SOUND_MUTE); + soundCtrl(SOUND_MUTE); unmuteFlag = false; } } diff --git a/game-ctrl/game.c b/game-ctrl/game.c index 921f6c1..688de74 100644 --- a/game-ctrl/game.c +++ b/game-ctrl/game.c @@ -41,7 +41,7 @@ void gameExec(void *handle) { // --- phase: game -------------------------------------------------------- case e_Start: canvasClear(); - soundCtrl(e_SOUND_START_BACKGROUND); + soundCtrl(SOUND_START); level = 1; score = 0; displaySetValue(score); @@ -73,7 +73,7 @@ void gameExec(void *handle) { case e_Down: if (! stoneMoveDown()) { - soundCtrl(e_SOUND_STONE_LOCKED); + soundCtrl(SOUND_LOCK); state = e_NewStone; } else { proceedDelay = delayFactor(level); @@ -83,8 +83,7 @@ void gameExec(void *handle) { // --- phase: game over --------------------------------------------------- case e_GameOver: - soundCtrl(e_SOUND_STOP_BACKGROUND); - soundCtrl(e_SOUND_START_GAMEOVER); + soundCtrl(SOUND_GAMEOVER); rowIndex = CANVAS_HEIGHT; phase = e_Phase_GameOver; state = e_GameOverFill; @@ -110,7 +109,6 @@ void gameExec(void *handle) { case e_GameOverDelay: gameOverDelay--; if (gameOverDelay == 0) { - soundCtrl(e_SOUND_STOP_GAMEOVER); state = e_Start; } break; @@ -129,10 +127,13 @@ void gameExec(void *handle) { wipeCnt += 1; } } - soundCtrl(e_SOUND_FANFARE_BASE + wipeCnt); + if (wipeCnt != 0) { + soundCtrl(SOUND_FANFARE); + } } } void gameInit() { schAdd(gameExec, NULL, 0, GAME_CYCLE_TIME); } + diff --git a/game-ctrl/sound.c b/game-ctrl/sound.c index 9ebaa28..1cde5e0 100644 --- a/game-ctrl/sound.c +++ b/game-ctrl/sound.c @@ -1,3 +1,4 @@ +#include #include "sound.h" #include "spi.h" @@ -7,10 +8,10 @@ void soundInit() { } -void soundCtrl(t_SoundCmd cmd) { +void soundCtrl(uint8_t cmd) { spiSendBegin(e_SPI_SOUND); - spiSendOctet((uint8_t)cmd); + spiSendOctet(cmd); spiSendEnd(e_SPI_SOUND); } diff --git a/game-ctrl/sound.h b/game-ctrl/sound.h index d335ac1..fccb760 100644 --- a/game-ctrl/sound.h +++ b/game-ctrl/sound.h @@ -1,32 +1,14 @@ #ifndef _SOUND_H_ #define _SOUND_H_ +#include + #define MUTE_DELAY 30 // seconds -typedef enum { - e_SOUND_IDLE = 0, - e_SOUND_MUTE = 1, - e_SOUND_UNMUTE, - e_SOUND_START_BACKGROUND, - e_SOUND_STOP_BACKGROUND, - e_SOUND_START_GAMEOVER, - e_SOUND_STOP_GAMEOVER, - e_SOUND_SPEED_UP, - e_SOUND_FANFARE_BASE, - e_SOUND_FANFARE_1, - e_SOUND_FANFARE_2, - e_SOUND_FANFARE_3, - e_SOUND_FANFARE_4, - e_SOUND_STONE_LOCKED, - e_SOUND_STONE_MOVE_LEFT, - e_SOUND_STONE_MOVE_RIGHT, - e_SOUND_STONE_ROTATE_LEFT, - e_SOUND_STONE_ROTATE_RIGHT, - e_SOUND_STONE_MOVE_DOWN, -} t_SoundCmd; +#include "../sound-driver/soundCodes.h" void soundInit(); -void soundCtrl(t_SoundCmd cmd); +void soundCtrl(uint8_t cmd); diff --git a/sound-driver/Makefile b/sound-driver/Makefile index 6bf22b6..19994eb 100644 --- a/sound-driver/Makefile +++ b/sound-driver/Makefile @@ -4,20 +4,25 @@ OBJDUMP=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-objdump ARTIFACT=firmware MCU=msp430g2553 -CFLAGS=-Wall -mmcu=$(MCU) -std=gnu99 -I $(TOOLCHAIN_PREFIX)/include -O1 -g0 +COMMONFLAGS=-Wall -mmcu=$(MCU) -I $(TOOLCHAIN_PREFIX)/include -O0 -g0 +CFLAGS=$(COMMONFLAGS) -std=gnu99 +ASFLAGS=$(COMMONFLAGS) -D__ASSEMBLER__ # for debugging -#CFLAGS+= -g3 -ggdb -gdwarf-2 +CFLAGS+= -g3 -ggdb -gdwarf-2 LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include -$(ARTIFACT).elf: main.o scheduler.o spi.o sequencer.o melody_tetris.o melody_tusch1.o ay_3_8913.o mute.o +$(ARTIFACT).elf: main.o scheduler.o spi.o spi_init.o sequencer.o melody_tetris.o melody_tusch1.o ay_3_8913.o mute.o $(CC) -o $@ $(LDFLAGS) $^ $(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt .c.o: $(CC) $(CFLAGS) -c $< +.S.o: + $(CC) $(ASFLAGS) -c $< + .PHONY: all all: $(ARTIFACT).elf diff --git a/sound-driver/main.c b/sound-driver/main.c index 7420b17..8e4a119 100644 --- a/sound-driver/main.c +++ b/sound-driver/main.c @@ -31,6 +31,8 @@ int main() { __enable_interrupt(); + // playMelodyTetris(); + while (1) { schExec(); } diff --git a/sound-driver/melody_tetris.c b/sound-driver/melody_tetris.c index 396c7b6..340eb3f 100644 --- a/sound-driver/melody_tetris.c +++ b/sound-driver/melody_tetris.c @@ -925,7 +925,8 @@ const t_tone voice3[] = { t_melodies tetrisTheme = { .melodies = { { .chip = 0, .amplitude = 8, .tones = voice1 }, { .chip = 0, .amplitude = 8, .tones = voice2 }, { .chip = 0, .amplitude = 8, .tones = voice3 } }, .numOfMelodies = 3, - .pace = 160 + .pace = 160, + .slotMask = 0x01 }; void playMelodyTetris() { diff --git a/sound-driver/melody_tusch1.c b/sound-driver/melody_tusch1.c index 8734d4c..5bb2d79 100644 --- a/sound-driver/melody_tusch1.c +++ b/sound-driver/melody_tusch1.c @@ -73,7 +73,8 @@ const t_tone tusch1voice3[] = { t_melodies tusch1 = { .melodies = { { .chip = 1, .amplitude = 12, .tones = tusch1voice1 }, { .chip = 1, .amplitude = 12, .tones = tusch1voice2 }, { .chip = 1, .amplitude = 12, .tones = tusch1voice3 } }, .numOfMelodies = 3, - .pace = 200 + .pace = 200, + .slotMask = 0x02 }; void playTusch1() { diff --git a/sound-driver/scheduler.h b/sound-driver/scheduler.h index d84efb4..0f8b24c 100644 --- a/sound-driver/scheduler.h +++ b/sound-driver/scheduler.h @@ -6,7 +6,7 @@ -#define MAX_NUM_OF_TASKS 8 +#define MAX_NUM_OF_TASKS 4 typedef struct { diff --git a/sound-driver/sequencer.c b/sound-driver/sequencer.c index 2118ab1..8c0b7e1 100644 --- a/sound-driver/sequencer.c +++ b/sound-driver/sequencer.c @@ -6,8 +6,10 @@ #include "psg.h" +uint8_t slots; void sequencerInit() { + slots = 0; } #pragma GCC diagnostic push @@ -97,12 +99,18 @@ void sequencerExec(void *handle) { break; case e_Terminate: schDel(melodies->taskId); + slots &= ~(melodies->slotMask); break; } } } -uint16_t sequencerPlayMelodies(t_melodies *melodies) { +void sequencerPlayMelodies(t_melodies *melodies) { + if ((slots & melodies->slotMask) != 0) { + return; + } + + slots |= melodies->slotMask; for (uint8_t i = 0; i < NUM_OF_CHANNELS; i++) { melodies->melodies[i].idx = 0; melodies->melodies[i].lengthCnt = 0; @@ -112,11 +120,10 @@ uint16_t sequencerPlayMelodies(t_melodies *melodies) { melodies->quarterLength = 60000 / melodies->pace / SEQUENCER_PERIOD; // duration of a 1/4 tone in ms melodies->taskId = schAdd(sequencerExec, (void*) melodies, 0, SEQUENCER_PERIOD); - - return melodies->taskId; } void sequencerStopMelodies(t_melodies *melodies) { + slots &= ~(melodies->slotMask); schDel(melodies->taskId); } diff --git a/sound-driver/sequencer.h b/sound-driver/sequencer.h index 982abac..0eb374b 100644 --- a/sound-driver/sequencer.h +++ b/sound-driver/sequencer.h @@ -52,6 +52,7 @@ typedef struct { #define SEQUENCER_PERIOD 4 // ms #define NUM_OF_CHANNELS 3 typedef struct { + uint8_t slotMask; uint8_t taskId; uint16_t quarterLength; uint8_t numOfMelodies; @@ -61,7 +62,7 @@ typedef struct { } t_melodies; void sequencerInit(); -uint16_t sequencerPlayMelodies(t_melodies *melodies); +void sequencerPlayMelodies(t_melodies *melodies); void sequencerStopMelodies(t_melodies *melodies); #endif // _SEQUENCER_H_ diff --git a/sound-driver/soundCodes.h b/sound-driver/soundCodes.h new file mode 100644 index 0000000..b5af55c --- /dev/null +++ b/sound-driver/soundCodes.h @@ -0,0 +1,14 @@ +#ifndef _SOUND_CODES_H_ +#define _SOUND_CODES_H_ + +#define SOUND_IDLE 0x00 +#define SOUND_MUTE 0x01 +#define SOUND_UNMUTE 0x02 +#define SOUND_START 0x04 +#define SOUND_GAMEOVER 0x08 +#define SOUND_FANFARE 0x10 +#define SOUND_LOCK 0x20 +#define SOUND_MOTION 0x40 +#define SOUND_SPEED_UP 0x80 + +#endif // _SOUND_CODES_H_ diff --git a/sound-driver/spi.S b/sound-driver/spi.S new file mode 100644 index 0000000..c61617f --- /dev/null +++ b/sound-driver/spi.S @@ -0,0 +1,70 @@ +#include +#include "soundCodes.h" + + .section ".data" + .global cmd +cmd: + .byte + + .section ".text","ax",@progbits +receive_isr: + bit #UCB0RXIFG, &UC0IFG + jz receive_isr_no_data + bis UCB0RXBUF, &cmd +receive_isr_no_data: + reti + + .global spiCmdHandler +spiCmdHandler: +spiCmdHandler_1: + bit #SOUND_MUTE, &cmd + jz spiCmdHandler_2 + call #mute + bic #SOUND_MUTE, &cmd +spiCmdHandler_2: + bit #SOUND_UNMUTE, &cmd + jz spiCmdHandler_3 + call #unMute + bic #SOUND_UNMUTE, &cmd +spiCmdHandler_3: + bit #SOUND_START, &cmd + jz spiCmdHandler_4 + call #playMelodyTetris + bic #SOUND_START, &cmd +spiCmdHandler_4: + bit #SOUND_GAMEOVER, &cmd + jz spiCmdHandler_5 + ;; insert a call here + bic #SOUND_GAMEOVER, &cmd +spiCmdHandler_5: + bit #SOUND_FANFARE, &cmd + jz spiCmdHandler_6 + call #playTusch1 + bic #SOUND_FANFARE, &cmd +spiCmdHandler_6: + bit #SOUND_LOCK, &cmd + jz spiCmdHandler_7 + ;; insert a call here + bic #SOUND_LOCK, &cmd +spiCmdHandler_7: + bit #SOUND_MOTION, &cmd + jz spiCmdHandler_8 + ;; insert a call here + bic #SOUND_MOTION, &cmd +spiCmdHandler_8: + bit #SOUND_SPEED_UP, &cmd + jz spiCmdHandler_end + ;; insert a call here + bic #SOUND_SPEED_UP, &cmd +spiCmdHandler_end: + ret + + + + + + .section "__interrupt_vector_8","ax",@progbits + .word receive_isr + + + .end diff --git a/sound-driver/spi.c b/sound-driver/spi.c deleted file mode 100644 index 930486c..0000000 --- a/sound-driver/spi.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include -#include -#include "spi.h" -#include "../game-ctrl/sound.h" -#include "scheduler.h" -#include "psg.h" -#include "mute.h" -#include "melody_tetris.h" -#include "melody_tusch1.h" - - -volatile t_SoundCmd cmd; - -void __attribute__ ((interrupt (USCIAB0RX_VECTOR))) receive() { - if (UC0IFG & UCB0RXIFG) { - // receive an octet - cmd = UCB0RXBUF; - } -} - -void spiCmdHandler(void *handle) { - t_SoundCmd cmdShadow; - - __disable_interrupt(); - cmdShadow = cmd; - __enable_interrupt(); - - /* - e_SOUND_IDLE = 0, - e_SOUND_MUTE = 1, - e_SOUND_UNMUTE, - e_SOUND_START_BACKGROUND, - e_SOUND_STOP_BACKGROUND, - e_SOUND_START_GAMEOVER, - e_SOUND_STOP_GAMEOVER, - e_SOUND_SPEED_UP, - e_SOUND_FANFARE_BASE, - e_SOUND_FANFARE_1, - e_SOUND_FANFARE_2, - e_SOUND_FANFARE_3, - e_SOUND_FANFARE_4, - e_SOUND_STONE_LOCKED, - e_SOUND_STONE_MOVE_LEFT, - e_SOUND_STONE_MOVE_RIGHT, - e_SOUND_STONE_ROTATE_LEFT, - e_SOUND_STONE_ROTATE_RIGHT, - e_SOUND_STONE_MOVE_DOWN, - */ - - switch (cmdShadow) { - case e_SOUND_MUTE: - mute(); - break; - case e_SOUND_UNMUTE: - unMute(); - break; - case e_SOUND_START_BACKGROUND: - playMelodyTetris(); - break; - case e_SOUND_STOP_BACKGROUND: - stopMelodyTetris(); - break; - case e_SOUND_START_GAMEOVER: - break; - case e_SOUND_STOP_GAMEOVER: - break; - case e_SOUND_SPEED_UP: - break; - case e_SOUND_FANFARE_1: - playTusch1(); - break; - case e_SOUND_FANFARE_2: - playTusch1(); - break; - case e_SOUND_FANFARE_3: - playTusch1(); - break; - case e_SOUND_FANFARE_4: - playTusch1(); - break; - case e_SOUND_STONE_LOCKED: - break; - case e_SOUND_STONE_MOVE_DOWN: - break; - case e_SOUND_STONE_MOVE_LEFT: - break; - case e_SOUND_STONE_MOVE_RIGHT: - break; - case e_SOUND_STONE_ROTATE_LEFT: - break; - case e_SOUND_STONE_ROTATE_RIGHT: - break; - default: - break; - } -} - -void spiInit() { - // SPI slave - // BIT4: UCB0STE - // BIT5: UCB0CLK - // BIT6: UCB0SOMI - // BIT7: UCB0SIMO - P1SEL |= BIT4 | BIT5 | BIT7; - P1SEL2 |= BIT4 | BIT5 | BIT7; - - // most significant bit first, enable STE - UCB0CTL0 = UCSYNC | UCMSB | UCMODE_2; - UCB0CTL1 = 0x00; - - // enable RX interrupt - UC0IE |= UCB0RXIE; - - schAdd(spiCmdHandler, NULL, 0, 10); -} - - diff --git a/sound-driver/spi.h b/sound-driver/spi.h index 4622917..9456ff7 100644 --- a/sound-driver/spi.h +++ b/sound-driver/spi.h @@ -3,7 +3,7 @@ void spiInit(); - +void spiCmdHandler(); #endif // _SPI_H_ diff --git a/sound-driver/spi_init.c b/sound-driver/spi_init.c new file mode 100644 index 0000000..4f70f12 --- /dev/null +++ b/sound-driver/spi_init.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include "scheduler.h" +#include "spi.h" +#include "soundCodes.h" + + +extern uint8_t cmd; + +void spiInit() { + // SPI slave + // BIT4: UCB0STE + // BIT5: UCB0CLK + // BIT6: UCB0SOMI + // BIT7: UCB0SIMO + P1SEL |= BIT4 | BIT5 | BIT7; + P1SEL2 |= BIT4 | BIT5 | BIT7; + + // most significant bit first, enable STE + UCB0CTL0 = UCSYNC | UCMSB | UCMODE_2; + UCB0CTL1 = 0x00; + + // enable RX interrupt + UC0IE |= UCB0RXIE; + + cmd = SOUND_IDLE; + schAdd(spiCmdHandler, NULL, 0, 100); +} + +