MCP4922にADSR波形を出力。

Dependencies:   mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "rtos.h"
00003 #include "AverageAnalogIn.h"
00004 
00005 #define SPIM_TIMER_PERIOD   (5)         // 5ms
00006 #define SPIM_RATE           (8000000)   // 8MHz
00007 #define SPIM_WAIT           /*(wait_us(1))*/
00008 
00009 // ピン・アサイン
00010 #define PIN_CHECK       PA_10
00011 #define PIN_DAC_CS      PA_9
00012 #define PIN_DAC_LDAC    PA_8
00013 
00014 SPI SpiM(SPI_MOSI, SPI_MISO, SPI_SCK); 
00015 DigitalOut DacCs(PIN_DAC_CS);
00016 DigitalOut DacLdac(PIN_DAC_LDAC);
00017 
00018 DigitalOut CheckPin(PIN_CHECK);
00019 
00020 AverageAnalogIn DurationIn(A0);
00021 AverageAnalogIn DecayIn(A1);
00022 AverageAnalogIn SustainIn(A2);
00023 
00024 int16_t beatLen = 25;
00025 
00026 int16_t level = 4095;
00027 int16_t duration = 400;
00028 int16_t decay = 100;
00029 int16_t sustain = 2000;
00030 
00031 int16_t decay_delta;
00032 int16_t release_delta = 1000;
00033 int16_t mod_value;
00034 
00035 int16_t tick;
00036 
00037 // DAC A Channelに出力
00038 // parameter: v: 出力値(0 .. 4095)
00039 void writeToDacA(int16_t v)
00040 {
00041     // Channel A
00042     DacLdac = 1;
00043     DacCs = 0;
00044     SpiM.write((v >> 8) | 0x30);    // 0x30: DAC_A(0) | Vref Unbuffered(0) | Vout 1x(1) | !SHDN(1)
00045     SpiM.write(v & 0xff);
00046     SPIM_WAIT;
00047     DacCs = 1;
00048     DacLdac = 0;
00049 }
00050 
00051 // DAC B ChannelにA ChannelのVrefを出力
00052 void outVref()
00053 {
00054     // Channel B
00055     DacLdac = 1;
00056     DacCs = 0;
00057     SpiM.write(0x08 | 0xB0);    // 0xB0: DAC_B(1) | Vref Unbuffered(0) | Vout 1x(1) | !SHDN(1)
00058     SpiM.write(0x00);  
00059     SPIM_WAIT;
00060     DacCs = 1;
00061     DacLdac = 0;
00062 }
00063 
00064 // ADSR波形を出力
00065 void outADSR(void const* arg)
00066 {
00067     tick++;
00068 
00069     if (tick > beatLen) {
00070         tick = 0;
00071         // モジュレーション波形を初期化する
00072         mod_value = level;
00073         decay_delta = (level - sustain) / decay;
00074     }
00075 
00076     // 出力値補正
00077     if (mod_value < 0) {
00078         mod_value = 0;
00079     }
00080     writeToDacA(mod_value);
00081 
00082     if (tick < decay) {
00083         mod_value -= decay_delta;
00084     }
00085     /*
00086     if (tick >= duration) {
00087         mod_value -= release_delta;
00088     }
00089     */
00090     if (tick == duration) {
00091         mod_value = 0;
00092     }
00093 }
00094 
00095 int main()
00096 {
00097     RtosTimer SpiM_timer(outADSR, osTimerPeriodic);
00098         
00099     SpiM.format(8, 0);
00100     SpiM.frequency(SPIM_RATE);
00101     
00102     outVref();
00103     
00104     SpiM_timer.start(SPIM_TIMER_PERIOD);
00105     
00106     while(true) {
00107         duration = DurationIn.read() * beatLen;
00108         decay    = DecayIn.read() * beatLen;
00109         sustain  = SustainIn.read() * 4095;
00110         
00111         printf("%d\t%d\t%d\r\n", duration, decay, sustain);
00112         
00113         Thread::wait(10);
00114     }
00115 }