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

Dependencies:   NetServices TextLCD mbed

Files at this revision

API Documentation at this revision

Comitter:
radiojunkbox
Date:
Sun May 06 07:17:59 2012 +0000
Commit message:
Rev. 1.0

Changed in this revision

NetServices.lib Show annotated file Show diff for this revision Revisions of this file
OSCReceiver.cpp Show annotated file Show diff for this revision Revisions of this file
OSCReceiver.h Show annotated file Show diff for this revision Revisions of this file
TextLCD.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NetServices.lib	Sun May 06 07:17:59 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/segundo/code/NetServices/#4e2468d7d5cb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OSCReceiver.cpp	Sun May 06 07:17:59 2012 +0000
@@ -0,0 +1,235 @@
+// 
+// OSC Receiver
+//
+// date: 2011/1/10
+// version: 0.7
+// written by: xshige
+//
+// please find OSC Sender program at the bottom of this file
+//
+/*
+  The followings are supported:
+
+    Transport Type: 
+      UDP
+
+    Features: 
+     Packet Parsing (Client)
+     Not Supported:Packet Construction (Server)
+     Bundle NOT Support
+     Timetag NOT Support
+
+    Type Support: 
+     i: int32
+     b: blob
+     s: string
+     f: float32
+     m: MIDI message(port id, status byte, data1, data2) // I don't know the detail
+ 
+*/
+
+
+#include "mbed.h"
+#include "OSCReceiver.h" // Add by RadioJunkBox 2012/05/16 
+
+/* comment out by RadioJunkBox 2012/05/16
+
+#include "EthernetNetIf.h"
+#include "UDPSocket.h"
+
+#define DHCP
+
+//#define INPUT_PORT 12000
+#define INPUT_PORT 12345
+
+#ifdef DHCP
+EthernetNetIf eth;
+#else
+EthernetNetIf eth(
+  IpAddr(192,168,0,25), //IP Address
+  IpAddr(255,255,255,0), //Network Mask
+  IpAddr(192,168,0,1), //Gateway
+  IpAddr(192,168,0,1)  //DNS
+);
+#endif
+//--- OSC related stuff ---
+union OSCarg {
+// char*, int and float are assumed four bytes
+        char *address;
+        char *typeTag;
+        int i;
+        float f;
+        char *s;
+        struct {
+            int len; // is "int i"
+            char *p;
+        } blob;
+        char m[4];  // for MIDI
+        char _b[4]; // endian conversion temp variable
+};
+*/
+void getOSCmsg(char *packet , union OSCarg *msg){
+// Caution: the returned result points to packet as blobs or strings (not newly allocatd)
+    char *p, *typeTag; char c;
+        
+    msg[0].address = packet; // address
+    msg[1].typeTag = packet+4*(strlen(msg[0].s)/4+1);//typeTag
+    typeTag=msg[1].s+1; // skip ','
+    p= msg[1].s+4*(strlen(msg[1].s)/4+1);
+    for(int n=0; n<strlen(typeTag); n++){
+        c = typeTag[n];
+        if (('s'==c)) {
+            msg[n+2].s=p;
+            p += 4*(strlen(msg[n+2].s)/4+1);
+        } else if (('i'==c)||('f'==c)) {
+            // chang endian (big to little)
+            msg[n+2]._b[3]=p[0]; 
+            msg[n+2]._b[2]=p[1]; 
+            msg[n+2]._b[1]=p[2];
+            msg[n+2]._b[0]=p[3];
+            p +=4;  
+        } else if ('b'==c) {
+            // chang endian (big to little)
+            // get lenth of blog (copy to msg[n].blog.len)
+            msg[n+2]._b[3]=p[0]; 
+            msg[n+2]._b[2]=p[1]; 
+            msg[n+2]._b[1]=p[2];
+            msg[n+2]._b[0]=p[3];
+            p +=4;  
+            // get ponter of blog (copy to msg[n].blog.p)
+            msg[n+2].blob.p=p;
+            p += 4*(msg[n+2].blob.len/4+1);       
+        } else if ('m'==c) {
+            // get midi data (copy to msg[n].m[])
+            msg[n+2].m[0]=p[0]; 
+            msg[n+2].m[1]=p[1]; 
+            msg[n+2].m[2]=p[2];
+            msg[n+2].m[3]=p[3];
+            p +=4;  
+        } else {
+            printf("*** Not Supported TypeTag:%s ****\n",typeTag);
+        }
+    };
+    
+}
+//-------------------------------------------
+
+/* comment out RadioJunkBox 2012/05/06
+
+UDPSocket udp;
+
+
+void onUDPSocketEvent(UDPSocketEvent e)
+{
+  union OSCarg msg[10];
+
+  switch(e)
+  {
+  case UDPSOCKET_READABLE: //The only event for now
+    char buf[256] = {0};
+    Host host;
+    while( int len = udp.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);
+      // address pattern samples
+      if (strcmp(msg[0].address,"/test")==0) {
+        printf("OSCmsg: %s %s %d %f %s %d\n", 
+            msg[0].address, msg[1].typeTag,msg[2].i, msg[3].f, msg[4].s, msg[5].blob.len);
+        printf("blob content:\n");
+        char *p=msg[5].blob.p;
+        for(int n=0; n<msg[5].blob.len; p++,n++) printf(" %02X",(unsigned char)(*p));
+        printf("\n");
+        break;
+      }
+      if (strcmp(msg[0].address,"/kb/m")==0) {
+        printf("OSCmsg: %s %s %d %d %d\n", 
+            msg[0].address, msg[1].typeTag,msg[2].i, msg[3].i, msg[4].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/cc/m")==0) {
+        printf("OSCmsg: %s %s %d %d %d\n", 
+            msg[0].address, msg[1].typeTag,msg[2].i, msg[3].i, msg[4].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/osc/padx")==0) {
+        printf("OSCmsg: %s %s %f\n", 
+            msg[0].address, msg[1].typeTag,msg[2].f);
+        break;
+      }
+      if (strcmp(msg[0].address,"/osc/pady")==0) {
+        printf("OSCmsg: %s %s %f\n", 
+            msg[0].address, msg[1].typeTag, msg[2].f);
+        break;
+      } 
+      if (strcmp(msg[0].address,"/osc/button1")==0) {
+        printf("OSCmsg: %s %s %i\n", 
+            msg[0].address, msg[1].typeTag, msg[2].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/osc/button2")==0) {
+        printf("OSCmsg: %s %s %i\n", 
+            msg[0].address, msg[1].typeTag, msg[2].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/mouse/dragged")==0) {
+        printf("OSCmsg: %s %s %i %i\n", 
+            msg[0].address, msg[1].typeTag, msg[2].i, msg[3].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/mouse/pressed")==0) {
+        printf("OSCmsg: %s %s %i %i\n", 
+            msg[0].address, msg[1].typeTag, msg[2].i, msg[3].i);
+        break;
+      }
+      if (strcmp(msg[0].address,"/1/xy")==0) {
+        printf("OSCmsg: %s %s %f %f %d\n", 
+            msg[0].address, msg[1].typeTag, msg[2].f, msg[3].f, msg[4].i);
+        break;
+      }
+      printf("undefined OSCmsg:%s %s\n",msg[0].address, msg[1].typeTag);
+    } // while
+    break;
+  } // case
+}
+
+int main() {
+// make debug port Fast
+//   Serial pc(USBTX, USBRX);
+//    pc.baud(9600);
+//    pc.baud(115200);
+//  pc.baud(230400);
+
+  printf("Setting up...\r\n");
+  EthernetErr ethErr = eth.setup();
+  if(ethErr)
+  {
+    printf("Error %d in setup.\r\n", ethErr);
+    return -1;
+  }
+  printf("Setup OK\r\n");
+  
+
+  // port setup
+//  Host recHost(IpAddr(192, 168, 0, 7), INPUT_PORT, NULL);
+  Host broadcast(IpAddr(eth.getIp()[0], eth.getIp()[1], eth.getIp()[2], 255), INPUT_PORT, NULL);
+  udp.setOnEvent(&onUDPSocketEvent);
+  udp.bind(broadcast);
+  
+  Timer tmr;
+  tmr.start();
+  while(true)
+  {
+    Net::poll();
+    if(tmr.read() > 5)
+    {
+      tmr.reset();
+    }
+  }
+
+}
+*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OSCReceiver.h	Sun May 06 07:17:59 2012 +0000
@@ -0,0 +1,30 @@
+//-------------------------------------------------------------
+// KAMUI OSC-CV Example
+// file : OSCReceiver.h
+//   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
+//-------------------------------------------------------------
+
+#ifndef MBED_OSCRECEIVER_H
+#define MBED_OSCRECEIVER_H
+
+union OSCarg {
+// char*, int and float are assumed four bytes
+        char *address;
+        char *typeTag;
+        int i;
+        float f;
+        char *s;
+        struct {
+            int len; // is "int i"
+            char *p;
+        } blob;
+        char m[4];  // for MIDI
+        char _b[4]; // endian conversion temp variable
+};
+
+void getOSCmsg(char *packet , union OSCarg *msg);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD.lib	Sun May 06 07:17:59 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/simon/code/TextLCD/#44f34c09bd37
--- /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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun May 06 07:17:59 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479