MCP4922にADSR波形を出力。

Dependencies:   mbed-rtos mbed

main.cpp

Committer:
ryood
Date:
2016-06-14
Revision:
0:d78518594116
Child:
1:6ebe35be504e

File content as of revision 0:d78518594116:

#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);
    }
}