KAMUI OSC-CV Example refer to OSCReceiver by xshige http://mbed.org/users/xshige/programs/OSCReceiver/
Dependencies: NetServices TextLCD mbed
main.cpp
00001 //------------------------------------------------------------- 00002 // KAMUI OSC-CV Exapmple 00003 // referred to xshige's OSCReceiver 00004 // http://mbed.org/users/xshige/programs/OSCReceiver/ 00005 // Copyright (C) 2012 RJB RadioJunkBox 00006 // Released under the MIT License: http://mbed.org/license/mit 00007 //------------------------------------------------------------- 00008 00009 #include "mbed.h" 00010 #include "TextLCD.h" 00011 #include "EthernetNetIf.h" 00012 #include "UDPSocket.h" 00013 #include "OSCReceiver.h" 00014 #include <stdlib.h> 00015 #include <ctype.h> 00016 #include <math.h> 00017 00018 //------------------------------------------------------------- 00019 // Define 00020 00021 #define AD5551 // 14bitDAC 00022 00023 #define SPI_RATE 1000000 // 1Mbps 00024 #define MIDI_RATE 31250 // 31.25kbps 00025 #define BEEP_FREQ 1760.0 // 1760Hz 00026 #define UPDATE_INTERVAL 100 // 100us 00027 #define SW_WATCH_INTERVAL (25000/UPDATE_INTERVAL) // 25ms 00028 #define PARAM_GLIDE 6554.0 00029 00030 #define UPDATE_MODE0 0 // Update Interval CV ch1-6 1200us, ch7,8 400us 00031 #define UPDATE_MODE1 1 // Update Interval CV ch1-6 N/A, ch7,8 200us 00032 00033 #define GATE1 0x01 00034 #define GATE2 0x02 00035 #define GATE3 0x04 00036 #define GATE4 0x08 00037 00038 #define SYNC1CLK 0x01 00039 #define SYNC1RUN 0x02 00040 #define SYNC2CLK 0x04 00041 #define SYNC2RUN 0x08 00042 00043 #define MODE_CV 0x00 00044 #define MODE_GATE 0x40 00045 #define MODE_SYNC 0x80 00046 #define MODE_SET_SYNC 0xC0 00047 00048 #define SW1 0x01 00049 #define SW2 0x02 00050 #define SW3 0x04 00051 #define SW4 0x08 00052 #define SYNC1CLK_IN 0x10 00053 #define SYNC1RUN_IN 0x20 00054 #define SYNC2CLK_IN 0x40 00055 #define GATE_IN 0x80 00056 00057 #define _ENABLE 0 00058 #define _DISABLE 1 00059 00060 //------------------------------------------------------------- 00061 // Functions 00062 00063 void InitKamui(void); 00064 void UpdateCV(void); 00065 unsigned char CheckSW(unsigned char); 00066 00067 void SetCV(void); 00068 int SetupEthNetIf(void); 00069 void onUDPSocketEvent(UDPSocketEvent); 00070 00071 //------------------------------------------------------------- 00072 // Global Variables 00073 00074 int gUpdateMode; 00075 unsigned short gCV[8]; 00076 unsigned char gGATE; 00077 unsigned char gSYNC; 00078 unsigned char gSW; 00079 00080 union { 00081 unsigned short WORD; 00082 struct { 00083 unsigned char L; 00084 unsigned char H; 00085 } BYTE; 00086 } gDAC; 00087 00088 float gGLIDE[8]; 00089 float gOSC_CV[8]; 00090 00091 //------------------------------------------------------------- 00092 // mbed Functions 00093 00094 // TextLCD 00095 TextLCD gLCD(p23, p24, p25, p26, p29, p30); // rs, e, d4-d7 00096 00097 // SPI 00098 SPI gSPI(p11,p12,p13); 00099 DigitalOut gCSA(p14); 00100 DigitalOut gCSB(p22); 00101 00102 // Sirial MIDI 00103 //Serial gMIDI(p9,p10); 00104 00105 // AnalogIn 00106 AnalogIn gAIN1(p15); // VR1 00107 AnalogIn gAIN2(p16); // VR2 00108 AnalogIn gAIN3(p17); // VR3 00109 AnalogIn gAIN4(p18); // VR4 00110 AnalogIn gAIN5(p19); // IN1 00111 AnalogIn gAIN6(p20); // IN2 00112 00113 // BEEP 00114 PwmOut gBEEP(p21); 00115 00116 // LED 00117 DigitalOut gLED1(LED1); 00118 DigitalOut gLED2(LED2); 00119 DigitalOut gLED3(LED3); 00120 DigitalOut gLED4(LED4); 00121 BusOut gLEDS(LED1,LED2,LED3,LED4); 00122 00123 // Ticker 00124 Ticker gTICKER; 00125 00126 // Ethernet 00127 EthernetNetIf gEth; 00128 UDPSocket gUdp; 00129 00130 //------------------------------------------------------------- 00131 // main 00132 00133 int main() { 00134 00135 int i; 00136 int pot[4],_pot[4]; 00137 unsigned char ch = 0; 00138 unsigned char mode = 7; // for Intialize 00139 unsigned char edit[4]; 00140 int val[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 00141 00142 // Initialize 00143 for( i=0; i<4; i++) { 00144 pot[i] = _pot[i] = 0; 00145 edit[i] = 0; 00146 gGLIDE[i] = 1.0 / expf(val[i]*656.0/PARAM_GLIDE); 00147 gGLIDE[i+4] = 1.0 / expf(val[i+4]*656.0/PARAM_GLIDE); 00148 } 00149 gSW = SW4; // for Intialize 00150 00151 InitKamui(); 00152 if(SetupEthNetIf() == -1) 00153 { 00154 gBEEP.write(0.5); 00155 wait(1); 00156 gBEEP.write(0.0); 00157 return -1; 00158 } 00159 00160 // loop 00161 while(1) { 00162 00163 // Ethernet Polling 00164 Net::poll(); 00165 00166 // Read pot 00167 pot[0] = gAIN1.read_u16(); 00168 pot[1] = gAIN2.read_u16(); 00169 pot[2] = gAIN3.read_u16(); 00170 pot[3] = gAIN4.read_u16(); 00171 00172 // change pot amount? 00173 if(abs(pot[ch] - _pot[ch]) > 0x2000) edit[ch] = 1; 00174 00175 if(edit[ch]) { 00176 switch(mode) { 00177 case 0: 00178 gGLIDE[ch] = 1.0 / expf(pot[ch]/PARAM_GLIDE); 00179 val[ch] = pot[ch] / 656; 00180 break; 00181 case 1: 00182 gGLIDE[ch+4] = 1.0 / expf(pot[ch]/PARAM_GLIDE); 00183 val[ch+4] = pot[ch] / 656; 00184 break; 00185 default: 00186 break; 00187 } 00188 } 00189 00190 // Push Mode SW 00191 if(gSW & SW4) { 00192 mode++; 00193 mode &= 0x01; 00194 for( i=0; i<4; i++) { 00195 _pot[i] = pot[i]; 00196 edit[i] = 0; 00197 } 00198 } 00199 gSW = 0; 00200 00201 // LCD Display 00202 gLCD.locate( 0, 1 ); 00203 switch(mode) { 00204 case 0: 00205 gLCD.printf("G1-4 %02d %02d %02d %02d", 00206 val[0], val[1], val[2], val[3]); 00207 break; 00208 case 1: 00209 gLCD.printf("G5-8 %02d %02d %02d %02d", 00210 val[4], val[5], val[6], val[7]); 00211 break; 00212 } 00213 00214 ch++; 00215 ch &= 0x03; 00216 } 00217 } 00218 00219 //------------------------------------------------------------- 00220 // Initialize KAMUI 00221 00222 void InitKamui() 00223 { 00224 // Init. Variables 00225 for( int i=0; i<8; i++) { 00226 gCV[i] = 0x8000; 00227 } 00228 gGATE = 0; 00229 gSYNC = 0; 00230 00231 gUpdateMode = UPDATE_MODE0; 00232 00233 // Init. SPI 00234 gCSA = _DISABLE; 00235 gCSB = _DISABLE; 00236 gSPI.format(8,0); 00237 gSPI.frequency(SPI_RATE); 00238 00239 // Init. Serial MIDI 00240 // gMIDI.baud(MIDI_RATE); 00241 00242 // Ticker 00243 gTICKER.attach_us(&UpdateCV, UPDATE_INTERVAL); 00244 00245 // Beep 00246 gBEEP.period(1.0/BEEP_FREQ); 00247 gBEEP.write(0.5); 00248 wait(0.2); 00249 gBEEP.write(0.0); 00250 00251 // Init Display 00252 gLCD.locate( 0, 0 ); 00253 // 123456789ABCDEF 00254 gLCD.printf("OSC-CV Example "); 00255 } 00256 00257 //------------------------------------------------------------- 00258 // Update CV, GATE, SYNC 00259 00260 void UpdateCV() 00261 { 00262 unsigned char rcv,ch; 00263 unsigned char ptn[] = { 0,1,6,7,2,3,6,7,4,5,6,7 }; 00264 const int numptn = (sizeof ptn / sizeof ptn[0]) - 1; 00265 static unsigned char cnt; 00266 00267 __disable_irq(); 00268 00269 // SET DAC 00270 ch = ptn[cnt]; 00271 if(gUpdateMode) ch |= 0x06; 00272 00273 #ifdef AD5551 // 14bitDAC 00274 gDAC.WORD = gCV[ch] >> 2; 00275 #else 00276 gDAC.WORD = gCV[ch]; 00277 #endif 00278 00279 gCSA = _ENABLE; 00280 gSPI.write(gDAC.BYTE.H); 00281 gSPI.write(gDAC.BYTE.L); 00282 gCSA = _DISABLE; 00283 00284 // GATE or SYNC OUT 00285 if(cnt & 0x01) { 00286 // GATE OUT 00287 gCSB = _ENABLE; 00288 rcv = gSPI.write(gGATE | MODE_GATE) & 0x0F; 00289 gCSB = _DISABLE; 00290 } 00291 else { 00292 // SYNC OUT 00293 gCSB = _ENABLE; 00294 rcv = gSPI.write(gSYNC | MODE_SYNC); 00295 gCSB = _DISABLE; 00296 } 00297 00298 // SEL CV CHANNEL 00299 gCSB = _ENABLE; 00300 gSPI.write(ch); 00301 gCSB = _DISABLE; 00302 00303 cnt < numptn ? cnt++ : cnt = 0; 00304 00305 __enable_irq(); 00306 00307 gSW |= CheckSW(rcv); 00308 SetCV(); 00309 } 00310 00311 //------------------------------------------------------------- 00312 // Check SW 00313 00314 unsigned char CheckSW(unsigned char c) { 00315 00316 static unsigned char swbuf[2]; 00317 static unsigned int cntsw; 00318 unsigned char ret = 0; 00319 00320 if(cntsw > SW_WATCH_INTERVAL) { 00321 if(c &= 0x0F) { 00322 if(!swbuf[1]) { 00323 if( swbuf[0] == c) { 00324 swbuf[1] = c; 00325 ret = c; 00326 } 00327 else { 00328 swbuf[0] = c; 00329 } 00330 } 00331 } 00332 else { 00333 swbuf[1] = 0; 00334 swbuf[0] = 0; 00335 } 00336 cntsw = 0; 00337 } 00338 cntsw++; 00339 return ret; 00340 } 00341 00342 //------------------------------------------------------------- 00343 // Set CV 00344 00345 void SetCV() 00346 { 00347 static unsigned char ch; 00348 static float cvf[8]; 00349 unsigned int cv; 00350 00351 // Calculate CV 00352 cvf[ch] = (gOSC_CV[ch] - cvf[ch]) * gGLIDE[ch] + cvf[ch]; 00353 cv = (unsigned int)cvf[ch] + 0x8000; 00354 if(cv > 0xFFFF) cv = 0xFFFF; 00355 gCV[ch] = cv; 00356 00357 ch++; 00358 ch &= 0x07; 00359 } 00360 00361 //------------------------------------------------------------- 00362 // Setup Ethernet port 00363 00364 int SetupEthNetIf() 00365 { 00366 gLCD.locate( 0, 1 ); 00367 gLCD.printf("Setting up... "); 00368 // printf("Setting up...\r\n"); 00369 00370 EthernetErr ethErr = gEth.setup(); 00371 if(ethErr) 00372 { 00373 gLCD.locate( 0, 1 ); 00374 gLCD.printf("Error in setup."); 00375 // printf("Error %d in setup.\r\n", ethErr); 00376 return -1; 00377 } 00378 // printf("Setup OK\r\n"); 00379 00380 // printf("IP address %d.%d.%d.%d\r\n", gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], gEth.getIp()[3]); 00381 Host broadcast(IpAddr(gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], 255), 12345, NULL); 00382 gUdp.setOnEvent(&onUDPSocketEvent); 00383 gUdp.bind(broadcast); 00384 00385 gLCD.locate( 0, 1 ); 00386 gLCD.printf("%03d.%03d.%03d.%03d", gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], gEth.getIp()[3]); 00387 wait(2.0); 00388 00389 return 0; 00390 } 00391 00392 //------------------------------------------------------------- 00393 // Handller receive UDP Packet 00394 00395 void onUDPSocketEvent(UDPSocketEvent e) 00396 { 00397 union OSCarg msg[10]; 00398 int num; 00399 00400 switch(e) 00401 { 00402 case UDPSOCKET_READABLE: //The only event for now 00403 char buf[256] = {0}; 00404 Host host; 00405 00406 while( int len = gUdp.recvfrom( buf, 256, &host ) ) 00407 { 00408 if(len <= 0) break; 00409 // printf("\r\nFrom %d.%d.%d.%d:\r\n", 00410 // host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3]); 00411 00412 getOSCmsg(buf,msg); 00413 // printf("OSCmsg: %s %s %f %i\r\n", 00414 // msg[0].address, msg[1].typeTag, msg[2].f, msg[2].i); 00415 00416 len = strlen(msg[0].address); 00417 if(isdigit(msg[0].address[len-1])) num = msg[0].address[len-1] - '0' - 1; 00418 else num = -1; 00419 00420 // address pattern CV 00421 if((strncmp(msg[0].address,"/kamui/cv",9)==0) && (num != -1)) { 00422 00423 if(num > 7) break; 00424 if(msg[1].typeTag[1] == 'f') gOSC_CV[num] = msg[2].f * 3072.0; 00425 if(msg[1].typeTag[1] == 'i') gOSC_CV[num] = msg[2].i * 3072.0; 00426 00427 break; 00428 } 00429 00430 // address pattern GATE 00431 if((strncmp(msg[0].address,"/kamui/gate",11)==0) && (num != -1)) { 00432 00433 if(num > 3) break; 00434 if(msg[2].i) gGATE |= (0x01 << num); 00435 else gGATE &= ~(0x01 << num); 00436 00437 break; 00438 } 00439 00440 // printf("undefined OSCmsg:%s %s\r\n",msg[0].address, msg[1].typeTag); 00441 } 00442 break; 00443 } 00444 }
Generated on Tue Jul 12 2022 17:52:31 by 1.7.2