#################################### Reverse Engineering The Kodak CDL144 #################################### .. highlight:: none .. warning:: The contents of this page derive from tinkering, poking, tracing, and other low-assurance methods of engineering! Please do not depend on any of the contents seriously. .. note:: If you are in any way responsible for the construction of this device, write to me and I will buy you several beverages of your choosing; seriously, this thing is amazing. What little information exists about this device online can be found at http://www.kodak.com/TW/en/business/dsCd.shtml ; the CDL144 I have is the larger of the two products of the family, the other being the CDL54. Mine came configured with 4 SCSI CD-ROM drives and 6 magazines (for a capacity of 108 CDs). I have subsequently replaced the drives with bluray capable SATA devices and put an embedded computer in some free space in the device. I will get pictures up eventually. Software Library ################ Based on the effort described on this page, I have started writing software to actually make use of the robot through its debugging interface. See the `README `_ . Hardware Description #################### Central logic board =================== Major ICs on the Kodak logic board include: * Motorola MC68332ACFC16 CPU; datasheet http://www.nxp.com/files/microcontrollers/doc/data_sheet/MC68332TS.pdf * Symbios Logic 53CF92 SCSI bridge * AMD AM29F040 FLASH (512Kx8) * Toshiba TC551001BFL-70L memory (128Kx8 SRAM) * ST M48Z08-100PC1 nonvolatile memory (8Kx8) * max708 supervisory circuit * PBL 3770A motor controllers (x2 for one stepper) * lmd18245t motor controllers (x2 for one stepper) Headers: * Every header is uniquely sized, so there's no possibility of confusion, other than J2/J18. The stepper goes in J18. * J1 is power. I'll get a pinout later. * J2 is clearly a debugging header of some form, as the wires chase off to the 68Ks debugging pins. Does not appear to be JTAG. * J4 is a serial interface for debugging and commanding the robot. Pin 1 is +5V power, then RX then TX, then ground. Due to the JST connector, it may be tempting to grab ground from nearby on J5. Don't do that; it yields a lot of bitflips for reasons unknown. * J5 is unknown, but it looks like board-edge-side is all ground pins and board-internal-side is logic lines pulled high. Some kind of configuration jumpers? * J10 interfaces to the supervisory circuit, possibly to be a reset button? * J11 connects to the mailbox circuitry * J16 connects to the top sensor board * J20 connects to terminator power on the SCSI bus. It appears that the device is held in some kind of very early RESET state (it doesn't even get as far as printing out the welcome message on the serial port) if there isn't external teriminator power... Jumping J20 solves that problem, but still requires that there be a terminator on the SCSI line. Picker ====== The picker itself contains a few sensors (the barcode scanner, a photo slot interruptor to measure tray arm position, and another photo slot interruptor to detect CD presence), but is mostly gears. Bottom Sensor Board =================== Contains three presumably-IR LEDs and attaches to a membrane contact sensor used to detect picker zero position. Top Sensor Board ================ Contains three OPL821 IR sensors from Optek (http://optekinc.com/datasheets/OPL820.PDF) and a Sharp GP1A70R photointerruptor sensor (http://media.digikey.com/pdf/Data%20Sheets/Sharp%20PDFs/GP1A70R_71R.pdf). The former stare into beam channels from the bottom sensor board and form the receiving end of the Drawer, Tray, and CD sensors. The latter is used as part of a disk encoder for the picker position. Serial Interface ################ Connecting at ``9600 8n1`` to J4 and powering up the machine yields:: (C)1996 KODAK AG Technik, Muehlhausen/Germany Lynx PM Firmware Version: 1.41 (Jul 18 1997) Lynx PM Download Version 1.01 (Jul 21 1997) KAGOS68K Version: V1.01 (May 20 1997) FLASH Checksum is OK: 01097577 Lynx Model: 144P Selftest of SCSI Controller successfully passed Status #0: IDLE: no errors. CDL> Asking for help yields:: Command (Abbr.) | Description ================|============= AddOffset (A) | add a offset to a location. Barcode (B) | read barcode of a magazine. CWHEEL (C) | read codewheel count. CLS | clear screen. DL | download a Lynx firmware. Drive (D) | open/close drive drawer. EX | display # of exceptions. GetCount | get the current SW actuation counter value. GetLogs | get the event logs or error logs. Help (H) | this menu. Init | initialize the robotics. Inv | initiate an inventory of magazines. LED | turn on/off/flash red and greed LED. Lift (L) | position the picker at an element. Loc | get/set the position of the elements. Mailbox (MB) | open/close mailbox. Move (M) | transportation of CD. MoveMag (MM) | transportation of all CDs of a magazine. ParBar | get/set barcode system parameters. ParLift | get/set lift system parameters. ParMB | get/set mailbox system parameters. ParTray | get/set tray system parameters. Pattern (PAT) | get/set the pattern of the stepper motors. Pick (P) | pick a CD out of tray. PickRel (PR) | pick and release a CD. Queue (Q) | display msg queue status. Ramp | modify the lift and tray motor ramp. Release (R) | release a CD into tray. Reset | reset the system. SCSI | view/change robotics SCSI-parameters Sensor (S) | get status of the sensors. Setbaud | change the RS232 interface baudrate. Status (ST) | get status of the robotics. Task | get the ready task queue. Tray (T) | open/close tray. Ver | display current version and Lynx model. Unfortunately, many commands seem to take parameters and there doesn't seem to be a way to find out what they are in all cases. * ``status`` is informative:: Tray Status: No errors. Inventory: Picker: CD=o Home=ffff Mailbox: CD=o Drives: D1=o D2=o D3=o D4=o Drivehome: D1=ffff D2=ffff D3=ffff D4=ffff Magazine 2: absent! Magazine 3: absent! Magazine 4: absent! Magazine 5: Barcode: 1, Slot 1-18= xxxxx xxxoo ooooo ooo Magazine 6: Barcode: 2, Slot 1-18= ooooo ooooo ooooo ooo Magazine 7: Barcode: 3, Slot 1-18= ooooo ooooo ooooo ooo Magazine 8: Barcode: 4, Slot 1-18= ooooo ooooo ooooo ooo Magazine 9: Barcode: 5, Slot 1-18= ooooo ooooo ooooo ooo Magazine 10: Barcode: 6, Slot 1-18= ooooo ooooo ooooo ooo ``Picker`` ``Home`` is the origin of the CD currently in the picker, and ``Drivehome`` ``Dn`` is the origin of the CD currently in drive ``n``. See `Hexadecimal Lift Positions`_ and `Drive Status Codes`_ below. * As is ``sensor``:: ClearPath: Drawer= o Tray= o CD=o Home: Lift= o Crank= o Mailbox: In = yes Out= no Button=clear Others: Door= closed CDPicked=no Barcode=0 Magazine Present [10..2]=111111000 * And ``SCSI``:: SCSI configuration settings: SCSI: ID=5, Parity=enabled, Slow Cable Mode=disabled Selftest successfully passed * The various parameter commands reveal a wealth of configuration material that is probably best left unchanged:: CDL>partray Tray system parameters: RS=-20.829°, RP=4.886°, RT=29.829°, PS=327.857°, PP=299.829°, PT=289.800° Gear=3.500, Rot=400steps, PCD=219.857°, RCD=99.771°, ICD0=79.971°, ICD1=229.886° PI=139.886°, RI=179.743°, PO=59.914°, RO=249.943° CDL>parmb Mailbox system parameters: PWM=20000Hz, Timeout=5s AccOpenCycle=85%, DecOpenCycle=20%, DecOpenTime=50ms, OpenedCycle=20% AccCloseCycle1=85%, DecCloseCycle=20%, DecCloseTime=20ms AccCloseCycle2=60%, AccCloseTime2=200ms, AccCloseCycle3=90%, AccCloseTime3=100ms ClosedCycle=20% CDL>parlift Lift system parameters: Min=-9.975mm, Max=600.000mm, Def=188.925mm Lead=30.000mm, Rot=400steps, Codewheel=50slots, CodewheelError=3slots CDL>parbar Barcode system parameters: MagOffset=-1.500mm, DrvOffset=-1.500mm, Length=42.000mm CDL>pat tray Tray Motor Pattern: D4 F2 D6 CF D7 F1 D5 CC Low Current Pattern: 111010xx CDL>pat lift Lift Motor Pattern: F0 E9 CD EB F3 EA CE E8 Low Current Pattern: 000101xx * As does ``loc`` :: Mailbox: 538.890mm Drivebases: 1=-19.110mm 2=33.890mm 3=86.890mm 4=139.890mm Driveoffset: 1=28.000mm 2=28.000mm 3=28.000mm 4=28.000mm Magazines: 2=29.890mm 3=82.890mm 4=135.890mm 5=188.890mm 6=241.890mm 7=294.890mm 8=347.890mm 9=400.890mm 10=453.890mm Slotoffset: 2.470mm * ``task`` seems to show information relevant to developers about the embedded (RT)OS:: ReadyTaskQueue: Position: Task Name(#): 0 idle(#2) 1 root(#1) TimeoutWaitQueue: Position: Task Name(#): 0 robo(#9) 1 conf(#11) 2 mail(#5) 3 led (#4) date = 01/01/0000, time = 00:10:56, tick = 29 * As does ``queue``:: Message Queue#0 'scro': 0 pending messages / 1 pending tasks Position: Task Name(#): 0 robo(#9) Message Queue#1 'rosc': 0 pending messages / 0 pending tasks Message Queue#2 'mail': 0 pending messages / 1 pending tasks Position: Task Name(#): 0 mail(#5) Message Queue#3 'mbsc': 0 pending messages / 0 pending tasks Message Queue#4 'mbro': 0 pending messages / 0 pending tasks Message Queue#5 'led ': 0 pending messages / 1 pending tasks Position: Task Name(#): 0 led (#4) Message Queue#6 'debg': 0 pending messages / 0 pending tasks Message Queue#7 'sccm': 0 pending messages / 1 pending tasks Position: Task Name(#): 0 scmd(#7) Message Queue#8 'cdbs': 0 pending messages / 1 pending tasks Position: Task Name(#): 0 dbas(#10) Message Queue#9 'dbsr': 0 pending messages / 0 pending tasks Message Queue#10 'dbss': 0 pending messages / 0 pending tasks Message Queue#11 'dbmb': 0 pending messages / 0 pending tasks Message Queue#12 'nvrr': 0 pending messages / 0 pending tasks Message Queue#13 'nvrd': 0 pending messages / 0 pending tasks Message Queue#14 'nvdb': 0 pending messages / 0 pending tasks Message Queue#15 'nvrs': 0 pending messages / 0 pending tasks Message Queue#16 'cnvr': 0 pending messages / 1 pending tasks Position: Task Name(#): 0 conf(#11) * ``mb o`` ("mailbox open") and ``mb c`` ("mailbox close") do what you'd expect. The robot will reinventory the mailbox after ``mb c``. ``mb s`` or just ``mb`` by itself will reveal the mailbox status. * ``init`` triggers some part of the startup sequence. Like ``b`` it cannot read barcodes, despite them being read correctly at startup? * ``inv`` takes inventory. ``all`` causes the machine to take inventory of everything and print the status information. ``m5`` inventories magazine 5. * ``tray`` shows the number of steps and degrees of the tray control arm. If given a floating point number, it will move the tray arm to that position. Since the pick arm is linked to the tray control arm, "t 4.886" (that is, RP= from above) and ``t 299.829`` (that is, PP= from above) will put down and pick up a CD, respectively. I suggest not steering the robot this way, though it is *excellent* when it comes to aligning a new CD drive. * ``led`` takes two parameters, a LED indicator (``{a,r,y,all}``) and a state (``{on,of,bl}``) (or ``{on,off,blink}``, even). ``a`` means both LEDs, ``r`` means the red LED, and ``y`` means the "busy" LED in the middle. None of the other single letters or digits seem to do anything; it is unclear to me what the third LED is wired to, if anything. The manual describes the third LED as meaning "power", however it is off on my device. * ``move`` takes two lift positions. WARNING: Opening the wrong drive will cause the system to drop the CD or crash into the tray, neither of which are what you want, I'm sure. Don't mess up. If you think you might mess up, do it with the chassis open and be ready to pull power immediately. * ``b m5`` is supposed to read a magazine barcode, but mostly I have seen it return ``ERROR``. Despite that, barcodes are read correctly at initialization time. (Sometimes it works and I cannot figure out why) * ``Pick``, ``Release`` and ``PickRel`` confuse me -- they take a lift position but don't appear to do anything with it, acting instead in situ and corrupting the status database. * ``Drive`` takes one parameter, being a number between 1 and 4... but I don't know what it does. I do not understand how it could do what it claims to do. Using "D", I think, I've managed to make "status" say "D1=e", but I don't know how. * ``Lift`` can be used to manually set the picker's elevation: * ``l 0`` will move the picker as low as it can go (but curiously will not change the ``Home`` ``sensor`` output) and other numeric arguments work as you might expect. * ``l d3``, ``l m5s3``, ``l mb`` all work as expected. Occasionally, the unit will complain about a ``ERROR #82: Clear Path error.`` and refuse to move the robotics. I assume this means that it thinks something has gotten in the way. A reset, with a full inventory, should suffice to clear the error; I wish there were a less obtrusive way. Hexadecimal Lift Positions ========================== Most of the time, the robot refers to things in a kind of logically named scheme: drives are ``dN``, magazines are ``mN``, slots within magazines are ``mNsN`` and the mailbox is ``mb``. The robot does, however, have some curious ideas about names for things in different contexts; the ``Drivehome`` status field, the ``Picker Home`` status field, and the ``Lift`` command refer to "lift element positions" (which are denoted in *hex*) and appear to behave as follows: * ``mb`` is element ``100`` * ``d1`` through ``d4`` are ``200`` through ``203`` in order * ``m2s1`` starts us off at ``1000`` and we count up from there; ``m5s1`` is ``1036``, ``m5s5`` is ``103a``, ``m5s18`` is ``1047``, ``m6s1`` is ``1048``, ``m6s18`` is ``1059``, ``m7s1`` is ``105a``, etc. * Everything else (intermediate positions or no home) are indicated by ``ffff`` (``-1``). In tabular form: +------------------------+-------------------+--------------------------+ | Human mnemonic | Numeric (hex) | What | +------------------------+-------------------+--------------------------+ | ``d1`` -- ``d4`` | ``200`` - ``203`` | Drives | +------------------------+-------------------+--------------------------+ | ``m2``, ``m3``, ... | n/a | Magazines | +------------------------+-------------------+--------------------------+ | ``m2s1``, ``m6s7``, ...| ``1000`` and up | Slots within magazines | +------------------------+-------------------+--------------------------+ | ``mb`` | ``100`` | Mailbox | +------------------------+-------------------+--------------------------+ Tray Positions ============== For use with "t" commands; integer approximations are accepted at the command line. +---------+-----------------------------------------------+---------------+ | Angle | State | ``partray`` | +---------+-----------------------------------------------+---------------+ | 4.886 | Tray fully closed | ``RP`` | +---------+-----------------------------------------------+---------------+ | 120.086 | Tray extended, picker on initial descent | | +---------+-----------------------------------------------+---------------+ | 139.886 | Tray extended, picker almost fully inserted | ``PI`` | +---------+-----------------------------------------------+---------------+ | 149.914 | Tray extended, picker near center range | | +---------+-----------------------------------------------+---------------+ | 180.000 | Tray extended, picker retracting with CD | near ``RI`` | +---------+-----------------------------------------------+---------------+ | 190.029 | Tray extended, picker almost fully retracted | | +---------+-----------------------------------------------+---------------+ | 327.857 | Tray fully retracted, picker has CD | ``PS`` | +---------+-----------------------------------------------+---------------+ Drive Status Codes ================== The "status" command will give single letters for drive status: "D1=?" where "?" is apparently one of... +-------+------------+ | ``b`` | blocked? | +-------+------------+ | ``e`` | error? | +-------+------------+ | ``o`` | empty | +-------+------------+ | ``u`` | unknown? | +-------+------------+ | ``x`` | full | +-------+------------+ The ``o`` and ``x`` have similar meanings for magazine information. Magazines can also display ``b`` if you permit the machine to inventory and forget to close the door lever. (Grinds a lot of gears, try to avoid it.)