KAMUI MIDI-CV Example

Dependencies:   TextLCD mbed

Committer:
radiojunkbox
Date:
Sat May 05 11:35:41 2012 +0000
Revision:
0:25a282f1141a
Rev. 1.0

Who changed what in which revision?

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