diff options
author | Bad Diode <bd@badd10de.dev> | 2023-02-08 13:26:41 +0100 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-02-08 13:26:41 +0100 |
commit | a1c96114819dc8eb59b2a5152cb2ccff408402d4 (patch) | |
tree | 614a959f8caa422ff178d6587dd0a14460d4e9ce /src | |
parent | 315d8d16fcd39073b4b868db342009c772da2256 (diff) | |
download | launchpad-polymaker-a1c96114819dc8eb59b2a5152cb2ccff408402d4.tar.gz launchpad-polymaker-a1c96114819dc8eb59b2a5152cb2ccff408402d4.zip |
Add example drawing routing for numbers
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 343 |
1 files changed, 192 insertions, 151 deletions
@@ -1,22 +1,22 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | 2 | ||
3 | Copyright (c) 2015, Focusrite Audio Engineering Ltd. | 3 | Copyright (c) 2015, Focusrite Audio Engineering Ltd. |
4 | All rights reserved. | 4 | All rights reserved. |
5 | 5 | ||
6 | Redistribution and use in source and binary forms, with or without | 6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met: | 7 | modification, are permitted provided that the following conditions are met: |
8 | 8 | ||
9 | * Redistributions of source code must retain the above copyright notice, this | 9 | * Redistributions of source code must retain the above copyright notice, this |
10 | list of conditions and the following disclaimer. | 10 | list of conditions and the following disclaimer. |
11 | 11 | ||
12 | * Redistributions in binary form must reproduce the above copyright notice, | 12 | * Redistributions in binary form must reproduce the above copyright notice, |
13 | this list of conditions and the following disclaimer in the documentation | 13 | this list of conditions and the following disclaimer in the documentation |
14 | and/or other materials provided with the distribution. | 14 | and/or other materials provided with the distribution. |
15 | 15 | ||
16 | * Neither the name of Focusrite Audio Engineering Ltd., nor the names of its | 16 | * Neither the name of Focusrite Audio Engineering Ltd., nor the names of its |
17 | contributors may be used to endorse or promote products derived from | 17 | contributors may be used to endorse or promote products derived from |
18 | this software without specific prior written permission. | 18 | this software without specific prior written permission. |
19 | 19 | ||
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
@@ -27,182 +27,223 @@ | |||
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | |||
31 | *****************************************************************************/ | ||
32 | 30 | ||
33 | //______________________________________________________________________________ | 31 | *****************************************************************************/ |
34 | // | ||
35 | // Headers | ||
36 | //______________________________________________________________________________ | ||
37 | 32 | ||
38 | #include "app.h" | 33 | #include "app.h" |
39 | 34 | ||
40 | //______________________________________________________________________________ | ||
41 | // | ||
42 | // This is where the fun is! Add your code to the callbacks below to define how | ||
43 | // your app behaves. | ||
44 | // | ||
45 | // In this example, we either render the raw ADC data as LED rainbows or store | ||
46 | // and recall the pad state from flash. | ||
47 | //______________________________________________________________________________ | ||
48 | |||
49 | // store ADC frame pointer | 35 | // store ADC frame pointer |
50 | static const u16 *g_ADC = 0; | 36 | static const u16 *g_ADC = 0; |
51 | 37 | ||
52 | // buffer to store pad states for flash save | 38 | // buffer to store pad states for flash save |
53 | #define BUTTON_COUNT 100 | 39 | #define BUTTON_COUNT 100 |
54 | 40 | u8 buttons[BUTTON_COUNT] = {0}; | |
55 | u8 g_Buttons[BUTTON_COUNT] = {0}; | 41 | u16 font_numbers[10] = { |
56 | 42 | /* | |
57 | //______________________________________________________________________________ | 43 | * 0: 111 | 1111 0110 1101 1110 |
58 | 44 | * 101 | | |
59 | void app_surface_event(u8 type, u8 index, u8 value) | 45 | * 101 | |
60 | { | 46 | * 101 | |
61 | switch (type) | 47 | * 111 | |
62 | { | 48 | */ |
63 | case TYPEPAD: | 49 | 0xF6DE, |
64 | { | 50 | /* |
51 | * 1: 010 | 0101 1001 0010 1110 | ||
52 | * 110 | | ||
53 | * 010 | | ||
54 | * 010 | | ||
55 | * 111 | | ||
56 | */ | ||
57 | 0x592E, | ||
58 | /* | ||
59 | * 2: 111 | 1110 0111 1100 1110 | ||
60 | * 001 | | ||
61 | * 111 | | ||
62 | * 100 | | ||
63 | * 111 | | ||
64 | */ | ||
65 | 0xE7CE, | ||
66 | /* | ||
67 | * 3: 111 | 1110 0101 1001 1110 | ||
68 | * 001 | | ||
69 | * 011 | | ||
70 | * 001 | | ||
71 | * 111 | | ||
72 | */ | ||
73 | 0xE59E, | ||
74 | /* | ||
75 | * 4: 101 | 1011 0110 1111 0010 | ||
76 | * 101 | | ||
77 | * 101 | | ||
78 | * 111 | | ||
79 | * 001 | | ||
80 | */ | ||
81 | 0xB6F2, | ||
82 | /* | ||
83 | * 5: 111 | 1111 0011 1001 1110 | ||
84 | * 100 | | ||
85 | * 111 | | ||
86 | * 001 | | ||
87 | * 111 | | ||
88 | */ | ||
89 | 0xF39E, | ||
90 | /* | ||
91 | * 6: 111 | 1111 0011 1101 1110 | ||
92 | * 100 | | ||
93 | * 111 | | ||
94 | * 101 | | ||
95 | * 111 | | ||
96 | */ | ||
97 | 0xF3DE, | ||
98 | /* | ||
99 | * 7: 111 | 1110 0101 0100 1000 | ||
100 | * 001 | | ||
101 | * 010 | | ||
102 | * 100 | | ||
103 | * 100 | | ||
104 | */ | ||
105 | 0xE548, | ||
106 | /* | ||
107 | * 8: 111 | 1111 0111 1101 1110 | ||
108 | * 101 | | ||
109 | * 111 | | ||
110 | * 101 | | ||
111 | * 111 | | ||
112 | */ | ||
113 | 0xF7DE, | ||
114 | /* | ||
115 | * 9: 111 | 1111 0111 1001 0010 | ||
116 | * 101 | | ||
117 | * 111 | | ||
118 | * 001 | | ||
119 | * 001 | | ||
120 | */ | ||
121 | 0xF792, | ||
122 | }; | ||
123 | |||
124 | void | ||
125 | app_surface_event(u8 type, u8 index, u8 value) { | ||
126 | switch (type) { | ||
127 | case TYPEPAD: { | ||
65 | // toggle it and store it off, so we can save to flash if we want to | 128 | // toggle it and store it off, so we can save to flash if we want to |
66 | if (value) | 129 | if (value) { |
67 | { | 130 | buttons[index] = MAXLED * !buttons[index]; |
68 | g_Buttons[index] = MAXLED * !g_Buttons[index]; | ||
69 | } | 131 | } |
70 | 132 | ||
71 | // example - light / extinguish pad LEDs | 133 | // example - light / extinguish pad LEDs |
72 | hal_plot_led(TYPEPAD, index, 0, 0, g_Buttons[index]); | 134 | // hal_plot_led(TYPEPAD, index, 0, 0, buttons[index]); |
73 | 135 | ||
74 | // example - send MIDI | 136 | // example - send MIDI |
75 | hal_send_midi(DINMIDI, NOTEON | 0, index, value); | 137 | // hal_send_midi(DINMIDI, NOTEON | 0, index, value); |
76 | 138 | } break; | |
77 | } | 139 | case TYPESETUP: { |
78 | break; | 140 | if (value) { |
79 | 141 | // Pressing the setup button will save the current buttons/pad | |
80 | case TYPESETUP: | 142 | // state to the flash. The flash memory is USER_AREA_SIZE bytes |
81 | { | 143 | // long and can be organized however we need. |
82 | if (value) | 144 | hal_write_flash(0, buttons, BUTTON_COUNT); |
83 | { | ||
84 | // save button states to flash (reload them by power cycling the hardware!) | ||
85 | hal_write_flash(0, g_Buttons, BUTTON_COUNT); | ||
86 | } | 145 | } |
87 | } | 146 | } break; |
88 | break; | ||
89 | } | 147 | } |
90 | } | 148 | } |
91 | 149 | ||
92 | //______________________________________________________________________________ | 150 | void |
93 | 151 | app_midi_event(u8 port, u8 status, u8 d1, u8 d2) { | |
94 | void app_midi_event(u8 port, u8 status, u8 d1, u8 d2) | 152 | if (port == USBMIDI) { |
95 | { | ||
96 | // example - MIDI interface functionality for USB "MIDI" port -> DIN port | ||
97 | if (port == USBMIDI) | ||
98 | { | ||
99 | hal_send_midi(DINMIDI, status, d1, d2); | 153 | hal_send_midi(DINMIDI, status, d1, d2); |
100 | } | 154 | } |
101 | 155 | if (port == DINMIDI) { | |
102 | // // example -MIDI interface functionality for DIN -> USB "MIDI" port port | ||
103 | if (port == DINMIDI) | ||
104 | { | ||
105 | hal_send_midi(USBMIDI, status, d1, d2); | 156 | hal_send_midi(USBMIDI, status, d1, d2); |
106 | } | 157 | } |
107 | } | 158 | } |
108 | 159 | ||
109 | //______________________________________________________________________________ | 160 | void |
110 | 161 | app_sysex_event(u8 port, u8 * data, u16 count) { | |
111 | void app_sysex_event(u8 port, u8 * data, u16 count) | ||
112 | { | ||
113 | // example - respond to UDI messages? | 162 | // example - respond to UDI messages? |
114 | } | 163 | } |
115 | 164 | ||
116 | //______________________________________________________________________________ | 165 | void |
117 | 166 | app_aftertouch_event(u8 index, u8 value) { | |
118 | void app_aftertouch_event(u8 index, u8 value) | ||
119 | { | ||
120 | // example - send poly aftertouch to MIDI ports | 167 | // example - send poly aftertouch to MIDI ports |
121 | hal_send_midi(USBMIDI, POLYAFTERTOUCH | 0, index, value); | 168 | // hal_send_midi(USBMIDI, POLYAFTERTOUCH | 0, index, value); |
122 | |||
123 | |||
124 | } | 169 | } |
125 | 170 | ||
126 | //______________________________________________________________________________ | 171 | void |
127 | 172 | app_cable_event(u8 type, u8 value) { | |
128 | void app_cable_event(u8 type, u8 value) | ||
129 | { | ||
130 | // example - light the Setup LED to indicate cable connections | 173 | // example - light the Setup LED to indicate cable connections |
131 | if (type == MIDI_IN_CABLE) | 174 | // if (type == MIDI_IN_CABLE) { |
132 | { | 175 | // hal_plot_led(TYPESETUP, 0, 0, value, 0); // green |
133 | hal_plot_led(TYPESETUP, 0, 0, value, 0); // green | 176 | // } else if (type == MIDI_OUT_CABLE) { |
134 | } | 177 | // hal_plot_led(TYPESETUP, 0, value, 0, 0); // red |
135 | else if (type == MIDI_OUT_CABLE) | 178 | // } |
136 | { | ||
137 | hal_plot_led(TYPESETUP, 0, value, 0, 0); // red | ||
138 | } | ||
139 | } | 179 | } |
140 | 180 | ||
141 | //______________________________________________________________________________ | 181 | void |
142 | 182 | print_number(u8 n, u16 r, u16 g, u16 b, u8 x, u8 y) { | |
143 | void app_timer_event() | 183 | u16 number = font_numbers[n]; |
144 | { | 184 | for (u8 row = 0; row < 5; row++) { |
145 | // example - send MIDI clock at 125bpm | 185 | u8 pos = 11 + 10 * (7 - x + y * 8) - row * 10; |
146 | #define TICK_MS 20 | 186 | u16 cur = number >> (13 - 3 * row); |
147 | 187 | for (u8 i = 0; i < 3; i++) { | |
148 | static u8 ms = TICK_MS; | 188 | if ((cur >> (2 - i)) & 0x1) { |
149 | 189 | hal_plot_led(TYPEPAD, pos + i, r, g, b); | |
150 | if (++ms >= TICK_MS) | 190 | } |
151 | { | 191 | } |
152 | ms = 0; | ||
153 | |||
154 | // send a clock pulse up the USB | ||
155 | hal_send_midi(USBSTANDALONE, MIDITIMINGCLOCK, 0, 0); | ||
156 | } | 192 | } |
157 | |||
158 | // alternative example - show raw ADC data as LEDs | ||
159 | for (int i=0; i < PAD_COUNT; ++i) | ||
160 | { | ||
161 | // raw adc values are 12 bit, but LEDs are 6 bit. | ||
162 | // Let's saturate into r;g;b for a rainbow effect to show pressure | ||
163 | u16 r = 0; | ||
164 | u16 g = 0; | ||
165 | u16 b = 0; | ||
166 | |||
167 | u16 x = (3 * MAXLED * g_ADC[i]) >> 12; | ||
168 | |||
169 | if (x < MAXLED) | ||
170 | { | ||
171 | r = x; | ||
172 | } | ||
173 | else if (x >= MAXLED && x < (2*MAXLED)) | ||
174 | { | ||
175 | r = 2*MAXLED - x; | ||
176 | g = x - MAXLED; | ||
177 | } | ||
178 | else | ||
179 | { | ||
180 | g = 3*MAXLED - x; | ||
181 | b = x - 2*MAXLED; | ||
182 | } | ||
183 | |||
184 | hal_plot_led(TYPEPAD, ADC_MAP[i], r, g, b); | ||
185 | } | ||
186 | } | 193 | } |
187 | 194 | ||
188 | //______________________________________________________________________________ | 195 | void |
196 | app_timer_event() { | ||
197 | // example - send MIDI clock at 125bpm | ||
198 | // #define TICK_MS 20 | ||
199 | |||
200 | // static u8 ms = TICK_MS; | ||
201 | |||
202 | // if (++ms >= TICK_MS) | ||
203 | // { | ||
204 | // ms = 0; | ||
205 | |||
206 | // // send a clock pulse up the USB | ||
207 | // hal_send_midi(USBSTANDALONE, MIDITIMINGCLOCK, 0, 0); | ||
208 | // } | ||
209 | |||
210 | // alternative example - show raw ADC data as LEDs | ||
211 | // for (int i = 0; i < PAD_COUNT; ++i) { | ||
212 | // // raw adc values are 12 bit, but LEDs are 6 bit. | ||
213 | // // Let's saturate into r;g;b for a rainbow effect to show pressure | ||
214 | // u16 r = 0; | ||
215 | // u16 g = 0; | ||
216 | // u16 b = 0; | ||
217 | |||
218 | // u16 x = (3 * MAXLED * g_ADC[i]) >> 12; | ||
219 | |||
220 | // if (x < MAXLED) { | ||
221 | // r = x; | ||
222 | // } else if (x >= MAXLED && x < (2*MAXLED)) { | ||
223 | // r = 2 * MAXLED - x; | ||
224 | // g = x - MAXLED; | ||
225 | // } | ||
226 | // else { | ||
227 | // g = 3 * MAXLED - x; | ||
228 | // b = x - 2*MAXLED; | ||
229 | // } | ||
230 | |||
231 | // print_number(i, r, g, b, 0, 0); | ||
232 | // break; | ||
233 | // // if (buttons[ADC_MAP[i]] == MAXLED) { | ||
234 | // // hal_plot_led(TYPEPAD, ADC_MAP[i], r, g, b); | ||
235 | // // } else { | ||
236 | // // hal_plot_led(TYPEPAD, ADC_MAP[i], 0, 0, MAXLED); | ||
237 | // // } | ||
238 | // } | ||
239 | print_number(9, MAXLED, MAXLED, MAXLED, 0, 0); | ||
240 | } | ||
189 | 241 | ||
190 | void app_init(const u16 *adc_raw) | 242 | void |
191 | { | 243 | app_init(const u16 *adc_raw) { |
192 | // example - load button states from flash | 244 | // example - load button states from flash |
193 | hal_read_flash(0, g_Buttons, BUTTON_COUNT); | 245 | hal_read_flash(0, buttons, BUTTON_COUNT); |
194 | 246 | ||
195 | // example - light the LEDs to say hello! | 247 | // store off the raw ADC frame pointer for later use |
196 | for (int i=0; i < 10; ++i) | 248 | g_ADC = adc_raw; |
197 | { | ||
198 | for (int j=0; j < 10; ++j) | ||
199 | { | ||
200 | u8 b = g_Buttons[j*10 + i]; | ||
201 | |||
202 | hal_plot_led(TYPEPAD, j*10 + i, 0, 0, b); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | // store off the raw ADC frame pointer for later use | ||
207 | g_ADC = adc_raw; | ||
208 | } | 249 | } |