Converting everything to unsigned gave a boost of a couple kHz (didn't measure the impact of changing the shifts). I didn't really find much information on outshr and inshr, so not sure if that's applicable.
Previously, the operation was as follows:
- Read 2 adc channels
- Compute stuff with adc values
- Output to the DAC
- Loop through channels 2k and 2k+1, k = [0,7]
The new new flow is:
- Read all 16 ADC channels (8 function calls) in an ADC thread
- Get the ADC values from the ADC thread
- Compute all DAC outputs
[tab=30]--> While this is happening, the ADC thread is reading the next batch of ADC values
The change in flow is what gave the bulk of the improvement (at a slight cost in latency), mostly due to the parallel reading. Having the ADCs read while doing other stuff also gave a nice boost. I may be able to go slightly faster, but the ADC datasheet is iffy on what happens when the RD pin is low before the CS pin is low.
ADC function to read the ADCs in parallel (combined into an int):
Code: Select all
inline unsigned int readBothADC(ADCPair &adc, Bus12b &bus, int channel) {
unsigned short data1, data2;
unsigned short msb, mid, lsb;
//Write the channel to read to both ADCs
adc.cs[0] <: 0;
adc.cs[1] <: 0;
adc.wr <: 0;
bus.msb <: 0; //Always zero, so cut out some instructions
bus.mid <: (channel << 1);
bus.lsb <: 0; //Always zero, so cut out some instructions
adc.wr <: 1;
adc.cs[0] <: 1;
adc.cs[1] <: 1;
//Conversion
adc.convst <: 0;
adc.clk <: CLOCK_OUTPUT;
sync(adc.clk);
adc.convst <: 1;
//Read channel
adc.cs[0] <: 0;
adc.rd <: 0;
adc.rd <: 0;
adc.rd <: 0;
bus.msb :> msb;
bus.mid :> mid;
bus.lsb :> lsb;
data1 = ((msb << 8) + (mid << 4) + lsb);
adc.cs[0] <: 1;
adc.rd <: 1;
//Read channel + 8
adc.cs[1] <: 0;
adc.rd <: 0;
adc.rd <: 0;
adc.rd <: 0;
bus.msb :> msb;
bus.mid :> mid;
bus.lsb :> lsb;
data2 = ((msb << 8) + (mid << 4) + lsb);
adc.cs[1] <: 1;
adc.rd <: 1;
return (data1 << 16)+data2;
}
Assembly for that function:
Code: Select all
0x10a40 readBothADC:
0x10a40 entsp (u6) 0x6
0x10a42 stw (ru6) r4, sp[0x5]
0x10a44 stw (ru6) r5, sp[0x4]
0x10a46 stw (ru6) r6, sp[0x3]
0x10a48 stw (ru6) r7, sp[0x2]
0x10a4a stw (ru6) r8, sp[0x1]
0x10a4c stw (ru6) r9, sp[0x0]
0x10a4e ldw (2rus) r6, r0[0x0]
0x10a50 ldc (ru6) r5, 0x0
0x10a52 out (r2r) res[r6], r5
0x10a54 ldw (2rus) r3, r0[0x1]
0x10a56 out (r2r) res[r3], r5
0x10a58 ldw (2rus) r7, r0[0x3]
0x10a5a out (r2r) res[r7], r5
0x10a5c ldw (2rus) r4, r1[0x0]
0x10a5e out (r2r) res[r4], r5
0x10a60 shl (2rus) r2, r2, 0x1
0x10a62 ldw (2rus) r11, r1[0x1]
0x10a64 out (r2r) res[r11], r2
0x10a66 ldw (2rus) r2, r1[0x2]
0x10a68 out (r2r) res[r2], r5
0x10a6a mkmsk (rus) r1, 0x1
0x10a6c out (r2r) res[r7], r1
0x10a6e out (r2r) res[r6], r1
0x10a70 out (r2r) res[r3], r1
0x10a72 ldw (2rus) r7, r0[0x2]
0x10a74 out (r2r) res[r7], r5
0x10a76 ldw (2rus) r8, r0[0x5]
0x10a78 ldw (lru6) r9, dp[0xc]
0x10a7c out (r2r) res[r8], r9
0x10a7e syncr (1r) res[r8]
0x10a80 out (r2r) res[r7], r1
0x10a82 out (r2r) res[r6], r5
0x10a84 ldw (2rus) r7, r0[0x4]
0x10a86 out (r2r) res[r7], r5
0x10a88 out (r2r) res[r7], r5
0x10a8a out (r2r) res[r7], r5
0x10a8c setc (ru6) res[r4], 0x1
0x10a8e in (2r) r0, res[r4]
0x10a90 setc (ru6) res[r11], 0x1
0x10a92 in (2r) r9, res[r11]
0x10a94 setc (ru6) res[r2], 0x1
0x10a96 in (2r) r8, res[r2]
0x10a98 out (r2r) res[r6], r1
0x10a9a out (r2r) res[r7], r1
0x10a9c out (r2r) res[r3], r5
0x10a9e out (r2r) res[r7], r5
0x10aa0 out (r2r) res[r7], r5
0x10aa2 out (r2r) res[r7], r5
0x10aa4 shl (2rus) r0, r0, 0x8
0x10aa6 shl (2rus) r5, r9, 0x4
0x10aa8 add (3r) r0, r5, r0
0x10aaa add (3r) r0, r0, r8
0x10aac shl (2rus) r0, r0, 0x10
0x10aae setc (ru6) res[r4], 0x1
0x10ab0 in (2r) r4, res[r4]
0x10ab2 setc (ru6) res[r11], 0x1
0x10ab4 shl (2rus) r4, r4, 0x8
0x10ab6 in (2r) r11, res[r11]
0x10ab8 shl (2rus) r11, r11, 0x4
0x10aba add (3r) r11, r11, r4
0x10abc setc (ru6) res[r2], 0x1
0x10abe in (2r) r2, res[r2]
0x10ac0 add (3r) r2, r11, r2
0x10ac2 zext (rus) r2, 0x10
0x10ac4 or (3r) r0, r2, r0
0x10ac6 out (r2r) res[r3], r1
0x10ac8 out (r2r) res[r7], r1
0x10aca ldw (ru6) r9, sp[0x0]
0x10acc ldw (ru6) r8, sp[0x1]
0x10ace ldw (ru6) r7, sp[0x2]
0x10ad0 ldw (ru6) r6, sp[0x3]
0x10ad2 ldw (ru6) r5, sp[0x4]
0x10ad4 ldw (ru6) r4, sp[0x5]
0x10ad6 retsp (u6) 0x6
Happy new years to you too, and thanks for all the help!