The 230JT..... code? I didn't see it anywhere on the PCB but it is a plain text string in the eeprom. or am i looking at the wrong place in LS?From the LS screen:
The 2.1 million Amps was promising
Also the VIN was showing back as an ASCII string from the eeprom dump. Is that the part number printed on the circuit board?
Hx represents battery conductance (inverse of resistance) per LeafSpy, and as such is not a percentage.The 3rd set of 4 bytes is also a percentage, math is uint32 / 1024 = Percent x 100. Possibly HX? It is set to 100.00% when the eeprom is reset but both my bin and the 30kwh bin shows a higher number than the initial value, and my 24kwh eeprom is significantly higher than the 32kwh eeprom which might make sense if its HX. Unconfirmed, just thinking out loud
void possiblyCrypto1?(void)
{
bool bVar1;
int iVar2;
ushort uVar3;
undefined1 *puVar4;
undefined1 *puVar5;
undefined1 *puVar6;
DAT_03ffc470 = 0x61;
DAT_03ffc471 = 0x65;
puVar5 = &DAT_03ffc472;
uVar3 = 0;
puVar4 = &DAT_03ffb9fc;
do {
*puVar5 = puVar4[3];
puVar5[1] = puVar4[2];
puVar5[2] = puVar4[1];
puVar5[3] = *puVar4;
puVar5[4] = puVar4[7];
puVar5[5] = puVar4[6];
puVar5[6] = puVar4[5];
puVar5[7] = puVar4[4];
puVar5[8] = puVar4[0xb];
puVar5[9] = puVar4[10];
uVar3 = uVar3 + 1;
puVar5[10] = puVar4[9];
puVar6 = puVar4 + 8;
puVar4 = puVar4 + 0xc;
puVar5[0xb] = *puVar6;
puVar5 = puVar5 + 0xc;
} while (uVar3 < 10);
iVar2 = 2;
puVar4 = &DAT_03ffba74;
do {
puVar6 = puVar5;
*puVar6 = puVar4[3];
puVar6[1] = puVar4[2];
puVar6[2] = puVar4[1];
puVar6[3] = *puVar4;
puVar6[4] = puVar4[7];
puVar6[5] = puVar4[6];
puVar6[6] = puVar4[5];
puVar6[7] = puVar4[4];
puVar6[8] = puVar4[0xb];
puVar6[9] = puVar4[10];
puVar6[10] = puVar4[9];
puVar6[0xb] = puVar4[8];
puVar6[0xc] = puVar4[0xf];
puVar6[0xd] = puVar4[0xe];
puVar6[0xe] = puVar4[0xd];
puVar5 = puVar4 + 0xc;
puVar4 = puVar4 + 0x10;
puVar6[0xf] = *puVar5;
bVar1 = iVar2 != 1;
iVar2 = iVar2 + -1;
puVar5 = puVar6 + 0x10;
} while (bVar1);
puVar6[0x10] = DAT_03ffba97;
puVar6[0x11] = DAT_03ffba96;
puVar6[0x12] = DAT_03ffba95;
puVar6[0x13] = DAT_03ffba94;
puVar6[0x14] = DAT_03ffba98._3_1_;
puVar6[0x15] = DAT_03ffba98._2_1_;
puVar6[0x16] = DAT_03ffba98._1_1_;
puVar6[0x17] = (undefined)DAT_03ffba98;
puVar6[0x18] = DAT_03ffba9c._3_1_;
puVar6[0x19] = DAT_03ffba9c._2_1_;
puVar6[0x1a] = DAT_03ffba9c._1_1_;
puVar6[0x1b] = (undefined)DAT_03ffba9c;
return;
}
Maybe that is the battery serial number, along the lines of Group 84 found in Dala's guide:The 230JT1125... code
Group 84
Name: Battery Serial
Type: String
Description: Battery serial number
Query:
0x79B 02 21 84 00 00 00 00 00;length,Pid,Group
0x79B 30 00 00 00 00 00 00 00; request more time
Answer:
0x7BB 10 16 61 84 32 33 30 55;reply,len,P,G,data
0x7BB 21 4B 31 31 39 32 45 30;2nd line reply, data
0x7BB 22 30 31 34 38 32 20 A0; 3rd "
0x7BB 23 00 00 00 00 00 00 00; 4th "
Formula: (323330554b313139324530303134383220A0).decode(’utf-8’)
undefined4 PID27_65(char param_1)
{
undefined4 uVar1;
if (DAT_03ffe371 == -0x40) {
if ((CAN_Process_State_Machine_Flag & 4) == 0) {
if ((Can_TX_Buffer_Byte_1 == 2) && (param_1 == 'e')) {
if (((CAN_Process_State_Machine_Flag & 0x20) == 0) && (Pid27_65_Timeout_Counter == 0)) {
uVar1 = GeneratePID27_65_Seed();
CAN_Process_State_Machine_Flag = CAN_Process_State_Machine_Flag | 0x20;
Can_TX_Buffer_Byte_5 = (undefined)((uint)uVar1 >> 0x10);
Can_TX_Buffer_Byte_2 = 0x67;
Can_TX_Buffer_Byte_4 = (undefined)((uint)uVar1 >> 0x18);
Can_TX_Buffer_Byte_3 = 0x65;
Can_TX_Buffer_Byte_6 = (undefined)((uint)uVar1 >> 8);
Can_TX_Buffer_Byte_7 = (undefined)uVar1;
Decypt_Seed(uVar1,&Decypted_Output_Array_Byte0);
return 6;
}
}
else {
if ((Can_TX_Buffer_Byte_1 != 10) || (param_1 != 0x66)) goto LAB_000157b4;
if ((CAN_Process_State_Machine_Flag & 0x20) != 0) {
Pid27_65_Timeout_Counter = 1000;
if (Decypted_Output_Array_Byte7 != CAN_RX_Buffer_Byte_10 ||
(Decypted_Output_Array_Byte6 != CAN_RX_Buffer_Byte_9 ||
(Decypted_Output_Array_Byte5 != CAN_RX_Buffer_Byte_8 ||
(Decypted_Output_Array_Byte4 != CAN_RX_Buffer_Byte_7 ||
(Decypted_Output_Array_Byte3 != CAN_RX_Buffer_Byte_6 ||
(Decypted_Output_Array_Byte2 != CAN_RX_Buffer_Byte_5 ||
(Decypted_Output_Array_Byte1 != CAN_RX_Buffer_Byte_4 ||
Decypted_Output_Array_Byte0 != CAN_RX_Buffer_Byte_3))))))) {
CAN_Process_State_Machine_Flag = CAN_Process_State_Machine_Flag & 0xdb;
Update_Can_TX_Buffer_2,3,4(0x27,0x35);
return 3;
}
Can_TX_Buffer_Byte_2 = 0x67;
Can_TX_Buffer_Byte_3 = 0x66;
CAN_Process_State_Machine_Flag = CAN_Process_State_Machine_Flag & 0xdf | 4;
Pid27_65_Timeout_Counter = 1000;
return 2;
}
}
}
Update_Can_TX_Buffer_2,3,4(0x27,0x22);
}
else {
LAB_000157b4:
Update_Can_TX_Buffer_2,3,4(0x27,0x12);
}
return 3;
}
#include <stdio.h>
#include <stdbool.h>
unsigned int FUN_0001539c(unsigned int param_1,unsigned int param_2)
{
bool bVar1;
unsigned int uVar2;
unsigned int uVar3;
unsigned int uVar4;
unsigned int uVar5;
unsigned int uVar6;
unsigned int uVar7;
unsigned int uVar8;
unsigned int uVar9;
unsigned int uVar10;
unsigned int uVar11;
int iVar12;
param_1 = param_1 & 0xffff;
param_2 = param_2 & 0xffff;
uVar10 = 0xffff;
iVar12 = 2;
do {
uVar2 = param_2;
if ((param_1 & 1) == 1) {
uVar2 = param_1 >> 1;
}
uVar3 = param_2;
if ((param_1 >> 1 & 1) == 1) {
uVar3 = param_1 >> 2;
}
uVar4 = param_2;
if ((param_1 >> 2 & 1) == 1) {
uVar4 = param_1 >> 3;
}
uVar5 = param_2;
if ((param_1 >> 3 & 1) == 1) {
uVar5 = param_1 >> 4;
}
uVar6 = param_2;
if ((param_1 >> 4 & 1) == 1) {
uVar6 = param_1 >> 5;
}
uVar7 = param_2;
if ((param_1 >> 5 & 1) == 1) {
uVar7 = param_1 >> 6;
}
uVar11 = param_1 >> 7;
uVar8 = param_2;
if ((param_1 >> 6 & 1) == 1) {
uVar8 = uVar11;
}
param_1 = param_1 >> 8;
uVar9 = param_2;
if ((uVar11 & 1) == 1) {
uVar9 = param_1;
}
uVar10 = (((((((((((((((uVar10 & 0x7fff) << 1 ^ uVar2) & 0x7fff) << 1 ^ uVar3) & 0x7fff) << 1 ^
uVar4) & 0x7fff) << 1 ^ uVar5) & 0x7fff) << 1 ^ uVar6) & 0x7fff) << 1 ^ uVar7)
& 0x7fff) << 1 ^ uVar8) & 0x7fff) << 1 ^ uVar9;
bVar1 = iVar12 != 1;
iVar12 = iVar12 + -1;
} while (bVar1);
return uVar10;
}
unsigned int FUN_000152ee(unsigned int param_1,unsigned int param_2,unsigned int param_3)
{
return (param_3 ^ 0x780 | param_2 ^ 0x116) * ((param_1 & 0xffff) >> 8 ^ param_1 & 0xff) & 0xffff;
}
short FUN_0001532a(short param_1,short param_2)
{
unsigned short uVar1;
uVar1 = param_2 + param_1 * 0x5ba & 0xff;
return (uVar1 + param_1) * (uVar1 + param_2);
}
int FUN_00015354(int param_1,int param_2)
{
unsigned int uVar1;
param_1 = param_1 & 0xffff;
param_2 = param_2 & 0xffff;
uVar1 = param_2 & (param_1 | 0x5ba) & 0xf;
return ((int)param_1 >> uVar1 | param_1 << (0x10 - uVar1 & 0x1f)) *
(param_2 << uVar1 | (int)param_2 >> (0x10 - uVar1 & 0x1f)) & 0xffff;
}
int CyptAlgo(unsigned int param_1,unsigned int param_2,unsigned int param_3)
{
int uVar1;
int uVar2;
int iVar3;
int iVar4;
uVar1 = FUN_00015354(param_2,param_3);
uVar2 = FUN_0001532a(param_2,param_3);
uVar1 = FUN_000152ee(param_1,uVar1,uVar2);
uVar2 = FUN_000152ee(param_1,uVar2,uVar1);
iVar3 = FUN_0001539c(uVar1,0xffc4);
iVar4 = FUN_0001539c(uVar2,0xffc4);
return iVar4 + iVar3 * 0x10000;
}
void Decypt_Seed(unsigned int SeedInput,char *Crypt_Output_Buffer)
{
int uVar1;
int uVar2;
uVar1 = CyptAlgo(0x609,0xdd2,SeedInput >> 0x10);
uVar2 = CyptAlgo(SeedInput & 0xffff,SeedInput >> 0x10,0x609);
*Crypt_Output_Buffer = (char)uVar1;
Crypt_Output_Buffer[7] = (char)((unsigned int)uVar1 >> 0x18);
Crypt_Output_Buffer[3] = (char)((unsigned int)uVar1 >> 8);
Crypt_Output_Buffer[2] = (char)((unsigned int)uVar2 >> 8);
Crypt_Output_Buffer[5] = (char)((unsigned int)uVar1 >> 0x10);
Crypt_Output_Buffer[4] = (char)((unsigned int)uVar2 >> 0x10);
Crypt_Output_Buffer[1] = (char)uVar2;
Crypt_Output_Buffer[6] = (char)((unsigned int)uVar2 >> 0x18);
return;
}
unsigned char OutputArray[8];
int main() {
Decypt_Seed(0xAC573D0B,OutputArray);
for (int i = 0; i < 8; i++) {
printf("0x%02X ", OutputArray);
}
printf("\n");
return 0;
}
void PID31_03(void)
{
if (CAN_Process_Flag == -0x40) {
if ((CAN_Process_State_Machine_Flag & 4) == 0) {
Update_Can_TX_Buffer_2,3,4(0x31,0x33);
Can_TX_len = 3;
return;
}
if (Can_TX_Buffer_Byte_1 == 3) {
if (CAN_RX_Buffer_Byte_3 == '\0') {
SOHx100 = 10000;
SOHx100_volatile = 10000;
SOCx100 = 10000;
SOCx100_volatile = 10000;
DAT_03ffb2ab = DAT_03ffb2ab & 0xf9;
Can_TX_Buffer_Byte_2 = 0x71;
Can_TX_Buffer_Byte_3 = 3;
Can_TX_Buffer_Byte_4 = 1;
Can_TX_len = 3;
return;
}
if (CAN_RX_Buffer_Byte_3 == '\x01') {
Can_TX_Buffer_Byte_2 = 0x71;
Can_TX_Buffer_Byte_3 = 3;
Can_TX_Buffer_Byte_4 = 2;
Can_TX_len = 3;
return;
}
}
}
Update_Can_TX_Buffer_2,3,4(0x31,0x12);
Can_TX_len = 3;
return;
}
void CAN_PID_0x10(void)
{
undefined4 uVar1;
if (Can_TX_Buffer_Byte_1 == 2) {
if (0xbf < Can_RX_Buffer_Byte_2) {
if (Can_RX_Buffer_Byte_2 == 0xc0) {
if (CAN_Process_Flag == -0x10) {
CAN_Process_State_Machine_Flag = CAN_Process_State_Machine_Flag & 0xf5;
}
else if (CAN_Process_Flag == -0xf) {
CAN_Process_State_Machine_Flag = CAN_Process_State_Machine_Flag & 0xee;
}
DAT_03ffe370 = CAN_Process_Flag;
CAN_Process_Flag = -0x40;
Can_TX_Buffer_Byte_2 = 0x50;
Can_TX_Buffer_Byte_3 = 0xc0;
uVar1 = 2;
FUN_000150f8();
goto LAB_00001030;
}
for sure you can help dumping the memory content of the eeprom (probably the same as shown in previous pthotos in the thread).I have a BMS sitting around that came with a junkyard battery I bought last spring. My leaf is a 2011 and the batter came out of a later model(I think 2013) so I can’t even use it in my car for anything.
I have it torn apart for curiosity sake and have been thinking about doing exactly what is going on in this thread.
PM me if I can be of help.
If you have a USB-Can bus interface, and a 12v power supply there are a few tests you could runI have a BMS sitting around that came with a junkyard battery I bought last spring. My leaf is a 2011 and the batter came out of a later model(I think 2013) so I can’t even use it in my car for anything.
I have it torn apart for curiosity sake and have been thinking about doing exactly what is going on in this thread.
PM me if I can be of help.
Sorry, I'm again quite late to the party; many things going on at present.So in my case, my SOH is 37.75%, which is stored as 3775 in SOHx100_volatile. It is then multiplied by 0xC20B2 (this number pops up a lot in the firmware, now we know why) = 0xB2D620CE and passed to Function 00023678.
That ss from post #60 shows the VIN in the header, whereas when reading just the battery pack we saw a "?? serial number?" in the header that had digits stored on the eeprom. i found another battery pack read with what i think is the serial number in the header,And the matching leafspy screenshot
Enter your email address to join: