Nucleo SPI Sequencer

Dependencies:   AverageAnalogIn N5110 Nucleo_rtos_UI_Test PinDetect RotaryEncoder Sequence mbed-rtos mbed FilterController

Fork of Nucleo_rtos_UI_Test by Ryo Od

Committer:
ryood
Date:
Sun Jun 12 07:13:18 2016 +0000
Revision:
5:e4b68faa6801
Parent:
4:d9a72e07749f
Child:
6:4e089888b809
Nucleo rtos UI Test?SpiSequencerSender???

Who changed what in which revision?

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