Hacking the Samsung CLP-315 Laser Printer
I am the happy owner of a Samsung CLP-315 laser printer. It is a fantastic printer for the price. Things were going great until it came time to replace the toner. At the time, the price of a full set of toner cartridges was around $150. To put things in perspective, the printer itself could be acquired for less on eBay. Not being the type of person who so easily bends to the will of “The Man”, I set out on a journey to find a cheaper source of toner.
A “journey”? Really? As it turns out, the answer is yes but in the end it was worth it. This is going to be a long post, so strap yourself in. If you’d prefer to cheat, you can skip straight to the good stuff.
How Stuff Works
Since I last purchased a laser printer (my circa 2001 LaserJet 1200 is still kicking) the industry has changed. Imagine that!? Apparently, it is now common practice for printers and even toner cartridges themselves to count the number of pages that have been printed in order to track the consumption of toner. The printers then use these page counts to project how much toner remains in the cartridge. To my knowledge, the cartridges don’t have a way to sense how much toner remains.
Why does this matter, you ask? Essentially, it would be like having a gas gauge in your car that only tracked how far you had driven, not how much gasoline was left in the tank. Depending on several factors (driving style, load, tire pressure, etc), the amount of fuel consumed in a mile can vary wildly. The end result; you either waste gas, or run out. Neither is good. The same can be said for the way modern laser printers track toner.
This causes two problems. First, toner is likely being wasted (which irks me). Second, refilling the cartridges with toner purchased in bulk does nothing to reset the accumulated page count. It is like putting gasoline in your tank, but not being able to start the car until the odometer is reset. Knowing all this, the only thing standing between me and cheap toner refills was finding a way to reset the counters.
Unsurprisingly, I am not the first person to try to address this problem. In fact, there is plenty of published hackery surrounding this printer. Not wanting to start from scratch, I got to reading. What I discovered is that the page counts are all stored on an EEPROM chip that is attached to an I²C bus (an ST M24C64, in this case). If that last sentence meant nothing to you, you might want to skip to the “Reset Procedure” section… It is going to get technical for a while.
After doing some homework, I decided to try watching the I²C traffic with a logic analyzer to see what memory locations were getting updated on the EEPROM after each print. I was able to catch the first handful of writes, but there were so many that I decided to take a slightly different approach.
I wrote an Arduino sketch to dump the entire memory of the EEPROM to the serial port. This allowed me to see a before and after memory snapshot. So, I would dump the EEPROM, print a page, and dump it again. I then compared the outputs using a diff program. I looked specifically for writes that looked like they incremented a value. Like I had suspected, there were lots of locations that were incrementing. Great!
The next thing I did was print off the printer’s “Configuration Report”. This is done by holding down The Button until the green light flashes rapidly. This report includes several counts, including the counts for our toner cartridges and the printer itself. By searching the dump file for these numbers (after converting them to hex), I was able to track down which memory locations were used to store which counts.
Now I had a list of memory locations that (I assumed) stored the page counts. I could use another Arduino sketch to write zeros back into those locations. Using our analogy from before, I hoped this would reset the “odometer” and register the tank as full.
I was able to successfully write zeros to all of the incrementing memory locations. Unfortunately, after printing the configuration report again, the “Toner Remaining” percentage hadn’t updated for any of the cartridges. Also, the low-toner warning lights remained lit for all colors. Apparently that percentage is a stored value, not one that is calculated on the fly based on the page count. If the numbers were stored as floating points, this could explain why they were harder to see, as they may not have changed by exactly 1 like the page counts did.
I needed a better way to analyze and flash the entire address space on the EEPROM. I hooked up my Bus Pirate to the I²C bus, and was going to start writing some software to accomplish this. Here is where things got really interesting…
I rebooted the printer with the Bus Pirate connected (I don’t remember which mode I had it in), and it took a really long time to start-up. I ran the configuration report and it had mysteriously zeroed or erased every field. All values, serial numbers, dates, and counts were blank or zero. I was terrified that I had bricked my printer!
So, I disconnected the Bus Pirate and printed another configuration report. Everything looked as I had left it with one exception. Now, the black toner cartridge registered zero pages and 100% remaining toner. And the warning light for the black toner was off… Eureka! (I didn’t really say that, but I think I did run and show my wife who said “That’s nice, honey”. I’m such a nerd.)
So what happened, and how could I now make it happen for the color cartridges, too? I hooked up the scope to the SDA and SCL lines of the bus so I could watch what was happening while booting with the Bus Pirate connected. After a couple of tries, I noticed that the SDA line was being held low by the Bus Pirate (like I said, I’m not sure what mode I had it in). I could see the clock line getting toggled as it booted, but holding the data line low seemed to be interrupting the flow of data between the EEPROM and the main processor. I can only assume that when this happens during a boot up, all of the count variables are left initialized to zero in the main processor’s memory.
So, the idea struck me. What if I interrupt the communications during boot (letting the in-memory values initialize to zero), but then print a page and see if it would run the same incrementing logic and write 1s for the page counts back to the EEPROM. Is double eureka a thing? It worked. All toner levels, page counts, image counts and everything had been written back to the EEPROM as if they had started at zero.
After Print and Reboot
After printing a few more pages (and giggling like a child to the wife), I was able to refine the reset process a bit. Here are the steps to perform the reset:
- Open the printer and solder a wire to the SDA pin of the EEPROM (see video below)
- Power up the printer with this line held to ground until it finishes initializing
- You can use chassis near the USB port is an easy spot to ground to.
- The printer will take longer than normal to initialize; don’t be alarmed
- Disconnect the SDA line from ground
- Print the demo page by pushing The Button until you see a slowly blinking green light (about 2 seconds)
- Print the configuration page by pushing The Button until you see a rapidly blinking green light (about 6 seconds)
- Turn off the power
- Turn on the power, and wait for it to initialize
- Print the configuration report again
- All your base are belong to us
One thing worth noting; my printer still has its original toner cartridges which are “chipless”. Retail replacement cartridges have a chip with its own EEPROM that has a unique identifier and stores its own count. Since I don’t have toner cartridges with these chips, I don’t know (but I suspect) that a different approach or additional steps may be necessary to reset the counts.
You may be able to tape off the exposed pads on the toner chips before performing this procedure and get the same effect, but I haven’t got the chipped cartridges to test with. (nor will I be buying any for $150!) YMMV.
It took some time to get there, but I think it was worth the effort. This printer is now happily kicking out full-color pages for 2¢ versus a whopping 15¢ (ouch). Life is good. Enjoy!