Main CPU is (according to some strings in the firmware) ARM7TDMI, ARMv4T architecture. It resides in the large DIGIC chip beside the DSP. The DSP core is JP51 (DIGIC II is JP52). Amount of the RAM is 32M, the flash is 8M. Storage medium is CompactFlash.
CCD is probably the mysterious Sony ICX451 (no public data, some sources mention it, like http://forums.dpreview.com/forums/read.asp?forum=1010&message=13210740 or http://forum.ixbt.com/topic.cgi?id=20:17287-133#5902 ). It's one of those CCD models manufactured with the "new" plastic package, mostly dying after a few years. The CCD seems to support 218 lines vertical resolution for normal preview and twice as much (436 lines) in VGA (30fps) video mode. The former is proven by the liveview resolution in photo mode, the latter is a guess (some constants in video mode show that value).
The firmware has some strings that mention ARM7TDMI. Either this is fully valid, or just means that the code was compiled to run on a generic CPU.
According to the manual, ARM7TDMI lacks cache, TCMs are not mentioned there, neither is memory protection.
In the firmware, there is no sign of the usual cp15 register accesses, there is some access to the 0xdfffxxxx memory region instead. ARM7TDMI does not have cp15, so far, so good.
There are functions that deal with UNcached memory (AllocateUncacheableMemory), shared addresses usually appear with the 0x10000000 bit set. This implies that there is cache -> CPU not ARM7TDMI or cache is implemented by some other means. Update: the cache controller is a device which is accessed using the 0xdfff00xx MMIO addresses. The cache is unified, there's no separate data and instruction cache.
The boot process (at least the firmware upgrade path) uses the addresses 0x40000000 and 0x40000004. On some later CHDK-supported cameras this is the data TCM area. I suspect the same here. A function named AllocateHPMemory allocates from this range.
screen write: ~6600 kB/s memory write: ~17100kB/s (less than half of a DIGICII model)
0x00000000 ... 0x01ffffff: RAM 0x10000000 ... 0x11ffffff: RAM mapped for uncached access 0x40000000 ... 0x40000fff: "high performance" RAM 0xc0xxxxxx ... : memory mapped devices (more/less similarity with DIGIC II +) 0xdfff00xx ... : memory mapped registers of the cache (+...?) controller 0xff000000 ... 0xff7fffff: flash ROM 0xff000000 ... 0xff00ffff: bootloader 0xff010000 ... 0xff6fffff: primary firmware and data 0xff700000 ... 0xff7fffff: secondary firmware (rescue)
Has many known and many unknown memory ranges.
Works (more or less) like on DIGIC II+:
- 0xc0f140c4, saturation adjustment for the LCD http://chdk.setepontos.com/index.php?topic=7697.0 (works: saturation of the U and V components)
Most of the camera's LEDs and buttons are handled by the so called Sub-CPU. Direct access (like on later DIGIC) is not available.
There's an event procedure to control LEDs. Example:
ExecuteEventProcedure("SetLED",0,1) 'lights up LED 0 (whichever it is)
The following lists the physical events on the serial console:
... which looks like this:
PhysicalEvent LogicalEventName Table [PhysicalEvent] [LogicalEventName] [0x81000024] [UnpressRightButton] [0x81000003] [OpenBatteryCover] [0x82000085] [UnpressRemoteUpButton] [0x81000008] [UnpressSwOne] [0x81000109] [ModeDialToM] [0x81000011] [UnpressDriveButton] [0x81000101] [ModeDialToP] [0x81000103] [ModeDialToStitchAssist] [0x81000106] [ModeDialToFastShutter] [0x82000087] [UnpressRemoteRightButton] [0x81000094] [PressISButton] [0x810000a5] [PressSetButton] [0x81000107] [ModeDialToSlowShutter] [0x8100000f] [OpenPopupStrobe] [0x82000088] [UnpressRemoteLeftButton] [0x81000040] [UnpressSwTwo] [0x82000005] [PressRemoteUpButton] [0x82000084] [UnpressRemoteSetButton] [0x810000bb] [PressTeleButton] [0x8100003b] [UnpressTeleButton] [0x82000001] [PressRemoteMultiButton] [0x81000025] [UnpressSetButton] [0x81000021] [UnpressUpButton] [0x81000202] [LCDPosition00] [0x81000200] [LCDPosition01] [0x82000008] [PressRemoteLeftButton] [0x810000a3] [PressLeftButton] [0x81000023] [UnpressLeftButton] [0x81000201] [LCDPosition02] [0x81004301] [CloseLensCover] [0x82000004] [PressRemoteSetButton] [0x81000203] [LCDPosition03] [0x810000b5] [ConnectVideoCable] [0x81000102] [ModeDialToMovie] [0x82000002] [PressRemoteMagnifyButton] [0x810000a1] [PressUpButton] [0x8100001e] [UnpressShortcutButton] [0x8100010c] [ModeDialToLandscape] [0x82000082] [UnpressRemoteMagnifyButton] [0x82000083] [UnpressRemoteDispButton] [0x81004201] [DetectBatterySafetyLow] [0x81000801] [CompletePhysicalSwNotify] [0x81000087] [PressOffButton] [0x8100010d] [ModeDialToAv] [0x81000001] [DisconnectACCable] [0x81000004] [RemoveCFCard] [0x81000090] [PressFlashButton] [0x810000a8] [PressMovieButton] [0x8100009e] [PressShortcutButton] [0x81004202] [DetectBatterySystemLow] [0x81000089] [ConnectUSBCable] [0x81000005] [UnpressPBButton] [0x82000003] [PressRemoteDispButton] [0x810000a6] [PressMenuButton] [0x81000026] [UnpressMenuButton] [0x8100009d] [PressDispButton] [0x8100008b] [TimerSignalOn] [0x8100001d] [UnpressDispButton] [0x810000ba] [PressWideButton] [0x8100003a] [UnpressWideButton] [0x81000007] [UnpressOffButton] [0x82000007] [PressRemoteRightButton] [0x81000035] [DisconnectVideoCable] [0x81000085] [PressPBButton] [0x82000086] [UnpressRemoteDownButton] [0x81000086] [PressRecButton] [0x8100009b] [PressSpotButton] [0x81000108] [ModeDialToPortrait] [0x81000100] [ModeDialToAuto] [0x8100008f] [ClosePopupStrobe] [0x8100001b] [UnpressSpotButton] [0x81000009] [DisconnectUSBCable] [0x81000010] [UnpressFlashButton] [0x81000028] [UnpressMovieButton] [0x82000081] [UnpressRemoteMultiButton] [0x81000088] [PressSwOne] [0x8100000b] [TimerSignalOff] [0x8100008a] [AlarmSignalOn] [0x82000006] [PressRemoteDownButton] [0x810000a2] [PressDownButton] [0x81000022] [UnpressDownButton] [0x81000006] [UnpressRecButton] [0x81004200] [DetectBatteryWarning] [0x810000a4] [PressRightButton] [0x81000091] [PressDriveButton] [0x81000082] [CloseCFCover] [0x81000002] [OpenCFCover] [0x81000105] [ModeDialToTv] [0x81000081] [ConnectACCable] [0x81000803] [CompleteSwHistoryNotify] [0x810000c0] [PressSwTwo] [0x81000084] [InsertCFCard] [0x81000013] [UnpressMFButton] [0x81000083] [CloseBatteryCover] [0x810000a7] [PressFuncButton] [0x81000027] [UnpressFuncButton] [0x8100010b] [ModeDialToC] [0x81000802] [CompleteBootReasonSwNotify] [0x0a0d] [AlarmSignalOff] [0x81004381] [OpenLensCover] [0x81000014] [UnpressISButton] [0x81000104] [ModeDialToNightScene] [0x81000093] [PressMFButton]
Despite the camera having no PhySw task, there seems to be a chance to gain control over the buttons.
strips the event procedures generated by the left button. Following that, one could register some other eventproc to the physical event (even a self-made eventproc, I bet), like this:
Which makes the left button behave like the off button :)
There's no support for diskboot. The bootloader supports 3 methods: PRIMARY, SECONDARY, downloaded (RAM, source is
probably the serial debug connection the firmware upgrade program).
There is support for a version of Canon Basic. No special preparation is necessary for the card. The script must be placed into a file named extend.m in the root of the CF. The script can be started by pressing SET in play mode (must start in playback mode for this, SET has to be the first button pressed). The script's status (and the possible syntax error) can be seen in the serial debug output (which was a big help for me). Scripts with errors can cause various effects ranging from nothing visible to a complete lockup or immediate shutdown.
The implemented Canon Basic differs a little from the later revisions. For example the Initialize subroutine lacks the brackets. Event procedures "just work", haven't found one yet that required some prior initialization (but there are probably some that require that). Other camera functions are blocked while the script runs.
The firmware contains many debug strings.
Memory dumping script
' dump ROM to /CF0R0V0/ROM.BIN DIM startaddr=0xFF000000 private sub Initialize romsize = 0xFF7FFFFC - startaddr dumpfile = creat("/CF0R0V0/ROM.BIN",2) write(dumpfile,startaddr,romsize) close(dumpfile) end sub
The script also works for RAM (uncached access doesn't work, write() chokes on a NULL pointer).
The property case system is based on using strings for propcase names, the property cases often store values as strings (adds nice overhead, the code is full of strlen and strcmp calls around propcase operations). Examples: the propcase "MovieQuality" can be "Fine" or "Normal", "Flashdecision" can be 0 or 1. Even the recording modes are stored as strings.
Event procedures are often used in the code, these are also referenced by name
(preliminary information only, based on a play mode RAM dump, using the LCD, PAL mode)
Start at 0x1049a650, 8bit/pixel, buffer dimensions=360x240. Used resolution is ~ 320x220 with LCD, 352x240 with TV-out.
Just like in later cameras, there are two (adjacent) bitmap buffers.
viewports in playback mode:Edit
buffer dimensions: 720x576, Y411, used area 640x218 (LCD mode) or 704x576 (TV-out, PAL)Edit
0x1055cb88, shifts to 0x1055c750 when TV-out is used
0x105F4988 (right after the previous one), same dimensions, also shifted in TV-out mode...
buffer dimensions: 704x480, Y411, completely filled with a 704x480 pictureEdit
viewports in record mode:Edit
There's 3 of them, resolution is 640x218 (still image mode), 640x480 (640x480 movie mode) - using the LCD.
As simple as this (?):
This (ShootPicture) eventproc does actually get called on shooting (among others), the above line successfully replaced the original procedure with my modified one (which put a string to the serial console).
The functionality is provided by (at least) two tasks here (SEQ_TASK, CAPTURE_SEQ_TASK).