KAMUI OSC-CV Example refer to OSCReceiver by xshige http://mbed.org/users/xshige/programs/OSCReceiver/

Dependencies:   NetServices TextLCD mbed

Revision:
0:eabe87e89290
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun May 06 07:17:59 2012 +0000
@@ -0,0 +1,444 @@
+//-------------------------------------------------------------
+// KAMUI OSC-CV Exapmple
+//   referred to xshige's OSCReceiver
+//   http://mbed.org/users/xshige/programs/OSCReceiver/
+// Copyright (C) 2012 RJB RadioJunkBox
+// Released under the MIT License: http://mbed.org/license/mit
+//-------------------------------------------------------------
+
+#include "mbed.h"
+#include "TextLCD.h"
+#include "EthernetNetIf.h"
+#include "UDPSocket.h"
+#include "OSCReceiver.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include <math.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     100     // 100us
+#define SW_WATCH_INTERVAL   (25000/UPDATE_INTERVAL) // 25ms
+#define PARAM_GLIDE         6554.0
+
+#define UPDATE_MODE0        0       // Update Interval CV ch1-6 1200us, ch7,8 400us
+#define UPDATE_MODE1        1       // Update Interval CV ch1-6 N/A,    ch7,8 200us
+
+#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
+
+//-------------------------------------------------------------
+// Functions
+
+void            InitKamui(void);
+void            UpdateCV(void);
+unsigned char   CheckSW(unsigned char);
+
+void            SetCV(void);
+int             SetupEthNetIf(void);
+void            onUDPSocketEvent(UDPSocketEvent);
+
+//-------------------------------------------------------------
+// Global Variables
+
+int gUpdateMode;
+unsigned short gCV[8];
+unsigned char  gGATE;
+unsigned char  gSYNC;
+unsigned char  gSW;
+
+union {
+    unsigned short    WORD;    
+    struct {
+        unsigned char L;
+        unsigned char H; 
+    } BYTE;
+} gDAC;
+
+float           gGLIDE[8];
+float           gOSC_CV[8];
+
+//-------------------------------------------------------------
+// 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;
+
+// Ethernet
+EthernetNetIf gEth;
+UDPSocket gUdp;
+
+//-------------------------------------------------------------
+// main
+
+int main() {
+
+    int i;
+    int pot[4],_pot[4];
+    unsigned char ch = 0;
+    unsigned char mode = 7; // for Intialize
+    unsigned char edit[4];
+    int val[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+    // Initialize
+    for( i=0; i<4; i++) {
+        pot[i] = _pot[i] = 0;
+        edit[i] = 0;
+        gGLIDE[i] = 1.0 / expf(val[i]*656.0/PARAM_GLIDE);
+        gGLIDE[i+4] = 1.0 / expf(val[i+4]*656.0/PARAM_GLIDE);
+    }
+    gSW = SW4; // for Intialize
+    
+    InitKamui();
+    if(SetupEthNetIf() == -1)
+    {
+        gBEEP.write(0.5);
+        wait(1);
+        gBEEP.write(0.0);
+        return -1;
+    }
+
+    // loop
+    while(1) {
+    
+        // Ethernet Polling
+        Net::poll();
+
+        // Read pot
+        pot[0] =  gAIN1.read_u16();
+        pot[1] =  gAIN2.read_u16();
+        pot[2] =  gAIN3.read_u16();
+        pot[3] =  gAIN4.read_u16();
+        
+        // change pot amount?
+        if(abs(pot[ch] - _pot[ch]) > 0x2000) edit[ch] = 1;
+
+        if(edit[ch]) {
+            switch(mode) {
+                case 0:
+                    gGLIDE[ch] = 1.0 / expf(pot[ch]/PARAM_GLIDE);
+                    val[ch] = pot[ch] / 656;
+                    break;
+                case 1:
+                    gGLIDE[ch+4] = 1.0 / expf(pot[ch]/PARAM_GLIDE);
+                    val[ch+4] = pot[ch] / 656;
+                    break;
+                default:
+                    break;
+            }
+        }
+        
+        // Push Mode SW
+        if(gSW & SW4) {
+            mode++;
+            mode &= 0x01;                      
+            for( i=0; i<4; i++) {
+                _pot[i] = pot[i];
+                edit[i] = 0;
+            }
+        }
+        gSW = 0;
+
+        // LCD Display
+        gLCD.locate( 0, 1 );
+        switch(mode) {
+            case 0:
+                gLCD.printf("G1-4 %02d %02d %02d %02d",
+                    val[0], val[1], val[2], val[3]);
+                break;
+            case 1:
+                gLCD.printf("G5-8 %02d %02d %02d %02d",
+                    val[4], val[5], val[6], val[7]);
+                break;
+        }
+
+        ch++;
+        ch &= 0x03;
+    }
+}
+
+//-------------------------------------------------------------
+// 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("OSC-CV Example ");
+}
+
+//-------------------------------------------------------------
+// Update CV, GATE, SYNC
+
+void UpdateCV()
+{ 
+    unsigned char rcv,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;
+
+    __disable_irq();
+
+    // 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;
+
+    __enable_irq();
+
+    gSW |= CheckSW(rcv);
+    SetCV();
+}
+
+//-------------------------------------------------------------
+// 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;
+}
+
+//-------------------------------------------------------------
+// Set CV
+
+void SetCV()
+{
+    static unsigned char ch;
+    static float cvf[8];
+    unsigned int cv;
+    
+    // Calculate CV
+    cvf[ch] = (gOSC_CV[ch] - cvf[ch]) * gGLIDE[ch] + cvf[ch];       
+    cv = (unsigned int)cvf[ch] + 0x8000;
+    if(cv > 0xFFFF) cv = 0xFFFF;
+    gCV[ch] = cv;
+
+    ch++;
+    ch &= 0x07;
+}
+
+//-------------------------------------------------------------
+// Setup Ethernet port
+
+int SetupEthNetIf()
+{
+    gLCD.locate( 0, 1 );
+    gLCD.printf("Setting up...   ");
+//    printf("Setting up...\r\n");
+
+    EthernetErr ethErr = gEth.setup();
+    if(ethErr)
+    {
+        gLCD.locate( 0, 1 );
+        gLCD.printf("Error in setup.");
+//        printf("Error %d in setup.\r\n", ethErr);
+        return -1;
+    }
+//    printf("Setup OK\r\n");
+
+//    printf("IP address %d.%d.%d.%d\r\n", gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], gEth.getIp()[3]);
+    Host broadcast(IpAddr(gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], 255), 12345, NULL);
+    gUdp.setOnEvent(&onUDPSocketEvent);
+    gUdp.bind(broadcast);
+
+    gLCD.locate( 0, 1 );
+    gLCD.printf("%03d.%03d.%03d.%03d", gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], gEth.getIp()[3]);
+    wait(2.0);
+    
+    return 0;
+}
+
+//-------------------------------------------------------------
+// Handller receive UDP Packet
+
+void onUDPSocketEvent(UDPSocketEvent e)
+{
+    union OSCarg msg[10];
+    int num;
+
+    switch(e)
+    {
+        case UDPSOCKET_READABLE: //The only event for now
+            char buf[256] = {0};
+            Host host;
+            
+            while( int len = gUdp.recvfrom( buf, 256, &host ) )
+            {
+                if(len <= 0)  break;
+                // printf("\r\nFrom %d.%d.%d.%d:\r\n", 
+                // host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3]);
+      
+                getOSCmsg(buf,msg);
+//                printf("OSCmsg: %s %s %f %i\r\n", 
+//                    msg[0].address, msg[1].typeTag, msg[2].f, msg[2].i);
+                
+                len = strlen(msg[0].address);
+                if(isdigit(msg[0].address[len-1])) num = msg[0].address[len-1] - '0' - 1;
+                else num = -1;
+
+                // address pattern CV
+                if((strncmp(msg[0].address,"/kamui/cv",9)==0) && (num != -1)) {
+
+                    if(num > 7) break;
+                    if(msg[1].typeTag[1] == 'f') gOSC_CV[num] = msg[2].f * 3072.0;
+                    if(msg[1].typeTag[1] == 'i') gOSC_CV[num] = msg[2].i * 3072.0;
+
+                    break;
+                }
+
+                // address pattern GATE
+                if((strncmp(msg[0].address,"/kamui/gate",11)==0) && (num != -1)) {
+
+                    if(num > 3) break;
+                        if(msg[2].i) gGATE |=  (0x01 << num);
+                        else         gGATE &= ~(0x01 << num);
+
+                    break;
+                }
+            
+                //  printf("undefined OSCmsg:%s %s\r\n",msg[0].address, msg[1].typeTag);
+        }
+        break;
+    }
+}