Author: wmb Date: Wed Nov 14 00:10:08 2012 New Revision: 3421 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/3421
Log: OLPC ARM - accelerometer selftest - manufacturing was seeing a small false-negative fallout from the accelerometer test. This change attempts to address it by: a) Changing the scale factor for acceleration components to 1000 units = 1 gravity, per the datasheet definition of "LSB" b) Changing the averaging from 64 samples to 5 samples, per the vendor's recommendation c) Changing the test limits to the vendor's recommended limits (in the new units) d) Fixing a bug in which the first test invocation often failed, due to the sensor initially being in low-resolution mode (so the granularity of the initial average was too coarse). e) Adding a gain test to check that the magnitude of the acceleration vector is about 1 gravity. f) Refactoring the test slightly so that "accelerometer-off" is paired more cleanly with "accelerometer-on" (inside close and open) instead of being all over the place.
Modified: cpu/arm/olpc/accelerometer.fth cpu/arm/olpc/roller.fth
Modified: cpu/arm/olpc/accelerometer.fth ============================================================================== --- cpu/arm/olpc/accelerometer.fth Thu Nov 8 08:43:41 2012 (r3420) +++ cpu/arm/olpc/accelerometer.fth Wed Nov 14 00:10:08 2012 (r3421) @@ -4,6 +4,8 @@ " accelerometer" name " lis3lv02d" +compatible
+true value hi-res? + \ reg is set dynamically by probing to find which chip is present
\ This is for the stand-alone accelerometers LIS3DHTR and LIS33DETR @@ -13,17 +15,23 @@ : acc-reg! ( b reg# -- ) " reg-b!" $call-parent ; : ctl1! ( b -- ) h# 20 acc-reg! ; : ctl4! ( b -- ) h# 23 acc-reg! ; -: accelerometer-on ( -- ) h# 47 ctl1! ; +: ctl4@ ( -- b ) h# 23 acc-reg@ ; +: accelerometer-on ( -- ) + h# 47 ctl1! + hi-res? if 8 ctl4! then \ High resolution mode +; : accelerometer-off ( -- ) h# 07 ctl1! ; \ should this be 00? : wext ( b -- n ) dup h# 8000 and if h# ffff0000 or then ; + +\ The scale factor for an acceleration component is 1 gravity = 1000 units. : acceleration@ ( -- x y z ) begin h# 27 acc-reg@ h# 08 and until \ wait for data available h# 0a8 1 6 " bytes-out-in" $call-parent ( xl xh yl yh zl zh ) - bwjoin wext 5 >>a ( xl xh yl yh z ) + bwjoin wext 4 >>a ( xl xh yl yh z ) >r ( xl xh yl yh r: z ) - bwjoin wext 5 >>a ( xl xh y r: z ) + bwjoin wext 4 >>a ( xl xh y r: z ) >r ( xl xh r: z y ) - bwjoin wext 5 >>a ( x r: z y ) + bwjoin wext 4 >>a ( x r: z y ) r> r> ( x y z ) ;
@@ -39,15 +47,17 @@ rot r> - ( z1 x3 y3 r: z2 ) rot r> - ( x3 y3 z3 ) ; + \ Averaging a lot of samples reduces the effect of vibration +\ The vendor recommends averaging 5 samples for selftest. : average-acceleration@ ( -- x y z ) acceleration@ ( x y z ) - d# 64 0 do + d# 4 0 do acceleration@ t+ ( x' y' z' ) - loop - rot 6 >>a - rot 6 >>a - rot 6 >>a + loop ( xsum ysum zsum ) + rot 5 / ( ysum zsum x ) + rot 5 / ( zsum x y ) + rot 5 / ( x y z ) ;
: delay ( -- ) d# 30 ms ; @@ -61,20 +71,16 @@ accelerometer-off ;
-\ The datasheet says the selftest change range is 3 to 32, but we -\ give a little headroom on the high end to allow for external -\ vibration. Typical is supposed to be 19. -\ Empirically, measured maximums were: -\ - Mitch's unit, 32 -\ - James' A3, 41 (on rubber mat on bare ground) -\ - James' A2, 39 - -d# 50 value min-x -d# 50 value min-y -d# 150 value min-z -d# 150 value max-x -d# 150 value max-y -d# 450 value max-z +\ The vendor recommends the following min/max values for LIS3DHTR selftest: +\ X:80..1700 Y:80..1700 Z:80..1400. +\ The numbers are in units of "1LSB = 1mg", 1000 unit = 1 gravity. + +d# 80 value min-x +d# 80 value min-y +d# 80 value min-z +d# 1700 value max-x +d# 1700 value max-y +d# 1400 value max-z : range? ( delta max-delta -- error? ) between 0= ;
: error? ( dx dy dz -- error? ) @@ -84,6 +90,20 @@ false ;
+\ Lower and upper test limits for the magnitude squared of the acceleration +\ vector when the device is stationary. The scaling is 1000 units = 1 gravity. + +d# 900 dup * constant gsq-min \ 0.9 gravity squared +d# 1100 dup * constant gsq-max \ 1.1 gravity squared + +: xyz>mag-sq ( z y z -- magnitude-squared ) + dup * swap dup * + swap dup * + +; +: not1g? ( x y z -- error? ) + xyz>mag-sq ( magnitude**2 ) + gsq-min gsq-max between 0= +; + : lis33de-selftest ( -- error? ) \ Use the device's selftest function to force a change in one direction delay ( ) @@ -95,7 +115,7 @@ \ because we subtract the new measurement from the old. rot negate -rot ( dx' dy dz ) negate ( dx dy dz' ) - error? if accelerometer-off true exit then + error? if true exit then
\ Use the device's selftest function to force a change in the opposite direction accelerometer-on delay ( ) \ Back to normal - STM and STP both off @@ -106,19 +126,26 @@ \ STP applies negative bias to X and Z, but our deltas are inverted \ because we subtract the new measurement from the old. swap negate swap ( dx dy' dz ) - error? if accelerometer-off true exit then - false + error? ; : lis3dhtr-selftest ( -- error? ) - \ Use the device's selftest function to force a change in one direction delay ( ) average-acceleration@ ( x y z ) + + \ Check that the magnitude of the acceleration vector is about 1 G + 3dup not1g? if ( x y z ) + 3drop ( ) + ." Acceleration is not 1 gravity" cr ( ) + true exit ( -- error? ) + then ( x y z ) + + \ Use the device's selftest function to force a change in one direction h# 0a ctl4! ( x y z ) \ High res, Selftest mode 0 delay average-acceleration@ t- ( dx dy dz ) rot negate rot negate rot negate h# 08 ctl4! ( x y z ) \ High res, Normal mode - error? if accelerometer-off true exit then + error? if true exit then
\ Use the device's selftest function to force a change in the opposite direction accelerometer-on delay ( ) \ Back to normal - STM and STP both off @@ -127,19 +154,20 @@ delay average-acceleration@ t- ( dx dy dz ) h# 08 ctl4! ( x y z ) \ High res, Normal mode - error? if accelerometer-off true exit then - - accelerometer-off - false + error? ; defer lis-selftest : selftest ( -- error? ) open 0= if true exit then
- final-test? if accelerometer-off false exit then + final-test? if + false + else + ." Don't move!" cr + lis-selftest + then
- ." Don't move!" cr - lis-selftest + close ;
: probe ( -- ) @@ -149,19 +177,21 @@ \ The attempt to talk at the old address failed, so we assume the new chip \ Support for new LIS3DHTR chip d# 400,000 to bus-speed - d# 50 to min-x d# 50 to min-y d# 50 to min-z - d# 150 to max-x d# 150 to max-y d# 450 to max-z + d# 80 to min-x d# 80 to min-y d# 80 to min-z + d# 1700 to max-x d# 1700 to max-y d# 1400 to max-z h# 19 1 reg ['] lis3dhtr-selftest to lis-selftest + true to hi-res? else accelerometer-off \ Something responded to the old address, so we assume it's the old chip \ Support for old LIS33DE chip d# 25,000 to bus-speed - d# 20 to min-x d# 20 to min-y d# 20 to min-z - d# 400 to max-x d# 400 to max-y d# 400 to max-z + d# 40 to min-x d# 40 to min-y d# 40 to min-z + d# 800 to max-x d# 800 to max-y d# 800 to max-z h# 1d 1 reg ['] lis33de-selftest to lis-selftest + false to hi-res? then ;
Modified: cpu/arm/olpc/roller.fth ============================================================================== --- cpu/arm/olpc/roller.fth Thu Nov 8 08:43:41 2012 (r3420) +++ cpu/arm/olpc/roller.fth Wed Nov 14 00:10:08 2012 (r3421) @@ -75,7 +75,7 @@
d# 19 d# 20 a/b>fraction value damping
-d# 1 d# 80 a/b>fraction value acc-scale +d# 1 d# 160 a/b>fraction value acc-scale
d# 20 constant ball-radius d# 40 constant ball-diameter
openfirmware@openfirmware.info