KIK 01 Prototype 05

Dependencies:   AverageMCP3008 mbed-rtos mbed mcp3008

Fork of KIK01_Proto03 by Ryo Od

main.cpp

Committer:
ryood
Date:
2017-09-28
Revision:
24:e9fbadd15e90
Parent:
23:da7c5f7feff1
Child:
25:b4977c7e0db7

File content as of revision 24:e9fbadd15e90:

/*
 * KIK01
 * Kick Machine
 *
 * 2017.09.16 Proto04: SPI1 for AD8402 Wein Bridge DCO & Internal DAC for Dual-OTA-VCA
 * 2017.07.04 Proto03: MCP4922 DCA
 * 2017.06.19 Proto02
 * 2017.06.04 created.
 *
 */

#include "mbed.h"
#include "rtos.h"
#include "mcp3008.h"
#include "EnvelopeAR.h"

#define UART_TRACE      (1)
#define PIN_CHECK       (1)
#define TITLE_STR1      ("KIK01 Kick Machine")
#define TITLE_STR2      ("20170916")

#define PI_F            (3.1415926f)

#define MCP3008_SPI_SPEED       (1000000)
#define AD8402_SPI_SPEED        (10000000)
#define ENVELOPE_UPDATE_RATE    (32000)  //  Hz

#define AD8402_RMAX (10000.0f)
#define AD8402_RMIN (50.0f)

AnalogOut Dac1(A2);

// AD8402 SPI
SPI SpiMAD8402(SPI_MOSI, SPI_MISO, SPI_SCK);
DigitalOut AD8402Cs(D10);

// MCP3008 SPI
SPI SpiM3(D4, D5, D3);
MCP3008 Adc0(&SpiM3, D6);
MCP3008 Adc1(&SpiM3, D7);

// Sync
DigitalOut SyncPin(D2);

// Check pins
DigitalOut Dout0(D8);
DigitalOut Dout1(D9);
DigitalOut Dout2(D14);

EnvelopeAR envelopeFrequency(5, 300, 880.0f, 120.0f, 40.0f, 0.36f, 0.1f);
EnvelopeAR envelopeAmplitude(50, 200, 0.99f, 1.0f, 0.0f);

volatile EnvelopeParam frequencyParam;
volatile EnvelopeParam amplitudeParam;

volatile int ticks;
volatile float frequency;
volatile float amplitude;

volatile float bpm;
volatile int envelopeLength;
volatile int stepLength;

void AD8402Write(uint8_t address, uint8_t value)
{
#if (PIN_CHECK)
    Dout1 = 1;
#endif    

    AD8402Cs = 0;
    SpiMAD8402.write(address);
    SpiMAD8402.write(value);
    AD8402Cs = 1;
    wait_us(1);

#if (PIN_CHECK)
    Dout1 = 0;
#endif
}

void DcoSetFrequency(float freq)
{
    const float c = 0.00000047;
    float r = 1.0f / (2.0f * PI_F * frequency * c);
    if (r < AD8402_RMIN) r = AD8402_RMIN;
    if (r > AD8402_RMAX) r = AD8402_RMAX;
    
    uint8_t v = 256.0f * (r - AD8402_RMIN) / AD8402_RMAX;

    AD8402Write(0, v);
    AD8402Write(1, v);
}

void DcaSetAmplitude(float amp)
{
    Dac1.write(amp);
}

void update()
{
#if (PIN_CHECK)
    Dout0 = 1;
#endif

    // Output Sync Signal per steps
    if (ticks % stepLength == 0) {
        SyncPin = 1;
    }

    // set envelope parameters
    envelopeAmplitude.setAttack(amplitudeParam.attack);
    envelopeAmplitude.setRelease(amplitudeParam.release);
    envelopeAmplitude.setV0(amplitudeParam.v0);
    envelopeAmplitude.setV1(amplitudeParam.v1);
    envelopeAmplitude.setV2(amplitudeParam.v2);
    envelopeAmplitude.setAttackTauRatio(amplitudeParam.attackTauRatio);
    envelopeAmplitude.setReleaseTauRatio(amplitudeParam.releaseTauRatio);

    envelopeFrequency.setAttack(frequencyParam.attack);
    envelopeFrequency.setRelease(frequencyParam.release);
    envelopeFrequency.setV0(frequencyParam.v0);
    envelopeFrequency.setV1(frequencyParam.v1);
    envelopeFrequency.setV2(frequencyParam.v2);
    envelopeFrequency.setAttackTauRatio(frequencyParam.attackTauRatio);
    envelopeFrequency.setReleaseTauRatio(frequencyParam.releaseTauRatio);

    frequency = envelopeFrequency.getAmplitude(ticks);
    amplitude = envelopeAmplitude.getAmplitude(ticks); 
    
    DcoSetFrequency(frequency);
    DcaSetAmplitude(amplitude);

    ticks++;
    if (ticks >= envelopeLength) {
        ticks = 0;
    }

    // Output SyncSignal
    SyncPin = 0;

#if (PIN_CHECK)
    Dout0 = 0;
#endif
}

void setParams()
{
    bpm = Adc0.read_input(7) * 180.0f + 60.0f;
    envelopeLength = 60 * ENVELOPE_UPDATE_RATE / bpm;
    stepLength = envelopeLength / 4;

    amplitudeParam.attack = Adc0.read_input(0) * envelopeLength;
    amplitudeParam.release = Adc0.read_input(1) * envelopeLength;
    amplitudeParam.v0 = Adc0.read_input(4);
    amplitudeParam.v1 = Adc0.read_input(5);
    amplitudeParam.v2 = Adc0.read_input(6);
    amplitudeParam.attackTauRatio = Adc0.read_input(2) + 0.01f;
    amplitudeParam.releaseTauRatio = Adc0.read_input(3) + 0.01f;

    frequencyParam.attack = Adc1.read_input(0) * envelopeLength * 0.1f;
    frequencyParam.release = Adc1.read_input(1) * envelopeLength + 1;
    frequencyParam.v0 = Adc1.read_input(4) * 4000.0f;
    frequencyParam.v1 = Adc1.read_input(5) * 400.0f;
    frequencyParam.v2 = Adc1.read_input(6) * 400.0f;
    frequencyParam.attackTauRatio = Adc1.read_input(2) + 0.01f;
    frequencyParam.releaseTauRatio = Adc1.read_input(3) + 0.01f;
}

int main()
{
    printf("%s %s\r\n", TITLE_STR1, TITLE_STR2);

    SpiMAD8402.format(8, 0);
    SpiMAD8402.frequency(AD8402_SPI_SPEED);

    SpiM3.format(8, 0);
    SpiM3.frequency(MCP3008_SPI_SPEED);

    frequency = 100.0f;
    amplitude = 1.0f;
    bpm = 120.0f;
    
    setParams();

    ticks = 0;
    Ticker samplingTicker;
    samplingTicker.attach(&update, (1.0f/ENVELOPE_UPDATE_RATE));

    for (;;) {
#if (PIN_CHECK)
        Dout2 = 1;
#endif
        setParams();
#if (PIN_CHECK)
        Dout2 = 0;
#endif

#if UART_TRACE
        printf("%.1f\t%d\t", bpm, envelopeLength);

        printf("%d\t%d\t", amplitudeParam.attack, amplitudeParam.release);
        printf("%.2f\t%.2f\t%.2f\t", amplitudeParam.v0, amplitudeParam.v1, amplitudeParam.v2);
        printf("%.2f\t%.2f\t", amplitudeParam.attackTauRatio, amplitudeParam.releaseTauRatio);

        printf("%d\t%d\t", frequencyParam.attack, frequencyParam.release);
        printf("%.2f\t%.2f\t%.2f\t", frequencyParam.v0, frequencyParam.v1, frequencyParam.v2);
        printf("%.2f\t%.2f\r\n", frequencyParam.attackTauRatio, frequencyParam.releaseTauRatio);
#endif

        Thread::wait(1);
    }
}