SanDisk Sansa Connect
History/Background
The Sansa Connect is designed by
Zing System Inc. (part of Dell), who showed off a WIFI device for listening to streaming radio stations, without any onboard storage. A prototype device was announced, but never put into production. Screenshots of the time show a similar UI design to the current Sansa Connect.
The Sansa Connect has 4Gb of onboard flash storage, as well as a Micro-SD slot, capable of using SDHC cards in the newer firmware versions.
Rockbox Status
There is a Sansa Connect Rockbox port in progress. Bootloader can boot both OF (by holding PREV button) and Rockbox. There is no software-only installation method available. To get unsigned code loading it is required to do
hardware modification.
Current Rockbox bootloader is supposed to work as replacement for vmlinux. After building bootloader, prepend resulting bootloader.bin file with .srr header
AA BB FF EE 00 00 00 01 10 00 12 00 FI LE SI ZE
where FILESIZE is bootloader.bin file size + 2048 (signature) coded in LE. Then from OF shell overwrite /dev/mtd2 with created file (don't use Recovery Mode as we don't have method yet to remove recoverzap bootloader variable which would result in recovery screen again on next boot).
Booting is quite slow due to bootloader checking signatures (the hardware modification only makes the file to be always accepted, the SHA-1 sum is still computed).
There is possibility to overwrite OF bootloader - if you are risky enough, edit firmware/target/arm/tms320dm320/boot.lds and change FLASH_OFFSET to 0, rebuild bootloader and then using hardware modification method flash the new bootloader (
don't append srr header).
WARNING: this has not been tested by anyone, we may still be missing some critical initialization (which would mean hard to recover brick).
Device |
Status |
Comments |
LCD driver |
90% |
Could make better use of OSD/Video windows |
Backlight |
100% |
|
Storage (SD) driver |
90% |
Not tested for internal storage (OF uses ext2) |
Button driver |
90% |
|
USB handler |
1% |
Clock handling is implemented. Linux sourcecode released by ZING seems to contain driver for TNETV105 |
RTC driver |
0% |
RTC doesn't seem to be accessible by I2C. HID_MONOTIME reads difference time, the base time retrieval is unknown (base+difference = Unix time) |
Power handling |
10% |
Battery meter uses fake linear scale (1 mV = 1%). Charging doesn't seem to work properly. |
Audio DAC driver |
80% |
|
WiFi driver |
0% |
|
(Software) I2C driver |
90% |
|
Additional work to be done:
- SD driver can use interrupts
- WiFi driver needs to be written (network subsystem needs to be added to Rockbox)
- Battery handling has to be added
- Use internal speaker
Hardware
AnythingButiPod performed a basic disassembly.
Further to this: the EMI shield is a frame and clip-on top shield - only the frame is soldered to the main PCB. The frame visually obscures some of the chips.
- DSP/CPU: TexasInstrumentsTMS320. This is a multicore device consisting of a ARM926EJ-S CPU core and TMS320vc5409 DSP.
- Secondary CPU: ATMEL MEGA165PV. The Atmel AVR line has great support of open source developement tools (GCC et all). It's referred internally as "HID", and it's used as an interface to external devices - handles display sleep & wakeup, for example. Interfaced via SPI.
- Power Management: TI TPS 65021. Interfaced via I2C.
- LCD: 2.2 inch - CT022TND4 V.6 M1-B
- SDRAM: Samsung K4M51323LC-DN75
- USB 2.0: TNETV105. Not to be confused with TI's TNETV105 (DSP/CPU bundle), this handles USB for the device. The TMS320 has an internal USB controller but it is disabled on boot. Interfaced via VLYNQ.
- Codec: Ti AC3106I. DAC and stereo power amplifier, with programmable filters. Most likely interfaced via I2C.
- EEPROM: Atmel AT88SC - 64kbit fused, cryptographically secure. Holds individual device information such as USB deviceid, MAC address and device certificate. Interfaced via I2C.
- Flash: Sandisk SDINB1-4096. 4GB iNAND flash module. Holds filesystem.
Visually obscured chips:
- Flash: Samsung K8D3216UBC (located just under DSP/CPU) - NOR Flash 32MBIT. Holds bootloader, linux kernel, persistent variables, platform.
- WIFI: Murata (chip has the MAC address engraved on it - vendor digits are 00:13:E0) - possible model numbers start KK6T6... or LBWA-.... Interfaced via SPI. Actually, after desoldering the chip, it turned out to be tiny PCB - the chipset is labelled MARVELL W8686B12 717AEUP: http://www.arm9board.net/download/FL6410/datasheet/mavell_88w8686.pdf
- RTC: ST M41T62 - interfacing method unknown
- TPS61042 Led driver (package marking BHS)
Clock speeds
These are obtained from the initialization code on the linux kernel patch for the Connect:
- TMS320 ARM core: 120 MHz
- SDRAM: 72 MHz
- TMS320 DSP core: 72 MHz
- DMA coprocessor: 144 MHz
TMS320 general purpose I/O pins mapping
This is the detail for the known GPIO pins in the Connect:
Pin |
Device |
Name |
Comments |
Direction |
GIO0 |
TMS320 |
STANDBY |
Buttons state changed IRQ |
In |
GIO2 |
Headphones |
PRESENT |
Headphones inserted |
In |
GIO5 |
iNAND |
SELECT |
Selects iNAND when low |
Out |
GIO6 |
SD Card |
SELECT |
Selects SD slot when low |
Out |
GIO7 |
USB |
RESET |
TNETV105PAP reset (active low) |
Out |
GIO8 |
I2C |
INTR |
Data available on dock I2C to UART connector (rising edge) |
In |
GIO9 |
USB |
DETECT |
low when USB cable connected |
In |
GIO11 |
I2C |
DTCT |
Available at dock connector, low if I2C to UART is not connected |
In |
GIO12 |
I2C |
SCL |
Available at dock connector (pin 22) |
In/Out |
GIO13 |
I2C |
SDA |
Available at dock connector (pin 21) |
In/Out |
GIO14 |
SD Card |
CARD_DETECT |
Low when card inserted |
In |
GIO16 |
AIC3X |
MCLK |
Audio interface master clock |
Out |
GIO29 |
SIF1 |
ENABLE |
AVR's SS (active low) |
Out |
GIO30 |
SIF1 |
Clock |
|
Out |
GIO31 |
SIF1 |
Data In |
|
In |
GIO32 |
SIF1 |
Data Out |
|
Out |
GIO33 |
USB |
CLK |
USB clock (source from M48XI) |
Out |
GIO34 |
Backlight |
PWM |
Backlight PWM (active high) |
Out |
GIO35 |
I2C |
SDA |
I2C data line |
In/Out |
GIO36 |
I2C |
SCL |
I2C clock |
In/Out |
GIO37 |
SD Card |
CARD_POWER |
Powers SD slot when low |
Out |
GIO38 |
iNAND |
iNAND_POWER |
Powers iNAND when low |
Out |
GIO39 |
LCD |
VENC |
FIELD_VENC |
Out |
Contents of the /proc/gio:
GIO# |
User ID |
Function |
Dir |
Invert |
Level |
IRQ |
IRQ Edge |
Debounce |
0 |
|
GIO |
in |
normal |
asserted |
21 |
falling |
normal |
1 |
spi0-wifi-irq |
GIO |
in |
normal |
asserted |
22 |
falling |
normal |
2 |
|
GIO |
in |
inverted |
deasserted |
23 |
any |
normal |
3 |
wifi-reset |
GIO |
out |
normal |
asserted |
GIO |
-- |
normal |
4 |
spi0-wifi-cs |
GIO |
out |
normal |
asserted |
GIO |
-- |
normal |
5 |
|
GIO |
out |
normal |
asserted |
GIO |
-- |
normal |
6 |
|
GIO |
out |
normal |
asserted |
GIO |
-- |
normal |
7 |
TNETV USB nreset |
GIO |
out |
normal |
asserted |
GIO |
-- |
normal |
8 |
|
GIO |
in |
normal |
deasserted |
GIO |
-- |
normal |
9 |
|
GIO |
in |
normal |
deasserted |
30 |
any |
normal |
10 |
|
GIO |
in |
normal |
deasserted |
GIO |
-- |
normal |
11 |
|
GIO |
in |
normal |
asserted |
32 |
any |
normal |
12 |
GIO I2C SCL |
GIO |
in |
normal |
asserted |
GIO |
-- |
normal |
13 |
GIO I2C SDA |
GIO |
in |
normal |
asserted |
GIO |
-- |
normal |
14 |
|
GIO |
in |
normal |
asserted |
35 |
any |
normal |
15 |
|
GIO |
in |
normal |
asserted |
GIO |
-- |
normal |
16 |
|
CLKOUT0 |
|
|
|
|
|
|
17 |
|
VLYNQ RXD0 |
|
|
|
|
|
|
18 |
|
VLYNQ RXD1 |
|
|
|
|
|
|
19 |
|
VLYNQ RXD2 |
|
|
|
|
|
|
20 |
|
VLYNQ RXD3 |
|
|
|
|
|
|
21 |
|
VLYNQ_TXD0 |
|
|
|
|
|
|
22 |
|
VLYNQ TXD1 |
|
|
|
|
|
|
23 |
|
VLYNQ TXD2 |
|
|
|
|
|
|
24 |
|
VLYNQ TXD3 |
|
|
|
|
|
|
25 |
|
VLYNQ SCRU |
|
|
|
|
|
|
26 |
|
VLYNQ CLK |
|
|
|
|
|
|
27 |
|
GIO |
in |
normal |
asserted |
GIO |
-- |
normal |
28 |
|
GIO |
out |
normal |
deasserted |
GIO |
-- |
normal |
29 |
SPI-nSS |
GIO |
out |
normal |
asserted |
GIO |
-- |
normal |
30 |
|
SPI SCLK1 |
|
|
|
|
|
|
31 |
|
SPI SDI1 |
|
|
|
|
|
|
32 |
|
SPI SDO1 |
|
|
|
|
|
|
33 |
|
CLKOUT1B |
|
|
|
|
|
|
34 |
|
PWM1 |
|
|
|
|
|
|
35 |
GIO I2C SDA |
GIO |
in |
normal |
asserted |
GIO |
-- |
normal |
36 |
GIO I2C SCL |
GIO |
in |
normal |
asserted |
GIO |
-- |
normal |
37 |
|
GIO |
out |
normal |
asserted |
GIO |
-- |
normal |
38 |
|
GIO |
out |
normal |
deasserted |
GIO |
-- |
normal |
39 |
|
FIELD VENC |
|
|
|
|
|
|
40 |
|
GIO |
out |
normal |
deasserted |
GIO |
-- |
normal |
Addresses available on I2c bus:
- 0x18 - Codec AIC3X
- 0x48 - Power Management TPS65021
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f - UNKNOWN
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f - UNKNOWN
TMS320 memory maps
Physical memory:
Region name |
Description |
Start |
End |
Size |
Comments |
DM320_RESET_VECTOR_PADDR |
CPU reset vector |
0x00000000 |
0x00000003 |
4 bytes |
Should point to bootloader |
DM320_IRAM_PADDR |
CPU internal RAM |
0x00000004 |
0x00003FFF |
Approx. 16Kb |
|
DM320_PERIPHERALS_PADDR |
ARM peripherials registers |
0x00030000 |
0x0003FFFF |
4Kb |
|
DM320_DSP_ONCHIP_RAM_PADDR |
DSP internal RAM |
0x00040000 |
0x0005FFFF |
128Kb |
|
DM320_AHB_PADDR |
TMS320 internal AHB bus |
0x00060000 |
0x00063FFF |
4Kb |
|
DM320_COPRO_SUB_PADDR |
DMA coprocessor interface |
0x00080000 |
0x0009FFFF |
128Kb |
|
DM320_EXT_MEM_PADDR |
External memory |
0x00100000 |
0x010FFFFF |
16Mb |
Maps to Flash exclusively (cached) Bootloader and kernel are stored here |
DM320_CFI_PADDR |
CFI Flash interface |
0x40000000 |
0x40FFFFFF |
16Mb |
|
DM320_SSFDC_PADDR |
SmartMedia interface |
0x48000000 |
0x48FFFFFF |
16Mb |
|
DM320_CE1_PADDR |
Control enable 1 (???) |
0x50000000 |
0x50FFFFFF |
16Mb |
Related to Comm. port 1 (external interface) |
DM320_CE2_PADDR |
Control enable 1 (???) |
0x60000000 |
0x60FFFFFF |
16Mb |
Related to Comm. port 2 (external interface) |
DM320_VLYNQ_PADDR |
VLYNQ interface |
0x70000000 |
0x73FFFFFF |
64MB |
More details in http://en.wikipedia.org/wiki/VLYNQ |
DM320_USBOTG_PADDR |
USB On-The-Go inteface |
0x80000000 |
0x800003FF |
1Kb |
More details in http://en.wikipedia.org/wiki/USB_On-The-Go |
Virtual memory:
(..more to come..)
Flash:
Flash starts at 0x100000. Start and End values in table are absolute addresses.
Region name |
Description |
zsi_fw address |
Start |
End |
Size |
Comments |
BOOT |
rrload bootloader |
N/A |
0x00010000 |
0x00012000 |
64 Kb |
Hardware write-protected |
ENVIRO |
Persistent variables |
N/A |
0x01000000 |
0x01007FFF |
32 Kb |
Bootloader variables (recoverzap, usbautoboot, etc.) |
KERNEL |
vmlinux kernel image |
0x01008000 |
0x00120000 |
0x0031FFFF |
2 Mb |
Stock kernel image is about 1,6 Mb big |
INITRD |
initrd compressed ROM image |
0x04400020 |
0x00320000 |
0x004FFFFF |
1.875 Mb |
At least 1,6 Mb big |
Power managment
After loading the Linux kernel, the TPS 65021 is programmed via
I2C (/usr/share/lua/5.1/pwrfix.lua) - devices'
I2C address is 0x48.
- Device is set to PWM mode (register 0x04 = 10110010b).
- Core voltage set to 1.5V (register 0x06 = 00011100b).
- Codec and USB power line (LD02) to 1.8V, LCD display module (LD01) to 2.85V (register 0x08 = 00110110b).
HID (ATMEL MEGA165PV microcontroller)
The HID handles external devices - it is interfaced to the CPU via its built SPI interfase, clocked at 200 KHz.
This device is initialized on boot - the firmware loaded on it is located on /lib/clicky165.bin. The Fuse high byte register is set to 0xd1 (OCD and JTAG enabled, watchdog always on, uses reset vector), while the fuse low byte is set to 0xC2 (divide clock by 8, enable clock output, use clock source 1).
Once programmed, it accepts commands (via SPI) which are defined in /usr/include/hidif.lu. These are used to control & query external devices:
Name |
Command |
Description |
CMD_SYNC |
0xAA |
Sync with device to send/receive Marks the beginning of a command |
CMD_CLOSE |
0xCC |
Close sync Marks the end of a command |
CMD_VER |
0xBC |
|
CMD_FILL |
0xFF |
Filler - seems to be used to signal HID that it can send data back |
CMD_CODEC_RESET |
0xD7 |
Reset codec |
CMD_ADC_START |
0xD8 |
Initalize ADC |
CMD_ADC_RESULT |
0xD9, 0xFFFF |
|
CMD_SYS_CTRL |
0xDA |
Sends command SYS_CTRL_xxx |
SYS_CTRL_POWEROFF |
0x00 |
Powers off the Connect |
SYS_CTRL_RESET |
0x01 |
Reset the Connect |
SYS_CTRL_SLEEP |
0x02 |
Sleeps the Connect |
SYS_CTRL_DIS_WD |
0x03 |
|
SYS_CTRL_KICK_WD |
0x4 |
|
SYS_CTRL_EN_HDQ_THERM |
0x5 |
|
SYS_CTRL_EN_TS_THERM |
0x6 |
|
SYS_CTRL_FRESET |
0x80 |
|
CMD_SET_INTCHRG |
0xD1 |
|
CMD_GET_INTCHRG |
0xD2, 0xFF |
|
CMD_SET_EXTCHRG |
0xC6 |
|
CMD_GET_EXTCHRG |
0xC7, 0xFF |
|
CMD_GPIOD_SET_BANK |
0xDB |
|
CMD_GPIOD_SET_PORT |
0xDC |
|
CMD_GPIOD_GET_PIN |
0xDF, 0xFF |
|
CMD_GPIOD_SET_DDR |
0xE0 |
|
CMD_HDQ_READ |
0xC0 |
Read HDQ (battery) data |
CMD_HDQ_WRITE |
0xC1 |
Write HDQ (battery) data |
CMD_HDQ_STATUS |
0xC2, 0xFFFF |
OK = 0, not ready = 1, timeout = 2 |
CMD_STATE |
0xBB, 0xFFFFFFFFFFFFFFFF |
|
CMD_PGMWAKE |
0xBF |
|
CMD_LCM_POWER |
0xC9 |
Sends command LCM_xxx to LCD driver |
LCM_POWER_OFF |
0x00 |
LCD power off |
LCM_POWER_ON |
0x01 |
LCD power on |
LCM_POWER_SLEEP |
0x02 |
LCD sleep |
LCM_POWER_WAKE |
0x03 |
LCD wakeup |
LCM_REPOWER_ON |
0x04 |
|
CMD_WHEEL_EN |
0xD0 |
|
CMD_MONOTIME |
0xBD, 0xFFFFFFFF |
|
CMD_MONORSTCNT |
0xE4, 0xFFFF |
|
CMD_SET_USBCHRG |
0xE2 |
|
CMD_GET_USBCHRG |
0xE3, 0xFF |
|
CMD_GET_DOCK_STATE |
0xE5, 0xFF |
|
CMD_READ_DOCK_STATE |
0xE6 |
|
Sync sequence is CMD_SYNC -> CMD_VER -> CMD_FILL -> CMD_CLOSE, while command sequence is CMD_SYNC ->
command -> CMD_CLOSE -> CMD_FILL Communication to this device is handled by /usr/bin/hidtool, which is a binary file.
Device also seems to work as a watchdog.
Atmel AT88SC EEPROM and USB.
This device is read by the /bin/setupenv script - it retrieves both deviceid and MAC address and loads them into the $deviceid and $mac environment variables, respectively. Other environment variables (/etc/setupenv) are:
- Manufacturer:"SanDisk"
- Product name: "Sansa Connect"
- Vendor ID: 0x0781
- Product ID: 0x7480 (MTP more), 0x0F02 (Ethernet-over-USB mode), or 0x7482 (recovery mode)
- Product revision: 0x0101
Recovery Mode
Recovery Mode can be reached by completely powering down the device (by holding off for 10 seconds). Holding the volume-up and right keys while powering the device back on switch it to recovery mode. In recovery mode the device uses different USB IDs (0781:7481 and 0781:7482, vs 0781:7480 in normal operation) - if installed under Windows the Sansa Connect Device Recovery software will automatically launch when a Connect in recovery mode is connected.
USB ID 0781:7481 is used for writing .SRR files to Flash, while 0781:7482 acceses the "Zaprecover" service (complete with a kernel module!!!), which handles dumping files to the filesystem.
Once linux is loaded, recovery mode is signaled by a persistent variable ("recoverzap") stored in flash. This flag is only removed after a sucessful recovery operation, so there's no way to exit recovery mode once entered without running the recovery operation (and therefore wiping the unit) with the stock initrd file.
Recovery sequence
- Turn off the device completely (hold power key for 10 seconds)
- Turn the device on while holding volume-up and the right button (above the wheel)
- The device will boot showing a "recovery needed" indicator. On this mode the device exposes the USB ID 0781:7481, which zsi_fw.exe communicates to. This is NOT handled by linux - so it's either the linux bootloader or maybe even a previous instance of software. This mode is persistent after reboot.
- Once the USB cable is connected the indicator is changed to "recovery in progress".
- After a suceessful firmware load with zsi_fw.exe, the device will attempt to boot the vmlinux image (after a small delay). If the device reboots to recovery mode something went wrong with the firmware load. otherwise Linux will boot correctly and go to recovery mode, exposing the USB ID 0781:748 (Zaprecover service) and displaying a "starting recovery" message (with a yellow clock on top). How the device determines it has to go into recovery mode after boot is unclear - most likely it's because the flash filesystem is wiped after a firwmare write.
- Once a platform load is started with zaprecover.exe the message changes to_"receiving software"_.
- Once finished, the message now changes to "verifying software" (signature check), then "installing software" (a message reading _"can't find image_" might flash briefly). The device proceeds now to extract the platform into the filesystem.
- After a small delay, if everything went ok the device should now reboot to the familiar Sansa loading screen (with the five color balls).
ZAP recovery service
Once linux is loaded, on recovery mode the device loads a kernel module called "zaprecover" (/bin/usb_switch_zaprecover), listening on 0781:7482. The driver is interfaced with /usr/bin/zsi_zap, which tells the module how many files to expect and where to store them. On recovery mode, it waits for both the platform file and signature to be sent, in that order (/etc/rc.recover):
/usr/bin/zsi_zap -f /disk/zap/ZAP.tar.gz -f /disk/zap/ZAP.tar.gz.sig
The device won't leave recovery mode unless both files are downloaded correctly and the signature is checked. The data protocol used by the zaprecover service is still uknown, but the source for it is freely readable on the kernel patch.
Software
Original Software information can be found on
SansaConnectOriginalFirmware.
Software/Hardware hacking
It is possible to replace the internal iNAND with microSD card - which allows to change the platform to for example start telnet.
Tips:
after connecting via wireless, stop
WiFiThread to prevent disconnection due to inactivity, this can be achieved by checking the thread pid cat /var/tmp/native_thread_map, and then sending SIGSTOP to it(kill -s SIGSTOP pid).
JTAG
There is JTAG on the PCB. Hirose Electric
FH19SC-16S-0.5SH(05) connector matches the footprint.
Connector pinout:
Volume up button
1 GND
2 RTCK (B1)
3 TDO (A13)
4 GND
5 TRST (F12)
6 TMS (A14)
7 TDI (B14)
8 TCK (C13)
9 GND
10 ? UNKNOWN
11 RXD0 (C2)
12 TXD0 (E5)
13 VDDIO (Vref for JTAG)
14 VDDIO (Vref for JTAG)
15 EMU0 (A2)
16 EMU1 (C3)
Volume down button
Vref is 3.3V. Bootloader configures UART0 to baud rate 115200, character format is 8N1, no flow control.
Free Software
The PDF that ships on the Sansa Connect CD includes a section called "Open Source Licences" and includes:
busybox
curl
Ezxml
Freetype
GPG
Linux
mDNSresponder
Mono
libpng
openssl
SSLeay
resample
Uclibc
wpa_supplicant
zlib
There are broken links in the PDF to the Sansa site to download modified source versions of the GPL licensed software. Instead these downloads are available from the Zing site, substituting zing.net for sandisk.com in the links:
busybox,
GPG,
Linux,
Mono,
resample and
Uclibc. Also attached is a
diff created against the vanilla 2.6.4 kernel release.
Copyright © by the contributing authors.