Ryo Od
/
Nucleo_MCP4922_DCA_Test
MCP4922にADSR波形を出力。
Diff: main.cpp
- 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); + } +}