Radio Junk Box
/
KAMUI_DIN-SYNC_Example
KAMUI DIN-SYNC Example
main.cpp
- Committer:
- radiojunkbox
- Date:
- 2012-05-05
- Revision:
- 0:e3174b02ec81
File content as of revision 0:e3174b02ec81:
//------------------------------------------------------------- // 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; }