Compare commits
140 Commits
game_ctrl_
...
configmode
Author | SHA1 | Date | |
---|---|---|---|
d9769c6b28 | |||
d9fd18d799 | |||
7894359f30 | |||
4cb0a10617 | |||
a92a3beb96 | |||
ccd395d6ab | |||
eb75e31577 | |||
ba4248ff24 | |||
2cc5a6a4f3 | |||
5c86d55458 | |||
b9e5813223 | |||
1b4a93d9e1 | |||
30d50dcc5e | |||
1607dc62dd | |||
78df7eee66 | |||
09fe302e63
|
|||
d28e62fdd3
|
|||
01d4fe3f85
|
|||
5de2761fde | |||
1f807cdb7c | |||
735599ee7f | |||
7a2c9f96d4 | |||
5d7a94c3b2 | |||
1d915baf77
|
|||
08b96a6617
|
|||
ff95034605 | |||
ac4801c7cf
|
|||
a4cb8129c5
|
|||
f5fa1e5e22
|
|||
1d96cee661 | |||
7a560959c1 | |||
8d8a818cf9
|
|||
b400431607 | |||
7933aa46ae
|
|||
076c0f3f1a | |||
b49665512f | |||
36d3b2f735 | |||
d68dae167d
|
|||
3412197cae
|
|||
8dc0569407
|
|||
ac6ca860cb
|
|||
2711f5fb4b
|
|||
9674bc8ef5
|
|||
c0ee849cec
|
|||
78c906ef26
|
|||
0c4533bfac
|
|||
3eed2e30eb
|
|||
3cebb5d351
|
|||
a29525ac9e
|
|||
83e6227581
|
|||
010c493b90
|
|||
2404910870
|
|||
53e538b112
|
|||
1232d0b884 | |||
a1d6422897 | |||
761de5a94d | |||
9a58eedcc4 | |||
2fb12f8af0 | |||
fef3f69f63 | |||
5b9194caae | |||
2f8e2937c1 | |||
3769b3eb05 | |||
8f777c9ac4 | |||
aeb7aeb7f2 | |||
20c01f2efa
|
|||
40cb04bde5 | |||
a1457e6a69 | |||
0303bbdc3c | |||
162bdaefee | |||
b9fd0099a8 | |||
d09f8d240f
|
|||
ed6da383de
|
|||
9328e22425 | |||
48b9fc7578
|
|||
d4d494ae7b | |||
1ebf85cb9d | |||
5a8323bddb | |||
97dc6ede70 | |||
a4563cd393 | |||
b435396d67 | |||
38ea1a7fdb | |||
6632630303 | |||
fdb524c8d4 | |||
2c3bccd147 | |||
ee98ba12a3 | |||
33242a09c1
|
|||
2097280f2b
|
|||
70b3b25a9d | |||
5e1e9dfa92 | |||
f397d0737b
|
|||
1c2414463b | |||
2e629f12aa | |||
9989a52c38 | |||
73d2bbc730 | |||
5e2f120432 | |||
152f171c66 | |||
9ddb747f16 | |||
bd11d12620 | |||
e5c6669284 | |||
202e91bfb6 | |||
48c83f0b2d | |||
d8e34ec209 | |||
5a491140c7 | |||
aaf709b0c9 | |||
32bb08696f | |||
85d243551e | |||
a32ef8fa5b | |||
10a09e3ad3 | |||
611c56b329 | |||
5b1dfde819
|
|||
1cc4785ddb | |||
9acd56b79b | |||
474fce2278 | |||
8597a9f736
|
|||
da21fac130
|
|||
5f9fab5f2c | |||
f524a08687 | |||
5c03232855 | |||
f69c5bc59e | |||
50486f6ec0 | |||
8c995f66ff | |||
ebe958ac49 | |||
fadb80c362 | |||
d1e13dc16a | |||
90a9294da6 | |||
cfc06ddb2d | |||
5e5c616bde | |||
2ca1d2e4ad | |||
a28cdcf6af | |||
7f6d027d1a | |||
97b1d19da8 | |||
8b2f18415d | |||
5615c80e8f | |||
a68f74559f | |||
326d0f66b0 | |||
feed11f977 | |||
fd3df973ec | |||
58ae9a641a
|
|||
e0aae175b0
|
|||
7e4285f280 |
4
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
*.o
|
||||
firmware.*
|
||||
firmware.txt
|
||||
firmware.elf
|
||||
firmware.map
|
||||
|
||||
|
31
display-driver/Makefile
Normal file
@ -0,0 +1,31 @@
|
||||
TOOLCHAIN_PREFIX=/opt/msp430-gcc
|
||||
CC=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-gcc
|
||||
OBJDUMP=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-objdump
|
||||
|
||||
ARTIFACT=firmware
|
||||
MCU=msp430g2553
|
||||
CFLAGS=-Wall -mmcu=$(MCU) -std=gnu99 -I $(TOOLCHAIN_PREFIX)/include -O1 -g0
|
||||
|
||||
# for debugging
|
||||
#CFLAGS+= -g3 -ggdb -gdwarf-2
|
||||
|
||||
LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include
|
||||
|
||||
$(ARTIFACT).elf: main.o
|
||||
$(CC) -o $@ $(LDFLAGS) $^
|
||||
$(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
|
||||
.PHONY: all
|
||||
all: $(ARTIFACT).elf
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -f *.o $(ARTIFACT).elf $(ARTIFACT).txt
|
||||
|
||||
.PHONY: upload
|
||||
upload: $(ARTIFACT).elf
|
||||
mspdebug rf2500 "prog $(ARTIFACT).elf"
|
BIN
display-driver/docs/MCU-Connection and Pattern.pdf
Executable file
BIN
display-driver/docs/Pinout-Display.pdf
Executable file
131
display-driver/main.c
Normal file
@ -0,0 +1,131 @@
|
||||
#include <msp430g2553.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
const uint8_t patterns[] = {
|
||||
0b00111111, // 0
|
||||
0b00000110, // 1
|
||||
0b01011011, // 2
|
||||
0b01001111, // 3
|
||||
0b01100110, // 4
|
||||
0b01101101, // 5
|
||||
0b01111101, // 6
|
||||
0b00100111, // 7
|
||||
0b01111111, // 8
|
||||
0b01101111, // 9
|
||||
};
|
||||
|
||||
|
||||
|
||||
volatile union {
|
||||
uint16_t value;
|
||||
uint8_t receiveBuffer[2];
|
||||
} value;
|
||||
|
||||
|
||||
static void delay() {
|
||||
asm volatile (
|
||||
"push r12\n"
|
||||
"mov.w #1000, r12\n"
|
||||
"loop:\n"
|
||||
"dec.w r12\n"
|
||||
"jnz loop\n"
|
||||
"pop r12\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void __attribute__ ((interrupt (USCIAB0RX_VECTOR))) receive() {
|
||||
static uint8_t octetNumber = 0;
|
||||
if (UC0IFG & UCB0RXIFG) {
|
||||
value.receiveBuffer[octetNumber] = UCB0RXBUF;
|
||||
octetNumber++;
|
||||
if (octetNumber > 1) {
|
||||
octetNumber = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mask 0x0f: digit value
|
||||
// mask 0x10: set dp
|
||||
// mask 0x20: digit off
|
||||
static void setDigit(uint16_t bit, uint8_t value) {
|
||||
P1OUT |= (BIT0 | BIT1 | BIT2 | BIT3);
|
||||
P2OUT = ((value & 0x20) ? 0 : patterns[value & 0x0f]) | ((value & 0x10) ? 0x80 : 0x00);
|
||||
P1OUT &= ~bit;
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
WDTCTL = WDTPW | WDTHOLD;
|
||||
|
||||
__disable_interrupt();
|
||||
|
||||
// highest possible system clock
|
||||
DCOCTL = DCO0 | DCO1 | DCO2;
|
||||
BCSCTL1 = XT2OFF | RSEL0 | RSEL1 | RSEL2 | RSEL3;
|
||||
BCSCTL2 = 0;
|
||||
BCSCTL3 = 0;
|
||||
|
||||
// SPI slave
|
||||
// BIT4: UCB0STE
|
||||
// BIT5: UCB0CLK
|
||||
// BIT6: UCB0SOMI
|
||||
// BIT7: UCB0SIMO
|
||||
P1SEL |= BIT4 | BIT5 | BIT6 | BIT7;
|
||||
P1SEL2 |= BIT4 | BIT5 | BIT6 | BIT7;
|
||||
// most significant bit first, enable STE
|
||||
UCB0CTL0 = UCCKPH | UCSYNC | UCMSB | UCMODE_2;
|
||||
UCB0CTL1 = 0x00;
|
||||
// enable RX interrupt
|
||||
UC0IE |= UCB0RXIE;
|
||||
|
||||
// digit driver
|
||||
P1DIR |= BIT0 | BIT1 | BIT2 | BIT3;
|
||||
P1SEL &= ~(BIT0 | BIT1 | BIT2 | BIT3);
|
||||
P1SEL2 &= ~(BIT0 | BIT1 | BIT2 | BIT3);
|
||||
|
||||
// segment driver
|
||||
P2DIR = 0xff;
|
||||
P2SEL = 0x00;
|
||||
P2SEL2 = 0x00;
|
||||
|
||||
// all digits off
|
||||
P1OUT |= (BIT0 | BIT1 | BIT2 | BIT3);
|
||||
|
||||
// all segments off
|
||||
P2OUT &= ~(BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7);
|
||||
|
||||
// reset value to 0
|
||||
value.value = 0;
|
||||
|
||||
__enable_interrupt();
|
||||
|
||||
while (1) {
|
||||
__disable_interrupt();
|
||||
uint16_t shadowValue = value.value;
|
||||
__enable_interrupt();
|
||||
|
||||
uint8_t digit0 = shadowValue % 10;
|
||||
uint8_t digit1 = (shadowValue / 10) % 10;
|
||||
uint8_t digit2 = (shadowValue / 100) % 10;
|
||||
uint8_t digit3 = (shadowValue / 1000) % 10;
|
||||
|
||||
digit1 += (!((digit3 & 0x0f) | (digit2 & 0x0f) | (digit1 & 0x0f))) ? 0x20 : 0x00;
|
||||
digit2 += (!((digit3 & 0x0f) | (digit2 & 0x0f))) ? 0x20 : 0x00;
|
||||
digit3 += (!(digit3 & 0x0f)) ? 0x20 : 0x00;
|
||||
|
||||
setDigit(BIT0, digit0);
|
||||
delay();
|
||||
|
||||
setDigit(BIT1, digit1);
|
||||
delay();
|
||||
|
||||
setDigit(BIT2, digit2);
|
||||
delay();
|
||||
|
||||
setDigit(BIT3, digit3);
|
||||
delay();
|
||||
}
|
||||
}
|
BIN
docs/IMG_4936.jpg
Normal file
After Width: | Height: | Size: 2.0 MiB |
BIN
docs/IMG_4941.jpg
Normal file
After Width: | Height: | Size: 603 KiB |
BIN
docs/IMG_4958.jpeg
Normal file
After Width: | Height: | Size: 262 KiB |
BIN
docs/display-driver.jpg
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
docs/game-ctrl.jpg
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
docs/logo.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
docs/reset-ctrl.jpg
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
docs/rgb-driver.jpg
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
docs/schematics.pdf
Executable file
BIN
docs/sound-driver-1.jpg
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
docs/sound-driver-2.png
Normal file
After Width: | Height: | Size: 183 KiB |
BIN
docs/sound-driver-3.jpg
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
docs/sound-driver-4.jpg
Normal file
After Width: | Height: | Size: 74 KiB |
@ -7,11 +7,11 @@ MCU=msp430g2553
|
||||
CFLAGS=-Wall -mmcu=$(MCU) -std=gnu99 -I $(TOOLCHAIN_PREFIX)/include -O1 -g0
|
||||
|
||||
# for debugging
|
||||
# CFLAGS+= -g3 -ggdb -gdwarf-2
|
||||
#CFLAGS+= -g3 -ggdb -gdwarf-2
|
||||
|
||||
LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include
|
||||
|
||||
$(ARTIFACT).elf: main.o led.o time.o PontCoopScheduler.o displayDriver.o canvas.o shapes.o game.o buttons.o
|
||||
$(ARTIFACT).elf: main.o spi.o scheduler.o canvas.o shapes.o game.o buttons.o myrand.o display.o sound.o eeprom.o config.o
|
||||
$(CC) -o $@ $(LDFLAGS) $^
|
||||
$(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt
|
||||
|
||||
|
@ -1,98 +1,138 @@
|
||||
#include "stddef.h"
|
||||
#include "stdint.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <msp430g2553.h>
|
||||
|
||||
#include "buttons.h"
|
||||
#include "PontCoopScheduler.h"
|
||||
#include "scheduler.h"
|
||||
#include "shapes.h"
|
||||
#include "canvas.h"
|
||||
#include "led.h"
|
||||
#include "sound.h"
|
||||
|
||||
|
||||
// TEST CODE
|
||||
uint16_t counter;
|
||||
|
||||
bool mutedFlag = true;
|
||||
|
||||
static uint8_t buttonsMoveLeftPressed() {
|
||||
// -----------------------
|
||||
// TEST CODE
|
||||
//if (counter == 95) {
|
||||
// ledGreenToggle();
|
||||
// return 1;
|
||||
//}
|
||||
// -----------------------
|
||||
return 0;
|
||||
static uint8_t last = 0;
|
||||
uint8_t current = (P2IN & BIT4);
|
||||
uint8_t res = (current != 0) && (current != last);
|
||||
last = current;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool buttonsConfig1Pressed() {
|
||||
return buttonsMoveLeftPressed();
|
||||
}
|
||||
|
||||
static uint8_t buttonsMoveRightPressed() {
|
||||
// -----------------------
|
||||
// TEST CODE
|
||||
if (counter == 95) {
|
||||
ledGreenToggle();
|
||||
return 1;
|
||||
}
|
||||
// -----------------------
|
||||
return 0;
|
||||
static uint8_t last = 0;
|
||||
uint8_t current = (P2IN & BIT0);
|
||||
uint8_t res = (current != 0) && (current != last);
|
||||
last = current;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool buttonsConfig4Pressed() {
|
||||
return buttonsMoveRightPressed();
|
||||
}
|
||||
|
||||
static uint8_t buttonsRotateLeftPressed() {
|
||||
return 0;
|
||||
static uint8_t last = 0;
|
||||
uint8_t current = (P2IN & BIT3);
|
||||
uint8_t res = (current != 0) && (current != last);
|
||||
last = current;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool buttonsConfig2Pressed() {
|
||||
return buttonsRotateLeftPressed();
|
||||
}
|
||||
|
||||
static uint8_t buttonsRotateRightPressed() {
|
||||
// -----------------------
|
||||
// TEST CODE
|
||||
if (counter == 35) {
|
||||
ledGreenToggle();
|
||||
return 1;
|
||||
}
|
||||
// -----------------------
|
||||
// -----------------------
|
||||
// TEST CODE
|
||||
if (counter == 45) {
|
||||
ledGreenToggle();
|
||||
return 1;
|
||||
}
|
||||
// -----------------------
|
||||
return 0;
|
||||
static uint8_t last = 0;
|
||||
uint8_t current = (P2IN & BIT1);
|
||||
uint8_t res = (current != 0) && (current != last);
|
||||
last = current;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool buttonsConfig3Pressed() {
|
||||
return buttonsRotateRightPressed();
|
||||
}
|
||||
|
||||
|
||||
static uint8_t buttonsMoveDownPressed() {
|
||||
return P2IN & BIT2;
|
||||
}
|
||||
|
||||
bool isConfigMode() {
|
||||
return (P2IN & BIT2);
|
||||
}
|
||||
|
||||
|
||||
void buttonsExec(void *handle) {
|
||||
static uint32_t unmuteTimestamp;
|
||||
uint32_t currentTimestamp = getSeconds();
|
||||
|
||||
|
||||
if (! stoneIsValid()) {
|
||||
// don't do anything, the stone has not been initialized
|
||||
return;
|
||||
}
|
||||
|
||||
// TEST CODE
|
||||
counter++;
|
||||
|
||||
uint8_t buttonPressed = 0;
|
||||
|
||||
if (buttonsMoveLeftPressed()) {
|
||||
stoneMoveLeft();
|
||||
soundCtrl(SOUND_MOTION);
|
||||
buttonPressed = 1;
|
||||
}
|
||||
if (buttonsMoveRightPressed()) {
|
||||
stoneMoveRight();
|
||||
soundCtrl(SOUND_MOTION);
|
||||
buttonPressed = 1;
|
||||
}
|
||||
if (buttonsRotateLeftPressed()) {
|
||||
stoneRotateLeft();
|
||||
soundCtrl(SOUND_MOTION);
|
||||
buttonPressed = 1;
|
||||
}
|
||||
if (buttonsRotateRightPressed()) {
|
||||
stoneRotateRight();
|
||||
soundCtrl(SOUND_MOTION);
|
||||
buttonPressed = 1;
|
||||
}
|
||||
if (buttonsMoveDownPressed()) {
|
||||
stoneMoveDown();
|
||||
soundCtrl(SOUND_MOTION);
|
||||
buttonPressed = 1;
|
||||
}
|
||||
|
||||
if (buttonPressed == 1) {
|
||||
canvasShow();
|
||||
|
||||
if (mutedFlag) {
|
||||
soundCtrl(SOUND_UNMUTE);
|
||||
mutedFlag = false;
|
||||
}
|
||||
unmuteTimestamp = currentTimestamp;
|
||||
}
|
||||
|
||||
if ((! mutedFlag) && (unmuteTimestamp + MUTE_DELAY < currentTimestamp)) {
|
||||
soundCtrl(SOUND_MUTE);
|
||||
mutedFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
void buttonsInit() {
|
||||
// TEST CODE
|
||||
counter = 0;
|
||||
|
||||
schAdd(buttonsExec, NULL, 0, 100);
|
||||
P2DIR &= ~(BIT0|BIT1|BIT2|BIT3|BIT4);
|
||||
}
|
||||
|
||||
void buttonsStart() {
|
||||
schAdd(buttonsExec, NULL, 0, 25);
|
||||
}
|
||||
|
||||
bool isGameActive() {
|
||||
return ! mutedFlag;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,16 @@
|
||||
#ifndef _BUTTONS_H_
|
||||
#define _BUTTONS_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void buttonsInit();
|
||||
void buttonsStart();
|
||||
bool isGameActive();
|
||||
bool isConfigMode();
|
||||
bool buttonsConfig1Pressed();
|
||||
bool buttonsConfig2Pressed();
|
||||
bool buttonsConfig3Pressed();
|
||||
bool buttonsConfig4Pressed();
|
||||
|
||||
|
||||
#endif // _BUTTONS_H_
|
||||
|
@ -1,39 +1,84 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <msp430g2553.h>
|
||||
|
||||
#include "canvas.h"
|
||||
#include "displayDriver.h"
|
||||
#include "spi.h"
|
||||
#include "eeprom.h"
|
||||
#include "../rgb-driver/colors.h"
|
||||
|
||||
|
||||
static uint8_t canvasStorage[CANVAS_WIDTH * CANVAS_HEIGHT];
|
||||
const canvas_t canvas = {
|
||||
.height = CANVAS_HEIGHT,
|
||||
.width = CANVAS_WIDTH,
|
||||
.size = CANVAS_WIDTH * CANVAS_HEIGHT,
|
||||
.canvas = canvasStorage
|
||||
};
|
||||
|
||||
static uint8_t miniCanvasStorage[MINI_CANVAS_WIDTH * MINI_CANVAS_HEIGHT];
|
||||
const canvas_t miniCanvas = {
|
||||
.height = MINI_CANVAS_HEIGHT,
|
||||
.width = MINI_CANVAS_WIDTH,
|
||||
.canvas = miniCanvasStorage
|
||||
};
|
||||
|
||||
void canvasShow() {
|
||||
uint8_t brightness_offset = _brightness_offset * eepromReadBrightness();
|
||||
|
||||
// wait for signal waiting for data
|
||||
while (!(P1IN & BIT3));
|
||||
|
||||
spiSendBegin(e_SPI_CANVAS);
|
||||
|
||||
for (uint8_t i = 0; i < (CANVAS_WIDTH*CANVAS_HEIGHT); i++) {
|
||||
if ((*((canvas.canvas)+i) & 0x80) != 0) {
|
||||
*((canvas.canvas)+i) &= ~0x80;
|
||||
spiSendOctet(i);
|
||||
spiSendOctet((*((canvas.canvas)+i) == 0) ? 0 : (*((canvas.canvas)+i) + brightness_offset));
|
||||
}
|
||||
}
|
||||
for (uint8_t i = 0; i < (MINI_CANVAS_WIDTH*MINI_CANVAS_HEIGHT); i++) {
|
||||
if ((*((miniCanvas.canvas)+i) & 0x80) != 0) {
|
||||
*((miniCanvas.canvas)+i) &= ~0x80;
|
||||
spiSendOctet(i + (CANVAS_HEIGHT*CANVAS_WIDTH));
|
||||
spiSendOctet((*((miniCanvas.canvas)+i) == 0) ? 0 : (*((miniCanvas.canvas)+i) + brightness_offset));
|
||||
}
|
||||
}
|
||||
spiSendOctet(0xfe);
|
||||
|
||||
spiSendEnd(e_SPI_CANVAS);
|
||||
}
|
||||
|
||||
void canvasInit() {
|
||||
// P1.3 is signal line
|
||||
P1DIR &= ~BIT3;
|
||||
|
||||
canvasClear();
|
||||
displayDriverTransferCanvas();
|
||||
miniCanvasClear();
|
||||
canvasShow();
|
||||
}
|
||||
|
||||
void canvasClear() {
|
||||
memset(canvas.canvas, 0x80, canvas.size);
|
||||
memset(canvas.canvas, 0x80, CANVAS_WIDTH*CANVAS_HEIGHT);
|
||||
}
|
||||
|
||||
void canvasSetAll(uint8_t color) {
|
||||
memset(canvas.canvas, color + 0x80, canvas.size);
|
||||
void miniCanvasClear() {
|
||||
memset(miniCanvas.canvas, 0x80, MINI_CANVAS_WIDTH*MINI_CANVAS_HEIGHT);
|
||||
}
|
||||
|
||||
void canvasShow() {
|
||||
displayDriverTransferCanvas();
|
||||
}
|
||||
//void canvasSetAll(uint8_t color) {
|
||||
// memset(canvas.canvas, color + 0x80, CANVAS_WIDTH*CANVAS_HEIGHT);
|
||||
//}
|
||||
|
||||
void canvasSetPixel(uint8_t column, uint8_t row, uint8_t color) {
|
||||
*((canvas.canvas) + (row * canvas.width + column)) = (color + 0x80);
|
||||
}
|
||||
|
||||
void miniCanvasSetPixel(uint8_t column, uint8_t row, uint8_t color) {
|
||||
*((miniCanvas.canvas) + (row * miniCanvas.width + column)) = (color + 0x80);
|
||||
}
|
||||
|
||||
void canvasWipeRow(uint8_t row) {
|
||||
memmove(((canvas.canvas)+canvas.width), canvas.canvas, canvas.width*row);
|
||||
for (uint8_t i = 10; i < canvas.width*(row+1); i++) {
|
||||
@ -42,6 +87,13 @@ void canvasWipeRow(uint8_t row) {
|
||||
memset(canvas.canvas, 0x80, canvas.width);
|
||||
}
|
||||
|
||||
void canvasFillRow(uint8_t row, uint8_t color) {
|
||||
for (uint8_t c = 0; c < canvas.width; c++) {
|
||||
canvasSetPixel(c, row, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t canvasIsRowFilled(uint8_t row) {
|
||||
uint8_t res = 1;
|
||||
for (uint8_t column = 0; column < canvas.width; column++) {
|
||||
|
@ -3,9 +3,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Definition of CANVAS_WIDTH and CANVAS_HEIGHT
|
||||
// imported from rgb-driver
|
||||
#include "../rgb-driver/canvasSize.h"
|
||||
|
||||
#define CANVAS_WIDTH 10
|
||||
#define CANVAS_HEIGHT 11
|
||||
|
||||
typedef struct {
|
||||
const uint8_t width;
|
||||
@ -16,13 +17,14 @@ typedef struct {
|
||||
|
||||
void canvasInit();
|
||||
void canvasClear();
|
||||
void canvasSetAll(uint8_t color);
|
||||
void miniCanvasClear();
|
||||
//void canvasSetAll(uint8_t color);
|
||||
void canvasShow();
|
||||
void canvasSetPixel(uint8_t column, uint8_t row, uint8_t color);
|
||||
void miniCanvasSetPixel(uint8_t column, uint8_t row, uint8_t color);
|
||||
uint8_t canvasIsPixelFree(uint8_t column, uint8_t row);
|
||||
void canvasWipeRow(uint8_t row);
|
||||
void canvasFillRow(uint8_t row, uint8_t color);
|
||||
uint8_t canvasIsRowFilled(uint8_t row);
|
||||
|
||||
extern const canvas_t canvas;
|
||||
|
||||
#endif // _CANVAS_H_
|
||||
|
91
game-ctrl/config.c
Normal file
@ -0,0 +1,91 @@
|
||||
#include <stddef.h>
|
||||
#include "config.h"
|
||||
#include "canvas.h"
|
||||
#include "../rgb-driver/colors.h"
|
||||
#include "scheduler.h"
|
||||
#include "buttons.h"
|
||||
#include "eeprom.h"
|
||||
#include "display.h"
|
||||
#include "shapes.h"
|
||||
|
||||
|
||||
static bool configChanged = false;
|
||||
|
||||
static void configHandleFlash() {
|
||||
if (buttonsConfig2Pressed()) {
|
||||
configChanged = true;
|
||||
uint8_t color = eepromReadFlashColor() + 1;
|
||||
if (color > _color_end) {
|
||||
color = 0;
|
||||
}
|
||||
canvasFillRow(CANVAS_HEIGHT-1, color);
|
||||
displaySetValue(color);
|
||||
eepromSetFlashColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
static void configHandleResetHighScore() {
|
||||
displaySetValue(eepromReadHighScore());
|
||||
|
||||
if (buttonsConfig2Pressed()) {
|
||||
configChanged = true;
|
||||
eepromSetHighScore(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void configHandleBrightness() {
|
||||
displaySetValue(eepromReadBrightness());
|
||||
|
||||
if (buttonsConfig2Pressed()) {
|
||||
configChanged = true;
|
||||
uint8_t brightness = eepromReadBrightness() + 1;
|
||||
if (brightness > _brightness_shifts) {
|
||||
brightness = 0;
|
||||
}
|
||||
eepromSetBrightness(brightness);
|
||||
|
||||
stoneDrawConfigPattern();
|
||||
}
|
||||
}
|
||||
|
||||
void (*configHandler[])(void) = { configHandleFlash, configHandleResetHighScore, configHandleBrightness };
|
||||
|
||||
|
||||
void configExec(void *handle) {
|
||||
static uint8_t configState = 0;
|
||||
static uint8_t lastConfigState = 255;
|
||||
|
||||
if (configState != lastConfigState) {
|
||||
lastConfigState = configState;
|
||||
|
||||
miniCanvasClear();
|
||||
canvasClear();
|
||||
miniCanvasSetPixel(configState, 0, _red);
|
||||
}
|
||||
|
||||
if (buttonsConfig1Pressed()) {
|
||||
configState += 1;
|
||||
if (configState >= sizeof(configHandler) / sizeof(configHandler[0])) {
|
||||
configState = 0;
|
||||
}
|
||||
}
|
||||
|
||||
configHandler[configState]();
|
||||
|
||||
if (configChanged) {
|
||||
miniCanvasSetPixel(0, 2, _red);
|
||||
if (buttonsConfig4Pressed()) {
|
||||
eepromCommit();
|
||||
configChanged = false;
|
||||
}
|
||||
} else {
|
||||
miniCanvasSetPixel(0, 2, _green);
|
||||
}
|
||||
|
||||
canvasShow();
|
||||
}
|
||||
|
||||
|
||||
void configInit() {
|
||||
schAdd(configExec, NULL, 0, 25);
|
||||
}
|
8
game-ctrl/config.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
|
||||
void configInit();
|
||||
|
||||
|
||||
#endif // _CONFIG_H_
|
@ -1,6 +1,6 @@
|
||||
#include "led.h"
|
||||
#include <msp430g2553.h>
|
||||
#include "PontCoopScheduler.h"
|
||||
#include "scheduler.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
26
game-ctrl/display.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "spi.h"
|
||||
|
||||
|
||||
|
||||
void displayInit() {
|
||||
}
|
||||
|
||||
|
||||
void displaySetValue(uint16_t v) {
|
||||
union {
|
||||
uint16_t value;
|
||||
uint8_t sendBuffer[2];
|
||||
} value;
|
||||
|
||||
value.value = v;
|
||||
|
||||
spiSendBegin(e_SPI_DISPLAY);
|
||||
|
||||
spiSendOctet(value.sendBuffer[0]);
|
||||
spiSendOctet(value.sendBuffer[1]);
|
||||
|
||||
spiSendEnd(e_SPI_DISPLAY);
|
||||
}
|
13
game-ctrl/display.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef _DISPLAY_H_
|
||||
#define _DISPLAY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
void displayInit();
|
||||
void displaySetValue(uint16_t v);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _DISPLAY_H_
|
@ -1,57 +0,0 @@
|
||||
#include "displayDriver.h"
|
||||
#include "led.h"
|
||||
#include "canvas.h"
|
||||
#include <msp430g2553.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
inline static void spiSendOctet(uint8_t v) {
|
||||
// wait for TX buffer empty
|
||||
while (!(UC0IFG & UCB0TXIFG));
|
||||
// load octet into TX buffer
|
||||
UCB0TXBUF = v;
|
||||
}
|
||||
|
||||
void displayDriverTransferCanvas() {
|
||||
// wait for signal waiting for data
|
||||
while ((P1IN & BIT3) == 0);
|
||||
|
||||
for (uint8_t i = 0; i < canvas.size; i++) {
|
||||
if ((*((canvas.canvas)+i) & 0x80) != 0) {
|
||||
*((canvas.canvas)+i) &= ~0x80;
|
||||
spiSendOctet(i);
|
||||
spiSendOctet(*((canvas.canvas)+i));
|
||||
}
|
||||
}
|
||||
spiSendOctet(0xfe);
|
||||
}
|
||||
|
||||
void displayDriverInit() {
|
||||
// SPI in master mode
|
||||
UCB0CTL0 = UCMST;
|
||||
// SPI timing config
|
||||
UCB0CTL1 = UCSSEL_3;
|
||||
// Faster than 8 ends up in strange communication errors
|
||||
// between the both MCUs.
|
||||
// With 8 the transfer of a complete 110 pixel canvas takes
|
||||
// about 720us.
|
||||
UCB0BR0 = 8;
|
||||
UCB0BR1 = 0;
|
||||
|
||||
// BIT5: UCB0CLK
|
||||
// BIT6: UCB0SOMI
|
||||
// BIT7: UCB0SIMO
|
||||
P1SEL |= BIT5 | BIT6 | BIT7;
|
||||
P1SEL2 |= BIT5 | BIT6 | BIT7;
|
||||
P1DIR |= BIT5 | BIT7;
|
||||
|
||||
// P1.3 is signal line
|
||||
P1DIR &= ~BIT3;
|
||||
|
||||
// enable SPI module
|
||||
UCB0CTL1 &= ~UCSWRST;
|
||||
}
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
#ifndef _DISPLAY_DRIVER_H_
|
||||
#define _DISPLAY_DRIVER_H_
|
||||
|
||||
void displayDriverInit();
|
||||
void displayDriverTransferCanvas();
|
||||
|
||||
|
||||
|
||||
#endif // _DISPLAY_DRIVER_H_
|
BIN
game-ctrl/docs/motion-definitions.pdf
Executable file
96
game-ctrl/eeprom.c
Normal file
@ -0,0 +1,96 @@
|
||||
#include <stdint.h>
|
||||
#include "eeprom.h"
|
||||
#include "spi.h"
|
||||
|
||||
|
||||
#define MAGIC 0xb000
|
||||
#define HIGHSCORE_ADDR 0x00
|
||||
#define DUMMY 0x00
|
||||
#define CMD_READ 0b00000011
|
||||
#define CMD_WRITE 0b00000010
|
||||
#define CMD_WRDI 0b00000100
|
||||
#define CMD_WREN 0b00000110
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t magic;
|
||||
uint16_t highScore;
|
||||
uint8_t flashColor;
|
||||
uint8_t brightness;
|
||||
} t_configBlock;
|
||||
|
||||
typedef union {
|
||||
t_configBlock v;
|
||||
uint8_t buffer[sizeof(t_configBlock)];
|
||||
} eepromBuf_t;
|
||||
|
||||
eepromBuf_t buf;
|
||||
|
||||
static void writeBuf() {
|
||||
spiSendBegin(e_SPI_EEPROM);
|
||||
spiSendOctet(CMD_WREN);
|
||||
spiSendEnd(e_SPI_EEPROM);
|
||||
|
||||
spiSendBegin(e_SPI_EEPROM);
|
||||
spiSendOctet(CMD_WRITE);
|
||||
spiSendOctet(HIGHSCORE_ADDR);
|
||||
for (uint8_t i = 0; i < sizeof(t_configBlock); i++) {
|
||||
spiSendOctet(buf.buffer[i]);
|
||||
}
|
||||
spiSendEnd(e_SPI_EEPROM);
|
||||
}
|
||||
|
||||
static void readBuf() {
|
||||
spiSendBegin(e_SPI_EEPROM);
|
||||
spiSendOctet(CMD_READ);
|
||||
spiReceiveOctet();
|
||||
spiSendOctet(HIGHSCORE_ADDR);
|
||||
spiReceiveOctet();
|
||||
for (uint8_t i = 0; i < sizeof(t_configBlock); i++) {
|
||||
spiSendOctet(DUMMY);
|
||||
buf.buffer[i] = spiReceiveOctet();
|
||||
}
|
||||
spiSendEnd(e_SPI_EEPROM);
|
||||
}
|
||||
|
||||
void eepromInit() {
|
||||
readBuf();
|
||||
|
||||
if (buf.v.magic != MAGIC) {
|
||||
buf.v.magic = MAGIC;
|
||||
buf.v.highScore = 0;
|
||||
buf.v.flashColor = 0;
|
||||
buf.v.brightness = 0;
|
||||
writeBuf();
|
||||
}
|
||||
}
|
||||
|
||||
void eepromCommit() {
|
||||
writeBuf();
|
||||
}
|
||||
|
||||
uint16_t eepromReadHighScore() {
|
||||
return buf.v.highScore;
|
||||
}
|
||||
|
||||
void eepromSetHighScore(uint16_t v) {
|
||||
buf.v.highScore = v;
|
||||
writeBuf();
|
||||
}
|
||||
|
||||
uint8_t eepromReadFlashColor() {
|
||||
return buf.v.flashColor;
|
||||
}
|
||||
|
||||
void eepromSetFlashColor(uint8_t v) {
|
||||
buf.v.flashColor = v;
|
||||
}
|
||||
|
||||
uint8_t eepromReadBrightness() {
|
||||
return buf.v.brightness;
|
||||
}
|
||||
|
||||
void eepromSetBrightness(uint8_t v) {
|
||||
buf.v.brightness = v;
|
||||
}
|
||||
|
18
game-ctrl/eeprom.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef _EEPROM_H_
|
||||
#define _EEPROM_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
void eepromInit();
|
||||
uint16_t eepromReadHighScore();
|
||||
void eepromSetHighScore(uint16_t v);
|
||||
uint8_t eepromReadFlashColor();
|
||||
void eepromSetFlashColor(uint8_t v);
|
||||
uint8_t eepromReadBrightness();
|
||||
void eepromSetBrightness(uint8_t v);
|
||||
void eepromCommit();
|
||||
|
||||
|
||||
|
||||
#endif // _EEPROM_H_
|
2
game-ctrl/firmware.gdb
Normal file
@ -0,0 +1,2 @@
|
||||
target remote localhost:2000
|
||||
file firmware.elf
|
183
game-ctrl/game.c
@ -1,67 +1,188 @@
|
||||
// #define STATE_DEBUGGING
|
||||
|
||||
#include "stddef.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#include "game.h"
|
||||
#include "PontCoopScheduler.h"
|
||||
#include "scheduler.h"
|
||||
#include "shapes.h"
|
||||
#include "canvas.h"
|
||||
#include "../rgb-driver/colors.h"
|
||||
#include "display.h"
|
||||
#include "sound.h"
|
||||
#include "eeprom.h"
|
||||
#include "buttons.h"
|
||||
|
||||
|
||||
typedef enum { e_idle, e_start, e_newStone, e_down, e_gameOver, e_delay } state_t;
|
||||
#define GAME_CYCLE_TIME 10
|
||||
#define GAMEOVER_DELAY 10
|
||||
#define MAX_LEVEL 100
|
||||
|
||||
|
||||
static uint16_t delayFactor(uint16_t level) {
|
||||
return MAX_LEVEL + 1 - level;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
e_Start, e_NewStone, e_Down, e_DownDelay,
|
||||
e_ClearRowInit, e_ClearRowNext, e_ClearRowCheck, e_ClearRowFlash, e_ClearRowFlashDelay, e_ClearRowWipe,
|
||||
e_GameOver, e_GameOverFill, e_GameOverWipe, e_GameOverDelay
|
||||
} state_t;
|
||||
|
||||
void gameExec(void *handle) {
|
||||
static state_t state = e_start;
|
||||
static uint8_t delay;
|
||||
static state_t state = e_Start;
|
||||
static uint8_t gameOverDelay;
|
||||
static uint8_t rowIndex;
|
||||
static uint16_t proceedDelay;
|
||||
static uint16_t level;
|
||||
static uint16_t filledLines;
|
||||
static uint16_t score;
|
||||
static bool newHighScoreAchieved;
|
||||
|
||||
static uint8_t clearCheckCnt;
|
||||
|
||||
#ifdef STATE_DEBUGGING
|
||||
displaySetValue(state);
|
||||
#endif
|
||||
// --- engine begin -------------------------------------------------------
|
||||
switch (state) {
|
||||
case e_idle:
|
||||
break;
|
||||
|
||||
case e_start:
|
||||
// --- phase: game --------------------------------------------------------
|
||||
case e_Start:
|
||||
canvasClear();
|
||||
state = e_newStone;
|
||||
soundCtrl(SOUND_START);
|
||||
level = 1;
|
||||
filledLines = 0;
|
||||
score = 0;
|
||||
newHighScoreAchieved = false;
|
||||
state = e_NewStone;
|
||||
break;
|
||||
|
||||
case e_newStone:
|
||||
case e_NewStone:
|
||||
stoneCreate();
|
||||
if (stoneDraw()) {
|
||||
state = e_down;
|
||||
proceedDelay = delayFactor(level);
|
||||
state = e_DownDelay;
|
||||
} else {
|
||||
state = e_gameOver;
|
||||
state = e_GameOver;
|
||||
}
|
||||
break;
|
||||
|
||||
case e_down:
|
||||
|
||||
case e_DownDelay:
|
||||
proceedDelay--;
|
||||
if (proceedDelay == 0) {
|
||||
state = e_Down;
|
||||
}
|
||||
break;
|
||||
|
||||
case e_Down:
|
||||
if (! stoneMoveDown()) {
|
||||
state = e_newStone;
|
||||
soundCtrl(SOUND_LOCK);
|
||||
stoneLock();
|
||||
state = e_ClearRowInit;
|
||||
} else {
|
||||
proceedDelay = delayFactor(level);
|
||||
state = e_DownDelay;
|
||||
}
|
||||
break;
|
||||
|
||||
case e_gameOver:
|
||||
for (uint8_t c = 0; c < canvas.width; c++) {
|
||||
canvasSetPixel(c, 0, 0x0d);
|
||||
canvasSetPixel(c, canvas.height-1, 0x0d);
|
||||
}
|
||||
for (uint8_t r = 0; r < canvas.height; r++) {
|
||||
canvasSetPixel(0, r, 0x0d);
|
||||
canvasSetPixel(canvas.width-1, r, 0x0d);
|
||||
}
|
||||
delay = 10;
|
||||
state = e_delay;
|
||||
// --- phase: clear rows --------------------------------------------------
|
||||
case e_ClearRowInit:
|
||||
clearCheckCnt = 0;
|
||||
state = e_ClearRowCheck;
|
||||
break;
|
||||
|
||||
case e_delay:
|
||||
delay--;
|
||||
if (delay == 0) {
|
||||
state = e_start;
|
||||
case e_ClearRowNext:
|
||||
if (clearCheckCnt >= CANVAS_HEIGHT) {
|
||||
state = e_NewStone;
|
||||
} else {
|
||||
clearCheckCnt += 1;
|
||||
state = e_ClearRowCheck;
|
||||
}
|
||||
break;
|
||||
|
||||
case e_ClearRowCheck:
|
||||
if (canvasIsRowFilled(clearCheckCnt)) {
|
||||
score += level;
|
||||
if (score > eepromReadHighScore()) {
|
||||
newHighScoreAchieved = true;
|
||||
eepromSetHighScore(score);
|
||||
eepromCommit();
|
||||
}
|
||||
state = e_ClearRowFlash;
|
||||
} else {
|
||||
state = e_ClearRowNext;
|
||||
}
|
||||
break;
|
||||
|
||||
case e_ClearRowFlash:
|
||||
canvasFillRow(clearCheckCnt, eepromReadFlashColor());
|
||||
state = e_ClearRowFlashDelay;
|
||||
break;
|
||||
|
||||
case e_ClearRowFlashDelay:
|
||||
state = e_ClearRowWipe;
|
||||
break;
|
||||
|
||||
case e_ClearRowWipe:
|
||||
canvasWipeRow(clearCheckCnt);
|
||||
filledLines += 1;
|
||||
|
||||
if ((filledLines > 0) && ((filledLines % 10) == 0)) {
|
||||
if (level < MAX_LEVEL) {
|
||||
level += 1;
|
||||
}
|
||||
soundCtrl(SOUND_FANFARE);
|
||||
} else {
|
||||
soundCtrl(SOUND_PLING);
|
||||
}
|
||||
state = e_ClearRowNext;
|
||||
break;
|
||||
|
||||
// --- phase: game over ---------------------------------------------------
|
||||
case e_GameOver:
|
||||
soundCtrl(SOUND_GAMEOVER);
|
||||
rowIndex = CANVAS_HEIGHT;
|
||||
state = e_GameOverFill;
|
||||
break;
|
||||
|
||||
case e_GameOverFill:
|
||||
rowIndex--;
|
||||
canvasFillRow(rowIndex, newHighScoreAchieved ? _green : _red);
|
||||
if (rowIndex == 0) {
|
||||
state = e_GameOverWipe;
|
||||
}
|
||||
break;
|
||||
|
||||
case e_GameOverWipe:
|
||||
canvasWipeRow(rowIndex);
|
||||
rowIndex++;
|
||||
if (rowIndex == CANVAS_HEIGHT) {
|
||||
gameOverDelay = GAMEOVER_DELAY;
|
||||
state = e_GameOverDelay;
|
||||
}
|
||||
break;
|
||||
|
||||
case e_GameOverDelay:
|
||||
gameOverDelay--;
|
||||
if (gameOverDelay == 0) {
|
||||
state = e_Start;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// --- engine end ---------------------------------------------------------
|
||||
|
||||
canvasShow();
|
||||
|
||||
#ifndef STATE_DEBUGGING
|
||||
if (isGameActive()) {
|
||||
displaySetValue(score);
|
||||
} else {
|
||||
displaySetValue(eepromReadHighScore());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void gameInit() {
|
||||
schAdd(gameExec, NULL, 0, 1000);
|
||||
schAdd(gameExec, NULL, 0, GAME_CYCLE_TIME);
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,16 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "time.h"
|
||||
#include "PontCoopScheduler.h"
|
||||
#include "led.h"
|
||||
#include "displayDriver.h"
|
||||
#include "scheduler.h"
|
||||
#include "canvas.h"
|
||||
#include "game.h"
|
||||
#include "buttons.h"
|
||||
#include "shapes.h"
|
||||
#include "myrand.h"
|
||||
#include "spi.h"
|
||||
#include "display.h"
|
||||
#include "eeprom.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
int main() {
|
||||
@ -24,17 +27,23 @@ int main() {
|
||||
BCSCTL2 = 0;
|
||||
BCSCTL3 = 0;
|
||||
|
||||
timeInit();
|
||||
schInit();
|
||||
|
||||
ledInit();
|
||||
displayDriverInit();
|
||||
spiInit();
|
||||
eepromInit();
|
||||
displayInit();
|
||||
myRandInit();
|
||||
canvasInit();
|
||||
|
||||
shapesInit();
|
||||
gameInit();
|
||||
buttonsInit();
|
||||
|
||||
if (isConfigMode()) {
|
||||
configInit();
|
||||
} else {
|
||||
shapesInit();
|
||||
gameInit();
|
||||
buttonsStart();
|
||||
}
|
||||
|
||||
__enable_interrupt();
|
||||
|
||||
while (1) {
|
||||
|
26
game-ctrl/myrand.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include <stdint.h>
|
||||
#include <msp430g2553.h>
|
||||
|
||||
#include "myrand.h"
|
||||
|
||||
void myRandInit() {
|
||||
ADC10CTL1 = INCH_10;
|
||||
ADC10CTL0 = SREF_1 | ADC10SHT_1 | REFON | ADC10ON;
|
||||
}
|
||||
|
||||
uint16_t myRandGet() {
|
||||
uint16_t res = 0;
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
ADC10CTL0 |= ENC | ADC10SC;
|
||||
|
||||
while ((ADC10CTL1 & ADC10BUSY));
|
||||
|
||||
res <<= 1;
|
||||
res |= ADC10MEM & 0x0001;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
8
game-ctrl/myrand.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _MYRAND_H_
|
||||
#define _MYRAND_H_
|
||||
|
||||
void myRandInit();
|
||||
uint16_t myRandGet();
|
||||
|
||||
|
||||
#endif // _MYRAND_H_
|
@ -1,21 +1,24 @@
|
||||
/*
|
||||
* PontCoopScheduler.c
|
||||
*
|
||||
* Created on: 29.08.2016
|
||||
* Originally created on: 29.08.2016
|
||||
* Author: wn
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <msp430g2553.h>
|
||||
|
||||
|
||||
#include "PontCoopScheduler.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
tTask tasks[MAX_NUM_OF_TASKS];
|
||||
|
||||
uint32_t seconds;
|
||||
|
||||
void schInit() {
|
||||
TACCR0 = 32;
|
||||
TACCTL0 = CCIE;
|
||||
TACTL = MC_1 | ID_0 | TASSEL_1 | TACLR;
|
||||
|
||||
for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
|
||||
tasks[i].delay = 0;
|
||||
tasks[i].period = 0;
|
||||
@ -23,6 +26,28 @@ void schInit() {
|
||||
tasks[i].exec = NULL;
|
||||
tasks[i].handle = NULL;
|
||||
}
|
||||
|
||||
seconds = 0;
|
||||
}
|
||||
|
||||
void __attribute__ ((interrupt (TIMER0_A0_VECTOR))) schUpdate() {
|
||||
static uint16_t milliSeconds = 0;
|
||||
if (milliSeconds >= 1000) {
|
||||
seconds += 1;
|
||||
milliSeconds = 0;
|
||||
}
|
||||
milliSeconds += 1;
|
||||
|
||||
for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
|
||||
if (tasks[i].exec != NULL) {
|
||||
if (tasks[i].delay == 0) {
|
||||
tasks[i].delay = tasks[i].period;
|
||||
tasks[i].run++;
|
||||
} else {
|
||||
tasks[i].delay--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void schAdd(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period) {
|
||||
@ -74,17 +99,13 @@ void schExec() {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t getSeconds() {
|
||||
uint32_t s;
|
||||
|
||||
__disable_interrupt();
|
||||
s = seconds;
|
||||
__enable_interrupt();
|
||||
|
||||
void schUpdate() {
|
||||
for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
|
||||
if (tasks[i].exec != NULL) {
|
||||
if (tasks[i].delay == 0) {
|
||||
tasks[i].delay = tasks[i].period;
|
||||
tasks[i].run++;
|
||||
} else {
|
||||
tasks[i].delay--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ void schDel(void (*exec)(void *), void *handle);
|
||||
void schExec();
|
||||
void schUpdate();
|
||||
uint8_t schTaskCnt();
|
||||
uint32_t getSeconds();
|
||||
|
||||
|
||||
#endif /* PONTCOOPSCHEDULER_H_ */
|
@ -1,7 +1,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "shapes.h"
|
||||
#include "myrand.h"
|
||||
#include "canvas.h"
|
||||
#include "../rgb-driver/colors.h"
|
||||
|
||||
@ -17,6 +20,7 @@ typedef struct {
|
||||
orientation_t orientation;
|
||||
uint8_t x; // column
|
||||
uint8_t y; // row
|
||||
bool locked;
|
||||
} stone_t;
|
||||
|
||||
typedef struct {
|
||||
@ -42,7 +46,7 @@ typedef struct {
|
||||
motion_t motion[5][4];
|
||||
} motionTable_t;
|
||||
|
||||
const motionTable_t motions[2] = { // 2 = number of implemented stones
|
||||
const motionTable_t motions[7] = { // size = number of implemented stones
|
||||
{ // I
|
||||
.color = _cyan,
|
||||
.nullRotation = 0,
|
||||
@ -120,13 +124,223 @@ const motionTable_t motions[2] = { // 2 = number of implemented stones
|
||||
},
|
||||
{
|
||||
// rotate right
|
||||
{ .set = { {-2, 1}, {-1, 1}, { 1, 1}, { 1, 1} }, .reset = { { 0, 0}, { 0, 2}, { 0, 3}, { 0, 3} }, .offset = {-2, 1} }, // 0
|
||||
{ .set = { { 1,-1}, { 1, 1}, { 1, 2}, { 1, 2} }, .reset = { { 0, 0}, { 2, 0}, { 3, 0}, { 3, 0} }, .offset = { 1,-1} }, // 90
|
||||
{ .set = { {-2, 1}, {-1, 1}, { 1, 1}, { 1, 1} }, .reset = { { 0, 0}, { 0, 2}, { 0, 3}, { 0, 3} }, .offset = {-2, 1} }, // 180
|
||||
{ .set = { { 1,-1}, { 1, 1}, { 1, 2}, { 1, 2} }, .reset = { { 0, 0}, { 2, 0}, { 3, 0}, { 3, 0} }, .offset = { 1,-1} }, // 270
|
||||
{ .set = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0} }, .reset = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0} }, .offset = { 0, 0} }, // 0
|
||||
{ .set = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0} }, .reset = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0} }, .offset = { 0, 0} }, // 90
|
||||
{ .set = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0} }, .reset = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0} }, .offset = { 0, 0} }, // 180
|
||||
{ .set = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0} }, .reset = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0} }, .offset = { 0, 0} }, // 270
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
{ // T
|
||||
.color = _violet,
|
||||
.nullRotation = 0,
|
||||
.draw = { { 0, 0}, { 1, 0}, { 2, 0}, { 1, 1} },
|
||||
.motion = {
|
||||
{
|
||||
// move down
|
||||
{ .set = { { 0, 1}, { 2, 1}, { 1, 2}, { 1, 2} }, .reset = { { 0, 0}, { 1, 0}, { 2, 0}, { 2, 0} }, .offset = { 0, 1} }, // 0
|
||||
{ .set = { { 0, 2}, { 1, 3}, { 1, 3}, { 1, 3} }, .reset = { { 1, 0}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 0, 1} }, // 90
|
||||
{ .set = { { 0, 2}, { 1, 2}, { 2, 2}, { 2, 2} }, .reset = { { 1, 0}, { 0, 1}, { 2, 1}, { 2, 1} }, .offset = { 0, 1} }, // 180
|
||||
{ .set = { { 0, 3}, { 1, 2}, { 1, 2}, { 1, 2} }, .reset = { { 0, 0}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = { 0, 1} }, // 270
|
||||
},
|
||||
{
|
||||
// move left
|
||||
{ .set = { {-1, 0}, { 0, 1}, { 0, 1}, { 0, 1} }, .reset = { { 1, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .offset = {-1, 0} }, // 0
|
||||
{ .set = { { 0, 0}, {-1, 1}, { 0, 2}, { 0, 2} }, .reset = { { 1, 0}, { 1, 1}, { 1, 2}, { 1, 2} }, .offset = {-1, 0} }, // 90
|
||||
{ .set = { {-1, 1}, { 0, 0}, { 0, 0}, { 0, 0} }, .reset = { { 1, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .offset = {-1, 0} }, // 180
|
||||
{ .set = { {-1, 0}, {-1, 1}, {-1, 2}, {-1, 2} }, .reset = { { 0, 0}, { 0, 2}, { 1, 1}, { 1, 1} }, .offset = {-1, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// move right
|
||||
{ .set = { { 3, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .reset = { { 0, 0}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = { 1, 0} }, // 0
|
||||
{ .set = { { 2, 0}, { 2, 1}, { 2, 2}, { 2, 2} }, .reset = { { 0, 1}, { 1, 0}, { 1, 2}, { 1, 2} }, .offset = { 1, 0} }, // 90
|
||||
{ .set = { { 3, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .reset = { { 0, 0}, { 0, 1}, { 1, 0}, { 1, 0} }, .offset = { 1, 0} }, // 180
|
||||
{ .set = { { 1, 0}, { 1, 2}, { 2, 1}, { 2, 1} }, .reset = { { 0, 0}, { 0, 1}, { 0, 2}, { 0, 2} }, .offset = { 1, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// rotate left
|
||||
{ .set = { { 1,-1}, { 1,-1}, { 1,-1}, { 1,-1} }, .reset = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0} }, .offset = { 1,-1} }, // 0
|
||||
{ .set = { { 2, 1}, { 2, 1}, { 2, 1}, { 2, 1} }, .reset = { { 1, 0}, { 1, 0}, { 1, 0}, { 1, 0} }, .offset = { 0, 1} }, // 90
|
||||
{ .set = { { 1, 2}, { 1, 2}, { 1, 2}, { 1, 2} }, .reset = { { 2, 1}, { 2, 1}, { 2, 1}, { 2, 1} }, .offset = { 0, 0} }, // 180
|
||||
{ .set = { {-1, 1}, {-1, 1}, {-1, 1}, {-1, 1} }, .reset = { { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2} }, .offset = {-1, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// rotate right
|
||||
{ .set = { { 1,-1}, { 1,-1}, { 1,-1}, { 1,-1} }, .reset = { { 2, 0}, { 2, 0}, { 2, 0}, { 2, 0} }, .offset = { 0,-1} }, // 0
|
||||
{ .set = { { 2, 1}, { 2, 1}, { 2, 1}, { 2, 1} }, .reset = { { 1, 2}, { 1, 2}, { 1, 2}, { 1, 2} }, .offset = { 0, 0} }, // 90
|
||||
{ .set = { { 1, 2}, { 1, 2}, { 1, 2}, { 1, 2} }, .reset = { { 0, 1}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 1, 0} }, // 180
|
||||
{ .set = { {-1, 1}, {-1, 1}, {-1, 1}, {-1, 1} }, .reset = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0} }, .offset = {-1, 1} }, // 270
|
||||
},
|
||||
}
|
||||
},
|
||||
{ // Z
|
||||
.color = _red,
|
||||
.nullRotation = 0,
|
||||
.draw = { { 0, 0}, { 1, 0}, { 1, 1}, { 2, 1} },
|
||||
.motion = {
|
||||
{
|
||||
// move down
|
||||
{ .set = { { 0, 1}, { 1, 2}, { 2, 2}, { 2, 2} }, .reset = { { 0, 0}, { 1, 0}, { 2, 1}, { 2, 1} }, .offset = { 0, 1} }, // 0
|
||||
{ .set = { { 1, 2}, { 0, 3}, { 0, 3}, { 0, 3} }, .reset = { { 1, 0}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 0, 1} }, // 90
|
||||
{ .set = { { 0, 1}, { 1, 2}, { 2, 2}, { 2, 2} }, .reset = { { 0, 0}, { 1, 0}, { 2, 1}, { 2, 1} }, .offset = { 0, 1} }, // 180
|
||||
{ .set = { { 1, 2}, { 0, 3}, { 0, 3}, { 0, 3} }, .reset = { { 1, 0}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 0, 1} }, // 270
|
||||
},
|
||||
{
|
||||
// move left
|
||||
{ .set = { {-1, 0}, { 0, 1}, { 0, 1}, { 0, 1} }, .reset = { { 1, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .offset = {-1, 0} }, // 0
|
||||
{ .set = { {-1, 1}, {-1, 2}, { 0, 0}, { 0, 0} }, .reset = { { 1, 0}, { 1, 1}, { 0, 2}, { 0, 2} }, .offset = {-1, 0} }, // 90
|
||||
{ .set = { {-1, 0}, { 0, 1}, { 0, 1}, { 0, 1} }, .reset = { { 1, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .offset = {-1, 0} }, // 180
|
||||
{ .set = { {-1, 1}, {-1, 2}, { 0, 0}, { 0, 0} }, .reset = { { 1, 0}, { 1, 1}, { 0, 2}, { 0, 2} }, .offset = {-1, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// move right
|
||||
{ .set = { { 3, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .reset = { { 0, 0}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = { 1, 0} }, // 0
|
||||
{ .set = { { 2, 0}, { 2, 1}, { 1, 2}, { 1, 2} }, .reset = { { 0, 1}, { 0, 2}, { 1, 0}, { 1, 0} }, .offset = { 1, 0} }, // 90
|
||||
{ .set = { { 3, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .reset = { { 0, 0}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = { 1, 0} }, // 180
|
||||
{ .set = { { 2, 0}, { 2, 1}, { 1, 2}, { 1, 2} }, .reset = { { 0, 1}, { 0, 2}, { 1, 0}, { 1, 0} }, .offset = { 1, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// rotate left
|
||||
{ .set = { { 1,-1}, { 0, 1}, { 0, 1}, { 0, 1} }, .reset = { { 2, 1}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = { 0,-1} }, // 0
|
||||
{ .set = { { 0, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .reset = { { 0, 2}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 0, 0} }, // 90
|
||||
{ .set = { { 1,-1}, { 0, 1}, { 0, 1}, { 0, 1} }, .reset = { { 2, 1}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = { 0,-1} }, // 180
|
||||
{ .set = { { 0, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .reset = { { 0, 2}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 0, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// rotate right
|
||||
{ .set = { { 1,-1}, { 0, 1}, { 0, 1}, { 0, 1} }, .reset = { { 2, 1}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = { 0,-1} }, // 0
|
||||
{ .set = { { 0, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .reset = { { 0, 2}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 0, 0} }, // 90
|
||||
{ .set = { { 1,-1}, { 0, 1}, { 0, 1}, { 0, 1} }, .reset = { { 2, 1}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = { 0,-1} }, // 180
|
||||
{ .set = { { 0, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .reset = { { 0, 2}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 0, 0} }, // 270
|
||||
},
|
||||
}
|
||||
},
|
||||
{ // S
|
||||
.color = _green,
|
||||
.nullRotation = 0,
|
||||
.draw = { { 0, 1}, { 1, 1}, { 1, 0}, { 2, 0} },
|
||||
.motion = {
|
||||
{
|
||||
// move down
|
||||
{ .set = { { 0, 2}, { 1, 2}, { 2, 1}, { 2, 1} }, .reset = { { 0, 1}, { 1, 0}, { 2, 0}, { 2, 0} }, .offset = { 0, 1} }, // 0
|
||||
{ .set = { { 0, 2}, { 1, 3}, { 1, 3}, { 1, 3} }, .reset = { { 0, 0}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = { 0, 1} }, // 90
|
||||
{ .set = { { 0, 2}, { 1, 2}, { 2, 1}, { 2, 1} }, .reset = { { 0, 1}, { 1, 0}, { 2, 0}, { 2, 0} }, .offset = { 0, 1} }, // 180
|
||||
{ .set = { { 0, 2}, { 1, 3}, { 1, 3}, { 1, 3} }, .reset = { { 0, 0}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = { 0, 1} }, // 270
|
||||
},
|
||||
{
|
||||
// move left
|
||||
{ .set = { { 0, 0}, {-1, 1}, {-1, 1}, {-1, 1} }, .reset = { { 2, 0}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = {-1, 0} }, // 0
|
||||
{ .set = { {-1, 0}, {-1, 1}, { 0, 2}, { 0, 2} }, .reset = { { 0, 0}, { 1, 1}, { 1, 2}, { 1, 2} }, .offset = {-1, 0} }, // 90
|
||||
{ .set = { { 0, 0}, {-1, 1}, {-1, 1}, {-1, 1} }, .reset = { { 2, 0}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = {-1, 0} }, // 180
|
||||
{ .set = { {-1, 0}, {-1, 1}, { 0, 2}, { 0, 2} }, .reset = { { 0, 0}, { 1, 1}, { 1, 2}, { 1, 2} }, .offset = {-1, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// move right
|
||||
{ .set = { { 2, 1}, { 3, 0}, { 3, 0}, { 3, 0} }, .reset = { { 1, 0}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 1, 0} }, // 0
|
||||
{ .set = { { 1, 0}, { 2, 1}, { 2, 2}, { 2, 2} }, .reset = { { 0, 0}, { 0, 1}, { 1, 2}, { 1, 2} }, .offset = { 1, 0} }, // 90
|
||||
{ .set = { { 2, 1}, { 3, 0}, { 3, 0}, { 3, 0} }, .reset = { { 1, 0}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 1, 0} }, // 180
|
||||
{ .set = { { 1, 0}, { 2, 1}, { 2, 2}, { 2, 2} }, .reset = { { 0, 0}, { 0, 1}, { 1, 2}, { 1, 2} }, .offset = { 1, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// rotate left
|
||||
{ .set = { { 0, 0}, { 0,-1}, { 0,-1}, { 0,-1} }, .reset = { { 0, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .offset = { 0,-1} }, // 0
|
||||
{ .set = { { 1, 0}, { 2, 0}, { 2, 0}, { 2, 0} }, .reset = { { 0, 0}, { 1, 2}, { 1, 2}, { 1, 2} }, .offset = { 0, 0} }, // 90
|
||||
{ .set = { { 0, 0}, { 0,-1}, { 0,-1}, { 0,-1} }, .reset = { { 0, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .offset = { 0,-1} }, // 180
|
||||
{ .set = { { 1, 0}, { 2, 0}, { 2, 0}, { 2, 0} }, .reset = { { 0, 0}, { 1, 2}, { 1, 2}, { 1, 2} }, .offset = { 0, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// rotate right
|
||||
{ .set = { { 0, 0}, { 0,-1}, { 0,-1}, { 0,-1} }, .reset = { { 0, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .offset = { 0,-1} }, // 0
|
||||
{ .set = { { 1, 0}, { 2, 0}, { 2, 0}, { 2, 0} }, .reset = { { 0, 0}, { 1, 2}, { 1, 2}, { 1, 2} }, .offset = { 0, 0} }, // 90
|
||||
{ .set = { { 0, 0}, { 0,-1}, { 0,-1}, { 0,-1} }, .reset = { { 0, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .offset = { 0,-1} }, // 180
|
||||
{ .set = { { 1, 0}, { 2, 0}, { 2, 0}, { 2, 0} }, .reset = { { 0, 0}, { 1, 2}, { 1, 2}, { 1, 2} }, .offset = { 0, 0} }, // 270
|
||||
},
|
||||
}
|
||||
},
|
||||
{ // L
|
||||
.color = _orange,
|
||||
.nullRotation = 0,
|
||||
.draw = { { 0, 0}, { 0, 1}, { 0, 2}, { 1, 2} },
|
||||
.motion = {
|
||||
{
|
||||
// move down
|
||||
{ .set = { { 0, 3}, { 1, 3}, { 1, 3}, { 1, 3} }, .reset = { { 0, 0}, { 1, 2}, { 1, 2}, { 1, 2} }, .offset = { 0, 1} }, // 0
|
||||
{ .set = { { 1, 1}, { 2, 1}, { 0, 2}, { 0, 2} }, .reset = { { 0, 0}, { 1, 0}, { 2, 0}, { 2, 0} }, .offset = { 0, 1} }, // 90
|
||||
{ .set = { { 0, 1}, { 1, 3}, { 1, 3}, { 1, 3} }, .reset = { { 0, 0}, { 1, 0}, { 1, 0}, { 1, 0} }, .offset = { 0, 1} }, // 180
|
||||
{ .set = { { 0, 2}, { 1, 2}, { 2, 2}, { 2, 2} }, .reset = { { 2, 0}, { 0, 1}, { 1, 1}, { 1, 1} }, .offset = { 0, 1} }, // 270
|
||||
},
|
||||
{
|
||||
// move left
|
||||
{ .set = { {-1, 0}, {-1, 1}, {-1, 2}, {-1, 2} }, .reset = { { 0, 0}, { 0, 1}, { 1, 2}, { 0, 0} }, .offset = {-1, 0} }, // 0
|
||||
{ .set = { {-1, 0}, {-1, 1}, {-1, 1}, {-1, 1} }, .reset = { { 0, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .offset = {-1, 0} }, // 90
|
||||
{ .set = { { 0, 1}, { 0, 2}, {-1, 0}, {-1, 0} }, .reset = { { 1, 0}, { 1, 1}, { 1, 2}, { 1, 2} }, .offset = {-1, 0} }, // 180
|
||||
{ .set = { {-1, 1}, { 1, 0}, { 1, 0}, { 1, 0} }, .reset = { { 2, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .offset = {-1, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// move right
|
||||
{ .set = { { 1, 0}, { 1, 1}, { 2, 2}, { 2, 2} }, .reset = { { 0, 0}, { 0, 1}, { 0, 2}, { 0, 2} }, .offset = { 1, 0} }, // 0
|
||||
{ .set = { { 1, 1}, { 3, 0}, { 3, 0}, { 3, 0} }, .reset = { { 0, 0}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 1, 0} }, // 90
|
||||
{ .set = { { 2, 0}, { 2, 1}, { 2, 2}, { 2, 2} }, .reset = { { 0, 0}, { 1, 1}, { 1, 2}, { 1, 2} }, .offset = { 1, 0} }, // 180
|
||||
{ .set = { { 3, 0}, { 3, 1}, { 3, 1}, { 3, 1} }, .reset = { { 0, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .offset = { 1, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// rotate left
|
||||
{ .set = { {-1, 2}, {-2, 2}, {-2, 2}, {-2, 2} }, .reset = { { 0, 0}, { 1, 2}, { 1, 2}, { 1, 2} }, .offset = {-2, 1} }, // 0
|
||||
{ .set = { { 0,-1}, { 0,-2}, { 0,-2}, { 0,-2} }, .reset = { { 0, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .offset = { 0,-2} }, // 90
|
||||
{ .set = { { 2, 0}, { 3, 0}, { 3, 0}, { 3, 0} }, .reset = { { 0, 0}, { 1, 2}, { 1, 2}, { 1, 2} }, .offset = { 1, 0} }, // 180
|
||||
{ .set = { { 2, 2}, { 2, 3}, { 2, 3}, { 2, 3} }, .reset = { { 0, 1}, { 2, 0}, { 2, 0}, { 2, 0} }, .offset = { 1, 1} }, // 270
|
||||
},
|
||||
{
|
||||
// rotate right
|
||||
{ .set = { { 0, 3}, { 2, 2}, { 2, 2}, { 2, 2} }, .reset = { { 0, 0}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 0, 2} }, // 0
|
||||
{ .set = { {-1, 0}, { 0, 2}, { 0, 2}, { 0, 2} }, .reset = { { 1, 0}, { 2, 0}, { 2, 0}, { 2, 0} }, .offset = {-1, 0} }, // 90
|
||||
{ .set = { {-1, 0}, { 1,-1}, { 1,-1}, { 1,-1} }, .reset = { { 1, 1}, { 1, 2}, { 1, 2}, { 1, 2} }, .offset = {-1,-1} }, // 180
|
||||
{ .set = { { 2,-1}, { 3, 1}, { 3, 1}, { 3, 1} }, .reset = { { 0, 1}, { 1, 1}, { 1, 1}, { 1, 1} }, .offset = { 2,-1} }, // 270
|
||||
},
|
||||
}
|
||||
},
|
||||
{ // J
|
||||
.color = _blue,
|
||||
.nullRotation = 0,
|
||||
.draw = { { 0, 2}, { 1, 0}, { 1, 1}, { 1, 2} },
|
||||
.motion = {
|
||||
{
|
||||
// move down
|
||||
{ .set = { { 0, 3}, { 1, 3}, { 1, 3}, { 1, 3} }, .reset = { { 0, 2}, { 1, 0}, { 1, 0}, { 1, 0} }, .offset = { 0, 1} }, // 0
|
||||
{ .set = { { 0, 2}, { 1, 2}, { 2, 2}, { 2, 2} }, .reset = { { 0, 0}, { 1, 1}, { 2, 1}, { 2, 1} }, .offset = { 0, 1} }, // 90
|
||||
{ .set = { { 0, 3}, { 1, 1}, { 1, 1}, { 1, 1} }, .reset = { { 0, 0}, { 1, 0}, { 1, 0}, { 1, 0} }, .offset = { 0, 1} }, // 180
|
||||
{ .set = { { 0, 1}, { 1, 1}, { 2, 2}, { 2, 2} }, .reset = { { 0, 0}, { 1, 0}, { 2, 0}, { 2, 0} }, .offset = { 0, 1} }, // 270
|
||||
},
|
||||
{
|
||||
// move left
|
||||
{ .set = { { 0, 0}, { 0, 1}, {-1, 2}, {-1, 2} }, .reset = { { 1, 0}, { 1, 1}, { 1, 2}, { 1, 2} }, .offset = {-1, 0} }, // 0
|
||||
{ .set = { {-1, 0}, {-1, 1}, {-1, 1}, {-1, 1} }, .reset = { { 0, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .offset = {-1, 0} }, // 90
|
||||
{ .set = { {-1, 0}, {-1, 1}, {-1, 2}, {-1, 2} }, .reset = { { 1, 0}, { 0, 1}, { 0, 2}, { 0, 2} }, .offset = {-1, 0} }, // 180
|
||||
{ .set = { {-1, 0}, { 1, 1}, { 1, 1}, { 1, 1} }, .reset = { { 2, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .offset = {-1, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// move right
|
||||
{ .set = { { 2, 0}, { 2, 1}, { 2, 2}, { 2, 2} }, .reset = { { 1, 0}, { 1, 1}, { 0, 2}, { 0, 2} }, .offset = { 1, 0} }, // 0
|
||||
{ .set = { { 1, 0}, { 3, 1}, { 3, 1}, { 3, 1} }, .reset = { { 0, 0}, { 0, 1}, { 0, 1}, { 0, 1} }, .offset = { 1, 0} }, // 90
|
||||
{ .set = { { 1, 1}, { 1, 2}, { 2, 0}, { 2, 0} }, .reset = { { 0, 0}, { 0, 1}, { 0, 2}, { 0, 2} }, .offset = { 1, 0} }, // 180
|
||||
{ .set = { { 3, 0}, { 3, 1}, { 3, 1}, { 3, 1} }, .reset = { { 0, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .offset = { 1, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// rotate left
|
||||
{ .set = { { 1, 3}, {-1, 2}, {-1, 2}, {-1, 2} }, .reset = { { 1, 0}, { 1, 1}, { 0, 0}, { 0, 0} }, .offset = {-1, 2} }, // 0
|
||||
{ .set = { {-1, 1}, { 0,-1}, { 0,-1}, { 0,-1} }, .reset = { { 1, 1}, { 2, 1}, { 2, 1}, { 2, 1} }, .offset = {-1,-1} }, // 90
|
||||
{ .set = { { 2, 0}, { 0,-1}, { 0,-1}, { 0,-1} }, .reset = { { 0, 1}, { 0, 2}, { 0, 2}, { 0, 2} }, .offset = { 0,-1} }, // 180
|
||||
{ .set = { { 2, 2}, { 3, 0}, { 3, 0}, { 3, 0} }, .reset = { { 0, 0}, { 1, 0}, { 1, 0}, { 1, 0} }, .offset = { 2, 0} }, // 270
|
||||
},
|
||||
{
|
||||
// rotate right
|
||||
{ .set = { { 2, 2}, { 3, 2}, { 3, 2}, { 3, 2} }, .reset = { { 1, 0}, { 0, 2}, { 0, 2}, { 0, 2} }, .offset = { 1, 1} }, // 0
|
||||
{ .set = { { 0, 2}, { 0, 3}, { 0, 3}, { 0, 3} }, .reset = { { 0, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .offset = { 0, 1} }, // 90
|
||||
{ .set = { {-1, 0}, {-2, 0}, {-2, 0}, {-2, 0} }, .reset = { { 1, 0}, { 0, 2}, { 0, 2}, { 0, 2} }, .offset = {-2, 0} }, // 180
|
||||
{ .set = { { 2,-1}, { 2,-2}, { 2,-2}, { 2,-2} }, .reset = { { 0, 0}, { 2, 1}, { 2, 1}, { 2, 1} }, .offset = { 1,-2} }, // 270
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const orientation_t nextOrientation[5][4] = { // 5 = number of directions to move, 4 = number of orientation a stone can have
|
||||
@ -138,21 +352,24 @@ const orientation_t nextOrientation[5][4] = { // 5 = number of directions to mov
|
||||
};
|
||||
|
||||
stone_t stone;
|
||||
shape_t nextShape;
|
||||
|
||||
void shapesInit() {
|
||||
stone.shape = e_ShapeInvalid;
|
||||
nextShape = e_Z;
|
||||
}
|
||||
|
||||
void stoneCreate() {
|
||||
static uint8_t cnt = 0;
|
||||
stone.shape = ((shape_t[]){ e_I, e_O, e_T, e_Z, e_S, e_L, e_J })[cnt];
|
||||
cnt++;
|
||||
if (cnt > 1) {
|
||||
cnt = 0;
|
||||
}
|
||||
stone.shape = nextShape;
|
||||
nextShape = ((shape_t[]){ e_I, e_O, e_T, e_Z, e_S, e_L, e_J })[myRandGet() % e_ShapeInvalid];
|
||||
stone.orientation = e_0;
|
||||
stone.x = 5;
|
||||
stone.x = 4;
|
||||
stone.y = 0;
|
||||
stone.locked = false;
|
||||
}
|
||||
|
||||
void stoneLock() {
|
||||
stone.locked = true;
|
||||
}
|
||||
|
||||
uint8_t stoneIsValid() {
|
||||
@ -161,44 +378,136 @@ uint8_t stoneIsValid() {
|
||||
|
||||
// all of them return 1 in case of success and 0 in case of error
|
||||
static uint8_t move(direction_t direction) {
|
||||
// if this is a rotation and the shape is marked with nullRotation (just the O), do nothing
|
||||
// and return success
|
||||
if (motions[stone.shape].nullRotation && (direction == e_RotateLeft || direction == e_RotateRight)) {
|
||||
return 1;
|
||||
}
|
||||
if (canvasIsPixelFree(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[0].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].set[0].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[1].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].set[1].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[2].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].set[2].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[3].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].set[3].y)) {
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].reset[0].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].reset[0].y, _off);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].reset[1].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].reset[1].y, _off);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].reset[2].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].reset[2].y, _off);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].reset[3].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].reset[3].y, _off);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[0].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].set[0].y, motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[1].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].set[1].y, motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[2].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].set[2].y, motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[3].x, stone.y + motions[stone.shape].motion[direction][stone.orientation].set[3].y, motions[stone.shape].color);
|
||||
|
||||
// if the stone is already locked, do nothing
|
||||
if (stone.locked) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check whether the pixels to move to are free
|
||||
if (canvasIsPixelFree(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[0].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].set[0].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[1].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].set[1].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[2].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].set[2].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[3].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].set[3].y)) {
|
||||
// if so, reset the pixels the shape moves away from
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].reset[0].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].reset[0].y,
|
||||
_off);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].reset[1].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].reset[1].y,
|
||||
_off);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].reset[2].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].reset[2].y,
|
||||
_off);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].reset[3].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].reset[3].y,
|
||||
_off);
|
||||
// and set the pixels the shape moves to to the shape's color
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[0].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].set[0].y,
|
||||
motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[1].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].set[1].y,
|
||||
motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[2].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].set[2].y,
|
||||
motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].motion[direction][stone.orientation].set[3].x,
|
||||
stone.y + motions[stone.shape].motion[direction][stone.orientation].set[3].y,
|
||||
motions[stone.shape].color);
|
||||
// set the new origin of the shape
|
||||
stone.x += motions[stone.shape].motion[direction][stone.orientation].offset.x;
|
||||
stone.y += motions[stone.shape].motion[direction][stone.orientation].offset.y;
|
||||
stone.orientation = (nextOrientation[direction][stone.orientation] == e_Keep) ? stone.orientation : nextOrientation[direction][stone.orientation];
|
||||
// set the new orientation of the shape, if required
|
||||
stone.orientation = (nextOrientation[direction][stone.orientation] == e_Keep) ?
|
||||
stone.orientation :
|
||||
nextOrientation[direction][stone.orientation];
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t stoneDraw() {
|
||||
void nextStoneDraw() {
|
||||
miniCanvasClear();
|
||||
miniCanvasSetPixel(motions[nextShape].draw[0].x,
|
||||
motions[nextShape].draw[0].y,
|
||||
motions[nextShape].color);
|
||||
miniCanvasSetPixel(motions[nextShape].draw[1].x,
|
||||
motions[nextShape].draw[1].y,
|
||||
motions[nextShape].color);
|
||||
miniCanvasSetPixel(motions[nextShape].draw[2].x,
|
||||
motions[nextShape].draw[2].y,
|
||||
motions[nextShape].color);
|
||||
miniCanvasSetPixel(motions[nextShape].draw[3].x,
|
||||
motions[nextShape].draw[3].y,
|
||||
motions[nextShape].color);
|
||||
}
|
||||
|
||||
uint8_t stoneDraw() {
|
||||
nextStoneDraw();
|
||||
|
||||
uint8_t res = 0;
|
||||
if (canvasIsPixelFree(stone.x + motions[stone.shape].draw[0].x, stone.y + motions[stone.shape].draw[0].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].draw[1].x, stone.y + motions[stone.shape].draw[1].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].draw[2].x, stone.y + motions[stone.shape].draw[2].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].draw[3].x, stone.y + motions[stone.shape].draw[3].y)) {
|
||||
canvasSetPixel(stone.x + motions[stone.shape].draw[0].x, stone.y + motions[stone.shape].draw[0].y, motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].draw[1].x, stone.y + motions[stone.shape].draw[1].y, motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].draw[2].x, stone.y + motions[stone.shape].draw[2].y, motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].draw[3].x, stone.y + motions[stone.shape].draw[3].y, motions[stone.shape].color);
|
||||
// check if the pixels the shape should be drawn at are free
|
||||
if (canvasIsPixelFree(stone.x + motions[stone.shape].draw[0].x,
|
||||
stone.y + motions[stone.shape].draw[0].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].draw[1].x,
|
||||
stone.y + motions[stone.shape].draw[1].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].draw[2].x,
|
||||
stone.y + motions[stone.shape].draw[2].y) &&
|
||||
canvasIsPixelFree(stone.x + motions[stone.shape].draw[3].x,
|
||||
stone.y + motions[stone.shape].draw[3].y)) {
|
||||
// if so, draw the shape
|
||||
canvasSetPixel(stone.x + motions[stone.shape].draw[0].x,
|
||||
stone.y + motions[stone.shape].draw[0].y,
|
||||
motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].draw[1].x,
|
||||
stone.y + motions[stone.shape].draw[1].y,
|
||||
motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].draw[2].x,
|
||||
stone.y + motions[stone.shape].draw[2].y,
|
||||
motions[stone.shape].color);
|
||||
canvasSetPixel(stone.x + motions[stone.shape].draw[3].x,
|
||||
stone.y + motions[stone.shape].draw[3].y,
|
||||
motions[stone.shape].color);
|
||||
res = 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void stoneJustDraw(uint8_t x, uint8_t y, shape_t shape) {
|
||||
canvasSetPixel(x + motions[shape].draw[0].x,
|
||||
y + motions[shape].draw[0].y,
|
||||
motions[shape].color);
|
||||
canvasSetPixel(x + motions[shape].draw[1].x,
|
||||
y + motions[shape].draw[1].y,
|
||||
motions[shape].color);
|
||||
canvasSetPixel(x + motions[shape].draw[2].x,
|
||||
y + motions[shape].draw[2].y,
|
||||
motions[shape].color);
|
||||
canvasSetPixel(x + motions[shape].draw[3].x,
|
||||
y + motions[shape].draw[3].y,
|
||||
motions[shape].color);
|
||||
}
|
||||
|
||||
void stoneDrawConfigPattern() {
|
||||
stoneJustDraw(1, 0, e_I);
|
||||
stoneJustDraw(3, 4, e_O);
|
||||
stoneJustDraw(4, 7, e_T);
|
||||
stoneJustDraw(5, 10, e_Z);
|
||||
stoneJustDraw(1, 12, e_S);
|
||||
stoneJustDraw(5, 15, e_L);
|
||||
stoneJustDraw(1, 17, e_J);
|
||||
}
|
||||
|
||||
uint8_t stoneMoveDown() {
|
||||
return move(e_MoveDown);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
void shapesInit();
|
||||
void stoneCreate();
|
||||
void stoneLock();
|
||||
uint8_t stoneIsValid();
|
||||
uint8_t stoneDraw();
|
||||
uint8_t stoneMoveDown();
|
||||
@ -13,5 +14,6 @@ uint8_t stoneMoveRight();
|
||||
uint8_t stoneRotateLeft();
|
||||
uint8_t stoneRotateRight();
|
||||
|
||||
void stoneDrawConfigPattern();
|
||||
|
||||
#endif // _SHAPES_H_
|
||||
|
18
game-ctrl/sound.c
Normal file
@ -0,0 +1,18 @@
|
||||
#include <stdint.h>
|
||||
#include "sound.h"
|
||||
#include "spi.h"
|
||||
|
||||
|
||||
|
||||
void soundInit() {
|
||||
}
|
||||
|
||||
|
||||
void soundCtrl(uint8_t cmd) {
|
||||
spiSendBegin(e_SPI_SOUND);
|
||||
|
||||
spiSendOctet(cmd);
|
||||
|
||||
spiSendEnd(e_SPI_SOUND);
|
||||
}
|
||||
|
15
game-ctrl/sound.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef _SOUND_H_
|
||||
#define _SOUND_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MUTE_DELAY 30 // seconds
|
||||
|
||||
#include "../sound-driver/soundCodes.h"
|
||||
|
||||
void soundInit();
|
||||
void soundCtrl(uint8_t cmd);
|
||||
|
||||
|
||||
|
||||
#endif // _SOUND_H_
|
56
game-ctrl/spi.c
Normal file
@ -0,0 +1,56 @@
|
||||
#include <msp430g2553.h>
|
||||
#include "spi.h"
|
||||
|
||||
void spiInit() {
|
||||
// SPI in master mode, most significant bit first
|
||||
UCB0CTL0 = UCCKPH | UCMST | UCMSB;
|
||||
// SPI timing config
|
||||
UCB0CTL1 = UCSSEL_3;
|
||||
// Faster than 8 ends up in strange communication errors
|
||||
// between the both MCUs.
|
||||
// With 8 the transfer of a complete 110 pixel canvas takes
|
||||
// about 720us.
|
||||
// 8 was still too fast and caused problems.
|
||||
UCB0BR0 = 16;
|
||||
UCB0BR1 = 0;
|
||||
|
||||
// BIT5: UCB0CLK
|
||||
// BIT6: UCB0SOMI
|
||||
// BIT7: UCB0SIMO
|
||||
P1SEL |= BIT5 | BIT6 | BIT7;
|
||||
P1SEL2 |= BIT5 | BIT6 | BIT7;
|
||||
// P1DIR |= BIT5 | BIT7;
|
||||
|
||||
// Device Select Lines: 0: Canvas, 1: Display, 2: Sound, 4: EEPROM
|
||||
P1DIR |= BIT0 | BIT1 | BIT2 | BIT4;
|
||||
// Disable all of them
|
||||
P1OUT |= BIT0 | BIT1 | BIT2 | BIT4;
|
||||
|
||||
// enable SPI module
|
||||
UCB0CTL1 &= ~UCSWRST;
|
||||
}
|
||||
|
||||
void spiSendBegin(t_SpiDeviceSelector d) {
|
||||
uint16_t bit = ((uint16_t[]){ BIT0, BIT1, BIT2, BIT4 })[d];
|
||||
P1OUT &= ~bit;
|
||||
}
|
||||
|
||||
void spiSendEnd(t_SpiDeviceSelector d) {
|
||||
while (UCB0STAT & UCBUSY);
|
||||
uint16_t bit = ((uint16_t[]){ BIT0, BIT1, BIT2, BIT4 })[d];
|
||||
P1OUT |= bit;
|
||||
}
|
||||
|
||||
void spiSendOctet(uint8_t v) {
|
||||
// wait for TX buffer empty
|
||||
while (!(UC0IFG & UCB0TXIFG));
|
||||
// load octet into TX buffer
|
||||
UCB0TXBUF = v;
|
||||
}
|
||||
|
||||
uint8_t spiReceiveOctet() {
|
||||
while (!(UC0IFG & UCB0RXIFG));
|
||||
uint8_t v = UCB0RXBUF;
|
||||
return v;
|
||||
}
|
||||
|
17
game-ctrl/spi.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef _SPI_H_
|
||||
#define _SPI_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef enum { e_SPI_CANVAS, e_SPI_DISPLAY, e_SPI_SOUND, e_SPI_EEPROM } t_SpiDeviceSelector;
|
||||
|
||||
void spiInit();
|
||||
void spiSendBegin(t_SpiDeviceSelector d);
|
||||
void spiSendEnd(t_SpiDeviceSelector d);
|
||||
void spiSendOctet(uint8_t v);
|
||||
uint8_t spiReceiveOctet();
|
||||
|
||||
|
||||
|
||||
#endif // _SPI_H_
|
@ -1,16 +0,0 @@
|
||||
#include <msp430g2553.h>
|
||||
|
||||
#include "time.h"
|
||||
#include "PontCoopScheduler.h"
|
||||
|
||||
|
||||
void __attribute__ ((interrupt (TIMER0_A0_VECTOR))) ta0_isr() {
|
||||
schUpdate();
|
||||
}
|
||||
|
||||
void timeInit() {
|
||||
TACCR0 = 32;
|
||||
TACCTL0 = CCIE;
|
||||
TACTL = MC_1 | ID_0 | TASSEL_1 | TACLR;
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
#ifndef TIME_H_
|
||||
#define TIME_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void timeInit();
|
||||
|
||||
|
||||
|
||||
#endif /* TIME_H_ */
|
68
readme.md
Normal file
@ -0,0 +1,68 @@
|
||||
# Tetris - Hardware and Software
|
||||
|
||||

|
||||
|
||||
Update Amplifier (separate input circuitry per PSG, it appears, that a silent PSG has a DC level on its output which is summarized to the AC output of the working PSG, so two input circuits with individual couping capacitor):
|
||||
|
||||

|
||||
|
||||
Update of the power switch of the amplifier (at appears, that the small transistor couldn't deliver enough current):
|
||||
|
||||

|
||||
|
||||
This Tetris implementation consists of a hardware and a software (running on that hardware).
|
||||
|
||||
The hardware utilizes four MSP430 microcontrollers for 1.) the game play, 2.) the play ground canvas, 3.) the score display and 4.) the sound effects.
|
||||
|
||||
Further documentation including calculations and drawing can be found in the `docs` subdirs of the four main subdirs.
|
||||
|
||||
## Game Play
|
||||
|
||||
Code is in subdir `game-ctrl` (https://gitea.hottis.de/wn/tetris/src/branch/main/game-ctrl).
|
||||
|
||||
In the firmware for this MSP430 microcontroller the whole game mechanics, reading the buttons, reading and writing the highscore EEPROM and the control of the peripherial microcontrollers are implemented.
|
||||
|
||||
The buttons are debounced using RC circuitry and Schmitt triggers and connected to GPIOs of the microcontroller.
|
||||
|
||||
The peripherial microcontrollers and the EEPROM are connected via SPI including individual chip select lines.
|
||||
|
||||

|
||||
|
||||
|
||||
## Play Ground Canvas
|
||||
|
||||
Code is in subdir `rgb-driver` (https://gitea.hottis.de/wn/tetris/src/branch/main/rgb-driver).
|
||||
|
||||
The play ground is implemented using a 10 * 20 matrix of PL9823 RGB LEDs which are controlled by another MSP430 microcontroller. The firmware for this microcontroller is implemented for performance and real time requirements in assembly code. Through some discret logic the signals for PL9823 LEDs are generated. Major challenge was to generated the signals according the datasheet of all 200 (including a mini canvas for the stone preview: 212) LEDs in real time without interrupts.
|
||||
|
||||
The communcation with the game play controller is implemented as a sequences of tuples of LED address (0 to 211) and color code. A single octet of 253 where the LED address is expected is taken as the end-of-telegram mark. Readiness to receive a telegram is signaled to the game play controller via a single line connected to a GPIO of the game play controller.
|
||||
|
||||

|
||||
|
||||
|
||||
## Score Display
|
||||
|
||||
Code is in subdir `display-driver` (https://gitea.hottis.de/wn/tetris/src/branch/main/display-driver).
|
||||
|
||||
In the first place, a MAX7221 was meant to be used for connecting a multiple digit seven-segment display. However, it appears, that the MAX7221 requires 3.5V as minimum voltage for the high-level, which caan't be provided by the MSP430 (which runs on 3.3V) and level-shifters haven't been around. Thus, the minimal required amount of functionality of the MAX7221 has been implemented in C on an MSP430. Just four digits are supported.
|
||||
|
||||
Communication with the game play controller is just a 16 bit number to be displayed.
|
||||
|
||||

|
||||
|
||||
|
||||
## Sound Effects
|
||||
|
||||
Code is in subdir `sound-driver` (https://gitea.hottis.de/wn/tetris/src/branch/main/sound-driver).
|
||||
|
||||
An MSP430 microcontroller and two mediaeval AY-3-8913 sound chips are deployed. The sound chips themselve run on 5V, their 8-bit-address/data bus is connected to the port 2 (bit 0 to 7) of the microcontroller. The bus control signal `_CS`, `BC1` and `BDIR` are generated in software and provided via GPIOs.
|
||||
|
||||
An amplifier following the proposal of the AY-3-8913 datasheet is implemented using a LM386 chip. A MOSFET BS108 controlled via a GPIO is use the shortcut the input of the amplifier to ground to mute sound effects.
|
||||
|
||||
The clock generator proposed by the AY-3-8913 does not work reliably, so an alternative design from "The Art of Electronics" has been used.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
@ -4,7 +4,8 @@ OBJDUMP=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-objdump
|
||||
|
||||
MCU=msp430g2553
|
||||
ARTIFACT=firmware
|
||||
COMMON=-Wall -mmcu=$(MCU) -std=gnu99 -I $(TOOLCHAIN_PREFIX)/include -Os -g0 -fdata-sections -ffunction-sections -ggdb -gdwarf-2
|
||||
COMMON=-Wall -mmcu=$(MCU) -std=gnu99 -I $(TOOLCHAIN_PREFIX)/include -Os -g0 -fdata-sections -ffunction-sections
|
||||
#COMMON+= -ggdb -gdwarf-2 # debug
|
||||
CFLAGS=$(COMMON)
|
||||
ASFLAGS=$(COMMON) -D__ASSEMBLER__
|
||||
|
||||
|
10
rgb-driver/canvasSize.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef _CANVAS_SIZE_H_
|
||||
#define _CANVAS_SIZE_H_
|
||||
|
||||
#define CANVAS_WIDTH 10
|
||||
#define CANVAS_HEIGHT 20
|
||||
|
||||
#define MINI_CANVAS_WIDTH 3
|
||||
#define MINI_CANVAS_HEIGHT 4
|
||||
|
||||
#endif // _CANVAS_SIZE_H_
|
@ -1,38 +1,55 @@
|
||||
#include "colors.h"
|
||||
|
||||
#define DIMM_FACTOR 3
|
||||
.section ".rodata","a"
|
||||
;; color definitions according to
|
||||
;; https://learn.sparkfun.com/tutorials/lilypad-protosnap-plus-activity-guide/3-custom-color-mixing
|
||||
colors:
|
||||
.global colors
|
||||
;; red, green, blue, padding
|
||||
off:
|
||||
.byte 0x00, 0x00, 0x00, 0
|
||||
blue:
|
||||
.byte 0x00>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0
|
||||
green:
|
||||
.byte 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0
|
||||
orange:
|
||||
.byte 0xff>>DIMM_FACTOR, 0x80>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0
|
||||
rose:
|
||||
.byte 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0x80>>DIMM_FACTOR, 0
|
||||
magenta:
|
||||
.byte 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0
|
||||
violet:
|
||||
.byte 0x80>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0
|
||||
azure:
|
||||
.byte 0x00>>DIMM_FACTOR, 0x80>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0
|
||||
cyan:
|
||||
.byte 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0
|
||||
springgreen:
|
||||
.byte 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0x80>>DIMM_FACTOR, 0
|
||||
chartreuse:
|
||||
.byte 0x80>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0
|
||||
yellow:
|
||||
.byte 0xff>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0
|
||||
white:
|
||||
.byte 0xff>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0
|
||||
red:
|
||||
.byte 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0
|
||||
.byte 0x00, 0x00, 0x00, 0 ;; off
|
||||
|
||||
.byte 0x00>>5, 0x00>>5, 0xff>>5, 0 ;; blue
|
||||
.byte 0x00>>5, 0xff>>5, 0x00>>5, 0 ;; green
|
||||
.byte 0xff>>5, 0x80>>5, 0x00>>5, 0 ;; orange
|
||||
.byte 0x80>>5, 0x00>>5, 0xff>>5, 0 ;; violet
|
||||
.byte 0x00>>5, 0xff>>5, 0xff>>5, 0 ;; cyan
|
||||
.byte 0xff>>5, 0xff>>5, 0x00>>5, 0 ;; yellow
|
||||
.byte 0xff>>5, 0x00>>5, 0x00>>5, 0 ;; red
|
||||
.byte 0xff>>5, 0xff>>5, 0xff>>5, 0 ;; white
|
||||
|
||||
.byte 0x00>>4, 0x00>>4, 0xff>>4, 0 ;; blue
|
||||
.byte 0x00>>4, 0xff>>4, 0x00>>4, 0 ;; green
|
||||
.byte 0xff>>4, 0x80>>4, 0x00>>4, 0 ;; orange
|
||||
.byte 0x80>>4, 0x00>>4, 0xff>>4, 0 ;; violet
|
||||
.byte 0x00>>4, 0xff>>4, 0xff>>4, 0 ;; cyan
|
||||
.byte 0xff>>4, 0xff>>4, 0x00>>4, 0 ;; yellow
|
||||
.byte 0xff>>4, 0x00>>4, 0x00>>4, 0 ;; red
|
||||
.byte 0xff>>4, 0xff>>4, 0xff>>4, 0 ;; white
|
||||
|
||||
.byte 0x00>>3, 0x00>>3, 0xff>>3, 0 ;; blue
|
||||
.byte 0x00>>3, 0xff>>3, 0x00>>3, 0 ;; green
|
||||
.byte 0xff>>3, 0x80>>3, 0x00>>3, 0 ;; orange
|
||||
.byte 0x80>>3, 0x00>>3, 0xff>>3, 0 ;; violet
|
||||
.byte 0x00>>3, 0xff>>3, 0xff>>3, 0 ;; cyan
|
||||
.byte 0xff>>3, 0xff>>3, 0x00>>3, 0 ;; yellow
|
||||
.byte 0xff>>3, 0x00>>3, 0x00>>3, 0 ;; red
|
||||
.byte 0xff>>3, 0xff>>3, 0xff>>3, 0 ;; white
|
||||
|
||||
.byte 0x00>>2, 0x00>>2, 0xff>>2, 0 ;; blue
|
||||
.byte 0x00>>2, 0xff>>2, 0x00>>2, 0 ;; green
|
||||
.byte 0xff>>2, 0x80>>2, 0x00>>2, 0 ;; orange
|
||||
.byte 0x80>>2, 0x00>>2, 0xff>>2, 0 ;; violet
|
||||
.byte 0x00>>2, 0xff>>2, 0xff>>2, 0 ;; cyan
|
||||
.byte 0xff>>2, 0xff>>2, 0x00>>2, 0 ;; yellow
|
||||
.byte 0xff>>2, 0x00>>2, 0x00>>2, 0 ;; red
|
||||
.byte 0xff>>2, 0xff>>2, 0xff>>2, 0 ;; white
|
||||
|
||||
.byte 0x00>>1, 0x00>>1, 0xff>>1, 0 ;; blue
|
||||
.byte 0x00>>1, 0xff>>1, 0x00>>1, 0 ;; green
|
||||
.byte 0xff>>1, 0x80>>1, 0x00>>1, 0 ;; orange
|
||||
.byte 0x80>>1, 0x00>>1, 0xff>>1, 0 ;; violet
|
||||
.byte 0x00>>1, 0xff>>1, 0xff>>1, 0 ;; cyan
|
||||
.byte 0xff>>1, 0xff>>1, 0x00>>1, 0 ;; yellow
|
||||
.byte 0xff>>1, 0x00>>1, 0x00>>1, 0 ;; red
|
||||
.byte 0xff>>1, 0xff>>1, 0xff>>1, 0 ;; white
|
||||
|
||||
|
@ -2,21 +2,20 @@
|
||||
#define _COLORS_H_
|
||||
|
||||
|
||||
#define _off 0x00
|
||||
#define _blue 0x01
|
||||
#define _green 0x02
|
||||
#define _orange 0x03
|
||||
#define _rose 0x04
|
||||
#define _magenta 0x05
|
||||
#define _violet 0x06
|
||||
#define _azure 0x07
|
||||
#define _cyan 0x08
|
||||
#define _springgreen 0x09
|
||||
#define _chartreuse 0x0a
|
||||
#define _yellow 0x0b
|
||||
#define _white 0x0c
|
||||
#define _red 0x0d
|
||||
#define _off 0
|
||||
|
||||
#define _blue 1
|
||||
#define _green 2
|
||||
#define _orange 3
|
||||
#define _violet 4
|
||||
#define _cyan 5
|
||||
#define _yellow 6
|
||||
#define _red 7
|
||||
#define _white 8
|
||||
|
||||
#define _brightness_offset 8
|
||||
#define _brightness_shifts 5
|
||||
#define _color_end (_brightness_offset * _brightness_shifts)
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <msp430g2553.h>
|
||||
#include "colors.h"
|
||||
#include "canvasSize.h"
|
||||
|
||||
|
||||
#define PC r0
|
||||
#define SP r1
|
||||
@ -59,13 +61,11 @@
|
||||
|
||||
.section ".data"
|
||||
screendata:
|
||||
.rept 110 ;; number of leds in hardward
|
||||
.rept (CANVAS_HEIGHT*CANVAS_WIDTH) + (MINI_CANVAS_HEIGHT*MINI_CANVAS_WIDTH) ;; number of leds in hardward
|
||||
.byte 0
|
||||
.endr
|
||||
screendataend:
|
||||
.byte 0xff
|
||||
data_forward_pointer:
|
||||
.word 0
|
||||
|
||||
|
||||
;; .text is the name of the section, it is a hint for the linker to
|
||||
@ -96,11 +96,12 @@ init:
|
||||
;; BIT3: Signal waiting for data
|
||||
mov.b #BIT0|BIT1|BIT2|BIT3, &P1DIR
|
||||
mov.b #0,&P1OUT
|
||||
;; BIT4: spi, UCB0STE
|
||||
;; BIT5: spi, UCB0CLK
|
||||
;; BIT6: spi, UCB0SOMI
|
||||
;; BIT7: spi, UCB0SIMO
|
||||
mov.b #BIT5|BIT6|BIT7, &P1SEL
|
||||
mov.b #BIT5|BIT6|BIT7, &P1SEL2
|
||||
mov.b #BIT4|BIT5|BIT6|BIT7, &P1SEL
|
||||
mov.b #BIT4|BIT5|BIT6|BIT7, &P1SEL2
|
||||
;; BIT4: long pulse
|
||||
;; BIT1: short pulse
|
||||
mov.b #BIT1|BIT4,&P2DIR
|
||||
@ -121,8 +122,8 @@ init:
|
||||
mov.w #OUTMOD_7,&TA1CCTL2
|
||||
|
||||
;; spi configuration
|
||||
;; USCI B to slave mode
|
||||
mov.b #UCSYNC, &UCB0CTL0
|
||||
;; USCI B to slave mode, enable STE and most significant bit first
|
||||
mov.b #UCCKPH|UCSYNC|UCMODE_2|UCMSB, &UCB0CTL0
|
||||
mov.b #0x00, &UCB0CTL1
|
||||
|
||||
;; make sure the isr will not immediately start
|
||||
@ -136,70 +137,20 @@ init:
|
||||
|
||||
;; ----------------------------------------------------
|
||||
mainloop:
|
||||
call #forwardscreen_init
|
||||
call #resetscreen
|
||||
|
||||
mainloop_draw:
|
||||
call #drawscreen
|
||||
|
||||
;; signal waiting for data
|
||||
set_signal_waiting_for_data
|
||||
|
||||
;call #forwardscreen
|
||||
;call #wait
|
||||
call #receivedata
|
||||
|
||||
;; data has been received, clear signal
|
||||
clear_signal_waiting_for_data
|
||||
|
||||
jmp mainloop_draw
|
||||
|
||||
|
||||
;; ----------------------------------------------------
|
||||
wait:
|
||||
push r11
|
||||
push r12
|
||||
|
||||
mov.w #0x0040, r11
|
||||
wait_continue_1:
|
||||
mov.w #0xffff, r12
|
||||
wait_continue_2:
|
||||
dec.w r12
|
||||
jnz wait_continue_2
|
||||
dec.w r11
|
||||
jnz wait_continue_1
|
||||
|
||||
pop r12
|
||||
pop r11
|
||||
ret
|
||||
|
||||
|
||||
;; ----------------------------------------------------
|
||||
forwardscreen_init:
|
||||
mov.w #screendata, &data_forward_pointer
|
||||
ret
|
||||
|
||||
;; ----------------------------------------------------
|
||||
forwardscreen:
|
||||
push r8
|
||||
push r10
|
||||
|
||||
mov.w #screendataend, r8
|
||||
mov.w data_forward_pointer, r10
|
||||
mov.b #_off, @r10
|
||||
inc.w r10
|
||||
mov.b #_blue, @r10
|
||||
cmp.w r10, r8
|
||||
jnz forwardscreen_done
|
||||
mov.w #screendata, r10
|
||||
forwardscreen_done:
|
||||
mov.w r10, data_forward_pointer
|
||||
|
||||
pop r10
|
||||
pop r8
|
||||
ret
|
||||
|
||||
|
||||
;; ----------------------------------------------------
|
||||
resetscreen:
|
||||
push r7
|
||||
@ -231,11 +182,6 @@ receivedata_wait_for_control_octet:
|
||||
|
||||
;; get control or address octet from buffer register
|
||||
mov.b UCB0RXBUF, r9
|
||||
;; check whether value == 0xff (wait for the whole
|
||||
;; set of data to fill the screendata)
|
||||
cmp.b #0xff, r9
|
||||
;; receive all data
|
||||
jz receivedata_wait_for_all_data
|
||||
;; check whether value == 0xfe (no more data)
|
||||
cmp.b #0xfe, r9
|
||||
;; no more data
|
||||
@ -253,10 +199,6 @@ receivedata_wait_for_octet:
|
||||
;; next address/control octet
|
||||
jmp receivedata_wait_for_control_octet
|
||||
|
||||
receivedata_wait_for_all_data:
|
||||
;; this is a bit dangerous, if the application controller
|
||||
;; sends too few data, we are in a dead lock
|
||||
|
||||
receivedata_end:
|
||||
pop r10
|
||||
pop r9
|
||||
|
35
sound-driver/Makefile
Normal file
@ -0,0 +1,35 @@
|
||||
TOOLCHAIN_PREFIX=/opt/msp430-gcc
|
||||
CC=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-gcc
|
||||
OBJDUMP=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-objdump
|
||||
|
||||
ARTIFACT=firmware
|
||||
MCU=msp430g2553
|
||||
DEBUGFLAGS=
|
||||
# DEBUGFLAGS+= -g3 -ggdb -gdwarf-2
|
||||
COMMONFLAGS=-Wall -mmcu=$(MCU) -I $(TOOLCHAIN_PREFIX)/include -O0 -g0 $(DEBUGFLAGS)
|
||||
CFLAGS=$(COMMONFLAGS) -std=gnu99
|
||||
ASFLAGS=$(COMMONFLAGS) -D__ASSEMBLER__
|
||||
|
||||
LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include
|
||||
|
||||
$(ARTIFACT).elf: main.o scheduler.o spi.o spi_init.o sequencer.o melody_tetris.o melody_tusch1.o psg.o mute.o melody_pling.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
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -f *.o $(ARTIFACT).elf $(ARTIFACT).txt
|
||||
|
||||
.PHONY: upload
|
||||
upload: $(ARTIFACT).elf
|
||||
mspdebug rf2500 "prog $(ARTIFACT).elf"
|
BIN
sound-driver/docs/Audio-Amplifier.pdf
Executable file
BIN
sound-driver/docs/Clock-Generation.pdf
Executable file
BIN
sound-driver/docs/Frequency-Codes-76489AN.xlsx
Normal file
BIN
sound-driver/docs/Frequency-Codes.pdf
Executable file
BIN
sound-driver/docs/Korobeiniki.svg.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
sound-driver/docs/MCU-Connection.pdf
Executable file
BIN
sound-driver/docs/Oktavskala.pdf
Executable file
BIN
sound-driver/docs/Registers.pdf
Executable file
BIN
sound-driver/docs/TetrisThemeThreeVoices.pdf
Executable file
BIN
sound-driver/docs/ay3-8910.pdf
Normal file
BIN
sound-driver/docs/lengths.xlsx
Normal file
2
sound-driver/firmware.gdb
Normal file
@ -0,0 +1,2 @@
|
||||
target remote localhost:2000
|
||||
file firmware.elf
|
38
sound-driver/main.c
Normal file
@ -0,0 +1,38 @@
|
||||
#include <msp430g2553.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "spi.h"
|
||||
#include "psg.h"
|
||||
#include "scheduler.h"
|
||||
#include "sequencer.h"
|
||||
#include "melody_tetris.h"
|
||||
#include "melody_tusch1.h"
|
||||
#include "mute.h"
|
||||
|
||||
int main() {
|
||||
WDTCTL = WDTPW | WDTHOLD;
|
||||
|
||||
__disable_interrupt();
|
||||
|
||||
// highest possible system clock
|
||||
DCOCTL = DCO0 | DCO1 | DCO2;
|
||||
BCSCTL1 = XT2OFF | RSEL0 | RSEL1 | RSEL2 | RSEL3;
|
||||
BCSCTL2 = 0;
|
||||
BCSCTL3 = 0;
|
||||
|
||||
|
||||
schInit();
|
||||
|
||||
spiInit();
|
||||
psgInit();
|
||||
muteInit();
|
||||
sequencerInit();
|
||||
|
||||
__enable_interrupt();
|
||||
|
||||
|
||||
while (1) {
|
||||
schExec();
|
||||
}
|
||||
}
|
32
sound-driver/melody_pling.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "psg.h"
|
||||
#include "sequencer.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
const t_tone plingVoice1[] = {
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_Cis, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_Dis, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_StopMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_EndMark, .legato = false, .staccato = false },
|
||||
};
|
||||
|
||||
t_melodies pling = {
|
||||
.melodies = { { .amplitude = 12, .tones = plingVoice1 } },
|
||||
.numOfMelodies = 1,
|
||||
.pace = 200,
|
||||
.chip = 1
|
||||
};
|
||||
|
||||
void playPling() {
|
||||
sequencerPlayMelodies(&pling);
|
||||
}
|
||||
|
||||
|
||||
|
8
sound-driver/melody_pling.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _MELODY_PLING_H_
|
||||
#define _MELODY_PLING_H_
|
||||
|
||||
|
||||
void playPling();
|
||||
|
||||
|
||||
#endif // _MELODY_PLING_H_
|
948
sound-driver/melody_tetris.c
Normal file
@ -0,0 +1,948 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "psg.h"
|
||||
#include "sequencer.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
|
||||
/*
|
||||
* three voices theme from https://www.gamemusicthemes.com/sheetmusic/gameboy/tetris/themea/Tetris_-_Theme_A_by_Gori_Fater.pdf
|
||||
*/
|
||||
const t_tone voice1[] = {
|
||||
// -------
|
||||
// 1. bar
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 2. bar
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 3. bar
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_4, .legato = true, .staccato = false }, // diese und die naechste zusammen: ein punktiertes Viertel
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 4. bar
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 5. bar
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_F, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_G, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_F, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 6. bar
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = true, .staccato = false }, // punktiert
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 7. bar
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 8. bar
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// -------
|
||||
// 1. bar, repeat
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 2. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 3. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_4, .legato = true, .staccato = false }, // diese und die naechste zusammen: ein punktiertes Viertel
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 4. bar, repeat
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 5. bar, repeat
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_F, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_G, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_F, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 6. bar, repeat
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = true, .staccato = false }, // punktiert
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 7. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_D, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 8. bar, repeat
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// -------
|
||||
// 9. bar
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 10. bar
|
||||
{ .octave = e_O_4, .note = e_D, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 11. bar
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 12. bar
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 13. bar
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 14. bar
|
||||
{ .octave = e_O_4, .note = e_D, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 15. bar
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 16. bar
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// -------
|
||||
// 9. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 10. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_D, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 11. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 12. bar, repeat
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 13. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 14. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_D, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 15. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 16. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_EndMark, .legato = false, .staccato = false },
|
||||
};
|
||||
|
||||
const t_tone voice2[] = {
|
||||
// -------
|
||||
// 1. bar
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 2. bar
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 3. bar
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 4. bar
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 5. bar
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_F, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 6. bar
|
||||
{ .octave = e_O_4, .note = e_G, .length = e_L_1_4, .legato = true, .staccato = false }, // punktiert
|
||||
{ .octave = e_O_4, .note = e_G, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_G, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_G, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_F, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 7. bar
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 8. bar
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// -------
|
||||
// 1. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 2. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 3. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 4. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 5. bar, repeat
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_F, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 6. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_G, .length = e_L_1_4, .legato = true, .staccato = false }, // punktiert
|
||||
{ .octave = e_O_4, .note = e_G, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_G, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_G, .length = e_L_1_16, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_F, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 7. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 8. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// -------
|
||||
// 9. bar
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 10. bar
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 11. bar
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 12. bar
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 13. bar
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 14. bar
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 15. bar
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 16. bar
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// -------
|
||||
// 9. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 10. bar, repeat
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 11. bar, repeat
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 12. bar, repeat
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 13. bar, repeat
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 14. bar, repeat
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 15. bar, repeat
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 16. bar, repeat
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_EndMark, .legato = false, .staccato = false },
|
||||
};
|
||||
|
||||
const t_tone voice3[] = {
|
||||
// -------
|
||||
// 1. bar
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 2. bar
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 3. bar
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 4. bar
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 5. bar
|
||||
{ .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_F, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 6. bar
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 7. bar
|
||||
{ .octave = e_O_2, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 8. bar
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// -------
|
||||
// 1. bar,repeat
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 2. bar,repeat
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 3. bar,repeat
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 4. bar,repeat
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 5. bar,repeat
|
||||
{ .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_F, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 6. bar,repeat
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 7. bar,repeat
|
||||
{ .octave = e_O_2, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 8. bar,repeat
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// -------
|
||||
// 9. bar
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 10. bar
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 11. bar
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 12. bar
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 13. bar
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 14. bar
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 15. bar
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 16. bar
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// -------
|
||||
// 9. bar, repeat
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 10. bar, repeat
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 11. bar, repeat
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 12. bar, repeat
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 13. bar, repeat
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 14. bar, repeat
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 15. bar, repeat
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
// 16. bar, repeat
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_EndMark, .legato = false, .staccato = false },
|
||||
};
|
||||
|
||||
#define INITIAL_PACE 160
|
||||
t_melodies tetrisTheme = {
|
||||
.melodies = { { .amplitude = 8, .tones = voice1 }, { .amplitude = 8, .tones = voice2 }, { .amplitude = 8, .tones = voice3 } },
|
||||
.numOfMelodies = 3,
|
||||
.pace = INITIAL_PACE,
|
||||
.chip = 0
|
||||
};
|
||||
|
||||
void playMelodyTetris() {
|
||||
tetrisTheme.pace = INITIAL_PACE; // reset to start value each time
|
||||
sequencerPlayMelodies(&tetrisTheme);
|
||||
}
|
||||
|
||||
void playMelodyTetrisFaster() {
|
||||
tetrisTheme.pace += 15;
|
||||
sequencerChangePace(&tetrisTheme);
|
||||
}
|
||||
|
||||
void stopMelodyTetris() {
|
||||
sequencerStopMelodies(&tetrisTheme);
|
||||
}
|
||||
|
||||
|
||||
|
9
sound-driver/melody_tetris.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef _MELODY_TETRIS_H_
|
||||
#define _MELODY_TETRIS_H_
|
||||
|
||||
|
||||
void playMelodyTetris();
|
||||
void stopMelodyTetris();
|
||||
void playMelodyTetrisFaster();
|
||||
|
||||
#endif // _MELODY_TETRIS_H_
|
87
sound-driver/melody_tusch1.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "psg.h"
|
||||
#include "sequencer.h"
|
||||
#include "scheduler.h"
|
||||
#include "melody_tetris.h"
|
||||
|
||||
const t_tone tusch1voice1[] = {
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = true },
|
||||
{ .octave = e_O_5, .note = e_F, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = true },
|
||||
{ .octave = e_O_5, .note = e_F, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_4, .legato = false, .staccato = true },
|
||||
{ .octave = e_O_5, .note = e_F, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_StopMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_EndMark, .legato = false, .staccato = false },
|
||||
};
|
||||
|
||||
const t_tone tusch1voice2[] = {
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_5, .note = e_C, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_HoldMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_EndMark, .legato = false, .staccato = false },
|
||||
};
|
||||
|
||||
const t_tone tusch1voice3[] = {
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false, .staccato = false },
|
||||
{ .octave = e_O_4, .note = e_A, .length = e_L_1_2, .legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_SyncMark,.legato = false, .staccato = false },
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_HoldMark,.legato = false, .staccato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_EndMark, .legato = false, .staccato = false },
|
||||
};
|
||||
|
||||
t_melodies tusch1 = {
|
||||
.melodies = { { .amplitude = 12, .tones = tusch1voice1 }, { .amplitude = 12, .tones = tusch1voice2 }, { .amplitude = 12, .tones = tusch1voice3 } },
|
||||
.numOfMelodies = 3,
|
||||
.pace = 200,
|
||||
.chip = 1
|
||||
};
|
||||
|
||||
void playTusch1() {
|
||||
sequencerPlayMelodies(&tusch1);
|
||||
// playMelodyTetrisFaster();
|
||||
}
|
||||
|
||||
|
||||
|
8
sound-driver/melody_tusch1.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _MELODY_TUSCH1_H_
|
||||
#define _MELODY_TUSCH1_H_
|
||||
|
||||
|
||||
void playTusch1();
|
||||
|
||||
|
||||
#endif // _MELODY_TUSCH1_H_
|
22
sound-driver/mute.c
Normal file
@ -0,0 +1,22 @@
|
||||
#include <msp430g2553.h>
|
||||
#include "mute.h"
|
||||
|
||||
|
||||
|
||||
void muteInit() {
|
||||
// BIT6: MuteCtrl
|
||||
P1DIR |= BIT6;
|
||||
|
||||
// initially, mute
|
||||
P1OUT &= ~BIT6;
|
||||
}
|
||||
|
||||
void mute() {
|
||||
P1OUT &= ~BIT6;
|
||||
}
|
||||
|
||||
void unMute() {
|
||||
P1OUT |= BIT6;
|
||||
}
|
||||
|
||||
|
8
sound-driver/mute.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _MUTE_H_
|
||||
#define _MUTE_H_
|
||||
|
||||
void muteInit();
|
||||
void mute();
|
||||
void unMute();
|
||||
|
||||
#endif // _MUTE_H_
|
166
sound-driver/psg.c
Normal file
@ -0,0 +1,166 @@
|
||||
#include <msp430g2553.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "psg.h"
|
||||
#include "scheduler.h"
|
||||
|
||||
|
||||
|
||||
const uint16_t frequencyCodes[8][12] = {
|
||||
// C, Cis, D, Dis, E, F, Fis, G, Gis, A, Ais, H
|
||||
{ 06535, 06234, 05747, 05474, 05233, 05002, 04563, 04353, 04153, 03762, 03600, 03424 }, // Octave 1
|
||||
{ 03256, 03116, 02764, 02636, 02515, 02401, 02271, 02165, 02065, 01771, 01700, 01612 }, // Octave 2
|
||||
{ 01527, 01447, 01372, 01317, 01247, 01201, 01135, 01073, 01033, 00774, 00740, 00705 }, // Octave 3
|
||||
{ 00654, 00624, 00575, 00550, 00523, 00500, 00456, 00435, 00415, 00376, 00360, 00342 }, // Octave 4
|
||||
{ 00326, 00312, 00276, 00264, 00252, 00240, 00227, 00217, 00207, 00177, 00170, 00161 }, // Octave 5
|
||||
{ 00153, 00145, 00137, 00132, 00125, 00120, 00114, 00107, 00103, 00100, 00074, 00071 }, // Octave 6
|
||||
{ 00065, 00062, 00060, 00055, 00052, 00050, 00046, 00044, 00042, 00040, 00036, 00034 }, // Octave 7
|
||||
{ 00033, 00031, 00030, 00026, 00025, 00024, 00023, 00022, 00021, 00020, 00017, 00016 } // Octave 8
|
||||
};
|
||||
|
||||
|
||||
#define ADDR_DATA_REG P2OUT
|
||||
#define BUS_CTRL_REG P1OUT
|
||||
#define BC1 BIT3
|
||||
#define BDIR BIT1
|
||||
#define _CS0 BIT2
|
||||
#define _CS1 BIT0
|
||||
|
||||
#define R0 0
|
||||
#define CHANNEL_A_TONE_PERIOD_FINE_REG R0
|
||||
#define R1 1
|
||||
#define CHANNEL_A_TONE_PERIOD_COARSE_REG R1
|
||||
#define R2 2
|
||||
#define CHANNEL_B_TONE_PERIOD_FINE_REG R2
|
||||
#define R3 3
|
||||
#define CHANNEL_B_TONE_PERIOD_COARSE_REG R3
|
||||
#define R4 4
|
||||
#define CHANNEL_C_TONE_PERIOD_FINE_REG R4
|
||||
#define R5 5
|
||||
#define CHANNEL_C_TONE_PERIOD_COARSE_REG R5
|
||||
#define R6 6
|
||||
#define NOISE_PERIOD_REG R6
|
||||
#define R7 7
|
||||
#define _ENABLE_REG R7
|
||||
#define R10 010
|
||||
#define CHANNEL_A_AMPLITUDE_REG R10
|
||||
#define R11 011
|
||||
#define CHANNEL_B_AMPLITUDE_REG R11
|
||||
#define R12 012
|
||||
#define CHANNEL_C_AMPLITUDE_REG R12
|
||||
#define R13 013
|
||||
#define ENVELOPE_PERIOD_FINE_REG R13
|
||||
#define R14 014
|
||||
#define ENVELOPE_PERIOD_COARSE_REG R13
|
||||
#define R15 015
|
||||
#define ENVELOPE_SHAPE_REG R15
|
||||
|
||||
uint8_t psgShadowRegisters[2][14];
|
||||
|
||||
inline static void BUS_OP_NACT() {
|
||||
BUS_CTRL_REG &= ~(BDIR | BC1);
|
||||
}
|
||||
inline static void BUS_OP_INTAK() {
|
||||
BUS_CTRL_REG |= BDIR | BC1;
|
||||
}
|
||||
inline static void BUS_OP_DWS() {
|
||||
BUS_CTRL_REG |= BDIR;
|
||||
BUS_CTRL_REG &= ~BC1;
|
||||
}
|
||||
inline static void BUS_OP_CS0_ENABLE() {
|
||||
BUS_CTRL_REG &= ~_CS0;
|
||||
}
|
||||
inline static void BUS_OP_CS0_DISABLE() {
|
||||
BUS_CTRL_REG |= _CS0;
|
||||
}
|
||||
inline static void BUS_OP_CS1_ENABLE() {
|
||||
BUS_CTRL_REG &= ~_CS1;
|
||||
}
|
||||
inline static void BUS_OP_CS1_DISABLE() {
|
||||
BUS_CTRL_REG |= _CS1;
|
||||
}
|
||||
|
||||
static uint8_t psgReadShadow(uint8_t chip, uint8_t address) {
|
||||
return psgShadowRegisters[chip][address];
|
||||
}
|
||||
|
||||
static void psgWrite(uint8_t chip, uint8_t address, uint8_t data) {
|
||||
psgShadowRegisters[chip][address] = data;
|
||||
|
||||
// according to "State Timing" (p. 15) of datasheet
|
||||
|
||||
if (chip == 0) {
|
||||
BUS_OP_CS0_ENABLE();
|
||||
} else {
|
||||
BUS_OP_CS1_ENABLE();
|
||||
}
|
||||
|
||||
// put bus into inactive state
|
||||
BUS_OP_NACT();
|
||||
|
||||
// put address on bus
|
||||
ADDR_DATA_REG = address;
|
||||
|
||||
// address latch mode
|
||||
BUS_OP_INTAK();
|
||||
|
||||
// latch address
|
||||
BUS_OP_NACT();
|
||||
|
||||
// put data on bus
|
||||
ADDR_DATA_REG = data;
|
||||
|
||||
// set write to psg
|
||||
BUS_OP_DWS();
|
||||
|
||||
// set inactive again
|
||||
BUS_OP_NACT();
|
||||
|
||||
if (chip == 0) {
|
||||
BUS_OP_CS0_DISABLE();
|
||||
} else {
|
||||
BUS_OP_CS1_DISABLE();
|
||||
}
|
||||
}
|
||||
|
||||
static void psgWriteFrequency(uint8_t chip, uint8_t channel, uint16_t frequencyCode) {
|
||||
psgWrite(chip, CHANNEL_A_TONE_PERIOD_FINE_REG + (channel * 2), (frequencyCode & 0x00ff));
|
||||
psgWrite(chip, CHANNEL_A_TONE_PERIOD_COARSE_REG + (channel * 2), ((frequencyCode >> 8) & 0x000f));
|
||||
}
|
||||
|
||||
void psgPlayTone(uint8_t chip, uint8_t channel, uint8_t volume, t_octave octave, t_note note) {
|
||||
if (note == e_Pause) {
|
||||
psgWrite(chip, _ENABLE_REG, psgReadShadow(chip, _ENABLE_REG) | (1 << channel));
|
||||
} else {
|
||||
psgWrite(chip, _ENABLE_REG, psgReadShadow(chip, _ENABLE_REG) & ~(1 << channel));
|
||||
psgAmplitude(chip, channel, volume);
|
||||
psgWriteFrequency(chip, channel, frequencyCodes[octave][note]);
|
||||
}
|
||||
}
|
||||
|
||||
void psgAmplitude(uint8_t chip, uint8_t channel, uint8_t volume) {
|
||||
psgWrite(chip, CHANNEL_A_AMPLITUDE_REG + channel, volume);
|
||||
}
|
||||
|
||||
void psgInit() {
|
||||
// address/data bus
|
||||
P2DIR = 0xff;
|
||||
P2SEL = 0;
|
||||
P2SEL2 = 0;
|
||||
|
||||
// bus control lines
|
||||
// BIT3: BC1
|
||||
// BIT1: BDIR
|
||||
// BIT0: _CS1
|
||||
// BIT2: _CS0
|
||||
P1DIR |= BIT0 | BIT1 | BIT2 | BIT3 ;
|
||||
|
||||
// put bus into inactive state
|
||||
BUS_CTRL_REG &= ~(BDIR | BC1);
|
||||
|
||||
// disable everything
|
||||
psgWrite(0, _ENABLE_REG, 0xff);
|
||||
psgWrite(1, _ENABLE_REG, 0xff);
|
||||
}
|
||||
|
46
sound-driver/psg.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef _PSG_H_
|
||||
#define _PSG_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
e_O_1 = 0,
|
||||
e_O_2,
|
||||
e_O_3,
|
||||
e_O_4,
|
||||
e_O_5,
|
||||
e_O_6,
|
||||
e_O_7,
|
||||
e_O_8,
|
||||
e_O_Null
|
||||
} t_octave;
|
||||
|
||||
typedef enum {
|
||||
e_C = 0,
|
||||
e_Cis,
|
||||
e_D,
|
||||
e_Dis,
|
||||
e_E,
|
||||
e_F,
|
||||
e_Fis,
|
||||
e_G,
|
||||
e_Gis,
|
||||
e_A,
|
||||
e_Ais,
|
||||
e_H,
|
||||
e_Pause,
|
||||
e_Null
|
||||
} t_note;
|
||||
|
||||
#define e_Es e_Dis
|
||||
#define e_As e_Gis
|
||||
#define e_B e_Ais
|
||||
|
||||
|
||||
void psgInit();
|
||||
|
||||
void psgPlayTone(uint8_t chip, uint8_t channel, uint8_t volume, t_octave octave, t_note note);
|
||||
void psgAmplitude(uint8_t chip, uint8_t channel, uint8_t volume);
|
||||
|
||||
|
||||
#endif // _PSG_H_
|
80
sound-driver/scheduler.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include <stdlib.h>
|
||||
#include <msp430g2553.h>
|
||||
#include "scheduler.h"
|
||||
|
||||
tTask tasks[MAX_NUM_OF_TASKS];
|
||||
|
||||
|
||||
void schInit() {
|
||||
TACCR0 = 19600;
|
||||
TACCTL0 = CCIE;
|
||||
TACTL = MC_1 | ID_0 | TASSEL_2 | TACLR;
|
||||
|
||||
for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
|
||||
tasks[i].delay = 0;
|
||||
tasks[i].period = 0;
|
||||
tasks[i].run = 0;
|
||||
tasks[i].exec = NULL;
|
||||
tasks[i].handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__ ((interrupt (TIMER0_A0_VECTOR))) schUpdate() {
|
||||
for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
|
||||
if (tasks[i].exec != NULL) {
|
||||
if (tasks[i].delay == 0) {
|
||||
tasks[i].delay = tasks[i].period;
|
||||
tasks[i].run++;
|
||||
} else {
|
||||
tasks[i].delay--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t schAdd(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period) {
|
||||
uint16_t taskId = 0xffff;
|
||||
for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
|
||||
if (tasks[i].exec == NULL) {
|
||||
tasks[i].delay = delay;
|
||||
tasks[i].period = period;
|
||||
if (delay == 0 && period == 0) {
|
||||
tasks[i].run = 1;
|
||||
} else {
|
||||
tasks[i].run = 0;
|
||||
}
|
||||
tasks[i].exec = exec;
|
||||
tasks[i].handle = handle;
|
||||
taskId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return taskId;
|
||||
}
|
||||
|
||||
void schDel(uint16_t taskId) {
|
||||
tasks[taskId].exec = NULL;
|
||||
}
|
||||
|
||||
void schExec() {
|
||||
for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
|
||||
// synchronize access to tasks[].run
|
||||
__disable_interrupt();
|
||||
if (tasks[i].exec != NULL && tasks[i].run > 0) {
|
||||
tasks[i].run--;
|
||||
// synchronize access to tasks[].run
|
||||
// reenable interrupts before actually executing task
|
||||
__enable_interrupt();
|
||||
tasks[i].exec(tasks[i].handle);
|
||||
if (tasks[i].period == 0) {
|
||||
tasks[i].exec = NULL;
|
||||
}
|
||||
} else {
|
||||
// synchronize access to tasks[].run
|
||||
// reenable interrupts in case task is not yet executable
|
||||
__enable_interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
28
sound-driver/scheduler.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef PONTCOOPSCHEDULER_H_
|
||||
#define PONTCOOPSCHEDULER_H_
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
#define MAX_NUM_OF_TASKS 4
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t delay;
|
||||
uint16_t period;
|
||||
uint8_t run;
|
||||
void (*exec)(void *handle);
|
||||
void *handle;
|
||||
} tTask;
|
||||
|
||||
|
||||
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();
|
||||
|
||||
|
||||
#endif /* PONTCOOPSCHEDULER_H_ */
|
140
sound-driver/sequencer.c
Normal file
@ -0,0 +1,140 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/param.h>
|
||||
#include "sequencer.h"
|
||||
#include "scheduler.h"
|
||||
#include "psg.h"
|
||||
|
||||
|
||||
uint8_t slots;
|
||||
|
||||
void sequencerInit() {
|
||||
slots = 0;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wswitch"
|
||||
#pragma GCC diagnostic ignored "-Wreturn-type"
|
||||
static uint16_t calcLength(t_melodies *m, t_noteLength l) {
|
||||
switch (l) {
|
||||
case e_L_1:
|
||||
return m->quarterLength << 2;
|
||||
case e_L_1_2:
|
||||
return m->quarterLength << 1;
|
||||
case e_L_1_4:
|
||||
return m->quarterLength;
|
||||
case e_L_1_8:
|
||||
return m->quarterLength >> 1;
|
||||
case e_L_1_16:
|
||||
return m->quarterLength >> 2;
|
||||
case e_L_1_32:
|
||||
return m->quarterLength >> 4;
|
||||
}
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
void sequencerExec(void *handle) {
|
||||
t_melodies *melodies = (t_melodies*) handle;
|
||||
|
||||
for (uint8_t channel = 0; channel < melodies->numOfMelodies; channel++) {
|
||||
t_melody *melody = &(melodies->melodies[channel]);
|
||||
|
||||
switch (melody->state) {
|
||||
case e_Init:
|
||||
melody->state = e_PlayTone;
|
||||
break;
|
||||
case e_PlayTone:
|
||||
if (melody->tones[melody->idx].length == e_L_SyncMark) {
|
||||
if (melodies->sync == 0) {
|
||||
melodies->sync = melodies->numOfMelodies;
|
||||
}
|
||||
melodies->sync -= 1;
|
||||
melody->state = e_Sync;
|
||||
} else if (melody->tones[melody->idx].length == e_L_HoldMark) {
|
||||
melody->state = e_Hold;
|
||||
} else if (melody->tones[melody->idx].length == e_L_StopMark) {
|
||||
melody->state = e_Terminate;
|
||||
} else {
|
||||
if (melody->tones[melody->idx].length == e_L_EndMark) {
|
||||
melody->idx = 0;
|
||||
}
|
||||
psgPlayTone(melodies->chip, channel, melody->amplitude, melody->tones[melody->idx].octave, melody->tones[melody->idx].note);
|
||||
melody->lengthCnt = (melody->tones[melody->idx].staccato) ?
|
||||
(calcLength(melodies, melody->tones[melody->idx].length) / 2) :
|
||||
calcLength(melodies, melody->tones[melody->idx].length);
|
||||
melody->state = e_HoldTone;
|
||||
}
|
||||
break;
|
||||
case e_Sync:
|
||||
if (melodies->sync == 0) {
|
||||
melody->state = e_SeparateTone;
|
||||
}
|
||||
break;
|
||||
case e_HoldTone:
|
||||
melody->lengthCnt -= 1;
|
||||
if (melody->lengthCnt == 0) {
|
||||
melody->state = (melody->tones[melody->idx].staccato) ? e_StaccatoBreak : e_SeparateTone;
|
||||
}
|
||||
break;
|
||||
case e_StaccatoBreak:
|
||||
psgPlayTone(melodies->chip, channel, 0, e_O_Null, e_Pause);
|
||||
melody->lengthCnt = calcLength(melodies, melody->tones[melody->idx].length) / 2;
|
||||
melody->state = e_HoldStaccatoBreak;
|
||||
break;
|
||||
case e_HoldStaccatoBreak:
|
||||
melody->lengthCnt -= 1;
|
||||
if (melody->lengthCnt == 0) {
|
||||
melody->state = e_SeparateTone;
|
||||
}
|
||||
break;
|
||||
case e_SeparateTone:
|
||||
if (! (melody->tones[melody->idx].legato)) {
|
||||
psgPlayTone(melodies->chip, channel, 0, e_O_Null, e_Pause);
|
||||
}
|
||||
melody->idx += 1;
|
||||
melody->state = e_PlayTone;
|
||||
break;
|
||||
case e_Hold:
|
||||
psgPlayTone(melodies->chip, channel, 0, e_O_Null, e_Pause);
|
||||
break;
|
||||
case e_Terminate:
|
||||
schDel(melodies->taskId);
|
||||
psgPlayTone(melodies->chip, channel, 0, e_O_Null, e_Pause);
|
||||
slots &= ~(melodies->slotMask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sequencerPlayMelodies(t_melodies *melodies) {
|
||||
melodies->slotMask = (1 << melodies->chip);
|
||||
|
||||
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;
|
||||
melodies->melodies[i].state = e_Init;
|
||||
}
|
||||
melodies->sync = 0;
|
||||
melodies->quarterLength = 60000 / melodies->pace / SEQUENCER_PERIOD; // duration of a 1/4 tone in ms
|
||||
|
||||
melodies->taskId = schAdd(sequencerExec, (void*) melodies, 0, SEQUENCER_PERIOD);
|
||||
}
|
||||
|
||||
void sequencerStopMelodies(t_melodies *melodies) {
|
||||
schDel(melodies->taskId);
|
||||
slots &= ~(melodies->slotMask);
|
||||
for (uint8_t channel = 0; channel < melodies->numOfMelodies; channel++) {
|
||||
psgPlayTone(melodies->chip, channel, 0, e_O_Null, e_Pause);
|
||||
}
|
||||
}
|
||||
|
||||
void sequencerChangePace(t_melodies *melodies) {
|
||||
melodies->quarterLength = 60000 / melodies->pace / SEQUENCER_PERIOD; // duration of a 1/4 tone in ms
|
||||
}
|
||||
|
69
sound-driver/sequencer.h
Normal file
@ -0,0 +1,69 @@
|
||||
#ifndef _SEQUENCER_H_
|
||||
#define _SEQUENCER_H_
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "psg.h"
|
||||
|
||||
typedef enum {
|
||||
e_L_1 = 0,
|
||||
e_L_1_2 = 1,
|
||||
e_L_1_4 = 2,
|
||||
e_L_1_8 = 3,
|
||||
e_L_1_16 = 4,
|
||||
e_L_1_32 = 5,
|
||||
e_L_LengthEnd = 6,
|
||||
e_L_HoldMark = 252,
|
||||
e_L_StopMark = 253,
|
||||
e_L_EndMark = 254,
|
||||
e_L_SyncMark = 255,
|
||||
} t_noteLength;
|
||||
|
||||
typedef struct {
|
||||
t_octave octave;
|
||||
t_note note;
|
||||
t_noteLength length;
|
||||
bool legato;
|
||||
bool staccato;
|
||||
} t_tone;
|
||||
|
||||
typedef enum {
|
||||
e_Init,
|
||||
e_PlayTone,
|
||||
e_Sync,
|
||||
e_HoldTone,
|
||||
e_StaccatoBreak,
|
||||
e_HoldStaccatoBreak,
|
||||
e_SeparateTone,
|
||||
e_Hold,
|
||||
e_Terminate
|
||||
} t_sequencerState;
|
||||
|
||||
typedef struct {
|
||||
uint16_t idx;
|
||||
uint16_t lengthCnt;
|
||||
t_sequencerState state;
|
||||
uint8_t amplitude;
|
||||
const t_tone *tones;
|
||||
} t_melody;
|
||||
|
||||
#define SEQUENCER_PERIOD 4 // ms
|
||||
#define NUM_OF_CHANNELS 3
|
||||
typedef struct {
|
||||
uint8_t slotMask;
|
||||
uint8_t chip;
|
||||
uint8_t taskId;
|
||||
uint16_t quarterLength;
|
||||
uint8_t numOfMelodies;
|
||||
uint16_t pace; // quarter notes per minute
|
||||
uint8_t sync;
|
||||
t_melody melodies[NUM_OF_CHANNELS];
|
||||
} t_melodies;
|
||||
|
||||
void sequencerInit();
|
||||
void sequencerPlayMelodies(t_melodies *melodies);
|
||||
void sequencerStopMelodies(t_melodies *melodies);
|
||||
void sequencerChangePace(t_melodies *melodies);
|
||||
|
||||
#endif // _SEQUENCER_H_
|
14
sound-driver/soundCodes.h
Normal file
@ -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_PLING 0x80
|
||||
|
||||
#endif // _SOUND_CODES_H_
|
64
sound-driver/spi.S
Normal file
@ -0,0 +1,64 @@
|
||||
#include <msp430g2553.h>
|
||||
#include "soundCodes.h"
|
||||
|
||||
|
||||
.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
|
||||
call #stopMelodyTetris
|
||||
bic #SOUND_GAMEOVER, &cmd
|
||||
spiCmdHandler_5:
|
||||
bit #SOUND_FANFARE, &cmd
|
||||
jz spiCmdHandler_6
|
||||
call #playMelodyTetrisFaster
|
||||
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_PLING, &cmd
|
||||
jz spiCmdHandler_end
|
||||
call #playPling
|
||||
bic #SOUND_PLING, &cmd
|
||||
spiCmdHandler_end:
|
||||
ret
|
||||
|
||||
|
||||
.section "__interrupt_vector_8","ax",@progbits
|
||||
.word receive_isr
|
||||
|
||||
|
||||
.end
|
9
sound-driver/spi.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef _SPI_H_
|
||||
#define _SPI_H_
|
||||
|
||||
|
||||
void spiInit();
|
||||
void spiCmdHandler();
|
||||
|
||||
|
||||
#endif // _SPI_H_
|
31
sound-driver/spi_init.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include <stddef.h>
|
||||
#include <msp430g2553.h>
|
||||
#include <stdint.h>
|
||||
#include "scheduler.h"
|
||||
#include "spi.h"
|
||||
#include "soundCodes.h"
|
||||
|
||||
|
||||
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 = UCCKPH | UCSYNC | UCMSB | UCMODE_2;
|
||||
UCB0CTL1 = 0x00;
|
||||
|
||||
// enable RX interrupt
|
||||
UC0IE |= UCB0RXIE;
|
||||
|
||||
cmd = SOUND_IDLE;
|
||||
schAdd(spiCmdHandler, NULL, 0, 100);
|
||||
}
|
||||
|
||||
|
64
sound-driver/utils/calc-76489an.py
Normal file
@ -0,0 +1,64 @@
|
||||
N = 3579545.0
|
||||
factor = 1.0594631
|
||||
base = 440.0
|
||||
|
||||
frequencies = []
|
||||
|
||||
BEFORE_A = 46
|
||||
f = base
|
||||
for i in range (BEFORE_A):
|
||||
idx = BEFORE_A - i - 1
|
||||
print(f"{idx}: {f}")
|
||||
frequencies.append(f)
|
||||
f = base / factor
|
||||
base = f
|
||||
frequencies.reverse()
|
||||
|
||||
AFTER_A = 50
|
||||
base = 440.0
|
||||
for i in range(AFTER_A):
|
||||
idx = BEFORE_A + i
|
||||
f = base * factor
|
||||
print(f"{idx}: {f}")
|
||||
frequencies.append(f)
|
||||
base = f
|
||||
|
||||
# print(f"{frequencies}")
|
||||
|
||||
codes = []
|
||||
for i in range(len(frequencies)):
|
||||
codes.append(round(N / (32.0 * frequencies[i])))
|
||||
|
||||
|
||||
#const uint16_t frequencyCodes[8][12] = {
|
||||
# // C, Cis, D, Dis, E, F, Fis, G, Gis, A, Ais, H
|
||||
# { 06535, 06234, 05747, 05474, 05233, 05002, 04563, 04353, 04153, 03762, 03600, 03424 }, // Octave 1
|
||||
# { 03256, 03116, 02764, 02636, 02515, 02401, 02271, 02165, 02065, 01771, 01700, 01612 }, // Octave 2
|
||||
# { 01527, 01447, 01372, 01317, 01247, 01201, 01135, 01073, 01033, 00774, 00740, 00705 }, // Octave 3
|
||||
# { 00654, 00624, 00575, 00550, 00523, 00500, 00456, 00435, 00415, 00376, 00360, 00342 }, // Octave 4
|
||||
# { 00326, 00312, 00276, 00264, 00252, 00240, 00227, 00217, 00207, 00177, 00170, 00161 }, // Octave 5
|
||||
# { 00153, 00145, 00137, 00132, 00125, 00120, 00114, 00107, 00103, 00100, 00074, 00071 }, // Octave 6
|
||||
# { 00065, 00062, 00060, 00055, 00052, 00050, 00046, 00044, 00042, 00040, 00036, 00034 }, // Octave 7
|
||||
# { 00033, 00031, 00030, 00026, 00025, 00024, 00023, 00022, 00021, 00020, 00017, 00016 } // Octave 8
|
||||
#};
|
||||
|
||||
|
||||
|
||||
print("const uint16_t frequencyCodes[8][12] = {")
|
||||
step = 12
|
||||
for i in range(len(codes)):
|
||||
if (i % step == 0):
|
||||
print(" { ", end='')
|
||||
print(f"{codes[i]}", end='')
|
||||
if ((i+1) % step != 0):
|
||||
print(", ", end='')
|
||||
if ((i+1) % step == 0):
|
||||
print(" }", end='')
|
||||
if ((i+1) != len(codes)):
|
||||
print(", ")
|
||||
else:
|
||||
print()
|
||||
print("};")
|
||||
|
||||
|
||||
|