I'm only really concerned with i2S input (not output), but I do want the full 32 bits in (in my application, the final 8 bits contain frame-sync info). I've tried various experimental values in the setpt and partout function but it doesn't seem obvious.
How can I modify this to be input-only, but full 32-bit?
Code: Select all
  while (1) {
    int t;
    // wait for WCK edge
    // timestamp this edge
    wck when pinsneq(lr) :> lr @ t;
    // set time for audio data input
    // split SETPT from IN using asm
    // basically a split transaction to allow multichannel timed input
    // input is always "up to" given time
    // I2S_SLAVE sample starts at t + 1, so capture "up to" t + 1 + 23
#pragma loop unroll
    for (int i = 0; i < I2S_SLAVE_NUM_OUT; i++) {
      asm("setpt res[%0], %1" :: "r"(din[i]), "r"(t + 24));
    }
    // output audio data
    // output is always "starting from" given time
    // next I2S_SLAVE sample starts at t + 33, so output at that time
    // must do partial output of 24 bits
    // full 32-bit output would span entire cycle not allowing consecutive SETPT's
#pragma loop unroll
    for (int i = 0; i < I2S_SLAVE_NUM_OUT; i++) {
      signed x = 0;
      c_out :> x;
      partout_timed(dout[i],24,bitrev(x),(t + 33));
    }
    // input audio data
    // port will capture I2S MSb at t + 1 and LSb at t + 24
    // bits 0..7 are older than I2S MSb and hence discard them
    // compiler would insert SETC FULL on DIN input, because it doesn't know about inline SETPT above
    // hence we need inline IN too
#pragma loop unroll
    for (int i = 0; i < I2S_SLAVE_NUM_IN; i++) {
      signed x;
			asm("in %0, res[%1]" : "=r"(x)  : "r"(din[i]));
      c_in <: bitrev(x) << 8;
    }
    frame_counter++;
  }

