Radio Junk Box / Mbed 2 deprecated KAMUI_DIN-SYNC_Example

Dependencies:   TextLCD mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //-------------------------------------------------------------
00002 // KAMUI DIN SYNC Example
00003 // Copyright (C) 2012 RJB RadioJunkBox
00004 // Released under the MIT License: http://mbed.org/license/mit
00005 //-------------------------------------------------------------
00006 
00007 #include "mbed.h"
00008 #include "TextLCD.h"
00009 
00010 //-------------------------------------------------------------
00011 // Define
00012 
00013 #define AD5551                      // 14bitDAC
00014 
00015 #define SPI_RATE            1000000 // 1Mbps
00016 #define MIDI_RATE           31250   // 31.25kbps
00017 #define BEEP_FREQ           1760.0  // 1760Hz
00018 #define UPDATE_INTERVAL     50      // 50us
00019 #define SW_WATCH_INTERVAL   (25000/UPDATE_INTERVAL) // 25ms
00020 
00021 #define UPDATE_MODE0        0       // Update Interval CV ch1-6 600us, ch7,8 200us
00022 #define UPDATE_MODE1        1       // Update Interval CV ch1-6 N/A, ch7,8 100us
00023 
00024 #define GATE1               0x01
00025 #define GATE2               0x02
00026 #define GATE3               0x04
00027 #define GATE4               0x08
00028 
00029 #define SYNC1CLK            0x01
00030 #define SYNC1RUN            0x02
00031 #define SYNC2CLK            0x04
00032 #define SYNC2RUN            0x08
00033 
00034 #define MODE_CV             0x00
00035 #define MODE_GATE           0x40
00036 #define MODE_SYNC           0x80
00037 #define MODE_SET_SYNC       0xC0
00038 
00039 #define SW1                 0x01
00040 #define SW2                 0x02
00041 #define SW3                 0x04
00042 #define SW4                 0x08
00043 #define SYNC1CLK_IN         0x10
00044 #define SYNC1RUN_IN         0x20
00045 #define SYNC2CLK_IN         0x40
00046 #define GATE_IN             0x80
00047 
00048 #define _ENABLE             0
00049 #define _DISABLE            1
00050 
00051 #define TBASE               (60*1000000/(48*UPDATE_INTERVAL))
00052 
00053 //-------------------------------------------------------------
00054 // Functions
00055 
00056 void InitKamui(void);
00057 void UpdateCV(void);
00058 void DinSync(unsigned char);
00059 unsigned char CheckSW(unsigned char);
00060 
00061 //-------------------------------------------------------------
00062 // Global Variables
00063 
00064 int gUpdateMode;
00065 unsigned short gCV[8];
00066 unsigned char  gGATE;
00067 unsigned char  gSYNC;
00068 unsigned short gT1,gT2;
00069 
00070 union {
00071     unsigned short    WORD;    
00072     struct {
00073         unsigned char L;
00074         unsigned char H; 
00075     } BYTE;
00076 } gDAC;
00077 
00078 //-------------------------------------------------------------
00079 // mbed Functions
00080 
00081 // TextLCD
00082 TextLCD gLCD(p23, p24, p25, p26, p29, p30); // rs, e, d4-d7
00083 
00084 // SPI
00085 SPI gSPI(p11,p12,p13);
00086 DigitalOut gCSA(p14);
00087 DigitalOut gCSB(p22);
00088 
00089 // Sirial MIDI
00090 Serial gMIDI(p9,p10);
00091 
00092 // AnalogIn
00093 AnalogIn    gAIN1(p15);   // VR1
00094 AnalogIn    gAIN2(p16);   // VR2
00095 AnalogIn    gAIN3(p17);   // VR3
00096 AnalogIn    gAIN4(p18);   // VR4
00097 AnalogIn    gAIN5(p19);   // IN1
00098 AnalogIn    gAIN6(p20);   // IN2
00099 
00100 // BEEP
00101 PwmOut gBEEP(p21);
00102 
00103 // LED
00104 DigitalOut gLED1(LED1);
00105 DigitalOut gLED2(LED2);
00106 DigitalOut gLED3(LED3);
00107 DigitalOut gLED4(LED4);
00108 BusOut gLEDS(LED1,LED2,LED3,LED4);
00109 
00110 // Ticker
00111 Ticker gTICKER;
00112 
00113 //-------------------------------------------------------------
00114 // main
00115 
00116 int main() {
00117 
00118     unsigned int pot1, pot2, pot3, pot4;
00119     unsigned int tempo;
00120     unsigned int t,s;
00121 
00122     InitKamui();    
00123 
00124     while(1) {
00125 
00126         // POT1 Tempo 40 - 220 bpm
00127         // POT2 Suffle Rate
00128         // POT3 CV1 - CV4     0V - +10V
00129         // POT4 CV5 - CV8   -10V - +10V
00130         
00131         pot1 = gAIN1.read_u16();
00132         pot2 = gAIN2.read_u16() / 0x0400;
00133         pot3 = gAIN3.read_u16() / 2 + 0x8000;
00134         pot4 = gAIN4.read_u16();
00135         
00136         tempo = pot1 / 364 + 40;
00137         t = TBASE / tempo;
00138         s = t * pot2 / 127; 
00139         
00140         gT1 = t + s;
00141         gT2 = t - s;
00142         
00143         gCV[0] = pot3; 
00144         gCV[1] = pot3; 
00145         gCV[2] = pot3;
00146         gCV[3] = pot3;
00147         gCV[4] = pot4;
00148         gCV[5] = pot4;
00149         gCV[6] = pot4;
00150         gCV[7] = pot4;
00151         
00152         gLCD.locate( 0, 1 );
00153         gLCD.printf("TEMPO=%03d SFL=%02d", tempo, pot2);    
00154     }
00155 }
00156 
00157 //-------------------------------------------------------------
00158 // Initialize KAMUI
00159 
00160 void InitKamui()
00161 {
00162     // Init. Variables
00163     for( int i=0; i<8; i++) {
00164         gCV[i] = 0x8000;
00165     }
00166     gGATE = 0;
00167     gSYNC = 0;
00168 
00169     gUpdateMode = UPDATE_MODE0;
00170   
00171     // Init. SPI
00172     gCSA = _DISABLE;
00173     gCSB = _DISABLE;
00174     gSPI.format(8,0);
00175     gSPI.frequency(SPI_RATE);
00176 
00177     // Init. Serial MIDI
00178     gMIDI.baud(MIDI_RATE);
00179     
00180     // Ticker
00181     gTICKER.attach_us(&UpdateCV, UPDATE_INTERVAL);
00182 
00183     // Beep
00184     gBEEP.period(1.0/BEEP_FREQ);
00185     gBEEP.write(0.5);
00186     wait(0.2);
00187     gBEEP.write(0.0);
00188 
00189     // Init Display
00190     gLCD.locate( 0, 0 );
00191               // 123456789ABCDEF
00192     gLCD.printf("DIN-SyncExample");
00193 }
00194 
00195 //-------------------------------------------------------------
00196 // Update CV, GATE, SYNC
00197 
00198 void UpdateCV()
00199 { 
00200     unsigned char rcv,sw,ch;
00201     unsigned char ptn[] = { 0,1,6,7,2,3,6,7,4,5,6,7 };
00202     const int numptn = (sizeof ptn / sizeof ptn[0]) - 1;
00203     static unsigned char  cnt;
00204 
00205     // SET DAC 
00206     ch = ptn[cnt];
00207     if(gUpdateMode) ch |= 0x06;
00208 
00209 #ifdef AD5551 // 14bitDAC
00210     gDAC.WORD = gCV[ch] >> 2;
00211 #else
00212     gDAC.WORD = gCV[ch];    
00213 #endif
00214     
00215     gCSA = _ENABLE;
00216     gSPI.write(gDAC.BYTE.H);
00217     gSPI.write(gDAC.BYTE.L);
00218     gCSA = _DISABLE;        
00219 
00220     // GATE or SYNC OUT
00221     if(cnt & 0x01) {
00222         // GATE OUT
00223         gCSB = _ENABLE;
00224         rcv = gSPI.write(gGATE | MODE_GATE) & 0x0F;
00225         gCSB = _DISABLE;
00226     }
00227     else {
00228         // SYNC OUT
00229         gCSB = _ENABLE;
00230         rcv = gSPI.write(gSYNC | MODE_SYNC);
00231         gCSB = _DISABLE;
00232     }
00233 
00234     // SEL CV CHANNEL
00235     gCSB = _ENABLE;
00236     gSPI.write(ch);
00237     gCSB = _DISABLE;
00238 
00239     cnt < numptn ? cnt++ : cnt = 0;
00240 
00241     sw = CheckSW(rcv);
00242     DinSync(sw);
00243 }
00244 
00245 //-------------------------------------------------------------
00246 // DIN Sync
00247 
00248 void DinSync(unsigned char sw) {
00249 
00250     static unsigned int   cnt;
00251     static unsigned char  cnt48;
00252     static unsigned char  _cnt48;
00253 
00254     // BEAT COUNTER
00255     if((cnt48 % 24) < 12) {
00256         if( cnt >= gT1) {
00257             cnt = 0;
00258             cnt48++;
00259         }
00260     } 
00261     else {
00262         if( cnt >= gT2) {
00263             cnt = 0;
00264             cnt48++;
00265         }
00266     }
00267     if(cnt48 >= 48) cnt48 = 0;
00268 
00269     // START/STOP
00270     if(sw & (SW1 | SW2)) {
00271         if( !(gSYNC & (SYNC1RUN | SYNC2RUN))){
00272             cnt   = 0;
00273             cnt48 = 0;
00274             gGATE = 0;
00275         }
00276         if(sw & SW1) gSYNC ^= SYNC1RUN;
00277         if(sw & SW2) gSYNC ^= SYNC2RUN;
00278     }
00279 
00280     // TOGGLE SYNC CLOCK
00281     if(cnt48 & 0x01) {
00282         gSYNC &= ~(SYNC1CLK | SYNC2CLK);
00283     }
00284     else {
00285         gSYNC |= (SYNC1CLK | SYNC2CLK);
00286     }
00287 
00288     // SYNC LED
00289     gLED1 = gSYNC & SYNC1RUN ? 1 : 0;
00290     gLED2 = gSYNC & SYNC2RUN ? 1 : 0;
00291     gLED4 = cnt48 < 8 ? 1 : 0;
00292 
00293     // TOGGLE GATE OUT
00294     if(gSYNC & (SYNC1RUN | SYNC2RUN)) {
00295         if(cnt48 != _cnt48) {
00296             if((cnt48 %  6) == 0) gGATE ^= GATE1;
00297             if((cnt48 % 12) == 0) gGATE ^= GATE2;
00298             if((cnt48 % 24) == 0) gGATE ^= GATE3;
00299             if((cnt48 % 48) == 0) gGATE ^= GATE4;
00300         }
00301     }
00302     else gGATE = 0;
00303     _cnt48 = cnt48;        
00304 
00305     cnt++;
00306 }
00307 
00308 //-------------------------------------------------------------
00309 // Check SW
00310 
00311 unsigned char CheckSW(unsigned char c) {
00312 
00313     static unsigned char  swbuf[2];
00314     static unsigned int   cntsw;
00315     unsigned char ret = 0;
00316 
00317     if(cntsw > SW_WATCH_INTERVAL) {
00318         if(c &= 0x0F) {
00319             if(!swbuf[1]) {
00320                 if( swbuf[0] == c) {
00321                     swbuf[1] = c;
00322                     ret = c;
00323                 }
00324                 else {
00325                     swbuf[0] = c;
00326                 }
00327             }
00328         }
00329         else {
00330             swbuf[1] = 0;
00331             swbuf[0] = 0;
00332         }
00333         cntsw = 0;
00334     }
00335     cntsw++;
00336     return ret;
00337 }