'' ================================================================================================= '' '' File....... lanc_commander_16_byte_Canon_local.spin '' Purpose.... '' Author..... Jon "JonnyMac" McPhalen '' Copyright (c) 2014 John Huffman '' -- see below for terms of use '' E-mail..... jon@jonmcphalen.com '' Started.... '' Updated.... 01 MAY 2019 '' '' ================================================================================================= ' 2019-04-25 Derived from original code by Jon McPhalen 2014 ' 2019-04-25 Modified for Canon Extended LANC protocol for Canon XF705 camera and RC-V100 controller. ' 2019-04-12 Modified for Remote Board testing (SIO = P22) ' 2019-04-23 Modified for Local Board testing (SIO = P24) ' 2019-05-01 Added any 16 byte command codes currently available for the Canon XF705 con { timing } _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' use 5MHz crystal CLK_FREQ = (_clkmode >> 6) * _xinfreq ' system freq as a constant MS_001 = CLK_FREQ / 1_000 ' ticks in 1ms US_001 = CLK_FREQ / 1_000_000 ' ticks in 1us con { io pins } RX1 = 31 ' programming / terminal TX1 = 30 SDA = 29 ' eeprom / i2c SCL = 28 SIO = 22 ' lanc serial io obj ' main ' * master Spin cog time : "jm_time" ' timing and delays prng : "jm_prng" ' pseudo-random number generator io : "jm_io_basic" ' essential io term : "jm_fullduplexserial" ' * serial IO for terminal lanc : "jm_lanc16_test" ' * LANC tranciever ' * uses cog when loaded var long tc byte buffer[16] byte mode byte recording byte guide long f1, f2 dat Screen byte "Canon XF705 Extended LANC Monitor/Controller", 13 '0 byte 13 '1 byte "String from/to Camera", 13 '2 byte 13 '3 byte "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --", 13 '4 byte 13 '5 byte "Online..... No ", 13 '6 byte "Mode....... ", 13 '7 byte "Timecode... ", 13 '8 byte 13 '9 byte "Keyboard Commands:", 13 '10 byte " [P] Power ", 13 '11 byte " [R] Record - [V] Review Rec " , 13 '12 byte "*[T] Tele Zoom -*[W] Wide Zoom " , 13 '13 byte "*[N] Near Focus -*[F] Far Focus " , 13 '14 byte "*[O] Iris Open -*[C] Iris Close " , 13 '15 byte " [M] Menu - [.] Select " , 13 '16 byte " num pad arrow keys for navigation" , 13 '17 byte " [B] White Bal [X] White Bal Sel", 13 '18 byte " [Z] Shutter *[D] Neutral Dens" , 13 '19 byte "*[Q] Color Bars [ ] " , 13 '20 byte "* = command available " , 13 '21 byte 0 sign byte "+" pub main setup f1 := lanc.frame ' get frame counter repeat show_lanc_status lanc_command pub show_lanc_status | idx f2 := lanc.frame ' get frame counter if (f2 == 0) no_lanc elseif (f2 <> f1) ' new frame? bytemove(@buffer, lanc.address, 16) ' capture to local buffer move_to(0, 4) ' display frame repeat idx from 0 to 15 term.hex(buffer[idx], 2) term.tx(" ") mode := buffer[4] & %0000_0010 ' get camcorder mode has_lanc ' show status f1 := f2 ' save for next check pub no_lanc move_to(0, 2) term.str(string("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --")) move_to(12, 6) term.str(string("No ")) move_to(12, 7) term.tx(term#CLREOL) move_to(12, 8) term.tx(term#CLREOL) pub has_lanc | idx move_to(12, 6) term.str(string("Yes")) ' show connected move_to(12, 7) ' display camcorder mode if (mode) term.str(string("VTR")) else term.str(string("CAM")) move_to(16, 7) ' display device status if (mode) case buffer[4] $02: term.str(string("STOP", term#CLREOL)) $03: term.str(string("FWD", term#CLREOL)) $06: term.str(string("PLAY", term#CLREOL)) $07: term.str(string("PAUSE", term#CLREOL)) $46: term.str(string("PLAY >>", term#CLREOL)) $56: term.str(string("PLAY <<", term#CLREOL)) $83: term.str(string("RWD", term#CLREOL)) other: term.tx(term#CLREOL) else case buffer[4] $04: term.str(string("RECORD", term#CLREOL)) $14: term.str(string("PAUSE", term#CLREOL)) other: term.tx(term#CLREOL) guide := buffer[5] & $F0 ' guide for bytes 6/7 if (guide == $30) tc.byte[2] := buffer[7] ' minutes tc.byte[1] := buffer[6] ' seconds if (guide == $40) tc.byte[3] := buffer[6] ' hours tc.byte[0] := buffer[7] & $3F ' frames if (buffer[7] & $80) sign := "-" else sign := "+" move_to(12, 8) ' display timecode if (tc.byte[3] <> $FF) term.tx(sign) repeat idx from 3 to 0 term.hex(tc.byte[idx], 2) if (idx > 0) term.tx(":") else term.tx(term#CLREOL) pub lanc_command | c ' lanc.command($03, $00, $00, $00, $00, $00, $00, $00) ' let the camera know a controller is connected c := ucase(term.rxcheck) ' check keyboard if (c => 0) ' if key... case c "P": { power } if (lanc.available) ' lanc signal present? lanc.command($00, $00,$00, $00, $00, $00, $00, $00) ' power down else lanc.wake_up ' attempt wake-up term.rxflush "R": { toggle record } lanc.command($00, $00,$00, $00, $00, $00, $00, $00) term.rxflush "V": { review - recording } lanc.command($00, $00,$00, $00, $00, $00, $00, $00) "N": { focus near } lanc.command($05, $D8, $00, $00, $27, $03, $FF, $FF) "F": { focus far } lanc.command($05, $D5, $00, $00, $27, $03, $00, $01) "T": { zoom tele - fast } lanc.command($05, $DE, $00, $00, $22, $80, $00, $80) "W": { zoom wide - fast } lanc.command($05, $DF, $00, $00, $22, $80, $FF, $80) "O": { iris open } lanc.command($05, $47, $00, $00, $25, $93, $00, $01) "C": { iris close } lanc.command($05, $4A, $00, $00, $25, $93, $FF, $FF) "M": { menu } lanc.command($00, $00,$00, $00, $00, $00, $00, $00) ".": { select - execute } lanc.command($00, $00,$00, $00, $00, $00, $00, $00) "8": { Menu - up } lanc.command($00, $00,$00, $00, $00, $00, $00, $00) "2": { Menu - down } lanc.command($00, $00,$00, $00, $00, $00, $00, $00) "4": { Menu - left } lanc.command($00, $00,$00, $00, $00, $00, $00, $00) "6": { Menu - right } lanc.command($00, $00,$00, $00, $00, $00, $00, $00) "B": { white balance } lanc.command($00, $00,$00, $00, $00, $00, $00, $00) "X": { white balance select } lanc.command($00, $00,$00, $00, $00, $00, $00, $00) "Z": { shutter } lanc.command($00, $00,$00, $00, $00, $00, $00, $00) "D": { toggle neutral density } lanc.command($05, $3A, $00, $00, $25, $A1, $00, $00) term.rxflush "Q": { toggle color bars } lanc.command($05, $BF, $00, $00, $24, $1D, $00, $00) pub move_to(x, y) '' Move cursor for PST term.tx(term#GOTOXY) term.tx(x) term.tx(y) pub ucase(c) '' Converts lowercase alpha to uppercase if ((c => "a") and (c =< "z")) c -= 32 return c pub setup '' Setup IO and objects for application time.start ' setup timing & delays io.start(0, 0) ' clear all pins (master cog) term.start(RX1, TX1, %0000, 115_200) ' start serial for terminal * lanc.start(SIO) ' start lanc io * term.tx(term#CLS) move_to(0, 0) term.str(@Screen) dat {{ Copyright (C) 2014 Jon McPhalen Terms of Use: MIT License 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 NON-INFRINGEMENT. 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. }}