Nucleo Sequencer of my Base Machine

Dependencies:   Amp AverageAnalogIn Envelope FilterController Sequence BaseMachineComon mbed-rtos mbed

Fork of SpiSequenceSender_Test by Ryo Od

Committer:
ryood
Date:
Mon Oct 10 05:36:04 2016 +0000
Revision:
39:ed2704cdc7aa
Parent:
38:820cb3a7102b
Child:
40:fd75fb94898b
Remove: UI controll functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ryood 15:9813d8eaf57e 1 /*
ryood 15:9813d8eaf57e 2 * main.cpp
ryood 15:9813d8eaf57e 3 * SpiSequencerSender_test
ryood 15:9813d8eaf57e 4 *
ryood 39:ed2704cdc7aa 5 * 2016.10.10 UIを分離
ryood 15:9813d8eaf57e 6 * 2016.08.20 mbed Rev 121 / mbed-rtos Rev 117で動作確認
ryood 15:9813d8eaf57e 7 *
ryood 15:9813d8eaf57e 8 */
ryood 15:9813d8eaf57e 9
ryood 0:21e39bc75e31 10 #include "mbed.h"
ryood 5:4abac408b827 11 #include "rtos.h"
ryood 39:ed2704cdc7aa 12
ryood 0:21e39bc75e31 13
ryood 6:fc10eac60b91 14 #define UART_TRACE (0)
ryood 6:fc10eac60b91 15 #include "SpiSequenceSender.h"
ryood 9:3e4e08578e1c 16 #include "EnvelopeGenerator.h"
ryood 9:3e4e08578e1c 17 #include "SpiAmpController.h"
ryood 12:c248781608af 18 #include "SpiFilterController.h"
ryood 0:21e39bc75e31 19
ryood 16:b0419e3c9079 20 #define TITLE_STR1 ("BaseMachine Sequencer")
ryood 39:ed2704cdc7aa 21 #define TITLE_STR2 ("20161010")
ryood 16:b0419e3c9079 22
ryood 6:fc10eac60b91 23 #define SEQUENCE_N (16)
ryood 39:ed2704cdc7aa 24 #define SPI1_RATE (10000000)
ryood 39:ed2704cdc7aa 25 #define SPI2_RATE (3000000) // Actual frequency about 2.6MHz
ryood 39:ed2704cdc7aa 26
ryood 39:ed2704cdc7aa 27 enum SequencerCmd {
ryood 39:ed2704cdc7aa 28 CMD_RCV_PLAYING_STEP = 0x01,
ryood 39:ed2704cdc7aa 29 CMD_RUN = 0x11,
ryood 39:ed2704cdc7aa 30 CMD_BPM = 0x12,
ryood 39:ed2704cdc7aa 31 CMD_ACCENT_LEVEL = 0x13,
ryood 39:ed2704cdc7aa 32 CMD_WAVE_SHAPE = 0x21,
ryood 39:ed2704cdc7aa 33 CMD_PULSE_WIDTH = 0x22,
ryood 39:ed2704cdc7aa 34 CMD_CUTOFF = 0x31,
ryood 39:ed2704cdc7aa 35 CMD_RESONANCE = 0x32,
ryood 39:ed2704cdc7aa 36 CMD_LEVEL = 0x41,
ryood 39:ed2704cdc7aa 37 CMD_DURATION = 0x42,
ryood 39:ed2704cdc7aa 38 CMD_DECAY = 0x43,
ryood 39:ed2704cdc7aa 39 CMD_SUSTAIN = 0x44,
ryood 39:ed2704cdc7aa 40 CMD_NOTE = 0x51,
ryood 39:ed2704cdc7aa 41 CMD_PITCH = 0x52,
ryood 39:ed2704cdc7aa 42 };
ryood 0:21e39bc75e31 43
ryood 14:c173e03ee3ad 44 const int samplingPeriod = 1; // ms
ryood 10:fb04f9959fd9 45 const int bpm = 120;
ryood 10:fb04f9959fd9 46 const int envelopeLength = (60 * 1000 / (bpm * 4)) / samplingPeriod;
ryood 20:00d3b6ace8c7 47 const int waveShape = SpiSequenceSender::WAVESHAPE_SQUARE;
ryood 20:00d3b6ace8c7 48 const int baseNoteNumber = 36;
ryood 14:c173e03ee3ad 49
ryood 14:c173e03ee3ad 50 // Initial Sequence
ryood 26:fbf48a178aeb 51 const int noteOn[SEQUENCE_N] = { 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0 };
ryood 26:fbf48a178aeb 52 const int pitch[SEQUENCE_N] = {36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36 };
ryood 26:fbf48a178aeb 53 const int tie[SEQUENCE_N] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
ryood 26:fbf48a178aeb 54 const int accent[SEQUENCE_N] = { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 };
ryood 10:fb04f9959fd9 55
ryood 16:b0419e3c9079 56 // Devices
ryood 16:b0419e3c9079 57 //
ryood 39:ed2704cdc7aa 58 //SPI1 (PinName mosi, PinName miso, PinName sclk, PinName ssel=NC)
ryood 39:ed2704cdc7aa 59 SPI SpiMaster(PA_7, PA_6, PA_5);
ryood 10:fb04f9959fd9 60
ryood 39:ed2704cdc7aa 61 //SPI2 (PinName mosi, PinName miso, PinName sclk, PinName ssel)
ryood 39:ed2704cdc7aa 62 SPISlave SpiSlave(PB_15, PB_14, PB_13, PB_12);
ryood 39:ed2704cdc7aa 63 DigitalOut StepChangePin(PB_1);
ryood 20:00d3b6ace8c7 64
ryood 39:ed2704cdc7aa 65 BusOut Leds(PA_0, PA_1, PA_4, PB_0, PC_1, PC_0, PA_10, PB_3);
ryood 34:602ee5e771e3 66
ryood 16:b0419e3c9079 67 // Grobal Variables
ryood 16:b0419e3c9079 68 //
ryood 16:b0419e3c9079 69 Sequence sequences[SEQUENCE_N];
ryood 39:ed2704cdc7aa 70 SpiSequenceSender sequenceSender(&SpiMaster, D9, sequences, SEQUENCE_N, samplingPeriod, bpm);
ryood 6:fc10eac60b91 71
ryood 10:fb04f9959fd9 72 Envelope envelope(4095, envelopeLength, envelopeLength*3/4, envelopeLength/2, 2047);
ryood 9:3e4e08578e1c 73 EnvelopeGenerator envelopeGenerator;
ryood 39:ed2704cdc7aa 74 SpiAmpController ampController(&SpiMaster, D8, D7);
ryood 17:557658db3e81 75
ryood 39:ed2704cdc7aa 76 SpiFilterController filterController(&SpiMaster, D10);
ryood 16:b0419e3c9079 77
ryood 39:ed2704cdc7aa 78 int playingStep = 0;
ryood 39:ed2704cdc7aa 79 int editingStep = 0;
ryood 39:ed2704cdc7aa 80 bool isRunning = false;
ryood 16:b0419e3c9079 81
ryood 16:b0419e3c9079 82 //------------------------------------------------------------------------
ryood 16:b0419e3c9079 83 // Callback functions
ryood 16:b0419e3c9079 84 //------------------------------------------------------------------------
ryood 35:0165b610796d 85 void updateTicks(int ticks)
ryood 8:de409197ff95 86 {
ryood 8:de409197ff95 87 if (ticks == 0) {
ryood 9:3e4e08578e1c 88 envelopeGenerator.init(envelope);
ryood 36:50ad7e0a9a95 89 playingStep = sequenceSender.getStep();
ryood 39:ed2704cdc7aa 90 // Masterにinterruptをかける。
ryood 39:ed2704cdc7aa 91 StepChangePin.write(1);
ryood 39:ed2704cdc7aa 92 StepChangePin.write(0);
ryood 8:de409197ff95 93 }
ryood 14:c173e03ee3ad 94
ryood 27:c382689e652b 95 if (sequences[sequenceSender.getStep()].isNoteOn()) {
ryood 14:c173e03ee3ad 96 uint16_t level = envelopeGenerator.getModLevel();
ryood 27:c382689e652b 97 if (!sequences[sequenceSender.getStep()].isAccent()) {
ryood 35:0165b610796d 98 level = level * 1 / 2;
ryood 27:c382689e652b 99 }
ryood 14:c173e03ee3ad 100 ampController.outDca(level);
ryood 14:c173e03ee3ad 101 } else {
ryood 14:c173e03ee3ad 102 ampController.outDca(0);
ryood 14:c173e03ee3ad 103 }
ryood 9:3e4e08578e1c 104 envelopeGenerator.update();
ryood 12:c248781608af 105
ryood 15:9813d8eaf57e 106 filterController.outDcf();
ryood 8:de409197ff95 107 }
ryood 8:de409197ff95 108
ryood 16:b0419e3c9079 109 //------------------------------------------------------------------------
ryood 16:b0419e3c9079 110 // Functions
ryood 16:b0419e3c9079 111 //------------------------------------------------------------------------
ryood 20:00d3b6ace8c7 112
ryood 39:ed2704cdc7aa 113 void spiSlaveRecieve()
ryood 18:309f794eba74 114 {
ryood 39:ed2704cdc7aa 115 if (SpiSlave.receive()) {
ryood 39:ed2704cdc7aa 116 SpiSlave.reply(playingStep);
ryood 39:ed2704cdc7aa 117 uint16_t recievedVal = SpiSlave.read();
ryood 39:ed2704cdc7aa 118 uint8_t cmd = recievedVal >> 8;
ryood 39:ed2704cdc7aa 119 uint8_t data = recievedVal & 0xff;
ryood 39:ed2704cdc7aa 120 switch(cmd) {
ryood 39:ed2704cdc7aa 121 case CMD_RCV_PLAYING_STEP:
ryood 39:ed2704cdc7aa 122 // Do nothing
ryood 39:ed2704cdc7aa 123 break;
ryood 39:ed2704cdc7aa 124 case CMD_RUN:
ryood 39:ed2704cdc7aa 125 if (data == 0) {
ryood 39:ed2704cdc7aa 126 ampController.outDca(0);
ryood 39:ed2704cdc7aa 127 sequenceSender.stop();
ryood 39:ed2704cdc7aa 128 isRunning = false;
ryood 39:ed2704cdc7aa 129 }
ryood 39:ed2704cdc7aa 130 else {
ryood 39:ed2704cdc7aa 131 sequenceSender.run(playingStep);
ryood 39:ed2704cdc7aa 132 isRunning = true;
ryood 39:ed2704cdc7aa 133 }
ryood 39:ed2704cdc7aa 134 break;
ryood 39:ed2704cdc7aa 135 case CMD_BPM:
ryood 39:ed2704cdc7aa 136 sequenceSender.setBpm(data);
ryood 39:ed2704cdc7aa 137 break;
ryood 39:ed2704cdc7aa 138 case CMD_ACCENT_LEVEL:
ryood 39:ed2704cdc7aa 139 // ToDo: Impl. accentLevel
ryood 39:ed2704cdc7aa 140 break;
ryood 39:ed2704cdc7aa 141 case CMD_WAVE_SHAPE:
ryood 39:ed2704cdc7aa 142 // ToDo: SequenceSender::WaveShapeとdataの値を合わせる。
ryood 39:ed2704cdc7aa 143 Leds.write(data);
ryood 39:ed2704cdc7aa 144 if (data == 0) {
ryood 39:ed2704cdc7aa 145 sequenceSender.setWaveShape(SpiSequenceSender::WAVESHAPE_SQUARE);
ryood 39:ed2704cdc7aa 146 }
ryood 39:ed2704cdc7aa 147 else if (data == 1) {
ryood 39:ed2704cdc7aa 148 sequenceSender.setWaveShape(SpiSequenceSender::WAVESHAPE_SAW);
ryood 39:ed2704cdc7aa 149 }
ryood 39:ed2704cdc7aa 150 break;
ryood 39:ed2704cdc7aa 151 case CMD_PULSE_WIDTH:
ryood 39:ed2704cdc7aa 152 sequenceSender.setPulseWidth(data << 1);
ryood 39:ed2704cdc7aa 153 break;
ryood 39:ed2704cdc7aa 154 case CMD_CUTOFF:
ryood 39:ed2704cdc7aa 155 filterController.setCutoff(data << 1);
ryood 39:ed2704cdc7aa 156 break;
ryood 39:ed2704cdc7aa 157 case CMD_RESONANCE:
ryood 39:ed2704cdc7aa 158 filterController.setResonance(data << 1);
ryood 39:ed2704cdc7aa 159 break;
ryood 39:ed2704cdc7aa 160 case CMD_LEVEL:
ryood 39:ed2704cdc7aa 161 envelope.setLevel(data << 5);
ryood 39:ed2704cdc7aa 162 break;
ryood 39:ed2704cdc7aa 163 case CMD_DURATION:
ryood 39:ed2704cdc7aa 164 envelope.setDuration((float)data / 128.0f * envelopeLength);
ryood 39:ed2704cdc7aa 165 break;
ryood 39:ed2704cdc7aa 166 case CMD_DECAY:
ryood 39:ed2704cdc7aa 167 envelope.setDecay((float)data / 128.0f * envelopeLength);
ryood 39:ed2704cdc7aa 168 break;
ryood 39:ed2704cdc7aa 169 case CMD_SUSTAIN:
ryood 39:ed2704cdc7aa 170 envelope.setSustain(data << 5);
ryood 39:ed2704cdc7aa 171 break;
ryood 39:ed2704cdc7aa 172 case CMD_NOTE:
ryood 39:ed2704cdc7aa 173 editingStep = data >> 4;
ryood 39:ed2704cdc7aa 174 sequences[editingStep].setNoteOn(data & 0x01);
ryood 39:ed2704cdc7aa 175 sequences[editingStep].setTie((data & 0x02) >> 1);
ryood 39:ed2704cdc7aa 176 sequences[editingStep].setAccent((data & 0x04) >> 2);
ryood 39:ed2704cdc7aa 177 break;
ryood 39:ed2704cdc7aa 178 case CMD_PITCH:
ryood 39:ed2704cdc7aa 179 sequences[editingStep].setPitch(data);
ryood 39:ed2704cdc7aa 180 break;
ryood 39:ed2704cdc7aa 181 default:
ryood 39:ed2704cdc7aa 182 Leds.write(cmd);
ryood 39:ed2704cdc7aa 183 error("invalid SPI cmd");
ryood 18:309f794eba74 184 }
ryood 18:309f794eba74 185 }
ryood 28:d8614d2b82f9 186 }
ryood 28:d8614d2b82f9 187
ryood 16:b0419e3c9079 188 //------------------------------------------------------------------------
ryood 16:b0419e3c9079 189 // Main routine
ryood 16:b0419e3c9079 190 //------------------------------------------------------------------------
ryood 0:21e39bc75e31 191 int main()
ryood 0:21e39bc75e31 192 {
ryood 18:309f794eba74 193 #if (UART_TRACE)
ryood 18:309f794eba74 194 printf("*** BaseMachine Sequencer ***\r\n");
ryood 18:309f794eba74 195 #endif
ryood 18:309f794eba74 196
ryood 39:ed2704cdc7aa 197 // Check LED
ryood 39:ed2704cdc7aa 198 for (int i = 0; i < 8; i++) {
ryood 39:ed2704cdc7aa 199 Leds[i].write(1);
ryood 39:ed2704cdc7aa 200 Thread::wait(500);
ryood 39:ed2704cdc7aa 201 }
ryood 39:ed2704cdc7aa 202 Leds.write(0x00);
ryood 39:ed2704cdc7aa 203
ryood 24:040cdcb2ff14 204 //--------------------------------------------------------------------
ryood 16:b0419e3c9079 205 // Setup Devices
ryood 16:b0419e3c9079 206 //
ryood 39:ed2704cdc7aa 207 SpiMaster.format(8, 0);
ryood 39:ed2704cdc7aa 208 SpiMaster.frequency(SPI1_RATE);
ryood 39:ed2704cdc7aa 209
ryood 39:ed2704cdc7aa 210 SpiSlave.format(16, 0);
ryood 39:ed2704cdc7aa 211 SpiSlave.frequency(SPI2_RATE);
ryood 0:21e39bc75e31 212
ryood 24:040cdcb2ff14 213 // Mute output
ryood 24:040cdcb2ff14 214 ampController.outDca(0);
ryood 24:040cdcb2ff14 215
ryood 24:040cdcb2ff14 216 //--------------------------------------------------------------------
ryood 22:82f1e7877f9f 217 // Initialize objects
ryood 0:21e39bc75e31 218 //
ryood 15:9813d8eaf57e 219 Sequence::setBaseNoteNumber(baseNoteNumber);
ryood 14:c173e03ee3ad 220
ryood 0:21e39bc75e31 221 for (int i = 0; i < SEQUENCE_N; i++) {
ryood 0:21e39bc75e31 222 Sequence& seq = sequenceSender.getSequences()[i];
ryood 14:c173e03ee3ad 223 seq.setPitch(pitch[i]);
ryood 15:9813d8eaf57e 224 seq.setNoteOn(noteOn[i]);
ryood 15:9813d8eaf57e 225 seq.setTie(tie[i]);
ryood 26:fbf48a178aeb 226 seq.setAccent(accent[i]);
ryood 0:21e39bc75e31 227 }
ryood 6:fc10eac60b91 228
ryood 9:3e4e08578e1c 229 envelopeGenerator.init(envelope);
ryood 12:c248781608af 230
ryood 35:0165b610796d 231 sequenceSender.attachUpdate(&updateTicks);
ryood 14:c173e03ee3ad 232 sequenceSender.setWaveShape(waveShape);
ryood 5:4abac408b827 233
ryood 24:040cdcb2ff14 234 //--------------------------------------------------------------------
ryood 24:040cdcb2ff14 235 // Main loop
ryood 24:040cdcb2ff14 236 //
ryood 5:4abac408b827 237 for (;;) {
ryood 39:ed2704cdc7aa 238 spiSlaveRecieve();
ryood 5:4abac408b827 239 }
ryood 39:ed2704cdc7aa 240
ryood 0:21e39bc75e31 241 }