Author: wmb
Date: 2009-08-09 05:30:55 +0200 (Sun, 09 Aug 2009)
New Revision: 1287
Added:
dev/olpc/viacamera/
dev/olpc/viacamera/camera.fth
dev/olpc/viacamera/loadpkg.fth
dev/olpc/viacamera/smbus.fth
Modified:
cpu/x86/pc/olpc/via/devices.fth
Log:
Via - added camera selftest.
Modified: cpu/x86/pc/olpc/via/devices.fth
===================================================================
--- cpu/x86/pc/olpc/via/devices.fth 2009-08-06 03:48:08 UTC (rev 1286)
+++ cpu/x86/pc/olpc/via/devices.fth 2009-08-09 03:30:55 UTC (rev 1287)
@@ -306,8 +306,9 @@
end-package
devalias screen /display
also hidden d# 34 to display-height previous \ For editing
-[then]
+fload ${BP}/dev/olpc/viacamera/loadpkg.fth \ Camera driver
+
fload ${BP}/cpu/x86/adpcm.fth \ ADPCM decoding
warning @ warning off
Added: dev/olpc/viacamera/camera.fth
===================================================================
--- dev/olpc/viacamera/camera.fth (rev 0)
+++ dev/olpc/viacamera/camera.fth 2009-08-09 03:30:55 UTC (rev 1287)
@@ -0,0 +1,564 @@
+\ See license at end of file
+purpose: Driver for OLPC camera connected to Via VX855 Video Capture Port
+
+headers
+hex
+
+" OV7670" " sensor" string-property
+
+: cl! ( l adr -- ) " mmio-base" $call-parent + rl! ;
+: cl@ ( adr -- l ) " mmio-base" $call-parent + rl@ ;
+
+\ ======================= OV7670 SMBUS operations ==========================
+
+h# 42 constant ov-sid
+h# 31 constant sccb-port
+
+: sccb-setup ( -- ) sccb-port to smb-port ov-sid to smb-slave ;
+: ov@ ( reg -- data ) sccb-setup smb-byte@ ;
+: ov! ( data reg -- ) sccb-setup smb-byte! ;
+
+: ovc ( val adr -- )
+ 2dup ov@ ( val reg# val actual )
+ tuck <> if ( val reg# actual )
+ ." Bad camera I2C value at " swap 2 u.r ( val actual )
+ ." expected " swap 2 u.r ." got " 2 u.r cr ( )
+ else ( val reg# actual )
+ 3drop ( )
+ then ( )
+;
+
+\ ============================= camera operations =============================
+
+false value ov7670-detected?
+
+: ((camera-init) ( -- )
+ 80 12 ov! 2 ms \ reset (reads back different)
+ 01 11 ov! \ 30 fps
+ 04 3a ov! \ UYVY or VYUY
+ 00 12 ov! \ VGA
+
+ \ Hardware window
+ 13 17 ov! \ Horiz start high bits
+ 01 18 ov! \ Horiz stop high bits
+ b6 32 ov! \ HREF pieces
+ 0a 19 ov! \ Vert start high bits
+ 7a 1a ov! \ Vert stop high bits
+ 0a 03 ov! \ GAIN, VSTART, VSTOP pieces
+
+ \ Mystery scaling numbers
+ 00 0c ov! \ Control 3
+ 00 3e ov! \ Control 14
+ 3a 70 ov! 35 71 ov! 11 72 ov! f0 73 ov!
+ 02 a2 ov!
+ 00 15 ov! \ Control 10
+
+ \ Gamma curve values
+ 20 7a ov! 10 7b ov! 1e 7c ov! 35 7d ov!
+ 5a 7e ov! 69 7f ov! 76 80 ov! 80 81 ov!
+ 88 82 ov! 8f 83 ov! 96 84 ov! a3 85 ov!
+ af 86 ov! c4 87 ov! d7 88 ov! e8 89 ov!
+
+ \ AGC and AEC parameters
+ e0 13 ov! \ Control 8
+ 00 00 ov! \ Gain lower 8 bits
+ 40 0d ov! \ Control 4 magic reserved bit
+ 18 14 ov! \ Control 9: 4x gain + magic reserved bit
+ 05 a5 ov! \ 50hz banding step limit
+ 07 ab ov! \ 60hz banding step limit
+ 95 24 ov! \ AGC upper limit
+ 33 25 ov! \ AGC lower limit
+ e3 24 ov! \ AGC/AEC fast mode op region
+ 78 9f ov! \ Hist AEC/AGC control 1
+ 68 a0 ov! \ Hist AEC/AGC control 2
+ 03 a1 ov! \ Magic
+ d8 a6 ov! \ Hist AEC/AGC control 3
+ d8 a7 ov! \ Hist AEC/AGC control 4
+ f0 a8 ov! \ Hist AEC/AGC control 5
+ 90 a9 ov! \ Hist AEC/AGC control 6
+ 94 aa ov! \ Hist AEC/AGC control 7
+ e5 13 ov! \ Control 8
+
+ \ Mostly magic
+ 61 0e ov! 4b 0f ov! 02 16 ov! 07 1e ov!
+ 02 21 ov! 91 22 ov! 07 29 ov! 0b 33 ov!
+ 0b 35 ov! 1d 37 ov! 71 38 ov! 2a 39 ov!
+ 78 3c ov! 40 4d ov! 20 4e ov! 00 69 ov!
+ 4a 6b ov! 10 74 ov! 4f 8d ov! 00 8e ov!
+ 00 8f ov! 00 90 ov! 00 91 ov! 00 96 ov!
+ 00 9a ov! 84 b0 ov! 0c b1 ov! 0e b2 ov!
+ 82 b3 ov! 0a b8 ov!
+
+ \ More magic, some of which tweaks white balance
+ 0a 43 ov! f0 44 ov! 34 45 ov! 58 46 ov!
+ 28 47 ov! 3a 48 ov! 88 59 ov! 88 5a ov!
+ 44 5b ov! 67 5c ov! 49 5d ov! 0e 5e ov!
+ 0a 6c ov! 55 6d ov! 11 6e ov!
+ 9f 6f ov! \ 9e for advance AWB
+ 40 6a ov!
+ 40 01 ov! \ Blue gain
+ 60 02 ov! \ Red gain
+ e7 13 ov! \ Control 8
+
+ \ Matrix coefficients
+ 80 4f ov! 80 50 ov! 00 51 ov! 22 52 ov!
+ 5e 53 ov! 80 54 ov! 9e 58 ov!
+
+ 08 41 ov! \ AWB gain enable
+ 00 3f ov! \ Edge enhancement factor
+ 05 75 ov! e1 76 ov! 00 4c ov! 01 77 ov!
+ c3 3d ov! \ Control 13
+ 09 4b ov! 60 c9 ov! \ Reads back differently
+ 38 41 ov! \ Control 16
+ 40 56 ov!
+
+ 11 34 ov!
+ 12 3b ov! \ Control 11
+ 88 a4 ov! 00 96 ov! 30 97 ov! 20 98 ov!
+ 30 99 ov! 84 9a ov! 29 9b ov! 03 9c ov!
+ 5c 9d ov! 3f 9e ov! 04 78 ov!
+
+ \ Extra-weird stuff. Some sort of multiplexor register
+ 01 79 ov! f0 c8 ov!
+ 0f 79 ov! 00 c8 ov!
+ 10 79 ov! 7e c8 ov!
+ 0a 79 ov! 80 c8 ov!
+ 0b 79 ov! 01 c8 ov!
+ 0c 79 ov! 0f c8 ov!
+ 0d 79 ov! 20 c8 ov!
+ 09 79 ov! 80 c8 ov!
+ 02 79 ov! c0 c8 ov!
+ 03 79 ov! 40 c8 ov!
+ 05 79 ov! 30 c8 ov!
+ 26 79 ov!
+
+ \ OVT says that rewrite this works around a bug in 565 mode.
+ \ The symptom of the bug is red and green speckles in the image.
+ 01 11 ov! \ 30 fps def 80
+;
+
+: config-check ( -- )
+ 01 11 ovc \ 30 fps
+ 04 3a ovc \ UYVY or VYUY
+ ( 00 12 ovc ) \ VGA
+
+ \ Hardware window
+ 13 17 ovc \ Horiz start high bits
+ 01 18 ovc \ Horiz stop high bits
+ b6 32 ovc \ HREF pieces
+ ( 0a 19 ovc ) \ Vert start high bits
+ 7a 1a ovc \ Vert stop high bits
+ 0a 03 ovc \ GAIN, VSTART, VSTOP pieces
+
+ \ Mystery scaling numbers
+ 00 0c ovc \ Control 3
+ 00 3e ovc \ Control 14
+ 3a 70 ovc 35 71 ovc 11 72 ovc f0 73 ovc
+ 02 a2 ovc
+ 00 15 ovc \ Control 10
+
+ \ Gamma curve values
+ 20 7a ovc 10 7b ovc 1e 7c ovc 35 7d ovc
+ 5a 7e ovc 69 7f ovc 76 80 ovc 80 81 ovc
+ 88 82 ovc 8f 83 ovc 96 84 ovc a3 85 ovc
+ af 86 ovc c4 87 ovc d7 88 ovc e8 89 ovc
+
+ \ AGC and AEC parameters
+ ( e0 13 ovc ) \ Control 8
+ ( 00 00 ovc ) \ Gain lower 8 bits
+ 40 0d ovc \ Control 4 magic reserved bit
+ ( 18 14 ovc ) \ Control 9: 4x gain + magic reserved bit
+ 05 a5 ovc \ 50hz banding step limit
+ 07 ab ovc \ 60hz banding step limit
+ ( 95 24 ovc ) \ AGC upper limit
+ 33 25 ovc \ AGC lower limit
+ e3 24 ovc \ AGC/AEC fast mode op region
+ 78 9f ovc \ Hist AEC/AGC control 1
+ 68 a0 ovc \ Hist AEC/AGC control 2
+ 03 a1 ovc \ Magic
+ d8 a6 ovc \ Hist AEC/AGC control 3
+ d8 a7 ovc \ Hist AEC/AGC control 4
+ f0 a8 ovc \ Hist AEC/AGC control 5
+ 90 a9 ovc \ Hist AEC/AGC control 6
+ 94 aa ovc \ Hist AEC/AGC control 7
+ ( e5 13 ovc ) \ Control 8
+
+ \ Mostly magic
+ 61 0e ovc 4b 0f ovc 02 16 ovc 07 1e ovc
+ 02 21 ovc 91 22 ovc 07 29 ovc 0b 33 ovc
+ 0b 35 ovc 1d 37 ovc 71 38 ovc 2a 39 ovc
+ 78 3c ovc 40 4d ovc 20 4e ovc 00 69 ovc
+ 4a 6b ovc 10 74 ovc 4f 8d ovc 00 8e ovc
+ 00 8f ovc 00 90 ovc 00 91 ovc 00 96 ovc
+ ( 00 9a ovc ) 84 b0 ovc 0c b1 ovc 0e b2 ovc
+ 82 b3 ovc 0a b8 ovc
+
+ \ More magic, some of which tweaks white balance
+ 0a 43 ovc f0 44 ovc 34 45 ovc 58 46 ovc
+ 28 47 ovc 3a 48 ovc 88 59 ovc 88 5a ovc
+ 44 5b ovc 67 5c ovc 49 5d ovc 0e 5e ovc
+ 0a 6c ovc 55 6d ovc 11 6e ovc
+ 9f 6f ovc \ 9e for advance AWB
+ ( 40 6a ovc )
+ ( 40 01 ovc ) \ Blue gain
+ ( 60 02 ovc ) \ Red gain
+ e7 13 ovc \ Control 8
+
+ \ Matrix coefficients
+ b3 4f ovc b3 50 ovc 00 51 ovc 3d 52 ovc
+ a7 53 ovc e4 54 ovc 9e 58 ovc
+
+ \ 08 41 ovc \ AWB gain enable
+ ( 00 3f ovc ) \ Edge enhancement factor
+ 05 75 ovc e1 76 ovc ( 00 4c ovc ) 01 77 ovc
+ c0 3d ovc \ Control 13
+ 09 4b ovc ( 60 c9 ovc )
+ 38 41 ovc \ Control 16
+ 40 56 ovc
+
+ 11 34 ovc
+ 12 3b ovc \ Control 11
+ 88 a4 ovc 00 96 ovc 30 97 ovc 20 98 ovc
+ 30 99 ovc 84 9a ovc 29 9b ovc 03 9c ovc
+ 5c 9d ovc 3f 9e ovc 04 78 ovc
+
+;
+
+: camera-init ( -- )
+ false to ov7670-detected?
+ ((camera-init)
+ 1d ov@ 1c ov@ bwjoin 7fa2 <> if exit then \ Manufacturing ID
+ b ov@ a ov@ bwjoin 7673 <> if exit then \ Product ID
+ true to ov7670-detected?
+;
+
+\ VGA RGB565
+: init-rgb565 ( -- )
+ 04 12 ov! \ VGA, RGB565
+ 00 8c ov! \ No RGB444
+ 40 04 ov! \ Control 1: CCIR656 (CaFe value is 00)
+ 10 40 ov! \ RGB565 output
+ 38 14 ov! \ 16x gain ceiling
+ b3 4f ov! \ v-red
+ b3 50 ov! \ v-green
+ 00 51 ov! \ v-blue
+ 3d 52 ov! \ u-red
+ a7 53 ov! \ u-green
+ e4 54 ov! \ u-blue
+ c0 3d ov! \ Gamma enable, UV saturation auto adjust
+;
+
+: read-agc ( -- n )
+ 3 ov@ h# c0 and 2 lshift 0 ov@ or
+;
+
+: read-aec ( -- n )
+ 7 ov@ h# 3f and d# 10 lshift
+ h# 10 ov@ 2 lshift or
+ 4 ov@ 3 and or
+;
+
+: set-hw ( vstop vstart hstop hstart -- )
+ dup 3 >> 17 ov! \ Horiz start high bits
+ over 3 >> 18 ov! \ Horiz stop high bits
+ 32 ov@ swap 7 and or swap 7 and 3 << or 10 ms 32 ov! \ Horiz bottom bits
+
+ dup 2 >> 19 ov! \ Vert start high bits
+ over 2 >> 1a ov! \ Vert start high bits
+ 03 ov@ swap 3 and or swap 3 and 2 << or 10 ms 03 ov! \ Vert bottom bits
+;
+
+: camera-config ( -- )
+ ((camera-init)
+ init-rgb565
+ d# 490 d# 10 d# 14 d# 158 set-hw \ VGA window info
+;
+
+\ ========================== video capture operations ==========================
+
+d# 640 constant VGA_WIDTH
+d# 480 constant VGA_HEIGHT
+
+VGA_WIDTH VGA_HEIGHT * 2* constant /dma-buf
+3 constant #dma-bufs
+0 value dma-bufs
+0 value dma-bufs-phys
+0 value next-buf
+
+: dma-sync ( virt phys size -- ) " dma-sync" $call-parent ;
+: dma-alloc ( len -- adr ) " dma-alloc" $call-parent ;
+: dma-free ( adr len -- ) " dma-free" $call-parent ;
+: dma-map-in ( virt size cache? -- phys ) " dma-map-in" $call-parent ;
+: dma-map-out ( virt phys size -- ) " dma-map-out" $call-parent ;
+
+: 'dma-buf ( i -- virt ) /dma-buf * dma-bufs + ;
+: 'dma-buf-phys ( i -- phys ) /dma-buf * dma-bufs-phys + ;
+
+0 [if]
+: alloc-dma-bufs ( -- )
+ dma-bufs 0= if
+ /dma-buf #dma-bufs * dup dma-alloc dup to dma-bufs
+ swap false dma-map-in to dma-bufs-phys
+ then
+;
+: free-dma-bufs ( -- )
+ dma-bufs ?dup if
+ /dma-buf #dma-bufs 1+ * 2dup dma-bufs-phys swap dma-map-out
+ dma-free
+ 0 to dma-bufs 0 to dma-bufs-phys
+ then
+;
+
+: setup-dma ( -- )
+ #dma-bufs 0 do
+ i 'dma-buf-phys 2 or i 4 * 340 + cl! \ Capture frame buffers
+ loop
+;
+[else]
+
+[ifdef] notdef
+\ XXX Capture video to video memory only. I don't know why I can't capture to
+\ XXX system memory. I'm using an arbitrary offset into the video memory.
+
+h# 200.0000 constant capture-base
+
+: alloc-dma-bufs ( -- )
+ dma-bufs 0= if
+ capture-base dup frame-buffer-adr + to dma-bufs
+ to dma-bufs-phys
+ then
+;
+: free-dma-bufs ( -- ) 0 to dma-bufs 0 to dma-bufs-phys ;
+[else]
+: alloc-dma-bufs ( -- )
+ dma-bufs 0= if
+ /dma-buf #dma-bufs * " alloc-capture-buffer" $call-parent to dma-bufs-phys to dma-bufs
+ then
+;
+: free-dma-bufs ( -- )
+ dma-bufs dma-bufs-phys /dma-buf #dma-bufs * " free-capture-buffer" $call-parent
+ 0 to dma-bufs 0 to dma-bufs-phys
+;
+[then]
+: setup-dma ( -- )
+ #dma-bufs 0 do
+ i 'dma-buf-phys 340 i 4 * + cl! \ Capture frame buffers
+ loop
+;
+
+[then]
+
+
+\ VGA RGB565
+: setup-image ( -- )
+ 0 31c cl! \ Active video scaling control
+ 01e2.00f0 334 cl! \ Maximum data count of active video
+;
+
+: ctlr-config ( -- )
+ setup-dma
+ setup-image
+;
+
+: ctlr-start ( -- ) 310 dup cl@ 1 or swap cl! ; \ Start the whole thing
+: ctlr-stop ( -- ) 310 dup cl@ 1 invert and swap cl! ; \ Stop the whole thing
+
+: read-setup ( -- )
+ camera-config
+ ctlr-config
+ 83 300 cl! \ Clear pending interrupts
+ 1000.0000 200 cl! \ Allow CAP0 end interrupt
+ ctlr-start
+ 0 to next-buf
+;
+
+: soft-reset ( -- ) ;
+
+: (init) ( -- )
+ 0 300 cl! \ Mask all interrupts
+ 8850.2114 310 cl! \ Enable CLK, FIFO threshold, UYVY, 8-bit CCIR656,
+ \ Capture odd/even in interlace, triple buffers
+ 500 350 cl! \ Disable coring and 640*2 stride
+;
+
+: power-up ( -- )
+ \ Disable UART
+ 8846 dup config-b@ 40 invert and swap config-b! \ Disable UART
+ 78 dup seq@ 80 invert and swap seq! \ Enable VCP/DVP1 interface
+
+ \ Setup VGPIO[2..3]
+ 2c dup seq@ 02 or swap seq! \ Enable VGPIO2..3 ports
+ 2c dup seq@ d0 or swap seq! \ cam_PWREN, cam_Reset
+ 1 ms
+ 2c dup seq@ f0 or swap seq! \ Release reset
+ 1 ms
+
+ \ Power on video capture port
+ 1e dup seq@ c0 or swap seq! \ Pad on/off according to PMS
+ 1 ms
+;
+
+: power-off ( -- )
+ 2c dup seq@ 20 invert and swap seq! \ Assert cam_Reset
+ 1 ms
+ 2c dup seq@ 10 invert and swap seq! \ Power off
+;
+
+: init ( -- )
+ (init)
+ power-up
+ sccb-setup smb-on
+ camera-init
+;
+
+
+\ ============================= read operation ==============================
+
+0 value buf-act
+: /string ( adr len n -- adr' len' ) tuck - -rot + swap ;
+: buf-done? ( -- done? )
+ 200 cl@ 1000 and dup if
+ 300 cl@ 3 >> 3 and to next-buf
+ then
+;
+
+: (read) ( adr len -- actual )
+ next-buf 'dma-buf -rot /dma-buf min dup >r move r> ( actual )
+ 300 cl@ 83 or 300 cl! \ Clear interrupts
+;
+
+external
+
+: camera-read ( adr len -- actual )
+ buf-done? if (read) else 2drop 0 then
+;
+
+: camera-open ( -- flag )
+ init
+ ov7670-detected? 0= if false exit then
+ alloc-dma-bufs
+ read-setup
+ true
+;
+
+: camera-close ( -- )
+ ctlr-stop
+ power-off
+ free-dma-bufs
+;
+
+
+\ ============================= selftest operation ===========================
+
+d# 10,000 constant movie-time
+0 constant test-x
+0 constant test-y
+
+\ Thanks to Cortland Setlow (AKA Blaketh) for the autobrightness code
+\ and the full-screen + mirrored display.
+
+: autobright ( -- )
+ read-agc 3 + 3 rshift h# f min " bright!" $call-parent
+;
+: full-brightness ( -- ) h# f " bright!" $call-parent ;
+
+: display-frame ( adr -- )
+\ test-x test-y VGA_WIDTH VGA_HEIGHT draw-rectangle
+ " expand-to-screen" $call-parent
+ autobright
+;
+
+: timeout-read ( adr len timeout -- actual )
+ >r 0 -rot r> 0 ?do ( actual adr len )
+ 2dup camera-read ?dup if 3 roll drop -rot leave then
+ 1 ms
+
+ loop 2drop
+;
+
+: shoot-movie ( -- error? )
+ /dma-buf #dma-bufs * dup dma-alloc swap ( adr len )
+ get-msecs movie-time + -rot ( timeout adr len )
+ begin
+ 2dup camera-read ?dup 0> if ( timeout adr len actual )
+ VGA_WIDTH VGA_HEIGHT * 2* / 0 ?do over display-frame loop
+ else
+ 1 ms
+ then ( timeout adr len )
+ get-msecs 3 pick u>
+ until ( timeout adr len )
+ dma-free drop false ( error? )
+;
+
+: shoot-still ( -- error? )
+ /dma-buf dup dma-alloc tuck ( adr len adr )
+ /dma-buf d# 1,000 timeout-read 0> if ( adr len )
+ over display-frame
+ false
+ else
+ true
+ then ( adr len error? )
+ -rot dma-free ( error? )
+;
+
+: mirrored ( -- ) h# 1e ov@ h# 20 or h# 1e ov! ;
+: unmirrored ( -- ) h# 1e ov@ h# 20 invert and h# 1e ov! ;
+
+: selftest ( -- error? )
+ camera-open 0= if true exit then
+ d# 300 ms
+ unmirrored shoot-still ?dup if camera-close exit then ( error? )
+ d# 1,000 ms
+ mirrored shoot-movie full-brightness ( error? )
+ camera-close ( error? )
+;
+
+: dump-regs ( run# -- )
+ 0 d# 16 " at-xy" eval
+ ." Pass " .d
+ key upc h# 47 = if ." Good" else ." Bad" then cr \ 47 is G
+
+ ." 0 1 2 3 4 5 6 7 8 9 a b c d e f" cr
+ ." -----------------------------------------------" cr
+ h# ca 0 do
+ i 2 u.r ." : "
+ i h# 10 bounds do
+ i h# ca < if i ov@ 3 u.r then
+ loop
+ cr
+ h# 10 +loop
+;
+
+: xselftest ( -- error? )
+ camera-open 0= if true exit then
+ h# 10 0 do
+ shoot-still drop d# 500 ms camera-config config-check
+ i dump-regs
+ loop
+ 0 camera-close ( error? )
+;
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2009 FirmWorks
+\
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
Property changes on: dev/olpc/viacamera/camera.fth
___________________________________________________________________
Added: svn:executable
+ *
Added: dev/olpc/viacamera/loadpkg.fth
===================================================================
--- dev/olpc/viacamera/loadpkg.fth (rev 0)
+++ dev/olpc/viacamera/loadpkg.fth 2009-08-09 03:30:55 UTC (rev 1287)
@@ -0,0 +1,27 @@
+dev screen
+\ XXX Capture video to video memory only. I don't know why I can't capture to
+\ XXX system memory. I'm using an arbitrary offset into the video memory.
+
+h# 200.0000 constant capture-base
+
+: alloc-capture-buffer ( len -- vadr padr )
+ >r ( r: len )
+ capture-base 0 h# 0200.0010 my-space or ( pci-phys.. r: len )
+ r> " map-in" $call-parent ( vadr )
+
+ dup >physical ( vadr padr )
+;
+
+: free-capture-buffer ( vadr padr len -- ) nip unmap ;
+
+: dma-alloc ( len -- adr ) " dma-alloc" $call-parent ;
+: dma-free ( adr len -- ) " dma-free" $call-parent ;
+
+new-device
+ " camera" device-name
+ fload ${BP}/dev/olpc/viacamera/smbus.fth
+ fload ${BP}/dev/olpc/viacamera/camera.fth
+finish-device
+
+device-end
+
Added: dev/olpc/viacamera/smbus.fth
===================================================================
--- dev/olpc/viacamera/smbus.fth (rev 0)
+++ dev/olpc/viacamera/smbus.fth 2009-08-09 03:30:55 UTC (rev 1287)
@@ -0,0 +1,132 @@
+[ifndef] seq!
+: seq! 3c4 pc! 3c5 pc! ;
+[then]
+
+[ifndef] seq@
+: seq@ 3c4 pc! 3c5 pc@ ;
+[then]
+
+0 value smb-port
+
+: smb-dly 4 us ;
+: crtsp-set ( mask -- ) smb-port seq@ or smb-port seq! smb-dly ;
+: crtsp-clr ( mask -- ) invert smb-port seq@ and smb-port seq! smb-dly ;
+: crtsp@ ( mask -- flag ) smb-port seq@ and 0<> ;
+
+: smb-data-hi ( -- ) h# 10 crtsp-set ;
+: smb-data-lo ( -- ) h# 10 crtsp-clr ;
+: smb-clk-hi ( -- ) h# 20 crtsp-set ;
+: smb-clk-lo ( -- ) h# 20 crtsp-clr ;
+: smb-data@ ( -- flag ) 4 crtsp@ ;
+: smb-clk@ ( -- ) 8 crtsp@ ;
+\ : smb-on ( -- ) 1 crtsp-set h# 30 crtsp-set d# 10 ms ;
+: smb-off ( -- ) 1 crtsp-clr ;
+: smb-on ( -- ) h# 31 crtsp-set ;
+: smb-bit@ ( -- ) smb-clk-hi smb-port seq@ 4 and 0<> smb-clk-lo ;
+
+h# 3500 constant smb-clk-timeout-us
+\ Slave can flow control by holding CLK low temporarily
+: smb-wait-clk-hi ( -- )
+ smb-clk-timeout-us 0 do
+ smb-clk@ if smb-dly unloop exit then 1 us
+ loop
+ true abort" I2C clock stuck low"
+;
+: smb-data-hi-w ( -- ) smb-data-hi smb-wait-clk-hi ;
+
+h# 3500 constant smb-data-timeout-us
+: smb-wait-data-hi ( -- )
+ smb-data-timeout-us 0 do
+ smb-data@ if unloop exit then 1 us
+ loop
+ true abort" I2C data stuck low"
+;
+
+: smb-restart ( -- )
+ smb-clk-hi smb-data-lo smb-clk-lo
+;
+
+: smb-start ( -- ) smb-clk-hi smb-data-hi smb-data-lo smb-clk-lo ;
+: smb-stop ( -- ) smb-clk-lo smb-data-lo smb-clk-hi smb-data-hi ;
+
+: smb-get-ack ( -- )
+ smb-data-hi
+ smb-clk-hi smb-wait-clk-hi
+ smb-data@ \ drop \ SCCB generates an don't care bit
+ if smb-stop true abort" I2c NAK" then
+ smb-clk-lo
+\ smb-wait-data-hi
+;
+: smb-bit ( flag -- )
+ if smb-data-hi else smb-data-lo then
+ smb-clk-hi smb-wait-clk-hi smb-clk-lo
+;
+
+: smb-byte ( b -- )
+ 8 0 do ( b )
+ dup h# 80 and smb-bit ( b )
+ 2* ( b' )
+ loop ( b )
+ drop ( )
+ smb-get-ack
+;
+: smb-byte-in ( ack=0/nak=1 -- b )
+ 0
+ 8 0 do ( n )
+ smb-clk-hi ( n )
+ 2* smb-data@ if 1 or then ( n' )
+ smb-clk-lo
+ loop
+ swap smb-bit smb-data-hi \ Send ACK or NAK
+;
+
+0 value smb-slave
+: smb-addr ( lowbit -- ) smb-slave or smb-byte ;
+
+: smb-byte! ( byte reg# -- )
+ smb-start
+ 0 smb-addr ( byte reg# )
+ smb-byte ( byte )
+ smb-byte ( )
+ smb-stop
+;
+
+: smb-byte@ ( reg# -- byte )
+ smb-start
+ 0 smb-addr ( reg# )
+ smb-byte ( )
+ smb-stop smb-start \ SCCB bus needs a stop and a start for the second phase
+ 1 smb-addr
+ 1 smb-byte-in ( byte )
+ smb-stop
+;
+
+: smb-word! ( word reg# -- )
+ smb-start
+ 0 smb-addr ( word reg# )
+ smb-byte ( word )
+ wbsplit swap smb-byte smb-byte ( )
+ smb-stop
+;
+
+: smb-word@ ( reg# -- word )
+ smb-start
+ 0 smb-addr ( reg# )
+ smb-byte ( )
+ smb-restart
+ 1 smb-addr ( )
+ 0 smb-byte-in 1 smb-byte-in bwjoin ( word )
+ smb-stop
+;
+
+\ This can useful for clearing out DCON SMB internal state
+: smb-pulses ( -- )
+ d# 32 0 do smb-clk-lo smb-clk-hi loop
+;
+
+h# 26 constant dcon-port
+: dcon-setup ( -- ) dcon-port to smb-port h# 1a to smb-slave ;
+: smb-init ( -- ) dcon-setup smb-on smb-pulses ;
+
+: dcon@ ( reg# -- word ) dcon-setup smb-word@ ;
+: dcon! ( word reg# -- ) dcon-setup smb-word! ;
Property changes on: dev/olpc/viacamera/smbus.fth
___________________________________________________________________
Added: svn:executable
+ *