sequencer and melody

This commit is contained in:
Wolfgang Hottgenroth 2024-06-11 21:24:54 +02:00
parent e9baf05baf
commit 48f6d71616
9 changed files with 152 additions and 101 deletions

View File

@ -12,7 +12,7 @@ ASFLAGS=$(COMMONFLAGS) -D__ASSEMBLER__
LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include
$(ARTIFACT).elf: main.o scheduler.o psg.o sequencer.o $(ARTIFACT).elf: main.o scheduler.o psg.o sequencer.o melody.o
$(CC) -o $@ $(LDFLAGS) $^ $(CC) -o $@ $(LDFLAGS) $^
$(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt $(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt

2
firmware.gdb Normal file
View File

@ -0,0 +1,2 @@
target remote localhost:2000
file firmware.elf

5
main.c
View File

@ -3,7 +3,9 @@
#include <stdlib.h> #include <stdlib.h>
#include "scheduler.h" #include "scheduler.h"
#include "sequencer.h"
#include "psg.h" #include "psg.h"
#include "melody.h"
int main() { int main() {
WDTCTL = WDTPW | WDTHOLD; WDTCTL = WDTPW | WDTHOLD;
@ -20,6 +22,9 @@ int main() {
schInit(); schInit();
psgInit(); psgInit();
sequencerInit();
melodyInit();
__enable_interrupt(); __enable_interrupt();

27
melody.c Normal file
View File

@ -0,0 +1,27 @@
#include "melody.h"
#include "sequencer.h"
const sequencerAction_t seq[] = {
CS(440, 15, 441, 15),
W(100),
CS(440, 15, 443, 15),
W(100),
CS(440, 15, 444, 15),
W(100),
CS(440, 15, 446, 15),
W(100),
CS(440, 15, 444, 15),
W(100),
CS(440, 15, 443, 15),
W(100),
CS(440, 15, 441, 15),
W(100),
R(),
E(),
};
void melodyInit() {
sequencerStart(seq);
}

8
melody.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _MELODY_H_
#define _MELODY_H_
void melodyInit();
#endif // _MELODY_H_

4
psg.c
View File

@ -173,8 +173,8 @@ void psgInit() {
//psgPlayTone(0, 0, 15, e_O_4, e_A); //psgPlayTone(0, 0, 15, e_O_4, e_A);
//psgPlayTone(1, 0, 15, e_O_5, e_A); //psgPlayTone(1, 0, 15, e_O_5, e_A);
psgPlayFrequency(0, 0, 15, 500); //psgPlayFrequency(0, 0, 15, 500);
psgPlayFrequency(1, 0, 15, 500); //psgPlayFrequency(1, 0, 15, 500);
// psgAmplitude(0, 0, 15); // psgAmplitude(0, 0, 15);
// psgWriteFrequencyCode(0, 0, 1023); // psgWriteFrequencyCode(0, 0, 1023);
// psgAmplitude(1, 0, 15); // psgAmplitude(1, 0, 15);

View File

@ -20,7 +20,6 @@ typedef struct {
void schInit(); void schInit();
uint16_t schAdd(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period); uint16_t schAdd(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period);
// void schDel(void (*exec)(void *), void *handle);
void schDel(uint16_t taskId); void schDel(uint16_t taskId);
void schExec(); void schExec();

View File

@ -15,89 +15,9 @@ typedef enum {
ACTION_RESULT_END ACTION_RESULT_END
} actionResult_t; } actionResult_t;
uint16_t taskId;
sequencerAction_t w(uint32_t wait) {
sequencerAction_t s = {
.type = SA_WAIT,
.u.wait = wait
};
return s;
}
sequencerAction_t cs(uint16_t frequency_a, uint8_t volume_a, uint16_t frequency_b, uint8_t volume_b) {
sequencerAction_t s = {
.type = SA_CHANGE_SOUND,
.u.cs.frequency_a = frequency_a,
.u.cs.frequency_b = frequency_b,
.u.cs.volume_a = volume_a,
.u.cs.volume_b = volume_b
};
return s;
}
sequencerAction_t ms(uint16_t frequency_a_0, uint8_t volume_a_0, uint16_t frequency_b_0, uint8_t volume_b_0,
uint16_t frequency_a_1, uint8_t volume_a_1, uint16_t frequency_b_1, uint8_t volume_b_1,
uint32_t move_time) {
sequencerAction_t s = {
.type = SA_MOVE_SOUND,
.u.ms.frequency_a_0 = frequency_a_0,
.u.ms.frequency_b_0 = frequency_b_0,
.u.ms.volume_a_0 = volume_a_0,
.u.ms.volume_b_0 = volume_b_0,
.u.ms.frequency_a_1 = frequency_a_1,
.u.ms.frequency_b_1 = frequency_b_1,
.u.ms.volume_a_1 = volume_a_1,
.u.ms.volume_b_1 = volume_b_1,
.u.ms.move_time = move_time
};
return s;
}
sequencerAction_t cv(uint8_t volume_a, uint8_t volume_b) {
sequencerAction_t s = {
.type = SA_CHANGE_VOLUME,
.u.cv.volume_a = volume_a,
.u.cv.volume_b = volume_b
};
return s;
}
sequencerAction_t mv(uint8_t volume_a_0, uint8_t volume_b_0,
uint8_t volume_a_1, uint8_t volume_b_1,
uint32_t move_time) {
sequencerAction_t s = {
.type = SA_MOVE_VOLUME,
.u.mv.volume_a_0 = volume_a_0,
.u.mv.volume_b_0 = volume_b_0,
.u.mv.volume_a_1 = volume_a_1,
.u.mv.volume_b_1 = volume_b_1,
.u.mv.move_time = move_time
};
return s;
}
sequencerAction_t r() {
sequencerAction_t s = {
.type = SA_REPEAT
};
return s;
}
sequencerAction_t e() {
sequencerAction_t s = {
.type = SA_END
};
return s;
}
static actionResult_t _repeat() {
return ACTION_RESULT_REPEAT;
}
static actionResult_t _end() {
return ACTION_RESULT_END;
}
static actionResult_t _wait(uint32_t wait) { static actionResult_t _wait(uint32_t wait) {
static bool running = false; static bool running = false;
@ -105,6 +25,7 @@ static actionResult_t _wait(uint32_t wait) {
actionResult_t res; actionResult_t res;
if (! running) { if (! running) {
running = true;
counter = wait; counter = wait;
res = ACTION_RESULT_STAY; res = ACTION_RESULT_STAY;
} else { } else {
@ -121,23 +42,74 @@ static actionResult_t _wait(uint32_t wait) {
static actionResult_t _change_sound(uint16_t frequency_a, uint8_t volume_a, uint16_t frequency_b, uint8_t volume_b) { static actionResult_t _change_sound(uint16_t frequency_a, uint8_t volume_a, uint16_t frequency_b, uint8_t volume_b) {
// set frequency_a and volume_a to generator 0 // set frequency_a and volume_a to generator 0
psgPlayFrequency(0, 0, volume_a, frequency_a);
// set frequency_b and volume_b to generator 1 // set frequency_b and volume_b to generator 1
psgPlayFrequency(1, 0, volume_b, frequency_b);
return ACTION_RESULT_NEXT; return ACTION_RESULT_NEXT;
} }
static bool _change_volume(uint8_t volume_a, uint8_t volume_b) { static bool _change_volume(uint8_t volume_a, uint8_t volume_b) {
// set volume_a to generator 0 // set volume_a to generator 0
psgAmplitude(0, 0, volume_a);
// set volume_b to generator 1 // set volume_b to generator 1
psgAmplitude(1, 0, volume_b);
return ACTION_RESULT_NEXT; return ACTION_RESULT_NEXT;
} }
void sequencerStart(sequencerAction_t *sequence) { void sequencerExec(void *handle) {
sequencerAction_t *seq = (sequencerAction_t*) handle;
static uint16_t seqIdx = 0;
sequencerAction_t *action = seq + seqIdx;
actionResult_t res;
switch (action->type) {
case SA_WAIT:
res = _wait(action->u.wait);
break;
case SA_REPEAT:
res = ACTION_RESULT_REPEAT;
break;
case SA_END:
res = ACTION_RESULT_END;
break;
case SA_CHANGE_SOUND:
res = _change_sound(
action->u.cs.frequency_a,
action->u.cs.volume_a,
action->u.cs.frequency_b,
action->u.cs.volume_b);
break;
case SA_CHANGE_VOLUME:
res = _change_volume(
action->u.cs.volume_a,
action->u.cs.volume_b);
break;
default:
break;
}
switch (res) {
case ACTION_RESULT_NEXT:
seqIdx += 1;
break;
case ACTION_RESULT_REPEAT:
seqIdx = 0;
break;
case ACTION_RESULT_STAY:
break;
case ACTION_RESULT_END:
schDel(taskId);
break;
}
} }
void sequencerExec(void *handle) { void sequencerStart(const sequencerAction_t *sequence) {
taskId = schAdd(sequencerExec, (void*) sequence, 0, CYCLE_TIME);
} }
void sequencerInit() { void sequencerInit() {
schAdd(sequencerExec, NULL, 0, CYCLE_TIME);
} }

View File

@ -1,9 +1,9 @@
#ifndef _SEQUENCER_H_ #ifndef _SEQUENCER_H_
#define _SEQUENCER_H_ #define _SEQUENCER_H_
#include <stdint.h>
typedef enum { typedef enum {
SA_IDLE,
SA_WAIT, SA_WAIT,
SA_CHANGE_SOUND, SA_CHANGE_SOUND,
SA_MOVE_SOUND, SA_MOVE_SOUND,
@ -48,19 +48,57 @@ typedef struct {
} u; } u;
} sequencerAction_t; } sequencerAction_t;
sequencerAction_t w(uint32_t wait); #define W(X0) (sequencerAction_t) { \
sequencerAction_t cs(uint16_t frequency_a, uint8_t volume_a, uint16_t frequency_b, uint8_t volume_b); .type = SA_WAIT, \
sequencerAction_t ms(uint16_t frequency_a_0, uint8_t volume_a_0, uint16_t frequency_b_0, uint8_t volume_b_0, .u.wait = X0 \
uint16_t frequency_a_1, uint8_t volume_a_1, uint16_t frequency_b_1, uint8_t volume_b_1, }
uint32_t move_time);
sequencerAction_t cv(uint8_t volume_a, uint8_t volume_b);
sequencerAction_t mv(uint8_t volume_a_0, uint8_t volume_b_0,
uint8_t volume_a_1, uint8_t volume_b_1,
uint32_t move_time);
sequencerAction_t r();
sequencerAction_t e();
void sequencerStart(sequencerAction_t *sequence); #define CS(X0, X1, X2, X3) (sequencerAction_t) { \
.type = SA_CHANGE_SOUND, \
.u.cs.frequency_a = X0, \
.u.cs.volume_a = X1, \
.u.cs.frequency_b = X2, \
.u.cs.volume_b = X3 \
}
#define MS(X0, X1, X2, X3, \
X4, X5, X6, X7, X8) (sequencerAction_t) { \
.type = SA_MOVE_SOUND, \
.u.ms.frequency_a_0 = X0, \
.u.ms.volume_a_0 = X1, \
.u.ms.frequency_b_0 = X2, \
.u.ms.volume_b_0 = X3, \
.u.ms.frequency_a_1 = X4, \
.u.ms.volume_a_1 = X5, \
.u.ms.frequency_b_1 = X6, \
.u.ms.volume_b_1 = X7, \
.u.ms.move_time = X8 \
}
#define CV(X0, X1) (sequencerAction_t) { \
.type = SA_CHANGE_VOLUME, \
.u.cv.volume_a = X0, \
.u.cv.volume_b = X1 \
}
#define MV(X0, X1, X2, X3, X4) (sequencerAction_t) { \
.type = SA_MOVE_VOLUME, \
.u.mv.volume_a_0 = X0, \
.u.mv.volume_b_0 = X1, \
.u.mv.volume_a_1 = X2, \
.u.mv.volume_b_1 = X3, \
.u.mv.move_time = X4 \
}
#define R() (sequencerAction_t) { \
.type = SA_REPEAT \
}
#define E() (sequencerAction_t) { \
.type = SA_END \
}
void sequencerStart(const sequencerAction_t *sequence);
void sequencerInit(); void sequencerInit();