Hacking a Dell power adapter — part III

Last night I worked for more than 2 hours only finding out the chip in the power adapter is damaged. This time, I want to use my working power adapter. Instead of trying to talk to it directly using OneWire protocol, I’d like to see what’s happening between laptop and the power adapter.  With a hand soldered adapter I was able to expose the signal pins from both power adapter side and laptop side and I’m going to hook it up with a uC to see what’s happening.

Without a scope or logic analyzer, it’s not easy to sniff the onewire protocol. So I decided to make a software one with MSP430G2553. This chip has a timer with capture capability and 512 bytes RAM.  So I should be able to setup the timer to capture both rising and falling edge of the signal line, and save the elapsed time to a 100-integer array in RAM.

Because of limited RAM, I will have to stop once the buffer is full. That means I will not get a full dump of the communication but it should be a good start.

OK. Let’s wire up and see what I can get. Having everything wired up, after plugging the power adapter into my laptop, the code running on uC quickly stops at the preset breakpoint which means I’ve collected 100 data about rising and falling edges (how stupid that TI’s code composer studio doesn’t allow you copy content in the expression watch window, I have to manually copy memory dump and convert them into decimal numbers using python):

[0, 1310, 23, 107, 931,

554, 25, 107, 412,

70, 10, 0
70, 10, 0
8, 72, 1
8, 71, 1
71, 10, 0
70, 10, 0
8, 72, 1
9, 72, 1

71, 10, 0
71, 21, 0
70, 9, 0
71, 10, 0
10, 70, 1
8, 72, 1
9, 70, 1
8, 73, 1

71, 10, 0
71, 10, 0
71, 10, 0
8, 72, 1
70, 10, 0
70, 21, 0
71, 9, 0
71, 10, 0

71, 10, 0
71, 10, 0
71, 10, 0
71, 10, 0
70, 10, 0
70, 10, 0
71, 10, 0
70, 11, 0

8, 72, 1
9, 84, 1
28, 53, 0
8, 72, 1
9, 73, 1
10, 73, 1
9, 72, 1
8, 74, 1

28, 53,
28, 5
4, 28,
52, 28,
53, 9, 72, 9]

I’m still assuming it’s OneWire communication. It’s easy to notice that the second line seems very likely to be the reset sequence: more than 480us low from host, and less than 60us high, then 60us to 240us low from device, and then pulling up.

After that, every pair of number is a read or write signal. I added the third row for what it writes/reads.

70/10 (or simliar) means 70us low and then 10us high. This should be “write 0″

8/72 (or simliar) means 8us low and then 72us high, this shoudl be “write 1″

Comparing to the OneWire spec, we can tell it’s writing 0xCC, which should be SKIP_ROM. Following that is 0xF0 (ReadMem), and two bytes starting address: 0x08, 0x00.

Then the numbers are getting weird, which is actually the reading sequence. Pairs like “8, 72″ with first number less than 10 is a “read 1″, and “28, 53″ is a “read 0″. According to the spec, after writing ReadMem command with start address, we should be reading a CRC code verifying the command and address are correctly received by the device. So in this case, the device returns a CRC code 0xFB.

Here is some quick C code calculating the CRC:

typedef unsigned char uint_8;

uint_8 CRC_8(uint_8 crc, uint_8 data)
 for (int i = 0; i < 8; i++)
 if ((crc ^ data) & 1)
 crc = (crc >> 1) ^ 0x8C;
 crc >>= 1;

data >>= 1;
 return crc;

int _tmain(int argc, _TCHAR* argv[])
 uint_8 crc = 0;
 crc = OW_CRC(crc, 0xF0);
 crc = OW_CRC(crc, 0x08);
 crc = OW_CRC(crc, 0x00);

return 0;

Run it, and we got: 0xFB, yes! So it is OneWire protocol! I ran my one wire code and dumped the information from the adapter:

RomID: 11 63 4D 8B 00 00 00 14 . Starting from LSB to MSB. 0x11 is the family code about which I can’t find any useful information .

Memory dump:

String format: DELL00AC090195046CN09T2157161543835EAL03

Hex format:

44 45 4C 4C 30 30 41 43 30 39 30 31 39 35 30 34 36 43 4E 30 39 54 32 31 35 37 31 36 31 35 34 33 38 33 35 45  41 4C 30 33 E0 A9 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

Listening the onewire protocl between laptop and power adapter shows that the laptop is actually reading 3 bytes from starting address 0x08, which is “090”. It looks like “090” is the wattage, and “1950” is the voltage (19.5v), then “46” is the amperage (4.6A), the reset looks like a serial#. And, my laptop doesn’t even care all the other parts except the wattage, neither does it care the RomID of the chip!

Well, now we have at least one simple solution: Simply buy a DS2502 device, program it with the above information, and make a “adapter” like thing but hook the center pin to that DS2502 device.

But, I like to over-engineer things, so I’m going to make a MSP430 chip and faking itself like a DS2502 chip. By doing this I can report whatever information I want to. This will be a more flexible design in case some crazy DELL model checks the RomID. Even further, it can even “import” the data from multiple working power adapters and switching between different models. More importantly, it’s a good chance to learn the onewire protocol!

To be continued…

About these ads
This entry was posted in MSP430 and tagged , , , . Bookmark the permalink.

5 Responses to Hacking a Dell power adapter — part III

  1. hclxing says:

    To decode the string “DELL00AC090195046CN09T2157161543835EAL03″, skipping “DELL00AC” (which, according to my investigation, they don’t really care since the laptop always start reading from offset 0x0A, which is the next byte), the first three digits “090” is the wattage, and then “1950” is the voltage (19.5v), and then the amperage (4.6A), after that “CN09T2157161543835EAL03″ should be the serial number of the power adapter.

  2. Pingback: Hacking Dell Laptop Charger Identification

  3. Cyber says:

    I check the DS2501 and DS2502 datasheet and found:
    0×11 is the family code of DS2501
    0x09 is the family code of DS2502

  4. mwsoft says:

    Small hint: you can use DS2431+ (1kbit eeprom).
    It doesn’t require 12V pulse like DS2502, so programming can be easily done with just plain Bus Pirate with external 2kohm pullup.

    Although DS2431 doesn’t send CRC byte after address bytes during Memory Read Command (0xF0) – it goes straight to memory array bytes. This can be fixed by programming right CRC value directly at address 0x08. So memory looks like:

    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFB 0x30 0x39 0x30 0xFF 0xFF 0xFF 0xFF ……

    This method worked with PA10 power supply and Dell D830 notebook.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s