Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Bonjour OSCReceiver TextLCD mbed mbed-rpc BurstSPI DebouncedInterrupt FastIO MIDI OSC OSCtoCV ClockControl
Revision 4:b9f5ae574447, committed 2013-01-19
- Comitter:
- casiotone401
- Date:
- Sat Jan 19 12:03:20 2013 +0000
- Parent:
- 3:ca15241dd6b4
- Child:
- 5:e305509d53f3
- Commit message:
- added Sequencer & Shift Register Mode
Changed in this revision
| main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Fri Jan 11 11:33:55 2013 +0000
+++ b/main.cpp Sat Jan 19 12:03:20 2013 +0000
@@ -41,6 +41,8 @@
#define MODE_QDor 3 // Dorian
#define MODE_Q5th 4 // 5th
#define MODE_QWht 5 // Wholetone
+#define MODE_SEQ 6 // Sequencer & Shift Register
+#define MODE_Calb 7 // Calibration (VCO Tuning)
#define QUAN_RES1 116 // Quantize voltage Steps
#define QUAN_RES2 69
@@ -48,7 +50,7 @@
#define QUAN_RES4 17
#define QUAN_RES5 58
-#define MODE_NUM 6 // Modes
+#define MODE_NUM 8 // Modes
#define SPI_RATE 40000000 // 40Mbps SPI Clock
#define SCALING_N 38400.0
@@ -77,15 +79,17 @@
//-------------------------------------------------------------
// Functions
-void NetPoll(void);
+inline void NetPoll(void);
void InitOSCCV(void);
-void UpdateCV(unsigned char, unsigned char, unsigned int);
+inline void UpdateCV(int, int, const unsigned int*);
void SetCV(void);
+void SeqCV(void);
void CheckSW(void);
-void CVMeter(unsigned int, unsigned int);
+void CVMeter(int, const unsigned int*);
+void LCD();
void WriteCustomChar(unsigned char, unsigned char*);
int SetupEthNetIf(void);
-void onUDPSocketEvent(UDPSocketEvent);
+inline void onUDPSocketEvent(UDPSocketEvent);
//-------------------------------------------------------------
// Silentway Calibration Data Mapping
@@ -164,7 +168,7 @@
};
-// 5th
+// Whole tone
const float calibMap5[QUAN_RES5] = {
0.00663080, 0.02202980, 0.03742880, 0.05282781, 0.06822681,
0.08362581, 0.09902481, 0.11442380, 0.12951356, 0.14392516,
@@ -196,8 +200,12 @@
//-------------------------------------------------------------
// Global Variables
-float gOSC_cv[8];
-float gGlide;
+static float gOSC_cv[8];
+static float gSeq_cv1[8];
+static float gSeq_cv2[8];
+static float gGlide;
+static float gCtrl[2];
+unsigned int gCtrlSW[2];
unsigned int gMode;
//-------------------------------------------------------------
@@ -216,7 +224,7 @@
AnalogIn gAIN(p17); // Glide Potentiometer
InterruptIn gSW(p30); // Mode SW
-Ticker gSetter; // Ticker SetCV
+Timer gTimer; // Timer
Ticker gPoller; // Ticker Polling
// Ethernet
@@ -228,12 +236,11 @@
int main()
{
- int i;
float pot, _pot;
if(SetupEthNetIf() == -1)
{
- for(i = 0; i < 4; i++)
+ for(int i = 0; i < 4; i++)
{
gLEDS[i] = 1;
wait(0.25);
@@ -244,6 +251,7 @@
// mdns (Bonjour)
HTTPServer svr;
mDNSResponder mdns;
+
svr.addHandler<SimpleHandler>("/");
svr.bind(INPUT_PORT);
IpAddr ip = gEth.getIp();
@@ -251,34 +259,41 @@
InitOSCCV();
- pot = _pot = 0;
-
- gLCD.locate( 9, 0 );
- gLCD.printf("OSC-CV");
+ pot = _pot = 0;
+ gGlide = gMode = 0;
+
+ LCD();
gLCD.locate( 0, 1 );
gLCD.printf("12345678 G>>%3.2f", gGlide);
-
// loop
while(1)
{
gGlide = pot = gAIN.read();
- if(abs(pot - _pot) > 0.01)
+ if(abs(pot - _pot) > 0.01f)
{
gLCD.locate( 0, 1 );
gLCD.printf("12345678 G>>%3.2f", gGlide);
+
_pot = gAIN.read();
}
- SetCV();
+ if(gMode == MODE_SEQ)
+ {
+ SeqCV();
+
+ } else {
+
+ SetCV();
+ }
}
}
//-------------------------------------------------------------
// Ethernet Polling
-void NetPoll()
+inline void NetPoll()
{
Net::poll();
}
@@ -305,11 +320,9 @@
UpdateCV(CLR, 0, 0); // Ignore CLR Pin
- gSW.mode(PullUp); //Use internal pullup for ModeSW
+ gSW.mode(PullUp); // Use internal pullup for ModeSW
wait(.001);
- gMode = 0;
-
gSW.rise(&CheckSW); // InterruptIn rising edge(ModeSW)
gPoller.attach_us(&NetPoll, POLLING_INTERVAL); // Ticker Polling
@@ -320,44 +333,43 @@
// SPI Transfer
// DAC8568 data word length 32bit (8bit shift out)
-void UpdateCV(unsigned char control, unsigned char address, unsigned int data)
+inline void UpdateCV(int control, int address, const unsigned int *data)
{
__disable_irq();
switch(control)
{
case WRITE_UPDATE_N:
- {
+
gSYNCMODE = _DISABLE;
- gSPI.write(00000000|control); //padding at beginning of byte and control bits
- gSPI.write(address << 4 | data >> 12); //address(ch) bits
- gSPI.write((data << 4) >> 8); // middle 8 bits of data
- gSPI.write((data << 12) >> 8 | 00001111);
+ gSPI.write(00000000|control); // padding at beginning of byte and control bits
+ gSPI.write(address << 4 | *data >> 12); // address(ch) bits
+ gSPI.write((*data << 4) >> 8); // middle 8 bits of data
+ gSPI.write((*data << 12) >> 8 | 00001111);
gSYNCMODE = _ENABLE;
gLDAC = _DISABLE;
gLDAC = _ENABLE;
break;
- }
+
case RESET:
- {
+
gSYNCMODE = _DISABLE;
- gSPI.write(00000111); //Software RESET
+ gSPI.write(00000111); // Software RESET
gSPI.write(00000000);
gSPI.write(00000000);
gSPI.write(00000000);
gSYNCMODE = _ENABLE;
break;
- }
+
case CLR:
- {
+
gSYNCMODE = _DISABLE;
- gSPI.write(00000101); //CLR Register
+ gSPI.write(00000101); // CLR Register
gSPI.write(00000000);
gSPI.write(00000000);
- gSPI.write(00000011); //Ignore CLR Pin
+ gSPI.write(00000011); // Ignore CLR Pin
gSYNCMODE = _ENABLE;
break;
- }
}
__enable_irq();
@@ -368,7 +380,7 @@
void SetCV()
{
- static unsigned int ch;
+ static int ch;
float glidecv[8];
unsigned int cv[8];
static float oldcv[8];
@@ -378,94 +390,314 @@
switch(gMode)
{
case MODE_LIN:
-
+
glidecv[ch] = oldcv[ch] * gGlide + gOSC_cv[ch] * (1.0f - gGlide);
oldcv[ch] = glidecv[ch];
cv[ch] = (unsigned int)glidecv[ch];
- UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
+ UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
break;
case MODE_QChr:
- quan = 43690 / QUAN_RES1;
- qcv = calibMap1[(unsigned int)(gOSC_cv[ch] / quan )];
+ quan = 40616 / QUAN_RES1;
+ qcv = calibMap1[(unsigned int)(gOSC_cv[ch] / quan)];
+
+ glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+ oldcv[ch] = glidecv[ch];
+ cv[ch] = (unsigned int)glidecv[ch];
+
+ UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
+ break;
+
+ case MODE_QMaj:
+
+ quan = 40616 / QUAN_RES2;
+ qcv = calibMap2[(unsigned int)(gOSC_cv[ch] / quan)];
glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
oldcv[ch] = glidecv[ch];
cv[ch] = (unsigned int)glidecv[ch];
- UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
+ UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
break;
+
+ case MODE_QDor:
- case MODE_QMaj:
-
- quan = 43690 / QUAN_RES2;
- qcv = calibMap2[(unsigned int)(gOSC_cv[ch] / quan )];
+ quan = 40616 / QUAN_RES3;
+ qcv = calibMap3[(unsigned int)(gOSC_cv[ch] / quan)];
glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
oldcv[ch] = glidecv[ch];
cv[ch] = (unsigned int)glidecv[ch];
- UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
+ UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
break;
+
+ case MODE_Q5th:
+
+ quan = 40616 / QUAN_RES4;
+ qcv = calibMap4[(unsigned int)(gOSC_cv[ch] / quan)];
- case MODE_QDor:
+ glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+ oldcv[ch] = glidecv[ch];
+ cv[ch] = (unsigned int)glidecv[ch];
+
+ UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
+ break;
- quan = 43690 / QUAN_RES3;
- qcv = calibMap3[(unsigned int)(gOSC_cv[ch] / quan )];
+ case MODE_QWht:
+
+ quan = 40616 / QUAN_RES5;
+ qcv = calibMap5[(unsigned int)(gOSC_cv[ch] / quan)];
glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
oldcv[ch] = glidecv[ch];
cv[ch] = (unsigned int)glidecv[ch];
- UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
- break;
-
- case MODE_Q5th:
-
- quan = 43690 / QUAN_RES4;
- qcv = calibMap4[(unsigned int)(gOSC_cv[ch] / quan )];
-
- glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
- oldcv[ch] = glidecv[ch];
- cv[ch] = (unsigned int)glidecv[ch];
-
- UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
+ UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
break;
- case MODE_QWht:
+ case MODE_Calb:
- quan = 43690 / QUAN_RES5;
- qcv = calibMap5[(unsigned int)(gOSC_cv[ch] / quan )];
-
- glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
- oldcv[ch] = glidecv[ch];
- cv[ch] = (unsigned int)glidecv[ch];
+ cv[ch] = 19212; // A440.0Hz
- UpdateCV(WRITE_UPDATE_N, ch, cv[ch]);
+ UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
break;
}
+
+ CVMeter(ch, &cv[ch]);
- CVMeter(ch, cv[ch]);
ch++;
ch &= 0x07;
}
//-------------------------------------------------------------
+// Sequence & Shift Out CV
+
+void SeqCV()
+{
+ static int ch;
+ static int count;
+ static unsigned int SeqMode;
+ static float glidecv[8];
+ unsigned int cv[8];
+ static float shiftcv[8];
+ static unsigned int quan;
+ float qcv;
+ static float clock;
+ static float time;
+
+ SeqMode = (unsigned int)(gCtrl[1] * (MODE_NUM - 3)); // Sequencer Quantize Mode
+
+ time = gTimer.read();
+ clock = gCtrl[0] * 0.5 + 0.01;
+
+ gLEDS[0] = gGATES[0] = 0; // Trigger
+
+ if(time > (clock / 2))
+ {
+ gLEDS[1] = gGATES[1] = 0; // Gate
+
+ } else if (count % 2) {
+
+ gLEDS[2] = gGATES[2] = 0;
+
+ } else if (count % 3) {
+
+ gLEDS[3] = gGATES[3] = 0;
+ count = 0;
+ }
+
+ switch(SeqMode)
+ {
+ case MODE_LIN:
+
+ if(ch < 8)
+ {
+ glidecv[0] = glidecv[0] * gGlide + gSeq_cv1[ch] * (1.0f - gGlide);
+
+ } else {
+
+ glidecv[0] = glidecv[0] * gGlide + gSeq_cv2[ch-8] * (1.0f - gGlide);
+ }
+
+ cv[0] = (unsigned int)glidecv[0];
+
+ UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+ break;
+
+ case MODE_QChr:
+
+ quan = 40616 / QUAN_RES1;
+
+ if(ch < 8)
+ {
+ qcv = calibMap1[(unsigned int)(gSeq_cv1[ch] / quan)];
+
+ } else {
+
+ qcv = calibMap1[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+ }
+
+ glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+ cv[0] = (unsigned int)glidecv[0];
+
+ UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+ break;
+
+ case MODE_QMaj:
+
+ quan = 40616 / QUAN_RES2;
+
+ if(ch < 8)
+ {
+ qcv = calibMap2[(unsigned int)(gSeq_cv1[ch] / quan)];
+
+ } else {
+
+ qcv = calibMap2[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+ }
+
+ glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+ cv[0] = (unsigned int)glidecv[0];
+
+ UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+ break;
+
+ case MODE_QDor:
+
+ quan = 40616 / QUAN_RES3;
+
+ if(ch < 8)
+ {
+ qcv = calibMap3[(unsigned int)(gSeq_cv1[ch] / quan)];
+
+ } else {
+
+ qcv = calibMap3[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+ }
+
+ glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+ cv[0] = (unsigned int)glidecv[0];
+
+ UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+ break;
+
+ case MODE_Q5th:
+
+ quan = 40616 / QUAN_RES4;
+
+ if(ch < 8)
+ {
+ qcv = calibMap4[(unsigned int)(gSeq_cv1[ch] / quan)];
+
+ } else {
+
+ qcv = calibMap4[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+ }
+
+ glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+ cv[0] = (unsigned int)glidecv[0];
+
+ UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+ break;
+
+ case MODE_QWht:
+
+ quan = 40616 / QUAN_RES5;
+
+ if(ch < 8)
+ {
+ qcv = calibMap5[(unsigned int)(gSeq_cv1[ch] / quan)];
+
+ } else {
+
+ qcv = calibMap5[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+ }
+
+ glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+ cv[0] = (unsigned int)glidecv[0];
+
+ UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
+ break;
+ }
+
+ for(int i = 1; i < 8; ++i)
+ {
+ glidecv[i] = glidecv[i] * gGlide + shiftcv[i] * (1.0f - gGlide);
+ cv[i] = (unsigned int)glidecv[i];
+
+ UpdateCV(WRITE_UPDATE_N, i, &cv[i]);
+ }
+
+ if(time > clock)
+ {
+ gLEDS[0] = gGATES[0] = 1;
+ gLEDS[1] = gGATES[1] = 1;
+ gLEDS[2] = gGATES[2] = 1;
+ gLEDS[3] = gGATES[3] = 1;
+
+ count++;
+
+ for(int j = 1; j < 8; ++j) // Shift Note
+ {
+ shiftcv[j] = glidecv[j-1];
+ }
+
+ ch++;
+ ch &= 0x0F;
+ gTimer.reset();
+ }
+
+ if(ch < 8)
+ {
+ CVMeter(ch, &cv[0]);
+
+ } else {
+
+ CVMeter((ch-8), &cv[0]);
+ }
+}
+
+//-------------------------------------------------------------
// Check SW
-void CheckSW()
+void CheckSW()
{
+ wait(0.01);
+
if(gMode < MODE_NUM - 1)
{
gMode++;
} else {
-
+
gMode = 0;
}
+ LCD();
+}
+
+//-------------------------------------------------------------
+// CV meter
+
+void CVMeter(int ch, const unsigned int *level)
+{
+ unsigned int cvmeter;
+
+ cvmeter = *level / 4860;
+ // cvmeter = *level / (SCALING_N / 7.9);
+
+ gLCD.locate ( ch, 0 );
+ gLCD.putc(cvmeter); // put custom char
+}
+
+//-------------------------------------------------------------
+// Print LCD Menu
+
+void LCD()
+{
switch(gMode)
{
case MODE_LIN:
@@ -497,23 +729,22 @@
gLCD.locate( 9, 0 );
gLCD.printf("QUAN_W ");
break;
+
+ case MODE_SEQ:
+ gLCD.locate( 9, 0 );
+ gLCD.printf("ASRSEQ ");
+
+ gTimer.start(); // Sequencer Timer Start
+ break;
+
+ case MODE_Calb:
+ gLCD.locate( 9, 0 );
+ gLCD.printf("Calibr ");
+ break;
}
}
//-------------------------------------------------------------
-// CV meter
-
-void CVMeter(unsigned int ch, unsigned int level)
-{
- unsigned int cvmeter;
-
- cvmeter = level / (SCALING_N / 7.9);
-
- gLCD.locate ( ch, 0 );
- gLCD.putc(cvmeter); // put custom char
-}
-
-//-------------------------------------------------------------
// Write command Custom Char LCD CGRAM(CV Meter)
void WriteCustomChar(unsigned char addr, unsigned char *c)
@@ -525,6 +756,7 @@
{
gLCD.writeCommand(addr | cnt);
gLCD.writeData(*c);
+
cnt++;
c++;
}
@@ -545,7 +777,6 @@
gLCD.locate( 0, 1 );
gLCD.printf("Error in setup.");
// printf("Error %d in setup.\r\n", ethErr);
-
return -1;
}
// printf("Setup OK\r\n");
@@ -554,10 +785,10 @@
Host broadcast(IpAddr(gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], 255), INPUT_PORT, 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);
+ wait(1.0);
return 0;
}
@@ -565,14 +796,14 @@
//-------------------------------------------------------------
// Handller receive UDP Packet
-void onUDPSocketEvent(UDPSocketEvent e)
+inline void onUDPSocketEvent(UDPSocketEvent e)
{
union OSCarg msg[10];
static int num;
switch(e)
{
- case UDPSOCKET_READABLE: //The only event for now
+ case UDPSOCKET_READABLE: // The only event for now
char buf[256] = {0};
Host host;
@@ -587,10 +818,16 @@
// 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;
+
+ if(isdigit(msg[0].address[len-1]))
+
+ num = msg[0].address[len-1] - '0' - 1;
- unsigned int absv = msg[2].f * 1; //convert -0 to 0
+ else
+
+ num = -1;
+
+ unsigned int absv = msg[2].f + 0; //convert -0 to 0
// address pattern SYNC & GATE (Type Tag int, float)
if((strncmp(msg[0].address+(len-1)-4, "sync", 4)==0) && (num == -1)) {
@@ -616,6 +853,7 @@
if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
else gLEDS[num] = gGATES[num] = 0;
break;
+
} else if ((strncmp(msg[0].address,"/1/multipush",12)==0) && (num != -1)) {
if(num > 3) break;
if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
@@ -654,7 +892,31 @@
} else if ((strncmp(msg[0].address+(len-1)-12, "multifader1/", 12)==0) && (num != -1)) {
if(num > 7) break;
if(msg[1].typeTag[1] == 'f') gOSC_cv[num] = msg[2].f * (SCALING_N);
+ break;
+
+ } else if ((strncmp(msg[0].address+(len-1)-11, "sequencer1/", 11)==0) && (num != -1)) {
+ if(num > 7) break;
+ if(msg[1].typeTag[1] == 'f') gSeq_cv1[num] = msg[2].f * (SCALING_N);
+ break;
+
+ } else if ((strncmp(msg[0].address+(len-1)-11, "sequencer2/", 11)==0) && (num != -1)) {
+ if(num > 7) break;
+ if(msg[1].typeTag[1] == 'f') gSeq_cv2[num] = msg[2].f * (SCALING_N);
+ break;
+ }
+
+ // address pattern controller
+ if ((strncmp(msg[0].address+(len-1)-6, "ctrlsw", 6)==0) && (num != -1)) {
+ if(num > 2) break;
+ if(absv >= 1 || msg[2].i >= 1) gCtrlSW[num] = 1;
+ else gCtrlSW[num] = 0;
+ break;
+
+ } else if ((strncmp(msg[0].address+(len-1)-4, "ctrl", 4)==0) && (num != -1)) {
+ if(num > 2) break;
+ if(msg[1].typeTag[1] == 'f') gCtrl[num] = msg[2].f;
+ break;
+ }
+ }
+ }
}
- }
- }
- }