-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSPIKE.h
193 lines (154 loc) · 5.66 KB
/
SPIKE.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#ifndef SPIKE_H
#define SPIKE_H
#define F_CPU 16000000
#define ever ;;
#define LOW 0
#define HIGH 1
#define TRUE 0xFF
#define FALSE 0x00
#define SND 5 // PORTD
/* Display Pins (PORTB) */
#define CS 1
#define DC 3
#define RST 2
#define SCK 0
/* Display Pins (PORTD) */
#define MOSI 1
/* Button Pins (PORTC) */
#define UP 6
#define DOWN 5
#define LEFT 4
#define RIGHT 3
#define BTN_A 2
#define BTN_B 1
#define BTN_C 0
/* Button Masks */
#define _UP 0b01000000
#define _DOWN 0b00100000
#define _LEFT 0b00010000
#define _RIGHT 0b00001000
#define _A 0b00000100
#define _B 0b00000010
#define _C 0b00000001
#define SPLASH_DELAY 1500
#define CMD LOW
#define DATA HIGH
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define HALF_SCREEN_WIDTH 128/2
#define HALF_SCREEN_HEIGHT 64/2
#define SCREEN_COLUMNS 16
#define SCREEN_ROWS 8
#define NOTE_DURATION_MULTIPLIER 15 // 1ms
typedef unsigned char byte;
typedef unsigned int word;
typedef unsigned long dword;
typedef unsigned char bool;
// http://www.soundoctor.com/freq.htm
// OCR1A FREQ.(Hz) Note
static const __flash word NOTES[] = {
0,
2273, // 440, Concert A(4)
2146, // 466, Bb(4)
2024, // 494, B(4)
1912, // 523, C(5)
1805, // 554, C#(5)
1703, // 587, D(5)
1608, // 622, D#(5)
1518, // 659, E(5)
1433, // 698, F(5)
1351, // 740, F#(5)
1337, // 748, G(5)
1203, // 831, G#(5)
1250, // 800, A(5)
1073, // 932, Bb(5)
1012, // 988, B(5)
142, // 7040, A(8)
71, // 14080 A(9)
};
#define _RST 0x0
#define _A4 0x1
#define _Bb4 0x2
#define _B4 0x3
#define _C5 0x4
#define _Cs5 0x5
#define _D5 0x6
#define _Ds5 0x7
#define _E5 0x8
#define _F5 0x9
#define _Fs5 0xA
#define _G5 0xB
#define _Gs5 0xC
#define _A5 0xD
#define _Bb5 0xE
#define _B5 0xF
#define _A8 16
#define _A9 17
static const __flash byte BEATS[8] = {
64, // SEMIBREVE
48, // DOTTED MINIM
32, // MINIM
16, // CROTCHET
8, // QUAVER
4, // SEMI QUAVER
2, // DEMI SEMI QUAVER
1, // HEMI DEMI SEMI QUAVER
};
#define SEMIBREVE 0 << 4
#define DMINIM 1 << 4
#define MINIM 2 << 4
#define CROTCHET 3 << 4
#define QUAVER 4 << 4
#define SQUAVER 5 << 4
#define DSQUAVER 6 << 4
#define HDSQUAVER 7 << 4
// Starting at 128 BPM
#define BEAT_ATOM 8 * 4 * NOTE_DURATION_MULTIPLIER // 8 Milliseconds
typedef struct Tune {
word length;
byte score[];
} Tune;
static const __flash Tune STARTUP_CHIME = {
.length = 3,
.score = {
DSQUAVER | _A4, DSQUAVER | _C5, SQUAVER | _E5,
},
};
byte buffer[SCREEN_WIDTH * SCREEN_ROWS];
typedef struct Image {
byte height;
byte width;
byte data[];
} Image;
//TODO: UPDATE TO GLYPH
static const __flash Image LOGO = {
.height = 24,
.width = 96,
.data = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x78, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xe8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0xf0, 0xe8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xe8, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xe8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x08, 0x00, 0x00,
0x00, 0x00, 0x02, 0x03, 0x03, 0x03, 0xff, 0x0e, 0xff, 0x03, 0x03, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x17, 0x18, 0x18, 0x18, 0x18, 0x08, 0x10, 0x18, 0x18, 0x18, 0x18, 0xd0, 0xe0, 0x00, 0x00, 0xef, 0xd7, 0x18, 0x18, 0x18, 0x18, 0x08, 0x10, 0x18, 0x18, 0x18, 0x18, 0x17, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xd7, 0x18, 0x18, 0x18, 0x18, 0x08, 0x00, 0x00, 0xc3, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xd7, 0x18, 0x18, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, 0x0f, 0x00, 0x00, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x17, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x10, 0x00, 0x00,
},
};
#define rngM 251
#define rngA 11
#define rngC 3
byte rng( void );
void delay_ms( word ms );
// http://www.oz4.us/2015/12/recoding-bare-millis-clock-on-avr.html
// https://github.com/sourceperl/millis/blob/master/millis.c
// https://www.avrfreaks.net/forum/tut-c-newbies-guide-avr-timers?page=all
void initialise( void );
dword millis( void );
/* OLED Function */
void shift_out_byte(byte val);
void initialise_oled(void);
void clear_buffer(void);
void draw(void);
void display_off(void);
void display_on(void);
void note(byte note, word dur);
void click( void );
void play_tune(const __memx Tune *t);
void stop_tune();
#endif