Welcome to the Parallax Discussion Forums, sign-up to participate.
' Smartpin I2S DAC driver proof of concept, 3 smartpins for MCLK, BCLK, DOUT, plus LRCLK bit-banged ' Mark Tillotson 2019-01-12 CON OSCMODE = $010c3f04 FREQ = 160_000_000 NCO_FREQ =%0000_0000_000_00000_00000000_01_00110_0 SYNC_TX = %0000_1001_000_00000_00000000_01_11100_0 ' sync serial tx using pin+1 as clk DOUT_PIN_NUM = 48 CLOCK_PIN_NUM = DOUT_PIN_NUM + 1 MCLK_PIN_NUM = 50 LRCLK_PIN_NUM = 51 ' must be a multiple of 8 for MCLK = 4*BCLK CLKS_PER_BIT = 64 ' for 39.0625kHz samplerate (1.5MHz bitclk) (would be 48kHz for sysclk = 12.288MHz x 16) ' 40 will give 62.5kSPS at 160MHz sysclk PUB demo | i, a clkset(OSCMODE, FREQ) pausems (1000) ' time for 'scope capture setup cognew (@tx_output) repeat pausems (1) DAT org 0 tx_output wrpin ##NCO_FREQ, #CLOCK_PIN_NUM wxpin ##CLKS_PER_BIT/2, #CLOCK_PIN_NUM ' every 64 cycles (32 instructions), bit clock wypin ##$80000000, #CLOCK_PIN_NUM ' toggle every other wrpin ##NCO_FREQ, #MCLK_PIN_NUM wxpin ##CLKS_PER_BIT/8, #MCLK_PIN_NUM ' every 16 cycles (8 instructions), master clock wypin ##$80000000, #MCLK_PIN_NUM ' toggle every other dirh ##CLOCK_PIN_NUM dirh ##MCLK_PIN_NUM ' start clocks together mov left, ##$80FFF000 ' test pat with bot 8 bits zero mov t, left rev t shl t, #1 dirh lrclk_pin wrpin ##SYNC_TX, dout_pin wxpin ##%011111, dout_pin wypin t, dout_pin GETCT time dirh dout_pin ADDCT1 time, idelay outl lrclk_pin jmp #.skipy ' compensate for truncated first bit shifted by smartpin sync serial mode .loop ' left channel outl lrclk_pin ' drive left/right clock .skipy WAITCT1 ADDCT1 time, delay sub right, #$37 ' testing pattern, 31 bits used, decrementing mov t, right ' preload right rev t shl t, #1 ' I2S justification, top bit is delayed 1 place wypin t, dout_pin WAITCT1 ADDCT1 time, delay ' right channel outh lrclk_pin ' drive left/right clock WAITCT1 ADDCT1 time, delay add left, #$100 ' testing pattern, strictly 24 bits mov t, left ' preload left rev t shl t, #1 wypin t, dout_pin WAITCT1 ADDCT1 time, delay jmp #.loop left long 0 right long 0 lrclk_pin long LRCLK_PIN_NUM dout_pin long DOUT_PIN_NUM delay long 16 * CLKS_PER_BIT idelay long 15 * CLKS_PER_BIT time res 1 t res 1
Comments
Nice to see interest in this topic!
Some months ago I bought a 6 channel analog amplifier, 6 speakers, 3 I2S modules (two channels per module) and a spdif-to-6-analog-out module (6 ch in DTS/DD mode) for doing exactly these kind of things on the P2. The plan is to have a cogdriver that can take multiple audio input streams, mix them together (pan, gain, sample rate conversion, antialaising) and output to smart pins, I2S or spdif with up to 6 out channels (think 5.1 setup). In spdif mode it is only realistic to have 2 out channels though, since realtime DD/DTS encoding is CPU heavy and complex. Having a pure sound driver/mixer in one cog and doing audio input and DSP in others is the best way to go I think. Then there needs to be some kind of hub mechanism to synchronize data producing cogs with the sounddriver/mixer cog.
not yet tested on a live DAC.
Think it might be time to spin up a 64000 extension/accessory board with I2S ADC + DAC