MarsTechHAN / ch552tool

An open sourced python tool for flashing WCH CH55x series USB microcontroller with bootloader v2.30, v2.31 & v2.40.
GNU General Public License v3.0
154 stars 24 forks source link

Tried with CH568L , unsuccess. But solution found :) will place PR in near weeks. #20

Open Pe3ucTop opened 2 years ago

Pe3ucTop commented 2 years ago

First of all , nice work ! But, would like to see more output. Like: Erasing ... Flashing ... Verifying ..

I added :

CH55X_IC_REF[0x68] = {
    'device_name': 'CH568',
    'device_flash_size': (128+64)*1024,
    'device_dataflash_size': 32*1024,
    'chip_id': 0x68}

and got response when tried to flash:

Found CH568.
BTVER: V2.40.
Flash done.
Restart and run.

But board do not startup / do not work. When uploading with WCHISPTool 3.0 result in working board. Will continue next week, will try to capture USB traffic for both applications.

Pe3ucTop commented 2 years ago

Small update:

In short minimal change which is needed is checksum calculation update. It need be calculated from 4 or 8 bytes of UID depend on Chip Sub ID . When ChipSubID is 0x11 (17) then calculate from 4 bytes. In other cases calculate from 8 bytes.

I checked with my CH568 chip based board and it works after code modification.

MarsTechHAN commented 2 years ago

Cool. I have my local version with debugging support, but it prints way too much stuff, and don't get time to clear it up. Welcome, PR!

karlp commented 2 years ago

I suspect you might need the new key for newer bootloader versions that @pablomarx found in https://github.com/pablomarx/ch552tool/commit/280d7ef980c16d437f38107c284e3a2896232799 and that I've included in my pr #22

i'm kinda curious whether it's bootloader version or "chip sub id" version that determines this, but I'd kinda lean towards bootloader version, rather than chip sub id

Pe3ucTop commented 2 years ago

@karlp It depend on "chip sub id" (we can call it other name) and it gotten from disassembled (and converted to C) original WCHISP software. Here is key generation function :

int __stdcall sub_1000AD20(_BYTE *a1, int payload_buff_p, _WORD *payload_size_p, _DWORD *a4)
{
  unsigned int v4; // eax
  int v6; // eax
  unsigned int pl_byte_cnt; // esi
  unsigned int chksum_calc_len; // eax
  char chk_sum; // bl
  unsigned int i; // ecx
  unsigned int payload_size; // [esp+4h] [ebp-Ch]

  v4 = time(0);
  srand(v4);

  if ( !chip_id || !chip_subid )
    return 0;

  v6 = rand();
  pl_byte_cnt = 0;
  payload_size = v6 % 31 + 30;
  if ( v6 % 31 != -30 ) // strange check, probably always !
  {
    do
    {
      *(_BYTE *)(payload_buff_p + pl_byte_cnt) = GetTickCount() + rand();
      ++pl_byte_cnt;
    }
    while ( pl_byte_cnt < payload_size );
  }

  // Calculation CheckSum of UID
  chksum_calc_len  = chip_subid != 17 ? 8 : 4;
  chk_sum = 0;
  for ( i = 0; i < chksum_calc_len; ++i )
    chk_sum += a1[12 + i];   // UID

  LOBYTE(dword_100247F8) = chk_sum ^ *(_BYTE *)(payload_buff_p + 4 * (payload_size / 7));
  BYTE1(dword_100247F8) =  chk_sum ^ *(_BYTE *)(payload_buff_p +      payload_size / 5 );
  BYTE2(dword_100247F8) =  chk_sum ^ *(_BYTE *)(payload_buff_p +      payload_size / 7 );
  HIBYTE(dword_100247F8) = chk_sum ^ *(_BYTE *)(payload_buff_p + 6 * (payload_size / 7));
  LOBYTE(dword_100247FC) = chk_sum ^ *(_BYTE *)(payload_buff_p + payload_size / 7 + 2 * (payload_size / 7));
  BYTE1(dword_100247FC) =  chk_sum ^ *(_BYTE *)(payload_buff_p + payload_size / 5 + 2 * (payload_size / 5));
  BYTE2(dword_100247FC) =  chk_sum ^ *(_BYTE *)(payload_buff_p + payload_size / 7 + 4 * (payload_size / 7));
  HIBYTE(dword_100247FC) = chip_id + dword_100247F8;

  *payload_size_p = payload_size;
  *a4    = dword_100247F8;
   a4[1] = dword_100247FC;
  return 1;
}