[openfirmware] [commit] r3424 - cpu/arm/olpc cpu/x86/pc/olpc dev/geode/ac97 dev/hdaudio
repository service
svn at openfirmware.info
Wed Nov 14 08:31:06 CET 2012
Author: wmb
Date: Wed Nov 14 08:31:04 2012
New Revision: 3424
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/3424
Log:
OLPC ARM audio test - workaround channel-swapping problem (trac #12096). Also added some experimental code.
Modified:
cpu/arm/olpc/sound.fth
cpu/x86/pc/olpc/plot.fth
dev/geode/ac97/selftest.fth
dev/hdaudio/noiseburst.fth
dev/hdaudio/test.fth
Modified: cpu/arm/olpc/sound.fth
==============================================================================
--- cpu/arm/olpc/sound.fth Wed Nov 14 08:11:21 2012 (r3423)
+++ cpu/arm/olpc/sound.fth Wed Nov 14 08:31:04 2012 (r3424)
@@ -219,6 +219,7 @@
;
: master-rx ( -- ) h# 0c sspa@ h# 8004.0001 or h# 0c sspa! ; \ Master, on
: slave-rx ( -- ) h# 0c sspa@ h# 8000.0001 or h# 0c sspa! ; \ Slave, on
+: flush-rx ( -- ) h# 0c sspa@ h# 8000.0004 or h# 0c sspa! ; \ Hit the flush bit
: disable-sspa-rx ( -- ) h# 0c sspa@ h# 8000.0004 or h# 4.0001 invert and h# 0c sspa! ;
: reset-tx ( -- ) h# 8000.0002 h# 8c sspa! ;
@@ -260,6 +261,7 @@
;
: master-tx ( -- ) h# 8c sspa@ h# 8004.0001 or h# 8c sspa! ; \ Master, on
: slave-tx ( -- ) h# 8c sspa@ h# 8000.0001 or h# 8c sspa! ; \ Slave, on
+: flush-tx ( -- ) h# 8c sspa@ h# 8000.0004 or h# 8c sspa! ; \ Hit the flush bit
: disable-sspa-tx ( -- ) h# 8c sspa@ h# 8000.0004 or h# 4.0001 invert and h# 8c sspa! ;
h# fc0 constant /audio-buf
@@ -289,9 +291,14 @@
out-desc h# 30 adma! \ Link to first descriptor
out-desc to my-out-desc
;
+
+0 value use-packmod?
+
: start-out-ring ( -- )
1 h# 80 adma! \ Enable DMA completion interrupts
- h# 0081.3020 h# 40 adma! \ 16 bits, pack, fetch next, enable, chain, hold dest, inc src
+ h# 0080.3020 \ 16 bits, fetch next, enable, chain, hold dest, inc src
+ use-packmod? if h# 1.0000 or then
+ h# 40 adma!
;
: stop-out-ring ( -- ) h# 100000 h# 40 adma! 0 h# 80 adma! ;
@@ -304,17 +311,43 @@
: start-in-ring ( -- )
1 h# 84 adma! \ Enable DMA completion interrupts
\ h# 0081.3008 h# 44 adma! \ 16 bits, pack, fetch next, enable, chain, inc dest, hold src
- h# 00a1.31c8 h# 44 adma! \ 16 bits, pack, fetch next, enable, chain, burst32, inc dest, hold src
+
+ h# 00a0.31c8 \ 16 bits, fetch next, enable, chain, burst32, inc dest, hold src
+ use-packmod? if h# 1.0000 or then
+ h# 44 adma!
;
: stop-in-ring ( -- ) h# 100000 h# 44 adma! 0 h# 84 adma! ;
+: unpack-move ( src dst packed-len -- )
+ 1 rshift 0 ?do ( src dst )
+ over i wa+ w@ ( src dst sample )
+ over i la+ wa1+ w! ( src dst )
+ loop ( src dst )
+ 2drop ( )
+;
+
+: pack-move ( src dst packed-len -- )
+ 1 rshift 0 ?do ( src dst )
+ over i la+ wa1+ w@ ( src dst sample )
+ over i wa+ w! ( src dst )
+ loop ( src dst )
+ 2drop ( )
+;
+
: copy-out ( -- )
- my-out-desc >r ( r: desc )
- out-len /audio-buf min ( this-len r: desc )
- dup r@ l! ( this-len r: desc )
- out-adr r@ la1+ l@ third move ( this-len r: desc )
- out-adr over + to out-adr ( this-len r: desc )
- out-len swap - to out-len ( r: desc )
+ my-out-desc >r ( r: desc )
+ use-packmod? if
+ out-len /audio-buf min ( this-packed-len r: desc )
+ dup r@ l! ( this-packed-len r: desc )
+ out-adr r@ la1+ l@ third move ( this-packed-len r: desc )
+ else
+ out-len /audio-buf 2/ min ( this-packed-len r: desc )
+ dup 2* r@ l! ( this-packed-len r: desc )
+ out-adr r@ la1+ l@ third unpack-move ( this-packed-len r: desc )
+ then
+
+ out-adr over + to out-adr ( this-packed-len r: desc )
+ out-len swap - to out-len ( r: desc )
out-len if
r> 3 la+ l@ to my-out-desc
else
@@ -323,11 +356,16 @@
;
: copy-in ( -- )
- in-len /audio-buf min ( this-len )
- my-in-desc 2 la+ l@ in-adr third move ( this-len )
- in-adr over + to in-adr ( this-len )
- in-len over - to in-len ( this-len )
- drop ( )
+ use-packmod? if
+ in-len /audio-buf min ( this-packed-len )
+ my-in-desc 2 la+ l@ in-adr third move ( this-packed-len )
+ else
+ in-len /audio-buf 2/ min ( this-packed-len )
+ my-in-desc 2 la+ l@ in-adr third pack-move ( this-packed-len )
+ then
+ in-adr over + to in-adr ( this-packed-len )
+ in-len over - to in-len ( this-packed-len )
+ drop ( )
my-in-desc 3 la+ l@ to my-in-desc
;
@@ -567,7 +605,17 @@
in-adr0 i la+ w@ in-adr0 i wa+ w!
loop
;
-: out-in ( out-adr out-len in-adr in-len -- )
+code startit ( sspa-adr -- )
+ set r0,#0x80f101f1
+ set r1,#0x80f501f1
+ str r0,[tos,#0x8c]
+ str r1,[tos,#0x0c]
+ pop tos,sp
+c;
+: startoutin ( -- ) disable-interrupts sspa-base startit enable-interrupts ;
+: xstartoutin ( -- ) slave-tx master-rx ;
+
+: out-in0 ( out-adr out-len in-adr in-len -- )
open-out-in
to in-len0 to in-adr0 ( out-adr out-len )
@@ -578,7 +626,7 @@
\ Resetting the clock at this point seems to prevent intermittent channel
\ reversal on reception.
- audio-clock-on drop ( ) \ This will mess up any frequency settings
+\ audio-clock-on drop ( ) \ This will mess up any frequency settings
setup-sspa-tx ( )
setup-sspa-rx ( )
@@ -591,7 +639,53 @@
start-in-ring ( )
start-out-ring ( )
+ xstartoutin
+\ slave-tx ( )
+\ master-rx ( ) \ Now the clock is on
+
+ true to playing?
+
+ begin in-len playing? or while ( )
+ in-ready? if copy-in then ( )
+ playing? if ?end-playing then ( )
+ repeat ( )
+ disable-sspa-rx ( )
+ disable-sspa-tx ( )
+
+ stop-in-ring
+ stop-out-ring
+
+ reset-rx
+ reset-tx
+
+ close-out-in
+ mono? if collapse-in then ( )
+;
+
+: out-in1 ( out-adr out-len in-adr in-len -- )
+ open-out-in
+
+ to in-len0 to in-adr0 ( out-adr out-len )
+ to out-len to out-adr ( )
+
+ in-adr0 to in-adr ( )
+ in-len0 mono? if 2* then to in-len
+
+ \ Resetting the clock at this point seems to prevent intermittent channel
+ \ reversal on reception.
+\ audio-clock-on drop ( ) \ This will mess up any frequency settings
+
+ make-out-ring ( )
+ copy-out ( ) \ Prefill the first Tx buffer
+ out-len if copy-out then ( ) \ Prefill the second Tx buffer
+
+ setup-sspa-rx ( )
+ make-in-ring ( )
+ start-in-ring ( )
master-rx ( ) \ Now the clock is on
+
+ start-out-ring ( )
+ setup-sspa-tx ( )
slave-tx ( )
true to playing?
@@ -613,6 +707,87 @@
mono? if collapse-in then ( )
;
+d# 20 value audio-dly
+: out-in2 ( out-adr out-len in-adr in-len -- )
+ open-out-in
+
+ to in-len0 to in-adr0 ( out-adr out-len )
+ to out-len to out-adr ( )
+
+ in-adr0 to in-adr ( )
+ in-len0 mono? if 2* then to in-len
+
+ \ Resetting the clock at this point seems to prevent intermittent channel
+ \ reversal on reception.
+\ audio-clock-on drop ( ) \ This will mess up any frequency settings
+
+ setup-sspa-tx ( )
+ setup-sspa-rx ( )
+
+ make-in-ring ( )
+ make-out-ring ( )
+ copy-out ( ) \ Prefill the first Tx buffer
+ out-len if copy-out then ( ) \ Prefill the second Tx buffer
+
+ xstartoutin
+
+ audio-dly us
+ flush-rx
+ flush-tx
+ start-in-ring ( )
+ start-out-ring ( )
+
+
+ true to playing?
+
+ begin in-len playing? or while ( )
+ in-ready? if copy-in then ( )
+ playing? if ?end-playing then ( )
+ repeat ( )
+ disable-sspa-rx ( )
+ disable-sspa-tx ( )
+
+ stop-in-ring
+ stop-out-ring
+
+ reset-rx
+ reset-tx
+
+ close-out-in
+ mono? if collapse-in then ( )
+;
+
+defer out-in ' out-in0 to out-in
+
+0 [if]
+working recipe: only one out-in in test-common
+out-in2
+disable-interrupts before audio-clock-on and enable after reset-rx
+dly 73 us
+read and discard rx fifo depth before flush-rx
+
+also works with dly 10 us
+reliably swaps with dly 1 us
+swaps with dly 5
+swap with dly 7
+not swap with dly 8
+
+Hmmm, maybe the basic issue is the double out-in in test-common -
+Try out-in0 using one out-in
+Try out-in2 without read/discard fifo depth using one out-in
+
+Swap alternates every 10 or so us, flipping at about 8 or 9 mod 10
+An extra 2 samples appear ever 10 or so us, at about 1 or 2 mod 10
+
+04 us is stable with swapping
+14 us is stable with no swapping
+
+If you remove flush-rx from fr ( : fr 1c sspa@ foo ! flush-rx ; )
+swapping always happens - 04, 14, 24 us all swap
+ This is because when you flush-rx with fifo depth 2, 6, a, etc,
+ that loses an odd number of channel samples
+[then]
+
0 [if] \ Interactive test words for out-in
h# 20000 constant tlen
: xb load-base 1meg + ;
@@ -730,6 +905,25 @@
fload ${BP}/dev/hdaudio/test.fth
warning !
+: wro
+ wlan-reset-gpio# gpio-dir-in \ So it doesn't fight the cross-wire
+;
+: input-normal ( -- )
+ \ Reconnect pin 36 to WLAN_RESET#
+ wlan-reset-gpio# af@ 7 invert and wlan-reset-gpio# af!
+
+ \ Reconnect pin 26 back to SSPA1 I2S_DATA_IN
+ d# 28 af@ 7 invert and 1 or d# 28 af!
+;
+: input-from-lrclk ( -- )
+ \ Move pin 26 from SSPA1 I2S_DATA_IN to SSPA2 I2S_DATA_IN
+ \ so it doesn't conflict with pin 36.
+ d# 28 af@ 7 invert and 3 or d# 28 af!
+
+ \ Connect pin 36 to SSPA1 I2S_DATA_IN
+ wlan-reset-gpio# af@ 7 invert and 2 or wlan-reset-gpio# af!
+;
+
finish-device
device-end
Modified: cpu/x86/pc/olpc/plot.fth
==============================================================================
--- cpu/x86/pc/olpc/plot.fth Wed Nov 14 08:11:21 2012 (r3423)
+++ cpu/x86/pc/olpc/plot.fth Wed Nov 14 08:31:04 2012 (r3424)
@@ -30,7 +30,10 @@
screen-height wave-height 2* - pitch* frame-buffer-adr +
;
-: wave0 ( -- ) screen-height wave-height - ;
+0 value wave#
+: set-wave# ( n -- ) to wave# ;
+
+: wave0 ( -- ) screen-height wave# 2* 1+ wave-height * - ;
: clear-waveform ( -- )
bg
Modified: dev/geode/ac97/selftest.fth
==============================================================================
--- dev/geode/ac97/selftest.fth Wed Nov 14 08:11:21 2012 (r3423)
+++ dev/geode/ac97/selftest.fth Wed Nov 14 08:31:04 2012 (r3424)
@@ -126,6 +126,14 @@
: copy-left-to-right ( adr len -- )
bounds ?do i w@ i wa1+ w! /l +loop
;
+: copy-pack ( adr len -- )
+ 0 ?do ( adr )
+ dup i + w@ ( adr w )
+ dup wljoin ( adr l )
+ over i 2/ + l! ( adr )
+ 8 +loop ( adr )
+ drop ( )
+;
\ The recording data format is stereo, but usually there is only one mic.
\ Depending on the CODEC used, the right channel of the recording is either
@@ -140,16 +148,18 @@
d# -3 set-volume play
;
+0 value skip-sweep?
: selftest ( -- error? )
open 0= if ." Failed to open /audio" cr true exit then
wav-test
record-len la1+ " dma-alloc" $call-parent to record-base
- sweep-test
+ skip-sweep? 0= if sweep-test then
mic-test
record-base record-len la1+ " dma-free" $call-parent
close
false
;
+alias st1 selftest
\ LICENSE_BEGIN
\ Copyright (c) 2007 FirmWorks
Modified: dev/hdaudio/noiseburst.fth
==============================================================================
--- dev/hdaudio/noiseburst.fth Wed Nov 14 08:11:21 2012 (r3423)
+++ dev/hdaudio/noiseburst.fth Wed Nov 14 08:31:04 2012 (r3424)
@@ -308,7 +308,7 @@
i <w@ 2 pick - h# 7fff min h# -7fff max i w!
i wa1+ <w@ over - h# 7fff min h# -7fff max i wa1+ w!
/l +loop ( mean )
- drop ( )
+ 2drop ( )
;
: lose-6db ( adr len -- )
bounds ?do ( )
@@ -447,6 +447,9 @@
h# 21000 value /rb \ Mono (stereo for loopback) - 8100 for fixture, 21000 for case,
: rb load-base 1meg + ;
+: pb+ pb wa1+ ;
+: rb+ rb wa1+ ;
+
: d.. ( -- ) <# # # # # ascii . hold # # # # ascii . hold #s #> type space ;
: find-max-mono ( -- )
pb rb /pb 2 / h# 100 - d# 160 d# 120 mono-covar-max .d max-covar d..
@@ -459,10 +462,28 @@
;
: #samples ( -- n ) /pb 4 / h# 100 - ;
-: left-range ( -- stereo-adr mono-adr #points ) pb rb #samples ;
-: right-range ( -- stereo-adr mono-adr #points ) pb wa1+ rb #samples ;
-: left-stereo-range ( -- stereo-adr mono-adr #points ) pb rb #samples ;
-: right-stereo-range ( -- stereo-adr mono-adr #points ) pb wa1+ rb wa1+ #samples ;
+
+defer mono-rb ' rb to mono-rb
+
+defer left-rb ' rb to left-rb
+defer right-rb ' rb+ to right-rb
+
+defer left-pb ' pb to left-pb
+defer right-pb ' pb+ to right-pb
+
+: swap-lr-pb ( -- )
+ ['] pb to right-pb
+ ['] pb+ to left-pb
+;
+: unswap-lr-pb ( -- )
+ ['] pb to left-pb
+ ['] pb+ to right-pb
+;
+
+: left-range ( -- stereo-adr mono-adr #points ) left-pb mono-rb #samples ;
+: right-range ( -- stereo-adr mono-adr #points ) right-pb mono-rb #samples ;
+: left-stereo-range ( -- stereo-adr mono-adr #points ) left-pb left-rb #samples ;
+: right-stereo-range ( -- stereo-adr mono-adr #points ) right-pb right-rb #samples ;
: fixture-analyze-left ( -- )
left-range d# 146 d# 141 sm-covar-sum dnegate
@@ -537,8 +558,8 @@
;
: calc-sm-impulse ( offset -- adr ) \ offset is 0 for left or 2 for right
?alloc-impulse-buf
- pb + rb #samples ( adr1 adr2 #samples )
- #impulse-response 0 do
+ if right-range else left-range then ( adr1 adr2 #samples )
+ #impulse-response 0 do ( adr1 adr2 #samples )
3dup swap i wa+ swap stereo-mono-covar ( adr1 adr2 #samples d.covar )
d# 500,000,000 m/mod nip ( adr1 adr2 #samples n.covar )
impulse-response i wa+ w! ( adr1 adr2 #samples )
@@ -547,9 +568,9 @@
impulse-response ( adr )
;
: calc-stereo-impulse ( offset -- adr ) \ offset is 0 for left or 2 for right
- ?alloc-impulse-buf
- dup pb + swap rb + #samples ( adr1 adr2 #samples )
- #impulse-response 0 do
+ ?alloc-impulse-buf ( offset )
+ if right-stereo-range else left-stereo-range then ( adr1 adr2 #samples )
+ #impulse-response 0 do ( adr1 adr2 #samples )
3dup swap i la+ swap stereo-covar ( adr1 adr2 #samples d.covar )
d# 50,000,000 m/mod nip ( adr1 adr2 #samples n.covar )
impulse-response i wa+ w! ( adr1 adr2 #samples )
@@ -575,7 +596,12 @@
\ This version puts the tone first into the left channel for
\ half the time, then into the right channel for the remainder
+
+\ This version puts a tone at one frequency in the left channel
+\ and a tone at twice that frequency in the right channel
+
: make-2tones ( adr len freq sample-rate -- )
+ 2over erase ( adr len freq sample-rate )
2dup set-freq ( adr len freq sample-rate )
3 pick make-cycle drop ( adr len freq sample-rate )
@@ -607,19 +633,17 @@
pb wa1+ /pb -stereo-wmean
pb /pb lose-6db
pb /pb rb /rb
- disable-interrupts
+\ disable-interrupts
;
: analyze-signal ( -- error? )
- enable-interrupts
+\ enable-interrupts
rb /rb fix-dc
false ( error? )
analyze-left if ( error? )
- ." Left channel failure" cr
1+
then
analyze-right if
- ." Right channel failure" cr
2+
then
;
Modified: dev/hdaudio/test.fth
==============================================================================
--- dev/hdaudio/test.fth Wed Nov 14 08:11:21 2012 (r3423)
+++ dev/hdaudio/test.fth Wed Nov 14 08:31:04 2012 (r3424)
@@ -95,18 +95,25 @@
$call-analyzer ( )
" prepare-signal" $call-analyzer ( pb /pb rb /rb )
\ First shorter run lets the input channel settle
- 2over 4 / 2over 4 / out-in ( pb /pb rb /rb )
+\ 2over 4 / 2over 4 / out-in ( pb /pb rb /rb )
out-in ( )
- " analyze-signal" $call-analyzer ( okay? )
+ " analyze-signal" $call-analyzer ( error? )
;
+: .test-error ( error? -- error? )
+ dup 1 and if ." Left channel failure" cr then
+ dup 2 and if ." Right channel failure" cr then
+;
+
false value plot? \ Set to true to plot the impulse response, for debugging
: plot-impulse ( adr -- )
d# 600 ( adr #samples )
- " 0 set-fg h# ffffffff set-bg single-drawing clear-drawing wave" evaluate
- key ascii d = if debug-me then
+ " 0 set-fg h# ffffffff set-bg single-drawing ( clear-drawing ) wave" evaluate
+\ key ascii d = if debug-me then
;
+: plot-impulse0 ( adr -- ) 0 " set-wave#" $call-screen plot-impulse ;
+: plot-impulse1 ( adr -- ) 1 " set-wave#" $call-screen plot-impulse ;
-: test-with-case ( -- )
+: test-with-case ( -- error? )
\ " setup-case" $call-analyzer
\ xxx - this needs to use the internal speakers and mic even though the loopback cable is attached
true to force-speakers? true to force-internal-mic?
@@ -114,11 +121,11 @@
input-test-settings mono
output-test-settings case-test-volume set-volume
." Testing internal speakers and microphone" cr
- " setup-case" test-common
+ " setup-case" test-common .test-error
false to force-speakers? false to force-internal-mic?
plot? if
- 0 " calc-sm-impulse" $call-analyzer plot-impulse
- 2 " calc-sm-impulse" $call-analyzer plot-impulse
+ 0 " calc-sm-impulse" $call-analyzer plot-impulse0
+ 2 " calc-sm-impulse" $call-analyzer plot-impulse1
then
;
: test-with-fixture ( -- error? )
@@ -127,22 +134,41 @@
input-test-settings mono
output-test-settings fixture-test-volume set-volume \ -23 prevents obvious visible clipping
." Testing internal speakers and microphone with fixture" cr
- " setup-fixture" test-common
+ " setup-fixture" test-common .test-error
false to force-speakers? false to force-internal-mic?
plot? if
- 0 " calc-sm-impulse" $call-analyzer plot-impulse
- 2 " calc-sm-impulse" $call-analyzer plot-impulse
+ 0 " calc-sm-impulse" $call-analyzer plot-impulse0
+ 2 " calc-sm-impulse" $call-analyzer plot-impulse1
then
;
+true value allow-swapping?
+: ?try-swapped ( error? -- error?' )
+ allow-swapping? 0= if exit then ( error? )
+ dup if ( error? )
+ " swap-lr-pb" $call-analyzer ( error? )
+ " analyze-signal" $call-analyzer ( error? swapped-error? )
+ " unswap-lr-pb" $call-analyzer ( error? swapped-error? )
+ 0= if ( error? )
+ \ If swapping left and right "fixes" the problem, we
+ \ don't report an error. This works around a hard-to-fix
+ \ random channel-swapping problem with Marvell MMP3.
+ ." Channel swap!" cr ( error? )
+ drop false ( 0 )
+ then ( error? )
+ then ( error? )
+;
: test-with-loopback ( -- error? )
mic-bias-off
input-test-settings stereo
output-test-settings loopback-test-volume set-volume
." Testing headphone and microphone jacks with loopback cable" cr
- " setup-loopback" test-common
+ " setup-loopback" test-common ( error? )
+ ?try-swapped
+ .test-error
+
plot? if
- 0 " calc-stereo-impulse" $call-analyzer plot-impulse
- 2 " calc-stereo-impulse" $call-analyzer plot-impulse
+ 0 " calc-stereo-impulse" $call-analyzer plot-impulse0
+ 2 " calc-stereo-impulse" $call-analyzer plot-impulse1
then
;
More information about the openfirmware
mailing list