MCP4922にADSR波形を出力。

Dependencies:   mbed-rtos mbed

Revision:
0:d78518594116
Child:
1:6ebe35be504e
diff -r 000000000000 -r d78518594116 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Jun 14 22:37:17 2016 +0000
@@ -0,0 +1,109 @@
+#include "mbed.h"
+#include "rtos.h"
+#include "AverageAnalogIn.h"
+
+#define SPIM_TIMER_PERIOD   (5)         // 5ms
+#define SPIM_RATE           (8000000)   // 8MHz
+#define SPIM_WAIT           /*(wait_us(1))*/
+
+// ピン・アサイン
+#define PIN_CHECK       PA_10
+#define PIN_DAC_CS      PA_9
+#define PIN_DAC_LDAC    PA_8
+
+SPI SpiM(SPI_MOSI, SPI_MISO, SPI_SCK); 
+DigitalOut DacCs(PIN_DAC_CS);
+DigitalOut DacLdac(PIN_DAC_LDAC);
+
+DigitalOut CheckPin(PIN_CHECK);
+
+AverageAnalogIn DurationIn(A0);
+AverageAnalogIn DecayIn(A1);
+AverageAnalogIn SustainIn(A2);
+
+int16_t beatLen = 100;
+
+int16_t level = 4095;
+int16_t duration = 400;
+int16_t decay = 100;
+int16_t sustain = 2000;
+
+int16_t decay_delta;
+int16_t mod_value;
+
+int16_t tick;
+
+// DAC A Channelに出力
+// parameter: v: 出力値(0 .. 4095)
+void writeToDacA(int16_t v)
+{
+    // Channel A
+    DacLdac = 1;
+    DacCs = 0;
+    SpiM.write((v >> 8) | 0x30);    // 0x30: DAC_A(0) | Vref Unbuffered(0) | Vout 1x(1) | !SHDN(1)
+    SpiM.write(v & 0xff);
+    SPIM_WAIT;
+    DacCs = 1;
+    DacLdac = 0;
+}
+
+// DAC B ChannelにA ChannelのVrefを出力
+void outVref()
+{
+    // Channel B
+    DacLdac = 1;
+    DacCs = 0;
+    SpiM.write(0x08 | 0xB0);    // 0xB0: DAC_B(1) | Vref Unbuffered(0) | Vout 1x(1) | !SHDN(1)
+    SpiM.write(0x00);  
+    SPIM_WAIT;
+    DacCs = 1;
+    DacLdac = 0;
+}
+
+// ADSR波形を出力
+void outADSR(void const* arg)
+{
+    tick++;
+
+    if (tick > beatLen) {
+        tick = 0;
+        // モジュレーション波形を初期化する
+        mod_value = level;
+        decay_delta = (level - sustain) / decay;
+    }
+
+    // 出力値補正
+    if (mod_value < 0) {
+        mod_value = 0;
+    }
+    writeToDacA(mod_value);
+
+    if (tick < decay) {
+        mod_value -= decay_delta;
+    }
+    if (tick == duration) {
+        mod_value = 0;
+    }
+}
+
+int main()
+{
+    RtosTimer SpiM_timer(outADSR, osTimerPeriodic);
+        
+    SpiM.format(8, 0);
+    SpiM.frequency(SPIM_RATE);
+    
+    outVref();
+    
+    SpiM_timer.start(SPIM_TIMER_PERIOD);
+    
+    while(true) {
+        duration = DurationIn.read() * beatLen;
+        decay    = DecayIn.read() * beatLen;
+        sustain  = SustainIn.read() * 4095;
+        
+        printf("%d\t%d\t%d\r\n", duration, decay, sustain);
+        
+        Thread::wait(10);
+    }
+}