sequencer and melody
This commit is contained in:
parent
e9baf05baf
commit
48f6d71616
2
Makefile
2
Makefile
@ -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
2
firmware.gdb
Normal file
@ -0,0 +1,2 @@
|
||||
target remote localhost:2000
|
||||
file firmware.elf
|
5
main.c
5
main.c
@ -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
27
melody.c
Normal 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
8
melody.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _MELODY_H_
|
||||
#define _MELODY_H_
|
||||
|
||||
|
||||
void melodyInit();
|
||||
|
||||
|
||||
#endif // _MELODY_H_
|
4
psg.c
4
psg.c
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
140
sequencer.c
140
sequencer.c
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
64
sequencer.h
64
sequencer.h
@ -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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user