summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-02-08 13:26:41 +0100
committerBad Diode <bd@badd10de.dev>2023-02-08 13:26:41 +0100
commita1c96114819dc8eb59b2a5152cb2ccff408402d4 (patch)
tree614a959f8caa422ff178d6587dd0a14460d4e9ce
parent315d8d16fcd39073b4b868db342009c772da2256 (diff)
downloadlaunchpad-polymaker-a1c96114819dc8eb59b2a5152cb2ccff408402d4.tar.gz
launchpad-polymaker-a1c96114819dc8eb59b2a5152cb2ccff408402d4.zip
Add example drawing routing for numbers
-rw-r--r--Makefile4
-rw-r--r--src/app.c343
2 files changed, 196 insertions, 151 deletions
diff --git a/Makefile b/Makefile
index cfb7766..42763b3 100644
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,7 @@ ELF = $(BUILDDIR)/launchpad_pro.elf
16HEX = $(BUILDDIR)/launchpad_pro.hex 16HEX = $(BUILDDIR)/launchpad_pro.hex
17HEXTOSYX = $(BUILDDIR)/hextosyx 17HEXTOSYX = $(BUILDDIR)/hextosyx
18SIMULATOR = $(BUILDDIR)/simulator 18SIMULATOR = $(BUILDDIR)/simulator
19PORT = hw:4,0,0
19 20
20# tools 21# tools
21HOST_GPP = g++ 22HOST_GPP = g++
@@ -65,3 +66,6 @@ $(BUILDDIR)/%.o: %.c
65 66
66clean: 67clean:
67 rm -rf $(BUILDDIR) 68 rm -rf $(BUILDDIR)
69
70run: $(SYX)
71 amidi -p $(PORT) -s $(SYX) -i 20
diff --git a/src/app.c b/src/app.c
index 4ce908e..667ce32 100644
--- a/src/app.c
+++ b/src/app.c
@@ -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
50static const u16 *g_ADC = 0; 36static 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 40u8 buttons[BUTTON_COUNT] = {0};
55u8 g_Buttons[BUTTON_COUNT] = {0}; 41u16 font_numbers[10] = {
56 42 /*
57//______________________________________________________________________________ 43 * 0: 111 | 1111 0110 1101 1110
58 44 * 101 |
59void 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
124void
125app_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//______________________________________________________________________________ 150void
93 151app_midi_event(u8 port, u8 status, u8 d1, u8 d2) {
94void 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//______________________________________________________________________________ 160void
110 161app_sysex_event(u8 port, u8 * data, u16 count) {
111void 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//______________________________________________________________________________ 165void
117 166app_aftertouch_event(u8 index, u8 value) {
118void 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//______________________________________________________________________________ 171void
127 172app_cable_event(u8 type, u8 value) {
128void 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//______________________________________________________________________________ 181void
142 182print_number(u8 n, u16 r, u16 g, u16 b, u8 x, u8 y) {
143void 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//______________________________________________________________________________ 195void
196app_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
190void app_init(const u16 *adc_raw) 242void
191{ 243app_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}