Mileage reset untuk RICOH SP 150SUw

Saya tidak percaya teori konspirasi produsen (elektronik) untuk mengurangi sumber daya produk, itu hanya mencari rasio harga / kualitas terbaik untuk segmen pasar tertentu. Tapi ada satu momen dimana saya terbakar habis-habisan tepat di bawah perut. Ini adalah produsen printer. Tidak hanya harga bahan habis pakai yang dapat dibenarkan hanya dengan adanya bayi yang lahir dari perawan di dalam darah, tetapi juga "serpihan" kartrid yang tersebar luas, yang telah beralih ke bukan unit laser yang paling hemat anggaran. Tapi yang benar-benar "membom" saya dari produk berikut: RICOH SP 150SUw. Perangkat ini dibeli karena perpindahan dari wilayah Moskow ke Minsk dan kebutuhan untuk menyalin / mencetak banyak dokumen untuk mendapatkan izin kerja / tinggal.



Pilihannya didasarkan pada persyaratan berikut: MFP tidak mahal, kompak, pencetakan jaringan, ketersediaan driver untuk Linux (Fedora / Mint / OpenSUSE). Pahlawan artikel memiliki semua karakteristik ini, tetapi satu nuansa tidak diperhatikan. Penghitung sumber daya melengkung. Jika Anda bertanya-tanya bagaimana cara menyembuhkan dan



(Memo untuk Tata Bahasa Nazi dari seseorang dengan disgrafia ringan)
, . . / , . , . ยซยป, . , , , / . , , , , . , , . , โ€”



Selamat datang!



Permasalahannya adalah,bahwa MFP tidak menghitung jumlah toner bekas, tetapi jumlah halaman yang dicetak. Jika saya mencetak kartrid starter dengan pengisian yang cukup besar, maka insiden yang kedua terjadi. Faktanya adalah bahwa istri saya dengan cepat bergabung dengan komunitas Angloms lokal dan bagian dari pekerjaan yang terkait dengan penyediaan percetakan jatuh pada kami. Jadi segala macam gambar kontur untuk pemotongan / pewarnaan / origami diisi toner, paling banyak 1% dari lembarannya. Akibatnya, saya menemukan diri saya "kosong" di atas meja, tetapi kenyataannya - kartrid 70 persen penuh. Tidak, saya tidak begitu miskin sehingga tidak mampu membeli yang baru, tidak terlalu berpendidikan lingkungan untuk mengalami siksaan moral, membuang produk yang dapat diservis ke tempat pembuangan sampah, tetapi dari perasaan bahwa Anda secara hukum dilempar - kursi itu mulai asap, yang merupakan dorongan untuk bertindak ...



Sejujurnya, saya tidak berharap menjadi "ibu peretas", mengingat perlindungan perangkat keras seperti itu sangat sulit untuk dihancurkan. Saya menghitung, setidaknya, pada algoritma enkripsi yang layak dan memori OTP (setelah dapat diprogram). Tapi kenyataannya ternyata jauh lebih lumrah. Untungnya, ada banyak instruksi tentang permintaan untuk mengatur ulang kartrid, dan "chip perlindungan" ternyata adalah I2C EEPROM AT24C01 yang cukup luas , disolder dengan "body kit" minimum, bukan papan. Pada umumnya, pada gambar berikutnya, Anda dapat menyelesaikan artikel:





Video asli



Dengan programmer mana pun, kami membaca konten sirkuit mikro, "nol" sel yang diuraikan dalam bingkai merah dan mengubah beberapa digit terakhir nomor seri. Perlu dicatat bahwa serial adalah string teks yang diakhiri dengan spasi, jadi Anda perlu mengubahnya dalam kisaran 0 ... 9 (0x30 ... 0x39). Alamat fisik sirkuit mikro yang disolder di papan adalah 0x03. Tapi ... Temui pembuat sepatu tanpa sepatu bot. Tidak ada programmer universal, jadi kami mengambil PIC16F819 dan PICKit 3, tidak, untuk promosi ke massa - Arduino UNO / Nano, sepasang resistor 4,7k (dari 3k hingga 10k untuk tugas ini - itu akan dilakukan), pengukur MGTF atau kabel favorit Anda dan pasang "Skema" berikutnya:







Rakitan terlihat seperti ini:







Saya melepas papan "perlindungan" dari kartrid untuk memastikan bahwa pinout yang diberikan di manual sesuai dengan kenyataan dan untuk mendapatkan alamat fisik sirkuit mikro di bus:





Bantalan kontak, dari kiri ke kanan: GND, + 5V, SCL . SDA.



Anda tidak harus pintar membuat adaptor, tetapi solder kabel langsung ke papan tanpa melepasnya dari kartrid. Selanjutnya, salin kode buruk saya ke Arduino IDE:



Sial
#include <stdint.h>
#include <Wire.h>

//----------------------------------------------------------------
#define EERROM_SZ         (0x80)
#define EERROM_PHY_ADDR   (0x03)
#define EERROM_HEAD       (0x50)
#define PRN_BUFF_SZ       (0x08)
#define SER_START_ADDR    (0x20)
#define SER_END_ADDR      (0x2B)
#define SER_MOD_ADDR0     (0x2A)
#define SER_MOD_ADDR1     (0x29)
#define SER_MOD_ADDR2     (0x28)

//----------------------------------------------------------------
static uint8_t eeprom_data[EERROM_SZ];
static bool erased;
static bool z_filled;
//----------------------------------------------------------------
static uint8_t ee_read(uint8_t phy_addr, uint8_t addr)
{
  uint8_t res;

  Wire.beginTransmission(EERROM_HEAD | phy_addr);
  Wire.write(addr);
  Wire.endTransmission();
  Wire.requestFrom(EERROM_HEAD | phy_addr, 1);
  res = Wire.read();
  
  return res;
}

//----------------------------------------------------------------
static void ee_write(uint8_t phy_addr, uint8_t addr, uint8_t data)
{
  Wire.beginTransmission(EERROM_HEAD | phy_addr);
  Wire.write(addr);
  Wire.write(data);
  Wire.endTransmission();
  delay(5);
}


//----------------------------------------------------------------
static void read_data(uint8_t phy_addr)
{
  uint8_t addr;
  uint8_t data;
  
  erased = true;
  z_filled = true;
  
  Serial.print("Read from phy addr ");
  Serial.print(phy_addr);

  for (addr = 0; addr < EERROM_SZ; addr++)
  {
    if (0 == (addr & 0x03))
    {
      Serial.print(".");
    }
    data = ee_read(phy_addr, addr);
    eeprom_data[addr] = data;

    if (0xFF != data)
    {
      erased = false;
    }

    if (0x00 != data)
    {
      z_filled = false;
    }
  }
  
  Serial.println("Ok");
}

//----------------------------------------------------------------
static void write_data(uint8_t phy_addr)
{
  uint8_t addr;

  Serial.print("Write to phy addr ");
  Serial.print(phy_addr);

  for (addr = 0; addr < EERROM_SZ; addr++)
  {
    if (0 == (addr & 0x03))
    {
      Serial.print(".");
    }
    ee_write(phy_addr, addr, eeprom_data[addr]);
  }

  Serial.println("Ok");
}

//----------------------------------------------------------------
static bool check_data(uint8_t phy_addr)
{
  uint8_t addr;
  uint8_t data;
  
  Serial.print("Check from phy addr ");
  Serial.print(phy_addr);

  for (addr = 0; addr < EERROM_SZ; addr++)
  {
    if (0 == (addr & 0x03))
    {
      Serial.print(".");
    }
    data = ee_read(phy_addr, addr);
    if (eeprom_data[addr] != data)
    {
      Serial.println("FAILED");
      return false;
    }
  }
  
  Serial.println("Ok");
  return true;
}


//----------------------------------------------------------------
static void print_data(void)
{
  uint16_t addr;
  char prn_buff[PRN_BUFF_SZ];
  
  for(addr = 0; addr < EERROM_SZ; addr++)
  {

    if (0x00 == (addr & 0x0F))
    {
      snprintf(prn_buff, PRN_BUFF_SZ, "%4X:  ", addr);
      Serial.print(prn_buff);
    }
    
    snprintf(prn_buff, PRN_BUFF_SZ, "%2X ", eeprom_data[addr]);
    Serial.print(prn_buff);
    
    if (0x0F == (addr & 0x0F))
    {
      Serial.print("\n\r");
    }
  }
  Serial.print("\n\r");
}

//----------------------------------------------------------------
static void prn_serial(void)
{
  Serial.print("Serial #: ");
  Serial.write(&eeprom_data[SER_START_ADDR], 1 + SER_END_ADDR - SER_START_ADDR);
  Serial.print("\n\r");
}

//----------------------------------------------------------------
static void mod_serial(void)
{
  eeprom_data[SER_MOD_ADDR0]++;
  if (eeprom_data[SER_MOD_ADDR0] > '9')
  {
    eeprom_data[SER_MOD_ADDR0] = '2';
  }

  eeprom_data[SER_MOD_ADDR1]++;
  if (eeprom_data[SER_MOD_ADDR1] > '9')
  {
    eeprom_data[SER_MOD_ADDR1] = '3';
    eeprom_data[SER_MOD_ADDR2]++;
    if (eeprom_data[SER_MOD_ADDR2] > '9')
    {
      eeprom_data[SER_MOD_ADDR2] = '1';
    }
  }
}

//----------------------------------------------------------------
static void reset_mileage(void)
{
  uint8_t i;
  
  for (i = 0x12; i <= 0x1F; i++)
  {
    eeprom_data[i] = 0;
  }

  for (i = 0x2C; i <= 0x7F; i++)
  {
    eeprom_data[i] = 0;
  }
}

//----------------------------------------------------------------
static bool test_magic(void)
{
  if (0x32 != eeprom_data[0]) return false;
  if (0x00 != eeprom_data[1]) return false;
  if (0x01 != eeprom_data[2]) return false;
  if (0x03 != eeprom_data[3]) return false;
  return true;
}

//----------------------------------------------------------------
void setup()
{
  int key;

  Serial.begin(9600);
  Wire.begin();

  Serial.println("\tSP 150 cartridge mileage resetter");
  Serial.println("Connect like this:");
  Serial.println("             TOP");
  Serial.println("______________________________");
  Serial.println("|o |GND| |+5V| |SCL| |SDA|  <=");
  Serial.println("|  |GND| | 5V| | A5| | A4|    ");
  Serial.println("------------------------------");
  Serial.println("        cartridge roller");
  
  Serial.println("\n\r\n\r\tTo start, press 'm' or any button for test (not prog)...\n\r");

  do
  {
    key = Serial.read();
  }
  while(-1 == key);
  
#if 0
  for (uint8_t paddr = 0; paddr < 8; paddr++)
  {
    Serial.print("Scan phy ");
    Serial.println(paddr);
    for (uint8_t i = 0; i < 5; i++)
    {
      Serial.print("Read from ");
      Serial.print(i);
      Serial.print(".........");
      Serial.println(ee_read(paddr, i));
    }
  }
  return;
#endif

  read_data(EERROM_PHY_ADDR);
  Serial.println("Read:");
  print_data();
    
  if (true == erased)
  {
    Serial.println("ERROR! The EEPROM is erased or the connection / phy addr is incorrect.");
    return;
  }

  if (true == z_filled)
  {
    Serial.println("ERROR! The EEPROM is Z filled.");
    return;
  }

  
  if (false == test_magic())
  {
    Serial.println("ERROR! Invalid magic number.");
    return;
  }

  prn_serial();
  
  mod_serial();
  reset_mileage();

  Serial.println("\n\rModified:");
  print_data();
  prn_serial();

  if ('m' != (char)key)
  {
    Serial.println("WARNING! The data was not modified in the EEPROM");
    return;
  }

  write_data(EERROM_PHY_ADDR);

  if (false == check_data(EERROM_PHY_ADDR))
  {
    return;
  }
  
  Serial.println("Fin");
}



void loop()
{
  //do nothing
}

      
      







(Tentang kode kotoran - ya, itu tidak dioptimalkan baik oleh memori (semua data dibaca ke dalam array), atau oleh kinerja (membaca dan menulis dilakukan byte demi byte), atau dengan fungsionalitas, tetapi untuk tugas yang sederhana - dan begitulah yang akan dilakukan!)



Kami mem-flash Arduinka, buka terminal apa saja (I18n, 9600 baud), Arduino IDE bawaan akan dilakukan, reset papan, tekan tombol apa saja:







Setelah itu, konten EEPROM akan dibaca, dimodifikasi, tetapi tidak tertulis. Jika prosedur berlanjut tanpa kesalahan, reset papan lagi, tekan m, setelah itu semua langkah akan dilakukan dan data yang dimodifikasi akan ditulis. Jika ada yang tidak beres, periksa diagram lagi dan coba lagi. Setelah berhasil memusatkan perhatian, kami menyolder kabel dan memasang kartrid di tempatnya. Level toner harus 100%.



Saya minta maaf untuk "air", instruksi 3 baris - sangat sedikit untuk posting. Saya harap informasinya bermanfaat, dan juga - penulis tidak bertanggung jawab atas kemungkinan kerusakan peralatan, pencabutan layanan garansi, semua yang Anda lakukan adalah risiko dan risiko Anda sendiri ...



Pembaruan lain, dump diterima dari kartrid saya:



Read from phy addr 3................................Ok
   0:  32  0  1  3  2  1  1  0  0  0 34 30 38 30 31 30 
  10:  16  5 4D 4D  1  2 11 70  0  0  0  0 14 14  5 21 
  20:  43 37 30 36 4D 39 30 33 31 39 35 20  0 45  0  0 
  30:  39  1  0  0  0  0  0  0 3E  4  0  0  0  0  0  0 
  40:   5  3  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
  50:   0  0  0  0  0  0  0  0 14  E  5 1B 14  E  5 1B 
  60:   0  0  0  0  0  0  0  0 77  2  0  0  0  0  0  0 
  70:  C3 23 2A  0 16  0  0 55  0  0  0  0  0  0  0  0 

      
      






All Articles