Skip to content

Commit

Permalink
Merge pull request #34 from dalathegreat/bugfix/P3196-dtc
Browse files Browse the repository at this point in the history
Bugfix: P3196 on ZE0
  • Loading branch information
dalathegreat committed Jun 17, 2024
2 parents b03b363 + b07b648 commit 24392a9
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 45 deletions.
67 changes: 62 additions & 5 deletions Software/CANBRIDGE-2port/source/Src/can-bridge-firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ static volatile uint8_t battery_soc = 0;
static volatile int16_t dash_soc = 0;
static volatile uint8_t swap_5c0_idx = 0;
static volatile uint8_t VCM_WakeUpSleepCommand = 0;
static volatile uint8_t Byte2_50B = 0;
static volatile uint8_t ALU_question = 0;
static volatile uint8_t cmr_idx = QUICK_CHARGE;
static volatile uint16_t GIDS = 0;
Expand All @@ -69,6 +70,7 @@ static volatile uint8_t alternate_5bc = 0; // for 2011 battery swap
static volatile uint8_t seen_1da = 0; // for 2011 battery swap
static volatile uint8_t seconds_without_1f2 = 0; // bugfix: 0x603/69C/etc. isn't sent upon charge start on the gen1 Leaf, so we need to trigger our reset on a simple absence of messages
static volatile uint16_t startup_counter_1DB = 0;
static volatile uint8_t startup_counter_39X = 0;
// bits 10 10 4 8 7 1 3 (2 space) 1 5 13
static Leaf_2011_5BC_message swap_5bc_remaining = {.LB_CAPR = 0x12C, .LB_FULLCAP = 0x32, .LB_CAPSEG = 0, .LB_AVET = 50, .LB_SOH = 99, .LB_CAPSW = 0, .LB_RLIMIT = 0, .LB_CAPBALCOMP = 1, .LB_RCHGTCON = 0x09, .LB_RCHGTIM = 0};
static Leaf_2011_5BC_message swap_5bc_full = {.LB_CAPR = 0x12C, .LB_FULLCAP = 0x32, .LB_CAPSEG = 12, .LB_AVET = 50, .LB_SOH = 99, .LB_CAPSW = 1, .LB_RLIMIT = 0, .LB_CAPBALCOMP = 1, .LB_RCHGTCON = 0x09, .LB_RCHGTIM = 0};
Expand All @@ -94,6 +96,9 @@ static CAN_FRAME swap_605_message = {.ID = 0x605, .dlc = 1, .ide = 0, .rtr = 0,
static CAN_FRAME swap_607_message = {.ID = 0x607, .dlc = 1, .ide = 0, .rtr = 0, .data = {0}};
static CAN_FRAME AZE0_45E_message = {.ID = 0x45E, .dlc = 1, .ide = 0, .rtr = 0, .data = {0x00}};
static CAN_FRAME AZE0_481_message = {.ID = 0x481, .dlc = 2, .ide = 0, .rtr = 0, .data = {0x40,0x00}};
volatile static uint8_t PRUN_39X = 0;
static CAN_FRAME AZE0_390_message = {.ID = 0x390, .dlc = 8, .ide = 0, .rtr = 0, .data = {0x04,0x00,0x00,0x00,0x00,0x80,0x3c,0x07}}; // Sending removes P3196
static CAN_FRAME AZE0_393_message = {.ID = 0x393, .dlc = 8, .ide = 0, .rtr = 0, .data = {0x00,0x10,0x00,0x00,0x20,0x00,0x00,0x02}}; // Sending removes P3196


static uint8_t crctable[256] = {0,133,143,10,155,30,20,145,179,54,60,185,40,173,167,34,227,102,108,233,120,253,247,114,80,213,223,90,203,78,68,193,67,198,204,73,216,93,87,210,240,117,127,250,107,238,228,97,160,37,47,170,59,190,180,49,19,150,156,25,136,13,7,130,134,3,9,140,29,152,146,23,53,176,186,63,174,43,33,164,101,224,234,111,254,123,113,244,214,83,89,220,77,200,194,71,197,64,74,207,94,219,209,84,118,243,249,124,237,104,98,231,38,163,169,44,189,56,50,183,149,16,26,159,14,139,129,4,137,12,6,131,18,151,157,24,58,191,181,48,161,36,46,171,106,239,229,96,241,116,126,251,217,92,86,211,66,199,205,72,202,79,69,192,81,212,222,91,121,252,246,115,226,103,109,232,41,172,166,35,178,55,61,184,154,31,21,144,1,132,142,11,15,138,128,5,148,17,27,158,188,57,51,182,39,162,168,45,236,105,99,230,119,242,248,125,95,218,208,85,196,65,75,206,76,201,195,70,215,82,88,221,255,122,112,245,100,225,235,110,175,42,32,165,52,177,187,62,28,153,147,22,135,2,8,141};
Expand All @@ -103,7 +108,8 @@ void calc_crc8(CAN_FRAME *frame);
void reset_state(void);
void convert_5bc_to_array(Leaf_2011_5BC_message * src, uint8_t * dest);
void convert_5c0_to_array(Leaf_2011_5C0_message * src, uint8_t * dest);
void calc_sum4(CAN_FRAME *frame);
void calc_sum2(CAN_FRAME *frame);
void calc_checksum4(CAN_FRAME *frame);

void convert_array_to_5bc(Leaf_2011_5BC_message * dest, uint8_t * src)
{
Expand All @@ -127,6 +133,8 @@ void calc_crc8(CAN_FRAME *frame)
void reset_state(void)
{
charging_state = 0; //Reset charging state
startup_counter_1DB = 0;
startup_counter_39X = 0;
}

void convert_5bc_to_array(Leaf_2011_5BC_message * src, uint8_t * dest)
Expand Down Expand Up @@ -154,7 +162,7 @@ void convert_5c0_to_array(Leaf_2011_5C0_message * src, uint8_t * dest)
}


void calc_sum4(CAN_FRAME *frame)
void calc_sum2(CAN_FRAME *frame)
{
uint8_t sum = 0;

Expand All @@ -168,6 +176,16 @@ void calc_sum4(CAN_FRAME *frame)
frame->data[7] = (frame->data[7] & 0xF0) + sum;
}

void calc_checksum4(CAN_FRAME *frame){ // Checksum. Sum of all nibbles (-4). End result in hex is anded with 0xF.
uint8_t sum = 0;
for(uint8_t m = 0; m < 7; m++){
sum += frame->data[m] >> 4; // Add the upper nibble
sum += frame->data[m] & 0x0F; // Add the lower nibble
}
sum = (sum - 4) & 0x0F; // Subtract 4 and AND with 0xF to get the checksum
frame->data[7] = (frame->data[7] & 0xF0) + sum; // Place the checksum in the lower nibble of data[7]
}


void one_second_ping( void )
{
Expand Down Expand Up @@ -320,7 +338,8 @@ void can_handler(uint8_t can_bus, CAN_FRAME *frame)
case 0x50B:

VCM_WakeUpSleepCommand = (frame->data[3] & 0xC0) >> 6;

Byte2_50B = frame->data[2];

if( My_Leaf == MY_LEAF_2011 )
{
CANMASK = (frame->data[2] & 0x04) >> 2;
Expand All @@ -337,6 +356,45 @@ void can_handler(uint8_t can_bus, CAN_FRAME *frame)
PushCan(battery_can_bus, CAN_TX, &ZE1_625_message); // 100ms
PushCan(battery_can_bus, CAN_TX, &ZE1_5C5_message); // 100ms
PushCan(battery_can_bus, CAN_TX, &ZE1_3B8_message); // 100ms

if( My_Leaf == MY_LEAF_2011 ) // ZE0 OBC messages wont satisfy the battery. Send 2013+ PDM messages towards it!
{

if(startup_counter_39X < 250){
startup_counter_39X++;
}
AZE0_390_message.data[0] = 0x04;
AZE0_390_message.data[3] = 0x00;
AZE0_390_message.data[5] = 0x80;
AZE0_390_message.data[6] = 0x3C;
AZE0_393_message.data[1] = 0x10;

if(startup_counter_39X > 13){
AZE0_390_message.data[3] = 0x02;
AZE0_390_message.data[6] = 0x00;
AZE0_393_message.data[1] = 0x20;
}
if(startup_counter_39X > 15){
AZE0_390_message.data[3] = 0x03;
AZE0_390_message.data[6] = 0x00;
}
if((startup_counter_39X > 20) && (Byte2_50B == 0)){ //Shutdown
AZE0_390_message.data[0] = 0x08;
AZE0_390_message.data[3] = 0x01;
AZE0_390_message.data[5] = 0x90;
AZE0_390_message.data[6] = 0x00;
AZE0_393_message.data[1] = 0x70;
}

PRUN_39X = (PRUN_39X + 1) % 3;
AZE0_390_message.data[7] = (uint8_t)(PRUN_39X << 4);
AZE0_393_message.data[7] = (uint8_t)(PRUN_39X << 4);
calc_checksum4(&AZE0_390_message);
calc_checksum4(&AZE0_393_message);

PushCan(battery_can_bus, CAN_TX, &AZE0_390_message); // 100ms
PushCan(battery_can_bus, CAN_TX, &AZE0_393_message); // 100ms
}

content_3B8++;
if (content_3B8 > 14)
Expand Down Expand Up @@ -723,7 +781,7 @@ void can_handler(uint8_t can_bus, CAN_FRAME *frame)
{
// Only for 40/62kWh packs retrofitted to ZE0
frame->data[3] = 0xA0; // Change from gen1->gen4+ . But doesn't seem to help much. We fix it anyways.
calc_sum4(frame);
calc_sum2(frame);
}

}
Expand All @@ -746,7 +804,6 @@ void can_handler(uint8_t can_bus, CAN_FRAME *frame)
case 0x68C:
case 0x603:
reset_state(); // Reset all states, vehicle is starting up
startup_counter_1DB = 0;
PushCan(battery_can_bus, CAN_TX, &swap_605_message); // Send these ZE1 messages towards battery
PushCan(battery_can_bus, CAN_TX, &swap_607_message);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ volatile uint16_t battery_soc_pptt = 0;

volatile uint8_t swap_idx = 0;
volatile uint8_t swap_5c0_idx = 0;
volatile uint8_t startup_counter = 0; //counts number of 10ms frames since startup
volatile uint8_t VCM_WakeUpSleepCommand = 0;
volatile uint8_t Byte2_50B = 0;
volatile uint8_t ALU_question = 0;
volatile uint8_t cmr_idx = QUICK_CHARGE;

Expand All @@ -76,6 +76,7 @@ volatile uint8_t seconds_without_1f2 = 0; //bugfix: 0x603/69C/etc. isn't sent
volatile uint8_t main_battery_temp = 0;
volatile uint8_t battery_can_bus = 2; //keeps track on which CAN bus the battery talks.
volatile uint16_t startup_counter_1DB = 0;
volatile uint8_t startup_counter_39X = 0;
//timer variables
volatile uint16_t sec_timer = 1; //actually the same as ms_timer but counts down from 1000

Expand Down Expand Up @@ -104,7 +105,10 @@ static can_frame_t swap_605_message = {.can_id = 0x605, .can_dlc = 1, .data =
static can_frame_t swap_607_message = {.can_id = 0x607, .can_dlc = 1, .data = {0}};
static can_frame_t AZE0_45E_message = {.can_id = 0x45E, .can_dlc = 1, .data = {0x00}};
static can_frame_t AZE0_481_message = {.can_id = 0x481, .can_dlc = 2, .data = {0x40,0x00}};
volatile uint8_t PRUN_39X = 0;

static can_frame_t AZE0_390_message = {.can_id = 0x390, .can_dlc = 8, .data = {0x04,0x00,0x00,0x00,0x00,0x80,0x3c,0x07}}; // Sending removes P3196
static can_frame_t AZE0_393_message = {.can_id = 0x393, .can_dlc = 8, .data = {0x00,0x10,0x00,0x00,0x20,0x00,0x00,0x02}}; // Sending removes P3196

void hw_init(void){
uint8_t caninit;
Expand Down Expand Up @@ -200,8 +204,9 @@ void hw_init(void){
}

void reset_state(){
startup_counter = 0; //car starting, reset startup counter for 1dc
charging_state = 0; //Reset charging state
startup_counter_1DB = 0;
startup_counter_39X = 0;
}

int main(void){
Expand Down Expand Up @@ -411,40 +416,10 @@ void can_handler(uint8_t can_bus){
My_Leaf = MY_LEAF_2011;
}
break;
case 0x1DC:

if (startup_counter == 0)
{
frame.data[0] = 0xFF;
frame.data[1] = 0xFF;
frame.data[2] = 0xFF;
frame.data[3] = 0xFF;
frame.data[4] = 0x1F;
frame.data[5] = 0xFF;
frame.data[6] = 0xFC;
}
else if (startup_counter < 7)
{
frame.data[0] = 0xFF;
frame.data[1] = 0xFF;
frame.data[2] = 0xFF;
frame.data[3] = 0xFF;
}
else
{
//we are started up! let messages thru as they are
}

if (startup_counter < 255)
{
startup_counter++;
}

calc_crc8(&frame);
break;
case 0x50B:

VCM_WakeUpSleepCommand = (frame.data[3] & 0xC0) >> 6;
Byte2_50B = frame.data[2];

if( My_Leaf == MY_LEAF_2011 )
{
Expand All @@ -462,10 +437,45 @@ void can_handler(uint8_t can_bus){
send_can(battery_can_bus, ZE1_5C5_message); // 100ms
send_can(battery_can_bus, ZE1_3B8_message); // 100ms

content_3B8 = (content_3B8 + 1) % 15;
//This takes advantage of the modulus operator % to reset the value of content_3B8 to 0 once it reaches 15.
//It also eliminates the need for an if statement and a conditional check, which improves performance (but sacrifices readability)
if( My_Leaf == MY_LEAF_2011 ) // ZE0 OBC messages wont satisfy the battery. Send 2013+ PDM messages towards it!
{

if(startup_counter_39X < 250){
startup_counter_39X++;
}
AZE0_390_message.data[0] = 0x04;
AZE0_390_message.data[3] = 0x00;
AZE0_390_message.data[5] = 0x80;
AZE0_390_message.data[6] = 0x3C;
AZE0_393_message.data[1] = 0x10;

if(startup_counter_39X > 13){
AZE0_390_message.data[3] = 0x02;
AZE0_390_message.data[6] = 0x00;
AZE0_393_message.data[1] = 0x20;
}
if(startup_counter_39X > 15){
AZE0_390_message.data[3] = 0x03;
AZE0_390_message.data[6] = 0x00;
}
if((startup_counter_39X > 20) && (Byte2_50B == 0)){ //Shutdown
AZE0_390_message.data[0] = 0x08;
AZE0_390_message.data[3] = 0x01;
AZE0_390_message.data[5] = 0x90;
AZE0_390_message.data[6] = 0x00;
AZE0_393_message.data[1] = 0x70;
}

PRUN_39X = (PRUN_39X + 1) % 3;
AZE0_390_message.data[7] = (PRUN_39X << 4);
AZE0_393_message.data[7] = (PRUN_39X << 4);
calc_checksum4(&AZE0_390_message);
calc_checksum4(&AZE0_393_message);
send_can(battery_can_bus, AZE0_390_message); // 100ms
send_can(battery_can_bus, AZE0_393_message); // 100ms
}

content_3B8 = (content_3B8 + 1) % 15;
ZE1_3B8_message.data[2] = content_3B8; // 0 - 14 (0x00 - 0x0E)

if (flip_3B8)
Expand Down Expand Up @@ -769,7 +779,7 @@ void can_handler(uint8_t can_bus){
{
// Only for 40/62kWh packs retrofitted to ZE0
frame.data[3] = 0xA0; // Change from gen1->gen4+ . But doesn't seem to help much. We fix it anyways.
calc_sum4(&frame);
calc_sum2(&frame);
}

}
Expand All @@ -794,7 +804,7 @@ void can_handler(uint8_t can_bus){
case 0x68C:
case 0x603:
reset_state(); // Reset all states, vehicle is starting up
startup_counter_1DB = 0;

send_can(battery_can_bus, swap_605_message); // Send these ZE1 messages towards battery
send_can(battery_can_bus, swap_607_message);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void calc_crc8(can_frame_t *frame){
(*frame).data[7] = crc;
}

void calc_sum4(can_frame_t *frame){
void calc_sum2(can_frame_t *frame){ // Checksum. All message nibbles summed together, plus 2. End result in hex is anded with 0xF.
uint8_t sum = 0;
for(uint8_t i = 0; i < 7; i++){
sum += (*frame).data[i] >> 4;
Expand All @@ -25,6 +25,15 @@ void calc_sum4(can_frame_t *frame){
(*frame).data[7] = ((*frame).data[7] & 0xF0) + sum;
}

void calc_checksum4(can_frame_t *frame){ // Checksum. Sum of all nibbles (-4). End result in hex is anded with 0xF.
uint8_t sum = 0;
for(uint8_t i = 0; i < 7; i++){
sum += (*frame).data[i] >> 4; // Add the upper nibble
sum += (*frame).data[i] & 0x0F; // Add the lower nibble
}
sum = (sum - 4) & 0x0F; // Subtract 4 and AND with 0xF to get the checksum
(*frame).data[7] = ((*frame).data[7] & 0xF0) + sum; // Place the checksum in the lower nibble of data[7]
}

void convert_5bc_to_array(volatile Leaf_2011_5BC_message * src, uint8_t * dest){
dest[0] = (uint8_t) (src->LB_CAPR >> 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ void int_to_3digit(int num, char * buffer);
void int_to_4digit_nodec(int num, char * buffer);
void int_to_hex(char * str, int num);
void calc_crc8(can_frame_t *frame);
void calc_sum4(can_frame_t *frame);
void calc_sum2(can_frame_t *frame);
void calc_checksum4(can_frame_t *frame);
void convert_5bc_to_array(volatile Leaf_2011_5BC_message * src, uint8_t * dest);
void convert_array_to_5bc(volatile Leaf_2011_5BC_message * dest, uint8_t * src);
void convert_5c0_to_array(volatile Leaf_2011_5C0_message * src, uint8_t * dest);

0 comments on commit 24392a9

Please sign in to comment.