数码之家

 找回密码
 立即注册
搜索
查看: 14871|回复: 21

[宏碁] 想解锁宏碁笔记本电池,尝试用cp2112调试板与电池通信

[复制链接]
发表于 2021-7-3 22:37:31 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我有个acer笔记本电池锁了,其实没有循环几次,多年来一直插着电源用,莫名其妙就锁了,拆了折腾过,保险熔断,电芯焊下测试有电,电压一致性也挺好,看不出来异常,焊过几次,就成了伊拉克成色:
IMG_20210703_195626.jpg
IMG_20210703_200030.jpg
电芯是LG的,保护板主控BQ20Z955,
IMG_20210703_195632.jpg
IMG_20210703_195653.jpg
IMG_20210703_195728.jpg

看到数码之家里有人解锁成功了,过程很复杂不太懂,自己也试试,春节刚过买了个cp2112小板,连了一次电池,初次可以识别,后来莫名其妙软件(Be2works)不认小板了,但是cp2112厂商的demo软件还是可以认的,研究了一番发现是PID、VID被改写后otp写死了,把Be2works网上能找到的那个版本反编译后看到destroy的字样,怀疑是软件破坏了。尝试用silicon lab自己的demo软件读电池信息试试:找出电池接口的针脚定义,
IMG_20210703_195744.jpg
这个是通信小板,与type-c的otg插头对比,很小巧,
IMG_20210703_200131.jpg

按针脚定义连线,用软件读一下,确实可以读到内容
捕获1.JPG
捕获2.JPG
其中目标地址相当于smbus命令地址,20、21分别表示电芯制造商、型号,根据返回的内容,对照asc2表,21地址返回值翻译过来就是AS10D81 , 20地址翻译过来是LGC,好像是那么回事儿?
捕获6.JPG
网上还有大神写了个基于cp2112与电池通信的代码,我下载回来编译完无法认小板,后来在源码里修改了pid vid为我的小板现在的数值,再编译后可以读一些信息了, 捕获7.JPG
这是我连接几个电池读到的部分信息:
捕获3.JPG
捕获4.JPG
捕获5.JPG

源代码里作者没有写解锁部分,我想在这儿蹲个现成的,有大神帮忙吗?  网上下载的那个源码是这样的我直接贴在这儿,侵删

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #include "smbus.h"

  4. /*
  5. NOTE: As command response lengths may differ between gas gauges, ensure
  6. sbsCommandResponseLength contains the correct lengths for your
  7. particular device (check datasheet).

  8. For example, some typical variations:
  9. Manufacturer Name [0x20] = 20+1 bytes / 11+1 bytes
  10. Device Name [0x21] = 20+1 bytes / 7+1 bytes
  11. */
  12. const WORD sbsCommandResponseLength[] = {
  13.     2, 2, 2, 2, 2, 2, 2, 2, 2, 2,   // 0x00 - 0x09
  14.     2, 2, 1, 1, 1, 2, 2, 2, 2, 2,   // 0x0A - 0x13
  15.     2, 2, 2, 2, 2, 2, 2, 2, 2, 0,   // 0x14 - 0x1D
  16.     0, 0, 21, 21, 5, 15             // 0x1E - 0x23
  17. };

  18. enum sbsCommands {
  19.     MANUFACTURER_ACCESS,        // 0x00
  20.     REMAINING_CAPACITY_ALARM,   // 0x01
  21.     REMAINING_TIME_ALARM,       // 0x02
  22.     BATTERY_MODE,               // 0x03
  23.     AT_RATE,                    // 0x04
  24.     AT_RATE_TIME_TO_FULL,       // 0x05
  25.     AT_RATE_TIME_TO_EMPTY,      // 0x06
  26.     AT_RATE_OK,                 // 0x07
  27.     TEMPERATURE,                // 0x08
  28.     VOLTAGE,                    // 0x09
  29.     CURRENT,                    // 0x0A
  30.     AVERAGE_CURRENT,            // 0x0B
  31.     MAX_ERROR,                  // 0x0C
  32.     RELATIVE_STATE_OF_CHARGE,   // 0x0D
  33.     ABSOLUTE_STATE_OF_CHARGE,   // 0x0E
  34.     REMAINING_CAPACITY,         // 0x0F
  35.     FULL_CHARGE_CAPACITY,       // 0x10
  36.     RUN_TIME_TO_EMPTY,          // 0x11
  37.     AVERAGE_TIME_TO_EMPTY,      // 0x12
  38.     AVERAGE_TIME_TO_FULL,       // 0x13
  39.     CHARGING_CURRENT,           // 0x14
  40.     CHARGING_VOLTAGE,           // 0x15
  41.     BATTERY_STATUS,             // 0x16
  42.     CYCLE_COUNT,                // 0x17
  43.     DESIGN_CAPACITY,            // 0x18
  44.     DESIGN_VOLTAGE,             // 0x19
  45.     SPECIFICATION_INFO,         // 0x1A
  46.     MANUFACTURER_DATE,          // 0x1B
  47.     SERIAL_NUMBER,              // 0x1C
  48.     RESERVED1,                  // 0x1D
  49.     RESERVED2,                  // 0x1E
  50.     RESERVED3,                  // 0x1F
  51.     MANUFACTURER_NAME,          // 0x20
  52.     DEVICE_NAME,                // 0x21
  53.     DEVICE_CHEMISTRY,           // 0x22
  54.     MANUFACTURER_DATA           // 0x23
  55. };

  56. #define BITRATE_HZ                  25000
  57. #define ACK_ADDRESS                 0x02
  58. #define AUTO_RESPOND                FALSE
  59. #define WRITE_TIMEOUT_MS            1000
  60. #define READ_TIMEOUT_MS             1000
  61. #define TRANSFER_RETRIES            0
  62. #define SCL_LOW_TIMEOUT             TRUE
  63. #define RESPONSE_TIMEOUT_MS         1000

  64. #define CHARGER_SLAVE_ADDRESS_W     0x12
  65. #define BATTERY_SLAVE_ADDRESS_W     0x16

  66. int main(int argc, char* argv[])
  67. {
  68.     HID_SMBUS_DEVICE    m_hidSmbus;
  69.     BYTE                buffer[HID_SMBUS_MAX_READ_RESPONSE_SIZE];
  70.     BYTE                targetAddress[16];

  71.     // Open device
  72.     if(SMBus_Open(&m_hidSmbus) != 0)
  73.     {
  74.         fprintf(stderr,"ERROR: Could not open device.\r\n");
  75.         SMBus_Close(m_hidSmbus);
  76.         return -1;
  77.     }
  78.     fprintf(stderr,"Device successfully opened.\r\n");

  79.     // Configure device
  80.     if(SMBus_Configure(m_hidSmbus, BITRATE_HZ, ACK_ADDRESS, AUTO_RESPOND, WRITE_TIMEOUT_MS, READ_TIMEOUT_MS, SCL_LOW_TIMEOUT, TRANSFER_RETRIES, RESPONSE_TIMEOUT_MS) != 0)
  81.     {
  82.         fprintf(stderr,"ERROR: Could not configure device.\r\n");
  83.         SMBus_Close(m_hidSmbus);
  84.         return -1;
  85.     }
  86.     fprintf(stderr,"Device successfully configured.\r\n");

  87.     // Voltage [0x09]
  88.     targetAddress[0] = VOLTAGE;
  89.     if (SMBus_Read(m_hidSmbus, buffer, BATTERY_SLAVE_ADDRESS_W, sbsCommandResponseLength[VOLTAGE], 1, targetAddress) != sbsCommandResponseLength[VOLTAGE])
  90.     {
  91.         fprintf(stderr,"ERROR: Could not perform SMBus read.\r\n");
  92.         SMBus_Close(m_hidSmbus);
  93.         return -1;
  94.     }
  95.     UINT16 voltage_mV = (buffer[1] << 8) | buffer[0];
  96.     fprintf(stderr, "Voltage = %d mV\r\n", voltage_mV);

  97.     // Current [0x0A]
  98.     targetAddress[0] = CURRENT;
  99.     if (SMBus_Read(m_hidSmbus, buffer, BATTERY_SLAVE_ADDRESS_W, sbsCommandResponseLength[CURRENT], 1, targetAddress) != sbsCommandResponseLength[CURRENT])
  100.     {
  101.         fprintf(stderr,"ERROR: Could not perform SMBus read.\r\n");
  102.         SMBus_Close(m_hidSmbus);
  103.         return -1;
  104.     }
  105.     INT16 current_mA = (buffer[1] << 8) | buffer[0];
  106.     fprintf(stderr, "Current = %d mA\r\n", current_mA);

  107.     // Relative State of Charge [0x0D]
  108.     targetAddress[0] = RELATIVE_STATE_OF_CHARGE;
  109.     if (SMBus_Read(m_hidSmbus, buffer, BATTERY_SLAVE_ADDRESS_W, sbsCommandResponseLength[RELATIVE_STATE_OF_CHARGE], 1, targetAddress) != sbsCommandResponseLength[RELATIVE_STATE_OF_CHARGE])
  110.     {
  111.         fprintf(stderr,"ERROR: Could not perform SMBus read.\r\n");
  112.         SMBus_Close(m_hidSmbus);
  113.         return -1;
  114.     }
  115.     BYTE rsoc = buffer[0];
  116.     fprintf(stderr, "RSOC = %d %%\r\n", rsoc);

  117.     // Remaining Capacity [0x0F]
  118.     targetAddress[0] = REMAINING_CAPACITY;
  119.     if (SMBus_Read(m_hidSmbus, buffer, BATTERY_SLAVE_ADDRESS_W, sbsCommandResponseLength[REMAINING_CAPACITY], 1, targetAddress) != sbsCommandResponseLength[REMAINING_CAPACITY])
  120.     {
  121.         fprintf(stderr,"ERROR: Could not perform SMBus read.\r\n");
  122.         SMBus_Close(m_hidSmbus);
  123.         return -1;
  124.     }
  125.     UINT16 remCap = (buffer[1] << 8) | buffer[0];
  126.     fprintf(stderr, "Remaining Capacity = %d mAh\r\n", remCap);

  127.     // Average Time to Empty [0x12]
  128.     targetAddress[0] = AVERAGE_TIME_TO_EMPTY;
  129.     if (SMBus_Read(m_hidSmbus, buffer, BATTERY_SLAVE_ADDRESS_W, sbsCommandResponseLength[AVERAGE_TIME_TO_EMPTY], 1, targetAddress) != sbsCommandResponseLength[AVERAGE_TIME_TO_EMPTY])
  130.     {
  131.         fprintf(stderr,"ERROR: Could not perform SMBus read.\r\n");
  132.         SMBus_Close(m_hidSmbus);
  133.         return -1;
  134.     }
  135.     UINT16 avgTimeToEmpty = (buffer[1] << 8) | buffer[0];
  136.     fprintf(stderr, "Average Time to Empty = %d min(s)\r\n", avgTimeToEmpty);

  137.     // Manufacturer Name [0x20]
  138.     targetAddress[0] = MANUFACTURER_NAME;
  139.     if (SMBus_Read(m_hidSmbus, buffer, BATTERY_SLAVE_ADDRESS_W, sbsCommandResponseLength[MANUFACTURER_NAME], 1, targetAddress) < 1)
  140.     {
  141.         fprintf(stderr,"ERROR: Could not perform SMBus read.\r\n");
  142.         SMBus_Close(m_hidSmbus);
  143.         return -1;
  144.     }
  145.     fprintf(stderr, "Manufacturer Name = ");
  146.     // NOTE: Length of string is stored in first received byte
  147.     for(int i = 1; i < buffer[0] + 1; i++)
  148.     {
  149.         fprintf(stderr, "%c", buffer[i]);
  150.     }
  151.     fprintf(stderr, "\r\n");

  152.     // Check if charger is present
  153.     // Charger Status [0x13]
  154.     targetAddress[0] = 0x13;
  155.     if (SMBus_Read(m_hidSmbus, buffer, CHARGER_SLAVE_ADDRESS_W, 2, 1, targetAddress) != 2)
  156.     {
  157.         fprintf(stderr, "ERROR: Could not perform SMBus read.\r\n");
  158.         SMBus_Close(m_hidSmbus);
  159.         return -1;
  160.     }
  161.     UINT16 chargerStatus = (buffer[1] << 8) | buffer[0];
  162.     if (chargerStatus & 0x8000)
  163.     {
  164.         fprintf(stderr, "Charger connected.\r\n");
  165.     }
  166.     else
  167.     {
  168.         fprintf(stderr, "Charger NOT connected.\r\n");
  169.     }

  170.     // Success
  171.     fprintf(stderr, "Done! Exiting...\r\n");
  172.     SMBus_Close(m_hidSmbus);
  173.     return 0;
  174. }
复制代码


知识到用的时候才恨少,感觉到被有知识的大佬降维打击






BQ20Z955,艰难的笔记本电池解锁,终于解决:https://www.mydigit.cn/forum.php?mod=viewthread&tid=265242

尝试低成本解锁ThinkPad笔记本电池:https://www.mydigit.cn/forum.php?mod=viewthread&tid=256068

打赏

参与人数 1家元 +50 收起 理由
家睦 + 50

查看全部打赏

发表于 2021-7-3 22:49:35 | 显示全部楼层
能读不能写也不行吧?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-7-3 23:01:32 | 显示全部楼层
大师们,救救我 doutub_img.png
回复 支持 反对

使用道具 举报

发表于 2021-7-4 07:56:14 来自手机浏览器 | 显示全部楼层
要先解封芯片吧
回复 支持 反对

使用道具 举报

发表于 2021-7-4 08:09:53 | 显示全部楼层
我 的惠普的是美信的芯片不知道能不能解锁
回复 支持 反对

使用道具 举报

发表于 2021-7-4 09:18:26 | 显示全部楼层
那个板华硕的电池可以吗?
回复 支持 反对

使用道具 举报

发表于 2021-7-4 10:45:28 | 显示全部楼层
刚把联想的X200容量恢复了。查芯片的数据手册,有读寄存器数据指令的。我看3060介绍是需要芯片在完全控制状态才能改写,需要读出密码,然后用指令00写入,我的是8030芯片是厂家定制的,所以开始用ACCP读不到密码。后来买了2112小板用BE2Works搞的。2112改写了PID和VID难道不能改回来么?用芯片厂家的组态程序,FT232RL什么的多可以修改回来
回复 支持 反对

使用道具 举报

发表于 2021-7-4 11:30:06 | 显示全部楼层
解锁你得有datasheet,知道命令啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-7-4 12:58:45 | 显示全部楼层
飞人18 发表于 2021-7-4 10:45
刚把联想的X200容量恢复了。查芯片的数据手册,有读寄存器数据指令的。我看3060介绍是需要芯片在完全控制状 ...

它otp了就改不动了,一次性烧录,无解,除非破解了软件,可是我没那个本事,只好再买一只小板,花的钱可以买个新电池了
回复 支持 反对

使用道具 举报

发表于 2021-7-8 22:25:04 | 显示全部楼层
拆电芯用吧、
回复 支持 反对

使用道具 举报

发表于 2021-7-8 23:34:14 | 显示全部楼层
如果没有BQ20Z955的资料,没法用指令来解锁吧,可以让其他网友读取一份没锁的固件写上,或者自己研究bin修改
回复 支持 反对

使用道具 举报

发表于 2021-10-15 02:32:51 来自手机浏览器 | 显示全部楼层
飞人18 发表于 2021-7-4 10:45
刚把联想的X200容量恢复了。查芯片的数据手册,有读寄存器数据指令的。我看3060介绍是需要芯片在完全控制状 ...

大神我也想修一下我的电池能不能发给我个Be2works破解版呢?
回复 支持 1 反对 0

使用道具 举报

发表于 2022-4-6 11:16:11 | 显示全部楼层
学习,感谢楼主分享。
回复 支持 反对

使用道具 举报

发表于 2022-4-8 17:58:09 | 显示全部楼层
命令行是怎么学的呢?我曾经学过四五天,但是很难摸到头绪,最后不得不放弃了。
回复 支持 反对

使用道具 举报

发表于 2022-5-19 23:02:02 | 显示全部楼层
拆电芯做充电宝吧。。太难了。。都可以买个新电池了。。而且每款电池用的芯片不一样。不是通吃啊。学了没用
回复 支持 反对

使用道具 举报

发表于 2022-5-29 07:20:36 来自手机浏览器 | 显示全部楼层
fangyinghh 发表于 2021-7-4 12:58
它otp了就改不动了,一次性烧录,无解,除非破解了软件,可是我没那个本事,只好再买一只小板,花的钱可 ...

打个补丁,cp2112就可以用了
回复 支持 反对

使用道具 举报

发表于 2022-6-20 08:55:43 | 显示全部楼层
sunbester 发表于 2022-5-29 07:20
打个补丁,cp2112就可以用了

打什么补丁呢?
回复 支持 反对

使用道具 举报

发表于 2022-10-19 23:59:59 | 显示全部楼层
软件下载不了啊。能不能给发个软件。谢谢。
回复 支持 反对

使用道具 举报

发表于 2023-3-9 09:18:30 | 显示全部楼层
sunbester 发表于 2022-5-29 07:20
打个补丁,cp2112就可以用了

我也遇到了同样问题,昨晚2112还可以访问电池,第二天be2works就找不到目标板了。用小板芯片厂商的软件能看到小板,好像设备管理器中驱动显示就不一样了,该怎么做呢???
回复 支持 反对

使用道具 举报

发表于 2023-3-13 19:32:00 | 显示全部楼层
用电芯做个充电宝,很好用
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-4-27 10:29 , Processed in 0.218400 second(s), 14 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

快速回复 返回顶部 返回列表