KAMUI DIN-SYNC Example

Dependencies:   TextLCD mbed

Revision:
0:e3174b02ec81
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat May 05 11:34:19 2012 +0000
@@ -0,0 +1,337 @@
+//-------------------------------------------------------------
+// KAMUI DIN SYNC Example
+// Copyright (C) 2012 RJB RadioJunkBox
+// Released under the MIT License: http://mbed.org/license/mit
+//-------------------------------------------------------------
+
+#include "mbed.h"
+#include "TextLCD.h"
+
+//-------------------------------------------------------------
+// Define
+
+#define AD5551                      // 14bitDAC
+
+#define SPI_RATE            1000000 // 1Mbps
+#define MIDI_RATE           31250   // 31.25kbps
+#define BEEP_FREQ           1760.0  // 1760Hz
+#define UPDATE_INTERVAL     50      // 50us
+#define SW_WATCH_INTERVAL   (25000/UPDATE_INTERVAL) // 25ms
+
+#define UPDATE_MODE0        0       // Update Interval CV ch1-6 600us, ch7,8 200us
+#define UPDATE_MODE1        1       // Update Interval CV ch1-6 N/A, ch7,8 100us
+
+#define GATE1               0x01
+#define GATE2               0x02
+#define GATE3               0x04
+#define GATE4               0x08
+
+#define SYNC1CLK            0x01
+#define SYNC1RUN            0x02
+#define SYNC2CLK            0x04
+#define SYNC2RUN            0x08
+
+#define MODE_CV             0x00
+#define MODE_GATE           0x40
+#define MODE_SYNC           0x80
+#define MODE_SET_SYNC       0xC0
+
+#define SW1                 0x01
+#define SW2                 0x02
+#define SW3                 0x04
+#define SW4                 0x08
+#define SYNC1CLK_IN         0x10
+#define SYNC1RUN_IN         0x20
+#define SYNC2CLK_IN         0x40
+#define GATE_IN             0x80
+
+#define _ENABLE             0
+#define _DISABLE            1
+
+#define TBASE               (60*1000000/(48*UPDATE_INTERVAL))
+
+//-------------------------------------------------------------
+// Functions
+
+void InitKamui(void);
+void UpdateCV(void);
+void DinSync(unsigned char);
+unsigned char CheckSW(unsigned char);
+
+//-------------------------------------------------------------
+// Global Variables
+
+int gUpdateMode;
+unsigned short gCV[8];
+unsigned char  gGATE;
+unsigned char  gSYNC;
+unsigned short gT1,gT2;
+
+union {
+    unsigned short    WORD;    
+    struct {
+        unsigned char L;
+        unsigned char H; 
+    } BYTE;
+} gDAC;
+
+//-------------------------------------------------------------
+// mbed Functions
+
+// TextLCD
+TextLCD gLCD(p23, p24, p25, p26, p29, p30); // rs, e, d4-d7
+
+// SPI
+SPI gSPI(p11,p12,p13);
+DigitalOut gCSA(p14);
+DigitalOut gCSB(p22);
+
+// Sirial MIDI
+Serial gMIDI(p9,p10);
+
+// AnalogIn
+AnalogIn    gAIN1(p15);   // VR1
+AnalogIn    gAIN2(p16);   // VR2
+AnalogIn    gAIN3(p17);   // VR3
+AnalogIn    gAIN4(p18);   // VR4
+AnalogIn    gAIN5(p19);   // IN1
+AnalogIn    gAIN6(p20);   // IN2
+
+// BEEP
+PwmOut gBEEP(p21);
+
+// LED
+DigitalOut gLED1(LED1);
+DigitalOut gLED2(LED2);
+DigitalOut gLED3(LED3);
+DigitalOut gLED4(LED4);
+BusOut gLEDS(LED1,LED2,LED3,LED4);
+
+// Ticker
+Ticker gTICKER;
+
+//-------------------------------------------------------------
+// main
+
+int main() {
+
+    unsigned int pot1, pot2, pot3, pot4;
+    unsigned int tempo;
+    unsigned int t,s;
+
+    InitKamui();    
+
+    while(1) {
+
+        // POT1 Tempo 40 - 220 bpm
+        // POT2 Suffle Rate
+        // POT3 CV1 - CV4     0V - +10V
+        // POT4 CV5 - CV8   -10V - +10V
+        
+        pot1 = gAIN1.read_u16();
+        pot2 = gAIN2.read_u16() / 0x0400;
+        pot3 = gAIN3.read_u16() / 2 + 0x8000;
+        pot4 = gAIN4.read_u16();
+        
+        tempo = pot1 / 364 + 40;
+        t = TBASE / tempo;
+        s = t * pot2 / 127; 
+        
+        gT1 = t + s;
+        gT2 = t - s;
+        
+        gCV[0] = pot3; 
+        gCV[1] = pot3; 
+        gCV[2] = pot3;
+        gCV[3] = pot3;
+        gCV[4] = pot4;
+        gCV[5] = pot4;
+        gCV[6] = pot4;
+        gCV[7] = pot4;
+        
+        gLCD.locate( 0, 1 );
+        gLCD.printf("TEMPO=%03d SFL=%02d", tempo, pot2);    
+    }
+}
+
+//-------------------------------------------------------------
+// Initialize KAMUI
+
+void InitKamui()
+{
+    // Init. Variables
+    for( int i=0; i<8; i++) {
+        gCV[i] = 0x8000;
+    }
+    gGATE = 0;
+    gSYNC = 0;
+
+    gUpdateMode = UPDATE_MODE0;
+  
+    // Init. SPI
+    gCSA = _DISABLE;
+    gCSB = _DISABLE;
+    gSPI.format(8,0);
+    gSPI.frequency(SPI_RATE);
+
+    // Init. Serial MIDI
+    gMIDI.baud(MIDI_RATE);
+    
+    // Ticker
+    gTICKER.attach_us(&UpdateCV, UPDATE_INTERVAL);
+
+    // Beep
+    gBEEP.period(1.0/BEEP_FREQ);
+    gBEEP.write(0.5);
+    wait(0.2);
+    gBEEP.write(0.0);
+
+    // Init Display
+    gLCD.locate( 0, 0 );
+              // 123456789ABCDEF
+    gLCD.printf("DIN-SyncExample");
+}
+
+//-------------------------------------------------------------
+// Update CV, GATE, SYNC
+
+void UpdateCV()
+{ 
+    unsigned char rcv,sw,ch;
+    unsigned char ptn[] = { 0,1,6,7,2,3,6,7,4,5,6,7 };
+    const int numptn = (sizeof ptn / sizeof ptn[0]) - 1;
+    static unsigned char  cnt;
+
+    // SET DAC 
+    ch = ptn[cnt];
+    if(gUpdateMode) ch |= 0x06;
+
+#ifdef AD5551 // 14bitDAC
+    gDAC.WORD = gCV[ch] >> 2;
+#else
+    gDAC.WORD = gCV[ch];    
+#endif
+    
+    gCSA = _ENABLE;
+    gSPI.write(gDAC.BYTE.H);
+    gSPI.write(gDAC.BYTE.L);
+    gCSA = _DISABLE;        
+
+    // GATE or SYNC OUT
+    if(cnt & 0x01) {
+        // GATE OUT
+        gCSB = _ENABLE;
+        rcv = gSPI.write(gGATE | MODE_GATE) & 0x0F;
+        gCSB = _DISABLE;
+    }
+    else {
+        // SYNC OUT
+        gCSB = _ENABLE;
+        rcv = gSPI.write(gSYNC | MODE_SYNC);
+        gCSB = _DISABLE;
+    }
+
+    // SEL CV CHANNEL
+    gCSB = _ENABLE;
+    gSPI.write(ch);
+    gCSB = _DISABLE;
+
+    cnt < numptn ? cnt++ : cnt = 0;
+
+    sw = CheckSW(rcv);
+    DinSync(sw);
+}
+
+//-------------------------------------------------------------
+// DIN Sync
+
+void DinSync(unsigned char sw) {
+
+    static unsigned int   cnt;
+    static unsigned char  cnt48;
+    static unsigned char  _cnt48;
+
+    // BEAT COUNTER
+    if((cnt48 % 24) < 12) {
+        if( cnt >= gT1) {
+            cnt = 0;
+            cnt48++;
+        }
+    } 
+    else {
+        if( cnt >= gT2) {
+            cnt = 0;
+            cnt48++;
+        }
+    }
+    if(cnt48 >= 48) cnt48 = 0;
+
+    // START/STOP
+    if(sw & (SW1 | SW2)) {
+        if( !(gSYNC & (SYNC1RUN | SYNC2RUN))){
+            cnt   = 0;
+            cnt48 = 0;
+            gGATE = 0;
+        }
+        if(sw & SW1) gSYNC ^= SYNC1RUN;
+        if(sw & SW2) gSYNC ^= SYNC2RUN;
+    }
+
+    // TOGGLE SYNC CLOCK
+    if(cnt48 & 0x01) {
+        gSYNC &= ~(SYNC1CLK | SYNC2CLK);
+    }
+    else {
+        gSYNC |= (SYNC1CLK | SYNC2CLK);
+    }
+
+    // SYNC LED
+    gLED1 = gSYNC & SYNC1RUN ? 1 : 0;
+    gLED2 = gSYNC & SYNC2RUN ? 1 : 0;
+    gLED4 = cnt48 < 8 ? 1 : 0;
+
+    // TOGGLE GATE OUT
+    if(gSYNC & (SYNC1RUN | SYNC2RUN)) {
+        if(cnt48 != _cnt48) {
+            if((cnt48 %  6) == 0) gGATE ^= GATE1;
+            if((cnt48 % 12) == 0) gGATE ^= GATE2;
+            if((cnt48 % 24) == 0) gGATE ^= GATE3;
+            if((cnt48 % 48) == 0) gGATE ^= GATE4;
+        }
+    }
+    else gGATE = 0;
+    _cnt48 = cnt48;        
+
+    cnt++;
+}
+
+//-------------------------------------------------------------
+// Check SW
+
+unsigned char CheckSW(unsigned char c) {
+
+    static unsigned char  swbuf[2];
+    static unsigned int   cntsw;
+    unsigned char ret = 0;
+
+    if(cntsw > SW_WATCH_INTERVAL) {
+        if(c &= 0x0F) {
+            if(!swbuf[1]) {
+                if( swbuf[0] == c) {
+                    swbuf[1] = c;
+                    ret = c;
+                }
+                else {
+                    swbuf[0] = c;
+                }
+            }
+        }
+        else {
+            swbuf[1] = 0;
+            swbuf[0] = 0;
+        }
+        cntsw = 0;
+    }
+    cntsw++;
+    return ret;
+}