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
$(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) $^
$(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 "scheduler.h"
#include "sequencer.h"
#include "psg.h"
#include "melody.h"
int main() {
WDTCTL = WDTPW | WDTHOLD;
@ -20,6 +22,9 @@ int main() {
schInit();
psgInit();
sequencerInit();
melodyInit();
__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(1, 0, 15, e_O_5, e_A);
psgPlayFrequency(0, 0, 15, 500);
psgPlayFrequency(1, 0, 15, 500);
//psgPlayFrequency(0, 0, 15, 500);
//psgPlayFrequency(1, 0, 15, 500);
// psgAmplitude(0, 0, 15);
// psgWriteFrequencyCode(0, 0, 1023);
// psgAmplitude(1, 0, 15);

View File

@ -20,7 +20,6 @@ typedef struct {
void schInit();
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 schExec();

View File

@ -15,89 +15,9 @@ typedef enum {
ACTION_RESULT_END
} 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 bool running = false;
@ -105,6 +25,7 @@ static actionResult_t _wait(uint32_t wait) {
actionResult_t res;
if (! running) {
running = true;
counter = wait;
res = ACTION_RESULT_STAY;
} 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) {
// 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
psgPlayFrequency(1, 0, volume_b, frequency_b);
return ACTION_RESULT_NEXT;
}
static bool _change_volume(uint8_t volume_a, uint8_t volume_b) {
// set volume_a to generator 0
psgAmplitude(0, 0, volume_a);
// set volume_b to generator 1
psgAmplitude(1, 0, volume_b);
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() {
schAdd(sequencerExec, NULL, 0, CYCLE_TIME);
}

View File

@ -1,9 +1,9 @@
#ifndef _SEQUENCER_H_
#define _SEQUENCER_H_
#include <stdint.h>
typedef enum {
SA_IDLE,
SA_WAIT,
SA_CHANGE_SOUND,
SA_MOVE_SOUND,
@ -48,19 +48,57 @@ typedef struct {
} u;
} sequencerAction_t;
sequencerAction_t w(uint32_t wait);
sequencerAction_t cs(uint16_t frequency_a, uint8_t volume_a, uint16_t frequency_b, uint8_t volume_b);
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 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();
#define W(X0) (sequencerAction_t) { \
.type = SA_WAIT, \
.u.wait = X0 \
}
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();