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++;
}