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:
Tue Jun 21 09:31:01 2016 +0000
Revision:
11:3aab82f74a75
Parent:
10:28082577ed5f
VCVS DCF??????FilterController???

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