KAMUI USB MIDI-CV Example

Dependencies:   TextLCD mbed

Committer:
radiojunkbox
Date:
Sat May 05 11:36:56 2012 +0000
Revision:
0:9ddbc6e0cd90
Rev. 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
radiojunkbox 0:9ddbc6e0cd90 1 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 2 // KAMUI USBMIDI-CV Exapmple
radiojunkbox 0:9ddbc6e0cd90 3 // Copyright (C) 2012 RJB RadioJunkBox
radiojunkbox 0:9ddbc6e0cd90 4 // Released under the MIT License: http://mbed.org/license/mit
radiojunkbox 0:9ddbc6e0cd90 5 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 6
radiojunkbox 0:9ddbc6e0cd90 7 #include "mbed.h"
radiojunkbox 0:9ddbc6e0cd90 8 #include "TextLCD.h"
radiojunkbox 0:9ddbc6e0cd90 9 #include "USBMIDI.h"
radiojunkbox 0:9ddbc6e0cd90 10 #include <stdlib.h>
radiojunkbox 0:9ddbc6e0cd90 11 #include <math.h>
radiojunkbox 0:9ddbc6e0cd90 12
radiojunkbox 0:9ddbc6e0cd90 13 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 14 // Define
radiojunkbox 0:9ddbc6e0cd90 15
radiojunkbox 0:9ddbc6e0cd90 16 #define AD5551 // 14bitDAC
radiojunkbox 0:9ddbc6e0cd90 17
radiojunkbox 0:9ddbc6e0cd90 18 #define SPI_RATE 1000000 // 1Mbps
radiojunkbox 0:9ddbc6e0cd90 19 #define MIDI_RATE 31250 // 31.25kbps
radiojunkbox 0:9ddbc6e0cd90 20 #define BEEP_FREQ 1760.0 // 1760Hz
radiojunkbox 0:9ddbc6e0cd90 21 #define UPDATE_INTERVAL 100 // 100us
radiojunkbox 0:9ddbc6e0cd90 22 #define SW_WATCH_INTERVAL (25000/UPDATE_INTERVAL) // 25ms
radiojunkbox 0:9ddbc6e0cd90 23 #define PARAM_GLIDE 6554.0
radiojunkbox 0:9ddbc6e0cd90 24 #define PARAM_DP 6912.0 // UPDATE_INTERVAL = 100us
radiojunkbox 0:9ddbc6e0cd90 25 //#define PARAM_DP 8192.0 // UPDATE_INTERVAL = 50us
radiojunkbox 0:9ddbc6e0cd90 26
radiojunkbox 0:9ddbc6e0cd90 27 #define UPDATE_MODE0 0 // Update Interval CV ch1-6 1200us, ch7,8 400us
radiojunkbox 0:9ddbc6e0cd90 28 #define UPDATE_MODE1 1 // Update Interval CV ch1-6 N/A, ch7,8 200us
radiojunkbox 0:9ddbc6e0cd90 29
radiojunkbox 0:9ddbc6e0cd90 30 #define GATE1 0x01
radiojunkbox 0:9ddbc6e0cd90 31 #define GATE2 0x02
radiojunkbox 0:9ddbc6e0cd90 32 #define GATE3 0x04
radiojunkbox 0:9ddbc6e0cd90 33 #define GATE4 0x08
radiojunkbox 0:9ddbc6e0cd90 34 #define GATE_LED5 0x10
radiojunkbox 0:9ddbc6e0cd90 35
radiojunkbox 0:9ddbc6e0cd90 36 #define SYNC1CLK 0x01
radiojunkbox 0:9ddbc6e0cd90 37 #define SYNC1RUN 0x02
radiojunkbox 0:9ddbc6e0cd90 38 #define SYNC2CLK 0x04
radiojunkbox 0:9ddbc6e0cd90 39 #define SYNC2RUN 0x08
radiojunkbox 0:9ddbc6e0cd90 40
radiojunkbox 0:9ddbc6e0cd90 41 #define MODE_CV 0x00
radiojunkbox 0:9ddbc6e0cd90 42 #define MODE_GATE 0x40
radiojunkbox 0:9ddbc6e0cd90 43 #define MODE_SYNC 0x80
radiojunkbox 0:9ddbc6e0cd90 44 #define MODE_SET_SYNC 0xC0
radiojunkbox 0:9ddbc6e0cd90 45
radiojunkbox 0:9ddbc6e0cd90 46 #define SW1 0x01
radiojunkbox 0:9ddbc6e0cd90 47 #define SW2 0x02
radiojunkbox 0:9ddbc6e0cd90 48 #define SW3 0x04
radiojunkbox 0:9ddbc6e0cd90 49 #define SW4 0x08
radiojunkbox 0:9ddbc6e0cd90 50 #define SYNC1CLK_IN 0x10
radiojunkbox 0:9ddbc6e0cd90 51 #define SYNC1RUN_IN 0x20
radiojunkbox 0:9ddbc6e0cd90 52 #define SYNC2CLK_IN 0x40
radiojunkbox 0:9ddbc6e0cd90 53 #define GATE_IN 0x80
radiojunkbox 0:9ddbc6e0cd90 54
radiojunkbox 0:9ddbc6e0cd90 55 #define _ENABLE 0
radiojunkbox 0:9ddbc6e0cd90 56 #define _DISABLE 1
radiojunkbox 0:9ddbc6e0cd90 57
radiojunkbox 0:9ddbc6e0cd90 58 #define BUFSIZE 32 // size of ring buffer (ex 4,8,16,32...)
radiojunkbox 0:9ddbc6e0cd90 59 #define LFO_WF_TRI 0
radiojunkbox 0:9ddbc6e0cd90 60 #define LFO_WF_SQR 1
radiojunkbox 0:9ddbc6e0cd90 61 #define LFO_WF_SAW 2
radiojunkbox 0:9ddbc6e0cd90 62 #define LFO_WF_NONE 3
radiojunkbox 0:9ddbc6e0cd90 63 #define MINIMUMNOTE 12
radiojunkbox 0:9ddbc6e0cd90 64 #define SYNC_TURN_TIME (5000/UPDATE_INTERVAL) // 5ms
radiojunkbox 0:9ddbc6e0cd90 65
radiojunkbox 0:9ddbc6e0cd90 66 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 67 // Functions
radiojunkbox 0:9ddbc6e0cd90 68
radiojunkbox 0:9ddbc6e0cd90 69 void InitKamui(void);
radiojunkbox 0:9ddbc6e0cd90 70 void UpdateCV(void);
radiojunkbox 0:9ddbc6e0cd90 71 unsigned char CheckSW(unsigned char);
radiojunkbox 0:9ddbc6e0cd90 72
radiojunkbox 0:9ddbc6e0cd90 73 void RcvMIDI(void);
radiojunkbox 0:9ddbc6e0cd90 74 void RcvUSBMIDI(MIDIMessage);
radiojunkbox 0:9ddbc6e0cd90 75 void MidiCV(void);
radiojunkbox 0:9ddbc6e0cd90 76 void CalcHzVTbl(void);
radiojunkbox 0:9ddbc6e0cd90 77 unsigned short OctVtoHzV(unsigned short);
radiojunkbox 0:9ddbc6e0cd90 78 void DinSync(void);
radiojunkbox 0:9ddbc6e0cd90 79 extern void MIDI_Parser(unsigned char);
radiojunkbox 0:9ddbc6e0cd90 80
radiojunkbox 0:9ddbc6e0cd90 81 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 82 // Global Variables
radiojunkbox 0:9ddbc6e0cd90 83
radiojunkbox 0:9ddbc6e0cd90 84 int gUpdateMode;
radiojunkbox 0:9ddbc6e0cd90 85 unsigned short gCV[8];
radiojunkbox 0:9ddbc6e0cd90 86 unsigned char gGATE;
radiojunkbox 0:9ddbc6e0cd90 87 unsigned char gSYNC;
radiojunkbox 0:9ddbc6e0cd90 88 unsigned char gSW;
radiojunkbox 0:9ddbc6e0cd90 89
radiojunkbox 0:9ddbc6e0cd90 90 union {
radiojunkbox 0:9ddbc6e0cd90 91 unsigned short WORD;
radiojunkbox 0:9ddbc6e0cd90 92 struct {
radiojunkbox 0:9ddbc6e0cd90 93 unsigned char L;
radiojunkbox 0:9ddbc6e0cd90 94 unsigned char H;
radiojunkbox 0:9ddbc6e0cd90 95 } BYTE;
radiojunkbox 0:9ddbc6e0cd90 96 } gDAC;
radiojunkbox 0:9ddbc6e0cd90 97
radiojunkbox 0:9ddbc6e0cd90 98 int gPtr_buf_in, gPtr_buf_out;
radiojunkbox 0:9ddbc6e0cd90 99 unsigned char gRxBuf[BUFSIZE];
radiojunkbox 0:9ddbc6e0cd90 100
radiojunkbox 0:9ddbc6e0cd90 101 float gGLIDE[4];
radiojunkbox 0:9ddbc6e0cd90 102 unsigned short gLFO_DP[4];
radiojunkbox 0:9ddbc6e0cd90 103 unsigned char gLFO_FORM[4];
radiojunkbox 0:9ddbc6e0cd90 104 unsigned char gMIDI_CH[4];
radiojunkbox 0:9ddbc6e0cd90 105 short gTblHzV[3072];
radiojunkbox 0:9ddbc6e0cd90 106
radiojunkbox 0:9ddbc6e0cd90 107 extern unsigned char gPlayNoteBuf[];
radiojunkbox 0:9ddbc6e0cd90 108 extern unsigned char gGateBuf[];
radiojunkbox 0:9ddbc6e0cd90 109 extern unsigned char gPitchBendBuf[];
radiojunkbox 0:9ddbc6e0cd90 110 extern unsigned char gModWheelBuf[];
radiojunkbox 0:9ddbc6e0cd90 111 extern unsigned char gMIDISYNC_CLK;
radiojunkbox 0:9ddbc6e0cd90 112 extern unsigned char gMIDISYNC_RUN;
radiojunkbox 0:9ddbc6e0cd90 113
radiojunkbox 0:9ddbc6e0cd90 114 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 115 // mbed Functions
radiojunkbox 0:9ddbc6e0cd90 116
radiojunkbox 0:9ddbc6e0cd90 117 // TextLCD
radiojunkbox 0:9ddbc6e0cd90 118 TextLCD gLCD(p23, p24, p25, p26, p29, p30); // rs, e, d4-d7
radiojunkbox 0:9ddbc6e0cd90 119
radiojunkbox 0:9ddbc6e0cd90 120 // SPI
radiojunkbox 0:9ddbc6e0cd90 121 SPI gSPI(p11,p12,p13);
radiojunkbox 0:9ddbc6e0cd90 122 DigitalOut gCSA(p14);
radiojunkbox 0:9ddbc6e0cd90 123 DigitalOut gCSB(p22);
radiojunkbox 0:9ddbc6e0cd90 124
radiojunkbox 0:9ddbc6e0cd90 125 // Sirial MIDI
radiojunkbox 0:9ddbc6e0cd90 126 // Serial gMIDI(p9,p10);
radiojunkbox 0:9ddbc6e0cd90 127
radiojunkbox 0:9ddbc6e0cd90 128 // AnalogIn
radiojunkbox 0:9ddbc6e0cd90 129 AnalogIn gAIN1(p15); // VR1
radiojunkbox 0:9ddbc6e0cd90 130 AnalogIn gAIN2(p16); // VR2
radiojunkbox 0:9ddbc6e0cd90 131 AnalogIn gAIN3(p17); // VR3
radiojunkbox 0:9ddbc6e0cd90 132 AnalogIn gAIN4(p18); // VR4
radiojunkbox 0:9ddbc6e0cd90 133 AnalogIn gAIN5(p19); // IN1
radiojunkbox 0:9ddbc6e0cd90 134 AnalogIn gAIN6(p20); // IN2
radiojunkbox 0:9ddbc6e0cd90 135
radiojunkbox 0:9ddbc6e0cd90 136 // BEEP
radiojunkbox 0:9ddbc6e0cd90 137 PwmOut gBEEP(p21);
radiojunkbox 0:9ddbc6e0cd90 138
radiojunkbox 0:9ddbc6e0cd90 139 // LED
radiojunkbox 0:9ddbc6e0cd90 140 DigitalOut gLED1(LED1);
radiojunkbox 0:9ddbc6e0cd90 141 DigitalOut gLED2(LED2);
radiojunkbox 0:9ddbc6e0cd90 142 DigitalOut gLED3(LED3);
radiojunkbox 0:9ddbc6e0cd90 143 DigitalOut gLED4(LED4);
radiojunkbox 0:9ddbc6e0cd90 144 BusOut gLEDS(LED1,LED2,LED3,LED4);
radiojunkbox 0:9ddbc6e0cd90 145
radiojunkbox 0:9ddbc6e0cd90 146 // Ticker
radiojunkbox 0:9ddbc6e0cd90 147 Ticker gTICKER;
radiojunkbox 0:9ddbc6e0cd90 148
radiojunkbox 0:9ddbc6e0cd90 149 //USBMIDI object
radiojunkbox 0:9ddbc6e0cd90 150 USBMIDI gUSBMIDI;
radiojunkbox 0:9ddbc6e0cd90 151
radiojunkbox 0:9ddbc6e0cd90 152 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 153 // main
radiojunkbox 0:9ddbc6e0cd90 154
radiojunkbox 0:9ddbc6e0cd90 155 int main() {
radiojunkbox 0:9ddbc6e0cd90 156
radiojunkbox 0:9ddbc6e0cd90 157 int i;
radiojunkbox 0:9ddbc6e0cd90 158 int pot[4],_pot[4];
radiojunkbox 0:9ddbc6e0cd90 159 unsigned char rb;
radiojunkbox 0:9ddbc6e0cd90 160 unsigned char ch = 0;
radiojunkbox 0:9ddbc6e0cd90 161 unsigned char mode = 7; // for Intialize
radiojunkbox 0:9ddbc6e0cd90 162 unsigned char edit[4];
radiojunkbox 0:9ddbc6e0cd90 163 int val[2][4] = { 0, 0, 0, 0, 50, 50, 50, 50 };
radiojunkbox 0:9ddbc6e0cd90 164 char *wave[4] = { "TR","SQ","SW","--" };
radiojunkbox 0:9ddbc6e0cd90 165
radiojunkbox 0:9ddbc6e0cd90 166 // Initialize
radiojunkbox 0:9ddbc6e0cd90 167 gPtr_buf_in = gPtr_buf_out = 0;
radiojunkbox 0:9ddbc6e0cd90 168 for( i=0; i<4; i++) {
radiojunkbox 0:9ddbc6e0cd90 169 pot[i] = _pot[i] = 0;
radiojunkbox 0:9ddbc6e0cd90 170 edit[i] = 0;
radiojunkbox 0:9ddbc6e0cd90 171 gGLIDE[i] = 1.0 / expf(val[0][i]*656.0/PARAM_GLIDE);
radiojunkbox 0:9ddbc6e0cd90 172 gLFO_DP[i] = expf(val[1][i]*656.0/PARAM_DP);
radiojunkbox 0:9ddbc6e0cd90 173 gLFO_FORM[i] = LFO_WF_TRI;
radiojunkbox 0:9ddbc6e0cd90 174 gMIDI_CH[i] = i;
radiojunkbox 0:9ddbc6e0cd90 175 }
radiojunkbox 0:9ddbc6e0cd90 176
radiojunkbox 0:9ddbc6e0cd90 177 for( i=0; i<16; i++) { // MIDI Data Buffers
radiojunkbox 0:9ddbc6e0cd90 178 gPlayNoteBuf[i] =24;
radiojunkbox 0:9ddbc6e0cd90 179 gGateBuf[i] = 0;
radiojunkbox 0:9ddbc6e0cd90 180 gPitchBendBuf[i] = 0x40;
radiojunkbox 0:9ddbc6e0cd90 181 gModWheelBuf[i] = 0;
radiojunkbox 0:9ddbc6e0cd90 182 }
radiojunkbox 0:9ddbc6e0cd90 183
radiojunkbox 0:9ddbc6e0cd90 184 gSW = 1; // for Intialize
radiojunkbox 0:9ddbc6e0cd90 185
radiojunkbox 0:9ddbc6e0cd90 186 CalcHzVTbl();
radiojunkbox 0:9ddbc6e0cd90 187 InitKamui();
radiojunkbox 0:9ddbc6e0cd90 188
radiojunkbox 0:9ddbc6e0cd90 189 // loop
radiojunkbox 0:9ddbc6e0cd90 190 while(1) {
radiojunkbox 0:9ddbc6e0cd90 191
radiojunkbox 0:9ddbc6e0cd90 192 // ring buffer empty?
radiojunkbox 0:9ddbc6e0cd90 193 if(gPtr_buf_in != gPtr_buf_out) {
radiojunkbox 0:9ddbc6e0cd90 194
radiojunkbox 0:9ddbc6e0cd90 195 // get 1byte from ring buffer
radiojunkbox 0:9ddbc6e0cd90 196 gPtr_buf_out++;
radiojunkbox 0:9ddbc6e0cd90 197 gPtr_buf_out &= (BUFSIZE - 1);
radiojunkbox 0:9ddbc6e0cd90 198 rb = gRxBuf[gPtr_buf_out];
radiojunkbox 0:9ddbc6e0cd90 199 MIDI_Parser(rb);
radiojunkbox 0:9ddbc6e0cd90 200 continue;
radiojunkbox 0:9ddbc6e0cd90 201 }
radiojunkbox 0:9ddbc6e0cd90 202
radiojunkbox 0:9ddbc6e0cd90 203 // Read pot
radiojunkbox 0:9ddbc6e0cd90 204 pot[0] = gAIN1.read_u16();
radiojunkbox 0:9ddbc6e0cd90 205 pot[1] = gAIN2.read_u16();
radiojunkbox 0:9ddbc6e0cd90 206 pot[2] = gAIN3.read_u16();
radiojunkbox 0:9ddbc6e0cd90 207 pot[3] = gAIN4.read_u16();
radiojunkbox 0:9ddbc6e0cd90 208
radiojunkbox 0:9ddbc6e0cd90 209 // change pot amount?
radiojunkbox 0:9ddbc6e0cd90 210 if(abs(pot[ch] - _pot[ch]) > 0x2000) edit[ch] = 1;
radiojunkbox 0:9ddbc6e0cd90 211
radiojunkbox 0:9ddbc6e0cd90 212 if(edit[ch]) {
radiojunkbox 0:9ddbc6e0cd90 213 switch(mode) {
radiojunkbox 0:9ddbc6e0cd90 214 case 0:
radiojunkbox 0:9ddbc6e0cd90 215 gGLIDE[ch] = 1.0 / expf(pot[ch]/PARAM_GLIDE);
radiojunkbox 0:9ddbc6e0cd90 216 val[0][ch] = pot[ch] / 656;
radiojunkbox 0:9ddbc6e0cd90 217 break;
radiojunkbox 0:9ddbc6e0cd90 218 case 1:
radiojunkbox 0:9ddbc6e0cd90 219 gLFO_DP[ch] = expf(pot[ch]/PARAM_DP);
radiojunkbox 0:9ddbc6e0cd90 220 val[1][ch] = pot[ch] / 656;
radiojunkbox 0:9ddbc6e0cd90 221 break;
radiojunkbox 0:9ddbc6e0cd90 222 case 2:
radiojunkbox 0:9ddbc6e0cd90 223 gLFO_FORM[ch] = pot[ch] / 0x4000;
radiojunkbox 0:9ddbc6e0cd90 224 break;
radiojunkbox 0:9ddbc6e0cd90 225 case 3:
radiojunkbox 0:9ddbc6e0cd90 226 gMIDI_CH[ch] = pot[ch] / 0x1000;
radiojunkbox 0:9ddbc6e0cd90 227 break;
radiojunkbox 0:9ddbc6e0cd90 228 default:
radiojunkbox 0:9ddbc6e0cd90 229 break;
radiojunkbox 0:9ddbc6e0cd90 230 }
radiojunkbox 0:9ddbc6e0cd90 231 }
radiojunkbox 0:9ddbc6e0cd90 232
radiojunkbox 0:9ddbc6e0cd90 233 // Push Mode SW
radiojunkbox 0:9ddbc6e0cd90 234 if(gSW & SW1) {
radiojunkbox 0:9ddbc6e0cd90 235 mode++;
radiojunkbox 0:9ddbc6e0cd90 236 mode &= 0x03;
radiojunkbox 0:9ddbc6e0cd90 237 for( i=0; i<4; i++) {
radiojunkbox 0:9ddbc6e0cd90 238 _pot[i] = pot[i];
radiojunkbox 0:9ddbc6e0cd90 239 edit[i] = 0;
radiojunkbox 0:9ddbc6e0cd90 240 }
radiojunkbox 0:9ddbc6e0cd90 241 }
radiojunkbox 0:9ddbc6e0cd90 242 gSW = 0;
radiojunkbox 0:9ddbc6e0cd90 243
radiojunkbox 0:9ddbc6e0cd90 244 // LCD Display
radiojunkbox 0:9ddbc6e0cd90 245 gLCD.locate( 0, 1 );
radiojunkbox 0:9ddbc6e0cd90 246 switch(mode) {
radiojunkbox 0:9ddbc6e0cd90 247 case 0:
radiojunkbox 0:9ddbc6e0cd90 248 gLCD.printf("GLID %02d %02d %02d %02d",
radiojunkbox 0:9ddbc6e0cd90 249 val[0][0], val[0][1], val[0][2], val[0][3]);
radiojunkbox 0:9ddbc6e0cd90 250 break;
radiojunkbox 0:9ddbc6e0cd90 251 case 1:
radiojunkbox 0:9ddbc6e0cd90 252 gLCD.printf("FREQ %02d %02d %02d %02d",
radiojunkbox 0:9ddbc6e0cd90 253 val[1][0], val[1][1], val[1][2], val[1][3]);
radiojunkbox 0:9ddbc6e0cd90 254 break;
radiojunkbox 0:9ddbc6e0cd90 255 case 2:
radiojunkbox 0:9ddbc6e0cd90 256 gLCD.printf("FORM %s %s %s %s",
radiojunkbox 0:9ddbc6e0cd90 257 wave[gLFO_FORM[0]], wave[gLFO_FORM[1]],
radiojunkbox 0:9ddbc6e0cd90 258 wave[gLFO_FORM[2]], wave[gLFO_FORM[3]]);
radiojunkbox 0:9ddbc6e0cd90 259 break;
radiojunkbox 0:9ddbc6e0cd90 260 case 3:
radiojunkbox 0:9ddbc6e0cd90 261 gLCD.printf("MIDI %02d %02d %02d %02d",
radiojunkbox 0:9ddbc6e0cd90 262 gMIDI_CH[0]+1, gMIDI_CH[1]+1,
radiojunkbox 0:9ddbc6e0cd90 263 gMIDI_CH[2]+1, gMIDI_CH[3]+1);
radiojunkbox 0:9ddbc6e0cd90 264 break;
radiojunkbox 0:9ddbc6e0cd90 265 }
radiojunkbox 0:9ddbc6e0cd90 266
radiojunkbox 0:9ddbc6e0cd90 267 ch++;
radiojunkbox 0:9ddbc6e0cd90 268 ch &= 0x03;
radiojunkbox 0:9ddbc6e0cd90 269 }
radiojunkbox 0:9ddbc6e0cd90 270 }
radiojunkbox 0:9ddbc6e0cd90 271
radiojunkbox 0:9ddbc6e0cd90 272 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 273 // Initialize KAMUI
radiojunkbox 0:9ddbc6e0cd90 274
radiojunkbox 0:9ddbc6e0cd90 275 void InitKamui()
radiojunkbox 0:9ddbc6e0cd90 276 {
radiojunkbox 0:9ddbc6e0cd90 277 // Init. Variables
radiojunkbox 0:9ddbc6e0cd90 278 for( int i=0; i<8; i++) {
radiojunkbox 0:9ddbc6e0cd90 279 gCV[i] = 0x8000;
radiojunkbox 0:9ddbc6e0cd90 280 }
radiojunkbox 0:9ddbc6e0cd90 281 gGATE = 0;
radiojunkbox 0:9ddbc6e0cd90 282 gSYNC = 0;
radiojunkbox 0:9ddbc6e0cd90 283
radiojunkbox 0:9ddbc6e0cd90 284 gUpdateMode = UPDATE_MODE0;
radiojunkbox 0:9ddbc6e0cd90 285
radiojunkbox 0:9ddbc6e0cd90 286 // Init. SPI
radiojunkbox 0:9ddbc6e0cd90 287 gCSA = _DISABLE;
radiojunkbox 0:9ddbc6e0cd90 288 gCSB = _DISABLE;
radiojunkbox 0:9ddbc6e0cd90 289 gSPI.format(8,0);
radiojunkbox 0:9ddbc6e0cd90 290 gSPI.frequency(SPI_RATE);
radiojunkbox 0:9ddbc6e0cd90 291
radiojunkbox 0:9ddbc6e0cd90 292 // Call Back for USBMIDI Messages Received
radiojunkbox 0:9ddbc6e0cd90 293 gUSBMIDI.attach(RcvUSBMIDI);
radiojunkbox 0:9ddbc6e0cd90 294
radiojunkbox 0:9ddbc6e0cd90 295 // Ticker
radiojunkbox 0:9ddbc6e0cd90 296 gTICKER.attach_us(&UpdateCV, UPDATE_INTERVAL);
radiojunkbox 0:9ddbc6e0cd90 297
radiojunkbox 0:9ddbc6e0cd90 298 // Beep
radiojunkbox 0:9ddbc6e0cd90 299 gBEEP.period(1.0/BEEP_FREQ);
radiojunkbox 0:9ddbc6e0cd90 300 gBEEP.write(0.5);
radiojunkbox 0:9ddbc6e0cd90 301 wait(0.2);
radiojunkbox 0:9ddbc6e0cd90 302 gBEEP.write(0.0);
radiojunkbox 0:9ddbc6e0cd90 303
radiojunkbox 0:9ddbc6e0cd90 304 // Init Display
radiojunkbox 0:9ddbc6e0cd90 305 gLCD.locate( 0, 0 );
radiojunkbox 0:9ddbc6e0cd90 306 // 123456789ABCDEF
radiojunkbox 0:9ddbc6e0cd90 307 gLCD.printf("USBMIDI-CV Exam");
radiojunkbox 0:9ddbc6e0cd90 308 }
radiojunkbox 0:9ddbc6e0cd90 309
radiojunkbox 0:9ddbc6e0cd90 310 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 311 // Update CV, GATE, SYNC
radiojunkbox 0:9ddbc6e0cd90 312
radiojunkbox 0:9ddbc6e0cd90 313 void UpdateCV()
radiojunkbox 0:9ddbc6e0cd90 314 {
radiojunkbox 0:9ddbc6e0cd90 315 unsigned char rcv,ch;
radiojunkbox 0:9ddbc6e0cd90 316 unsigned char ptn[] = { 0,1,6,7,2,3,6,7,4,5,6,7 };
radiojunkbox 0:9ddbc6e0cd90 317 const int numptn = (sizeof ptn / sizeof ptn[0]) - 1;
radiojunkbox 0:9ddbc6e0cd90 318 static unsigned char cnt;
radiojunkbox 0:9ddbc6e0cd90 319
radiojunkbox 0:9ddbc6e0cd90 320 __disable_irq();
radiojunkbox 0:9ddbc6e0cd90 321
radiojunkbox 0:9ddbc6e0cd90 322 // SET DAC
radiojunkbox 0:9ddbc6e0cd90 323 ch = ptn[cnt];
radiojunkbox 0:9ddbc6e0cd90 324 if(gUpdateMode) ch |= 0x06;
radiojunkbox 0:9ddbc6e0cd90 325
radiojunkbox 0:9ddbc6e0cd90 326 #ifdef AD5551 // 14bitDAC
radiojunkbox 0:9ddbc6e0cd90 327 gDAC.WORD = gCV[ch] >> 2;
radiojunkbox 0:9ddbc6e0cd90 328 #else
radiojunkbox 0:9ddbc6e0cd90 329 gDAC.WORD = gCV[ch];
radiojunkbox 0:9ddbc6e0cd90 330 #endif
radiojunkbox 0:9ddbc6e0cd90 331
radiojunkbox 0:9ddbc6e0cd90 332 gCSA = _ENABLE;
radiojunkbox 0:9ddbc6e0cd90 333 gSPI.write(gDAC.BYTE.H);
radiojunkbox 0:9ddbc6e0cd90 334 gSPI.write(gDAC.BYTE.L);
radiojunkbox 0:9ddbc6e0cd90 335 gCSA = _DISABLE;
radiojunkbox 0:9ddbc6e0cd90 336
radiojunkbox 0:9ddbc6e0cd90 337 // GATE or SYNC OUT
radiojunkbox 0:9ddbc6e0cd90 338 if(cnt & 0x01) {
radiojunkbox 0:9ddbc6e0cd90 339 // GATE OUT
radiojunkbox 0:9ddbc6e0cd90 340 gCSB = _ENABLE;
radiojunkbox 0:9ddbc6e0cd90 341 rcv = gSPI.write(gGATE | MODE_GATE) & 0x0F;
radiojunkbox 0:9ddbc6e0cd90 342 gCSB = _DISABLE;
radiojunkbox 0:9ddbc6e0cd90 343 }
radiojunkbox 0:9ddbc6e0cd90 344 else {
radiojunkbox 0:9ddbc6e0cd90 345 // SYNC OUT
radiojunkbox 0:9ddbc6e0cd90 346 gCSB = _ENABLE;
radiojunkbox 0:9ddbc6e0cd90 347 rcv = gSPI.write(gSYNC | MODE_SYNC);
radiojunkbox 0:9ddbc6e0cd90 348 gCSB = _DISABLE;
radiojunkbox 0:9ddbc6e0cd90 349 }
radiojunkbox 0:9ddbc6e0cd90 350
radiojunkbox 0:9ddbc6e0cd90 351 // SEL CV CHANNEL
radiojunkbox 0:9ddbc6e0cd90 352 gCSB = _ENABLE;
radiojunkbox 0:9ddbc6e0cd90 353 gSPI.write(ch);
radiojunkbox 0:9ddbc6e0cd90 354 gCSB = _DISABLE;
radiojunkbox 0:9ddbc6e0cd90 355
radiojunkbox 0:9ddbc6e0cd90 356 cnt < numptn ? cnt++ : cnt = 0;
radiojunkbox 0:9ddbc6e0cd90 357
radiojunkbox 0:9ddbc6e0cd90 358 __enable_irq();
radiojunkbox 0:9ddbc6e0cd90 359
radiojunkbox 0:9ddbc6e0cd90 360 gSW |= CheckSW(rcv);
radiojunkbox 0:9ddbc6e0cd90 361 DinSync();
radiojunkbox 0:9ddbc6e0cd90 362 MidiCV();
radiojunkbox 0:9ddbc6e0cd90 363 }
radiojunkbox 0:9ddbc6e0cd90 364
radiojunkbox 0:9ddbc6e0cd90 365 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 366 // Check SW
radiojunkbox 0:9ddbc6e0cd90 367
radiojunkbox 0:9ddbc6e0cd90 368 unsigned char CheckSW(unsigned char c) {
radiojunkbox 0:9ddbc6e0cd90 369
radiojunkbox 0:9ddbc6e0cd90 370 static unsigned char swbuf[2];
radiojunkbox 0:9ddbc6e0cd90 371 static unsigned int cntsw;
radiojunkbox 0:9ddbc6e0cd90 372 unsigned char ret = 0;
radiojunkbox 0:9ddbc6e0cd90 373
radiojunkbox 0:9ddbc6e0cd90 374 if(cntsw > SW_WATCH_INTERVAL) {
radiojunkbox 0:9ddbc6e0cd90 375 if(c &= 0x0F) {
radiojunkbox 0:9ddbc6e0cd90 376 if(!swbuf[1]) {
radiojunkbox 0:9ddbc6e0cd90 377 if( swbuf[0] == c) {
radiojunkbox 0:9ddbc6e0cd90 378 swbuf[1] = c;
radiojunkbox 0:9ddbc6e0cd90 379 ret = c;
radiojunkbox 0:9ddbc6e0cd90 380 }
radiojunkbox 0:9ddbc6e0cd90 381 else {
radiojunkbox 0:9ddbc6e0cd90 382 swbuf[0] = c;
radiojunkbox 0:9ddbc6e0cd90 383 }
radiojunkbox 0:9ddbc6e0cd90 384 }
radiojunkbox 0:9ddbc6e0cd90 385 }
radiojunkbox 0:9ddbc6e0cd90 386 else {
radiojunkbox 0:9ddbc6e0cd90 387 swbuf[1] = 0;
radiojunkbox 0:9ddbc6e0cd90 388 swbuf[0] = 0;
radiojunkbox 0:9ddbc6e0cd90 389 }
radiojunkbox 0:9ddbc6e0cd90 390 cntsw = 0;
radiojunkbox 0:9ddbc6e0cd90 391 }
radiojunkbox 0:9ddbc6e0cd90 392 cntsw++;
radiojunkbox 0:9ddbc6e0cd90 393 return ret;
radiojunkbox 0:9ddbc6e0cd90 394 }
radiojunkbox 0:9ddbc6e0cd90 395
radiojunkbox 0:9ddbc6e0cd90 396 //-------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 397 // Receive USBMIDI Data & Store Ring Buffer
radiojunkbox 0:9ddbc6e0cd90 398 void RcvUSBMIDI(MIDIMessage msg) {
radiojunkbox 0:9ddbc6e0cd90 399
radiojunkbox 0:9ddbc6e0cd90 400 if(msg.data[0] == 0) return;
radiojunkbox 0:9ddbc6e0cd90 401
radiojunkbox 0:9ddbc6e0cd90 402 // gGATE ^= GATE_LED5;
radiojunkbox 0:9ddbc6e0cd90 403 // printf("%02x %02x %02x %02x\r\n",msg.data[0],msg.data[1],msg.data[2],msg.data[3]);
radiojunkbox 0:9ddbc6e0cd90 404
radiojunkbox 0:9ddbc6e0cd90 405 for( int i=1; i<4; i++) {
radiojunkbox 0:9ddbc6e0cd90 406 gPtr_buf_in++;
radiojunkbox 0:9ddbc6e0cd90 407 gPtr_buf_in &= (BUFSIZE - 1);
radiojunkbox 0:9ddbc6e0cd90 408 gRxBuf[gPtr_buf_in] = msg.data[i];
radiojunkbox 0:9ddbc6e0cd90 409 }
radiojunkbox 0:9ddbc6e0cd90 410 }
radiojunkbox 0:9ddbc6e0cd90 411
radiojunkbox 0:9ddbc6e0cd90 412 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 413 // MIDI Data to CV, GATE
radiojunkbox 0:9ddbc6e0cd90 414
radiojunkbox 0:9ddbc6e0cd90 415 void MidiCV()
radiojunkbox 0:9ddbc6e0cd90 416 {
radiojunkbox 0:9ddbc6e0cd90 417 static unsigned char ch;
radiojunkbox 0:9ddbc6e0cd90 418 static unsigned short phase[4];
radiojunkbox 0:9ddbc6e0cd90 419 static float cvf[4];
radiojunkbox 0:9ddbc6e0cd90 420 int lfo,mod;
radiojunkbox 0:9ddbc6e0cd90 421 unsigned char midi_ch;
radiojunkbox 0:9ddbc6e0cd90 422 unsigned int cv;
radiojunkbox 0:9ddbc6e0cd90 423 unsigned int note;
radiojunkbox 0:9ddbc6e0cd90 424
radiojunkbox 0:9ddbc6e0cd90 425 midi_ch = gMIDI_CH[ch];
radiojunkbox 0:9ddbc6e0cd90 426
radiojunkbox 0:9ddbc6e0cd90 427 note = gPlayNoteBuf[midi_ch];
radiojunkbox 0:9ddbc6e0cd90 428 if( note < MINIMUMNOTE) note = MINIMUMNOTE;
radiojunkbox 0:9ddbc6e0cd90 429 note -= MINIMUMNOTE;
radiojunkbox 0:9ddbc6e0cd90 430
radiojunkbox 0:9ddbc6e0cd90 431 // DDS Phase
radiojunkbox 0:9ddbc6e0cd90 432 phase[ch] += gLFO_DP[ch];
radiojunkbox 0:9ddbc6e0cd90 433
radiojunkbox 0:9ddbc6e0cd90 434 // LFO DDS Genelator
radiojunkbox 0:9ddbc6e0cd90 435 switch(gLFO_FORM[ch]) {
radiojunkbox 0:9ddbc6e0cd90 436 case LFO_WF_TRI:
radiojunkbox 0:9ddbc6e0cd90 437 if(phase[ch] < 32738) lfo = phase[ch] - 16384;
radiojunkbox 0:9ddbc6e0cd90 438 else lfo = (16383 + 32768) - phase[ch];
radiojunkbox 0:9ddbc6e0cd90 439 break;
radiojunkbox 0:9ddbc6e0cd90 440 case LFO_WF_SQR:
radiojunkbox 0:9ddbc6e0cd90 441 if(phase[ch] < 32738) lfo = 32767;
radiojunkbox 0:9ddbc6e0cd90 442 else lfo = 0;
radiojunkbox 0:9ddbc6e0cd90 443 break;
radiojunkbox 0:9ddbc6e0cd90 444 case LFO_WF_SAW:
radiojunkbox 0:9ddbc6e0cd90 445 lfo = phase[ch] / 2 - 16384;
radiojunkbox 0:9ddbc6e0cd90 446 break;
radiojunkbox 0:9ddbc6e0cd90 447 default :
radiojunkbox 0:9ddbc6e0cd90 448 lfo = 0;
radiojunkbox 0:9ddbc6e0cd90 449 break;
radiojunkbox 0:9ddbc6e0cd90 450 }
radiojunkbox 0:9ddbc6e0cd90 451
radiojunkbox 0:9ddbc6e0cd90 452 // Modulation amount
radiojunkbox 0:9ddbc6e0cd90 453 mod = lfo * gModWheelBuf[midi_ch] >> 7;
radiojunkbox 0:9ddbc6e0cd90 454
radiojunkbox 0:9ddbc6e0cd90 455 // Calculate CV
radiojunkbox 0:9ddbc6e0cd90 456 cvf[ch] = ((float)(note << 8) - cvf[ch]) * gGLIDE[ch] + cvf[ch];
radiojunkbox 0:9ddbc6e0cd90 457 cv = (unsigned int)cvf[ch] + (0x8000 - (0x0040 << 3))
radiojunkbox 0:9ddbc6e0cd90 458 + (gPitchBendBuf[midi_ch] << 2) + mod;
radiojunkbox 0:9ddbc6e0cd90 459 if(cv > 0xFFFF) cv = 0xFFFF;
radiojunkbox 0:9ddbc6e0cd90 460 gCV[ch] = (unsigned short)cv;
radiojunkbox 0:9ddbc6e0cd90 461 gCV[ch+4] = OctVtoHzV(gCV[ch]);
radiojunkbox 0:9ddbc6e0cd90 462
radiojunkbox 0:9ddbc6e0cd90 463 // GATE
radiojunkbox 0:9ddbc6e0cd90 464 gGateBuf[midi_ch] ? gGATE |= (1<<ch) : gGATE &= ~(1<<ch);
radiojunkbox 0:9ddbc6e0cd90 465
radiojunkbox 0:9ddbc6e0cd90 466 ch++;
radiojunkbox 0:9ddbc6e0cd90 467 ch &= 0x03;
radiojunkbox 0:9ddbc6e0cd90 468 }
radiojunkbox 0:9ddbc6e0cd90 469
radiojunkbox 0:9ddbc6e0cd90 470 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 471 // Oct/V to Hz/V Converter
radiojunkbox 0:9ddbc6e0cd90 472
radiojunkbox 0:9ddbc6e0cd90 473 void CalcHzVTbl() // Calc Conv. Table
radiojunkbox 0:9ddbc6e0cd90 474 {
radiojunkbox 0:9ddbc6e0cd90 475 int i;
radiojunkbox 0:9ddbc6e0cd90 476 float v;
radiojunkbox 0:9ddbc6e0cd90 477
radiojunkbox 0:9ddbc6e0cd90 478 for( i=0; i<3072; i++) {
radiojunkbox 0:9ddbc6e0cd90 479 v = 24576.0 * pow(2.0,(i/3072.0));
radiojunkbox 0:9ddbc6e0cd90 480 gTblHzV[i] = (unsigned short)v;
radiojunkbox 0:9ddbc6e0cd90 481 }
radiojunkbox 0:9ddbc6e0cd90 482 }
radiojunkbox 0:9ddbc6e0cd90 483
radiojunkbox 0:9ddbc6e0cd90 484 unsigned short OctVtoHzV( unsigned short vin)
radiojunkbox 0:9ddbc6e0cd90 485 {
radiojunkbox 0:9ddbc6e0cd90 486 int oct,res;
radiojunkbox 0:9ddbc6e0cd90 487 unsigned short vout;
radiojunkbox 0:9ddbc6e0cd90 488
radiojunkbox 0:9ddbc6e0cd90 489 if(vin > 0xE400) vin = 0xE400; // Maximum Note E8 Vin = 10.794V
radiojunkbox 0:9ddbc6e0cd90 490 if(vin < 0x6800) vin = 0x6800; // Minimum Note C-2 Vin = -2.000V
radiojunkbox 0:9ddbc6e0cd90 491 vin -= 0x6800;
radiojunkbox 0:9ddbc6e0cd90 492
radiojunkbox 0:9ddbc6e0cd90 493 oct = vin / 0xC00; // 0xC00 : 3072
radiojunkbox 0:9ddbc6e0cd90 494 res = vin % 0xC00;
radiojunkbox 0:9ddbc6e0cd90 495
radiojunkbox 0:9ddbc6e0cd90 496 vout = ((unsigned short)gTblHzV[res] >> (10 - oct)) + 0x8000;
radiojunkbox 0:9ddbc6e0cd90 497 return vout;
radiojunkbox 0:9ddbc6e0cd90 498 }
radiojunkbox 0:9ddbc6e0cd90 499
radiojunkbox 0:9ddbc6e0cd90 500 //-------------------------------------------------------------
radiojunkbox 0:9ddbc6e0cd90 501 // DIN SYNC Control
radiojunkbox 0:9ddbc6e0cd90 502
radiojunkbox 0:9ddbc6e0cd90 503 void DinSync()
radiojunkbox 0:9ddbc6e0cd90 504 {
radiojunkbox 0:9ddbc6e0cd90 505 static unsigned int cnt;
radiojunkbox 0:9ddbc6e0cd90 506 static unsigned int cnt24 = 10;
radiojunkbox 0:9ddbc6e0cd90 507
radiojunkbox 0:9ddbc6e0cd90 508 if(gMIDISYNC_RUN) gSYNC |= (SYNC1RUN | SYNC2RUN);
radiojunkbox 0:9ddbc6e0cd90 509 else gSYNC &= ~(SYNC1RUN | SYNC2RUN);
radiojunkbox 0:9ddbc6e0cd90 510
radiojunkbox 0:9ddbc6e0cd90 511 if(cnt >= SYNC_TURN_TIME) gSYNC &= ~(SYNC1CLK | SYNC2CLK);
radiojunkbox 0:9ddbc6e0cd90 512
radiojunkbox 0:9ddbc6e0cd90 513 if(gMIDISYNC_CLK) {
radiojunkbox 0:9ddbc6e0cd90 514 gSYNC |= (SYNC1CLK | SYNC2CLK);
radiojunkbox 0:9ddbc6e0cd90 515 gMIDISYNC_CLK = 0;
radiojunkbox 0:9ddbc6e0cd90 516 cnt = 0;
radiojunkbox 0:9ddbc6e0cd90 517 cnt24++;
radiojunkbox 0:9ddbc6e0cd90 518 }
radiojunkbox 0:9ddbc6e0cd90 519 if(cnt24 >= 24) cnt24 = 0;
radiojunkbox 0:9ddbc6e0cd90 520
radiojunkbox 0:9ddbc6e0cd90 521 gLED3 = gSYNC & SYNC1RUN ? 1 : 0;
radiojunkbox 0:9ddbc6e0cd90 522 gLED4 = cnt24 < 4 ? 1 : 0;
radiojunkbox 0:9ddbc6e0cd90 523
radiojunkbox 0:9ddbc6e0cd90 524 cnt++;
radiojunkbox 0:9ddbc6e0cd90 525 }