User Interface Test on mbed RTOS
Dependencies: N5110 RotaryEncoder mbed-rtos mbed PinDetect
main.cpp@4:d9a72e07749f, 2016-05-27 (annotated)
- Committer:
- ryood
- Date:
- Fri May 27 00:23:46 2016 +0000
- Revision:
- 4:d9a72e07749f
- Parent:
- 3:8c8020dfd82f
???????????????
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ryood | 4:d9a72e07749f | 1 | /* |
ryood | 4:d9a72e07749f | 2 | * Nucleo RTOS Sequencer User Interface Test. |
ryood | 4:d9a72e07749f | 3 | * |
ryood | 4:d9a72e07749f | 4 | * 2016.05.27 |
ryood | 4:d9a72e07749f | 5 | * |
ryood | 4:d9a72e07749f | 6 | */ |
ryood | 4:d9a72e07749f | 7 | |
ryood | 0:468e49a35876 | 8 | #include "mbed.h" |
ryood | 0:468e49a35876 | 9 | #include "rtos.h" |
ryood | 2:8cc6dff1d7fd | 10 | #include "PinDetect.h" |
ryood | 2:8cc6dff1d7fd | 11 | #include "RotaryEncoder.h" |
ryood | 0:468e49a35876 | 12 | #include "N5110.h" |
ryood | 4:d9a72e07749f | 13 | #include "AverageAnalogIn.h" |
ryood | 2:8cc6dff1d7fd | 14 | |
ryood | 2:8cc6dff1d7fd | 15 | #define SEQUENCE_N 16 |
ryood | 2:8cc6dff1d7fd | 16 | #define OCTAVE_MIN -1 |
ryood | 2:8cc6dff1d7fd | 17 | #define OCTAVE_MAX 1 |
ryood | 2:8cc6dff1d7fd | 18 | #define PITCH_MAX 12 |
ryood | 0:468e49a35876 | 19 | |
ryood | 0:468e49a35876 | 20 | // SPI2 Morpho |
ryood | 0:468e49a35876 | 21 | // VCC, SCE, RST, D/C, MOSI, SCLK, LED |
ryood | 0:468e49a35876 | 22 | N5110 Lcd(PA_12, PB_1, PB_2, PB_12, PB_15, PB_13, PA_11); |
ryood | 2:8cc6dff1d7fd | 23 | |
ryood | 2:8cc6dff1d7fd | 24 | RotaryEncoder RotEnc1(D2, D3, 0, SEQUENCE_N - 1, 0); |
ryood | 2:8cc6dff1d7fd | 25 | RotaryEncoder RotEnc2(D4, D5, 0, PITCH_MAX, 0); |
ryood | 2:8cc6dff1d7fd | 26 | |
ryood | 4:d9a72e07749f | 27 | AverageAnalogIn Pots[] = { |
ryood | 4:d9a72e07749f | 28 | AverageAnalogIn(A0), |
ryood | 4:d9a72e07749f | 29 | AverageAnalogIn(A1), |
ryood | 4:d9a72e07749f | 30 | AverageAnalogIn(A2), |
ryood | 4:d9a72e07749f | 31 | AverageAnalogIn(A3), |
ryood | 4:d9a72e07749f | 32 | AverageAnalogIn(A4), |
ryood | 3:8c8020dfd82f | 33 | }; |
ryood | 3:8c8020dfd82f | 34 | |
ryood | 2:8cc6dff1d7fd | 35 | PinDetect Pins[] = { |
ryood | 3:8c8020dfd82f | 36 | PinDetect(PA_13, PullUp), |
ryood | 3:8c8020dfd82f | 37 | PinDetect(PA_14, PullUp), |
ryood | 3:8c8020dfd82f | 38 | PinDetect(PA_15, PullUp), |
ryood | 3:8c8020dfd82f | 39 | PinDetect(PB_7, PullUp), |
ryood | 3:8c8020dfd82f | 40 | PinDetect(PC_13, PullUp), |
ryood | 3:8c8020dfd82f | 41 | PinDetect(PB_10, PullUp), |
ryood | 3:8c8020dfd82f | 42 | PinDetect(PA_8, PullUp), |
ryood | 2:8cc6dff1d7fd | 43 | }; |
ryood | 2:8cc6dff1d7fd | 44 | |
ryood | 0:468e49a35876 | 45 | DigitalOut Led1(LED1); |
ryood | 4:d9a72e07749f | 46 | DigitalOut CheckPin(PC_8); |
ryood | 0:468e49a35876 | 47 | |
ryood | 2:8cc6dff1d7fd | 48 | // Grobal Variables |
ryood | 2:8cc6dff1d7fd | 49 | struct Sequence { |
ryood | 2:8cc6dff1d7fd | 50 | bool noteOn; |
ryood | 2:8cc6dff1d7fd | 51 | int octave; |
ryood | 2:8cc6dff1d7fd | 52 | int pitch; |
ryood | 2:8cc6dff1d7fd | 53 | bool tie; |
ryood | 2:8cc6dff1d7fd | 54 | bool accent; |
ryood | 2:8cc6dff1d7fd | 55 | } Sequence[SEQUENCE_N]; |
ryood | 2:8cc6dff1d7fd | 56 | |
ryood | 4:d9a72e07749f | 57 | struct Oscillator { |
ryood | 4:d9a72e07749f | 58 | int waveForm; |
ryood | 4:d9a72e07749f | 59 | int pulseWidth; |
ryood | 4:d9a72e07749f | 60 | } Oscillator; |
ryood | 4:d9a72e07749f | 61 | |
ryood | 4:d9a72e07749f | 62 | struct Filter { |
ryood | 4:d9a72e07749f | 63 | int cutOff; |
ryood | 4:d9a72e07749f | 64 | int resonance; |
ryood | 4:d9a72e07749f | 65 | int envMod; |
ryood | 4:d9a72e07749f | 66 | } Filter; |
ryood | 4:d9a72e07749f | 67 | |
ryood | 3:8c8020dfd82f | 68 | int currentNote = 0; |
ryood | 4:d9a72e07749f | 69 | int tempo = 120; |
ryood | 3:8c8020dfd82f | 70 | bool isRunning = true; |
ryood | 3:8c8020dfd82f | 71 | bool isDirty = true; |
ryood | 2:8cc6dff1d7fd | 72 | |
ryood | 2:8cc6dff1d7fd | 73 | void updateLCD() |
ryood | 0:468e49a35876 | 74 | { |
ryood | 0:468e49a35876 | 75 | char buff[20]; |
ryood | 0:468e49a35876 | 76 | |
ryood | 4:d9a72e07749f | 77 | //Lcd.clear(); |
ryood | 4:d9a72e07749f | 78 | sprintf(buff, "Note#: %d ", currentNote); |
ryood | 4:d9a72e07749f | 79 | Lcd.printString(buff, 0, 0); |
ryood | 4:d9a72e07749f | 80 | sprintf(buff, "pitch: %d ", Sequence[currentNote].pitch); |
ryood | 0:468e49a35876 | 81 | Lcd.printString(buff, 0, 1); |
ryood | 4:d9a72e07749f | 82 | sprintf(buff, "octave: %d " ,Sequence[currentNote].octave); |
ryood | 2:8cc6dff1d7fd | 83 | Lcd.printString(buff, 0, 2); |
ryood | 4:d9a72e07749f | 84 | sprintf(buff, "%1d %1d %1d %1d %3d", |
ryood | 4:d9a72e07749f | 85 | Sequence[currentNote].noteOn, Sequence[currentNote].tie, Sequence[currentNote].accent, |
ryood | 4:d9a72e07749f | 86 | isRunning, Oscillator.waveForm); |
ryood | 2:8cc6dff1d7fd | 87 | Lcd.printString(buff, 0, 3); |
ryood | 4:d9a72e07749f | 88 | sprintf(buff, "%3d %3d %3d", Oscillator.pulseWidth, Filter.envMod, tempo); |
ryood | 2:8cc6dff1d7fd | 89 | Lcd.printString(buff, 0, 4); |
ryood | 4:d9a72e07749f | 90 | sprintf(buff, "%3d %3d", Filter.cutOff, Filter.resonance); |
ryood | 4:d9a72e07749f | 91 | Lcd.printString(buff, 0, 5); |
ryood | 0:468e49a35876 | 92 | Lcd.refresh(); |
ryood | 0:468e49a35876 | 93 | } |
ryood | 0:468e49a35876 | 94 | |
ryood | 2:8cc6dff1d7fd | 95 | // CallBack routines |
ryood | 2:8cc6dff1d7fd | 96 | void swOctaveUpPressed() |
ryood | 2:8cc6dff1d7fd | 97 | { |
ryood | 2:8cc6dff1d7fd | 98 | Sequence[currentNote].octave++; |
ryood | 2:8cc6dff1d7fd | 99 | isDirty = true; |
ryood | 2:8cc6dff1d7fd | 100 | printf("swOctaveUpPressed\r\n"); |
ryood | 2:8cc6dff1d7fd | 101 | } |
ryood | 2:8cc6dff1d7fd | 102 | |
ryood | 2:8cc6dff1d7fd | 103 | void swOctaveDownPressed() |
ryood | 2:8cc6dff1d7fd | 104 | { |
ryood | 2:8cc6dff1d7fd | 105 | Sequence[currentNote].octave--; |
ryood | 2:8cc6dff1d7fd | 106 | isDirty = true; |
ryood | 2:8cc6dff1d7fd | 107 | printf("swOctaveDownPressed\r\n"); |
ryood | 2:8cc6dff1d7fd | 108 | } |
ryood | 2:8cc6dff1d7fd | 109 | |
ryood | 2:8cc6dff1d7fd | 110 | void swNoteOnOffPressed() |
ryood | 2:8cc6dff1d7fd | 111 | { |
ryood | 2:8cc6dff1d7fd | 112 | Sequence[currentNote].noteOn = !Sequence[currentNote].noteOn; |
ryood | 2:8cc6dff1d7fd | 113 | isDirty = true; |
ryood | 2:8cc6dff1d7fd | 114 | printf("swNoteOnOffPressed\r\n"); |
ryood | 2:8cc6dff1d7fd | 115 | } |
ryood | 2:8cc6dff1d7fd | 116 | |
ryood | 2:8cc6dff1d7fd | 117 | void swTiePressed() |
ryood | 2:8cc6dff1d7fd | 118 | { |
ryood | 2:8cc6dff1d7fd | 119 | Sequence[currentNote].tie = !Sequence[currentNote].tie; |
ryood | 2:8cc6dff1d7fd | 120 | isDirty = true; |
ryood | 2:8cc6dff1d7fd | 121 | printf("swTiePressed\r\n"); |
ryood | 2:8cc6dff1d7fd | 122 | } |
ryood | 2:8cc6dff1d7fd | 123 | |
ryood | 2:8cc6dff1d7fd | 124 | void swAccentPressed() |
ryood | 2:8cc6dff1d7fd | 125 | { |
ryood | 2:8cc6dff1d7fd | 126 | Sequence[currentNote].accent = !Sequence[currentNote].accent; |
ryood | 2:8cc6dff1d7fd | 127 | isDirty = true; |
ryood | 2:8cc6dff1d7fd | 128 | printf("swAccentPressed\r\n"); |
ryood | 2:8cc6dff1d7fd | 129 | } |
ryood | 2:8cc6dff1d7fd | 130 | |
ryood | 3:8c8020dfd82f | 131 | void swRunStopPressed() |
ryood | 3:8c8020dfd82f | 132 | { |
ryood | 3:8c8020dfd82f | 133 | isRunning = !isRunning; |
ryood | 3:8c8020dfd82f | 134 | isDirty = true; |
ryood | 3:8c8020dfd82f | 135 | printf("swRunStopPressed\r\n"); |
ryood | 3:8c8020dfd82f | 136 | } |
ryood | 3:8c8020dfd82f | 137 | |
ryood | 3:8c8020dfd82f | 138 | void swWaveFormPressed() |
ryood | 3:8c8020dfd82f | 139 | { |
ryood | 4:d9a72e07749f | 140 | Oscillator.waveForm++; |
ryood | 3:8c8020dfd82f | 141 | isDirty = true; |
ryood | 3:8c8020dfd82f | 142 | printf("swWaveFormPressed\r\n"); |
ryood | 3:8c8020dfd82f | 143 | } |
ryood | 3:8c8020dfd82f | 144 | |
ryood | 4:d9a72e07749f | 145 | // Thread |
ryood | 4:d9a72e07749f | 146 | void ledThread(void const *argument) |
ryood | 4:d9a72e07749f | 147 | { |
ryood | 4:d9a72e07749f | 148 | while (true) { |
ryood | 4:d9a72e07749f | 149 | Led1 = !Led1; |
ryood | 4:d9a72e07749f | 150 | Thread::wait(500); |
ryood | 4:d9a72e07749f | 151 | } |
ryood | 4:d9a72e07749f | 152 | } |
ryood | 4:d9a72e07749f | 153 | |
ryood | 4:d9a72e07749f | 154 | void pollingRotEncs(void const *argument) |
ryood | 3:8c8020dfd82f | 155 | { |
ryood | 4:d9a72e07749f | 156 | while (true) { |
ryood | 4:d9a72e07749f | 157 | int _note = RotEnc1.getVal(); |
ryood | 4:d9a72e07749f | 158 | if (_note != currentNote) { |
ryood | 4:d9a72e07749f | 159 | currentNote = _note; |
ryood | 4:d9a72e07749f | 160 | isDirty = true; |
ryood | 4:d9a72e07749f | 161 | } |
ryood | 4:d9a72e07749f | 162 | int _pitch = RotEnc2.getVal(); |
ryood | 4:d9a72e07749f | 163 | if (_pitch != Sequence[currentNote].pitch) { |
ryood | 4:d9a72e07749f | 164 | Sequence[currentNote].pitch = _pitch; |
ryood | 4:d9a72e07749f | 165 | isDirty = true; |
ryood | 4:d9a72e07749f | 166 | } |
ryood | 4:d9a72e07749f | 167 | Thread::wait(10); |
ryood | 3:8c8020dfd82f | 168 | } |
ryood | 3:8c8020dfd82f | 169 | } |
ryood | 3:8c8020dfd82f | 170 | |
ryood | 4:d9a72e07749f | 171 | void pollingPots(void const *argument) |
ryood | 3:8c8020dfd82f | 172 | { |
ryood | 4:d9a72e07749f | 173 | unsigned short tmp; |
ryood | 4:d9a72e07749f | 174 | |
ryood | 4:d9a72e07749f | 175 | while (true) { |
ryood | 4:d9a72e07749f | 176 | // pulse width |
ryood | 4:d9a72e07749f | 177 | tmp = Pots[0].read_u16() >> 9; // 7bit witdth |
ryood | 4:d9a72e07749f | 178 | if (tmp != Oscillator.pulseWidth) { |
ryood | 4:d9a72e07749f | 179 | Oscillator.pulseWidth = tmp; |
ryood | 4:d9a72e07749f | 180 | isDirty = true; |
ryood | 4:d9a72e07749f | 181 | } |
ryood | 4:d9a72e07749f | 182 | // filter envelope moduration |
ryood | 4:d9a72e07749f | 183 | tmp = Pots[1].read_u16() >> 9; // 7bit witdth |
ryood | 4:d9a72e07749f | 184 | if (tmp != Filter.envMod) { |
ryood | 4:d9a72e07749f | 185 | Filter.envMod = tmp; |
ryood | 4:d9a72e07749f | 186 | isDirty = true; |
ryood | 4:d9a72e07749f | 187 | } |
ryood | 4:d9a72e07749f | 188 | // tempo |
ryood | 4:d9a72e07749f | 189 | tmp = Pots[2].read_u16() >> 9; // 7bit witdth |
ryood | 4:d9a72e07749f | 190 | if (tmp != tempo) { |
ryood | 4:d9a72e07749f | 191 | tempo = tmp; |
ryood | 4:d9a72e07749f | 192 | isDirty = true; |
ryood | 4:d9a72e07749f | 193 | } |
ryood | 4:d9a72e07749f | 194 | // cutoff |
ryood | 4:d9a72e07749f | 195 | tmp = Pots[3].read_u16() >> 10; // 6bit witdth |
ryood | 4:d9a72e07749f | 196 | if (tmp != Filter.cutOff) { |
ryood | 4:d9a72e07749f | 197 | Filter.cutOff = tmp; |
ryood | 4:d9a72e07749f | 198 | isDirty = true; |
ryood | 4:d9a72e07749f | 199 | } |
ryood | 4:d9a72e07749f | 200 | // resonance |
ryood | 4:d9a72e07749f | 201 | tmp = Pots[4].read_u16() >> 10; // 6bit witdth |
ryood | 4:d9a72e07749f | 202 | if (tmp != Filter.resonance) { |
ryood | 4:d9a72e07749f | 203 | Filter.resonance = tmp; |
ryood | 4:d9a72e07749f | 204 | isDirty = true; |
ryood | 4:d9a72e07749f | 205 | } |
ryood | 4:d9a72e07749f | 206 | Thread::wait(20); |
ryood | 4:d9a72e07749f | 207 | } |
ryood | 3:8c8020dfd82f | 208 | } |
ryood | 3:8c8020dfd82f | 209 | |
ryood | 0:468e49a35876 | 210 | int main() |
ryood | 0:468e49a35876 | 211 | { |
ryood | 0:468e49a35876 | 212 | printf("\n\n\r*** RTOS UI Test ***\r\n"); |
ryood | 0:468e49a35876 | 213 | |
ryood | 0:468e49a35876 | 214 | // Init devices |
ryood | 2:8cc6dff1d7fd | 215 | RotEnc1.setInterval(500); |
ryood | 2:8cc6dff1d7fd | 216 | RotEnc2.setInterval(500); |
ryood | 2:8cc6dff1d7fd | 217 | |
ryood | 2:8cc6dff1d7fd | 218 | Pins[0].attach_asserted(&swOctaveUpPressed); |
ryood | 2:8cc6dff1d7fd | 219 | Pins[1].attach_asserted(&swOctaveDownPressed); |
ryood | 2:8cc6dff1d7fd | 220 | Pins[2].attach_asserted(&swNoteOnOffPressed); |
ryood | 2:8cc6dff1d7fd | 221 | Pins[3].attach_asserted(&swTiePressed); |
ryood | 2:8cc6dff1d7fd | 222 | Pins[4].attach_asserted(&swAccentPressed); |
ryood | 3:8c8020dfd82f | 223 | Pins[5].attach_asserted(&swRunStopPressed); |
ryood | 3:8c8020dfd82f | 224 | Pins[6].attach_asserted(&swWaveFormPressed); |
ryood | 3:8c8020dfd82f | 225 | for (int i = 0; i < 7; i++) { |
ryood | 2:8cc6dff1d7fd | 226 | Pins[i].setAssertValue(0); |
ryood | 2:8cc6dff1d7fd | 227 | Pins[i].setSampleFrequency(); |
ryood | 2:8cc6dff1d7fd | 228 | } |
ryood | 0:468e49a35876 | 229 | |
ryood | 0:468e49a35876 | 230 | Lcd.init(); |
ryood | 0:468e49a35876 | 231 | Lcd.normalMode(); // normal colour mode |
ryood | 0:468e49a35876 | 232 | Lcd.setBrightness(0.5); // put LED backlight on 50% |
ryood | 0:468e49a35876 | 233 | |
ryood | 2:8cc6dff1d7fd | 234 | // Thread start |
ryood | 4:d9a72e07749f | 235 | Thread thLed(ledThread, NULL, osPriorityNormal, DEFAULT_STACK_SIZE); |
ryood | 4:d9a72e07749f | 236 | Thread thRotEnc(pollingRotEncs, NULL, osPriorityNormal, DEFAULT_STACK_SIZE); |
ryood | 4:d9a72e07749f | 237 | Thread thPots(pollingPots, NULL, osPriorityNormal, DEFAULT_STACK_SIZE); |
ryood | 0:468e49a35876 | 238 | |
ryood | 0:468e49a35876 | 239 | // Main loop |
ryood | 0:468e49a35876 | 240 | while (true) { |
ryood | 4:d9a72e07749f | 241 | CheckPin = !CheckPin; |
ryood | 0:468e49a35876 | 242 | if (isDirty) { |
ryood | 2:8cc6dff1d7fd | 243 | updateLCD(); |
ryood | 0:468e49a35876 | 244 | isDirty = false; |
ryood | 0:468e49a35876 | 245 | } |
ryood | 0:468e49a35876 | 246 | } |
ryood | 0:468e49a35876 | 247 | } |