int sendControl(int c, int fileSize) { int size = 3 * sizeof(char) + sizeof(int); unsigned char * control = malloc(size); unsigned char * temp; temp = int32_to_byte(fileSize); control[0] = c; control[1] = 0; control[2] = 4; control[3] = temp[0]; control[4] = temp[1]; control[5] = temp[2]; control[6] = temp[3]; int i; for(i=0; i < size; i++ ) { toSend.buf[i] = control[i]; } toSend.length = size; llwrite(toSend); return 0; }
bool densoecu::listen_kernel() { unsigned char rsp; int datalen = szrxbuf; int i,addr,len; unsigned int crc; if (!dc->read_kernel_rsp_varlen(&rsp,rxbuf,&datalen)) return false; dump(rsp,rxbuf,datalen); // todo emulate kernel switch(rsp) { case kernel_cmd_get_version_info: if (!kernel_verify_command_length(datalen,0)) break; l->print(log_densoecu,"kernel get version info\n"); strcpy((char*)rxbuf,"OpenECU Kernel V0.01"); dc->write_kernel_rsp(kernel_rsp_get_version_info,rxbuf,(int)strlen((char*)rxbuf)); break; case kernel_rsp_get_version_info: l->print(log_densoecu,"kernel response version [%s]\n",rxbuf); break; case kernel_cmd_CRC_area: if (!kernel_verify_command_length(datalen,5)) break; addr = byte_to_int24(rxbuf); len = byte_to_int16(rxbuf+3); l->print(log_densoecu,"kernel crc32 area addr: %06X len %04X\n",addr,len); crc = crc32(rom+addr,len); l->print(log_densoecu,"crc32 result: %08X\n",crc); int32_to_byte(rxbuf,crc); dc->write_kernel_rsp(kernel_rsp_CRC_area,rxbuf,4); break; case kernel_rsp_CRC_area: if (!kernel_verify_command_length(datalen,4)) break; crc = byte_to_int32(rxbuf); l->print(log_densoecu,"kernel response crc32: %08X\n",crc); break; case kernel_cmd_read_area: if (!kernel_verify_command_length(datalen,5)) break; addr = byte_to_int24(rxbuf); len = byte_to_int16(rxbuf+3); l->print(log_densoecu,"kernel read area addr: %06X len %04X\n",addr,len); dc->write_kernel_rsp(kernel_rsp_read_area,rom+addr,len); break; case kernel_rsp_read_area: l->print(log_densoecu,"kernel response read area bytes: %04X\n",datalen); break; case kernel_cmd_read_programming_voltage: if (!kernel_verify_command_length(datalen,0)) break; l->print(log_densoecu,"kernel read programming voltage\n"); int16_to_byte(rxbuf,12*50); dc->write_kernel_rsp(kernel_rsp_read_programming_voltage,rxbuf,2); break; case kernel_rsp_read_programming_voltage: if (!kernel_verify_command_length(datalen,2)) break; l->print(log_densoecu,"kernel response programming voltage: %2.2lfV\n",byte_to_int16(rxbuf)/50.0); break; case kernel_cmd_flash_enable: if (!kernel_verify_command_length(datalen,0)) break; l->print(log_densoecu,"kernel flash enable\n"); kernel_flash_enabled = true; if (!listenmode) dc->write_kernel_rsp(kernel_rsp_flash_enable,NULL,0); break; case kernel_rsp_flash_enable: if (!kernel_verify_command_length(datalen,0)) break; l->print(log_densoecu,"kernel response flash enabled\n"); break; case kernel_cmd_flash_disable: if (!kernel_verify_command_length(datalen,0)) break; l->print(log_densoecu,"kernel flash disnable\n"); kernel_flash_enabled = false; if (!listenmode) dc->write_kernel_rsp(kernel_rsp_flash_disable,NULL,0); break; case kernel_rsp_flash_disable: if (!kernel_verify_command_length(datalen,0)) break; l->print(log_densoecu,"kernel response flash disabled\n"); break; case kernel_cmd_write_flash_buffer: if (datalen < 4) { l->print(log_densoecu,"kernel write flash buffer data length invalid!\n"); break; } addr = byte_to_int24(rxbuf); l->print(log_densoecu,"kernel write flash buffer addr:%06X len:%02X\n",addr,datalen-3); addr = addr % szpage4k; if (addr+datalen-3 > szpage4k) { l->print(log_densoecu,"simulation error!\n"); } else { memcpy(page4k+addr,rxbuf+3,datalen-3); if (!listenmode) dc->write_kernel_rsp(kernel_rsp_write_flash_buffer,NULL,0); } break; case kernel_rsp_write_flash_buffer: if (!kernel_verify_command_length(datalen,0)) break; l->print(log_densoecu,"kernel response write flash buffer OK\n"); break; case kernel_cmd_commit_flash_buffer: if (!kernel_verify_command_length(datalen,7)) break; addr = byte_to_int24(rxbuf); crc = byte_to_int32(rxbuf+3); l->print(log_densoecu,"kernel commit flash buffer addr:%06X crc:%08X\n",addr,crc); // verify crc if (crc != crc32(page4k,szpage4k)) { if (!listenmode) dc->write_kernel_rsp(kernel_rsp_error_bad_crc,NULL,0); break; } // do the full simulation of writing to flash for (i = 0; i < szpage4k; i++) { rom[addr+i] &= page4k[i]; // Vpp only turns 1's into 0's // todo: delay if (rom[addr+i] != page4k[i] || !kernel_flash_enabled) { if (!listenmode) dc->write_kernel_rsp(kernel_rsp_error_programming_failure,NULL,0); break; } } if (!listenmode) { delay(330); rxbuf[0] = 1; // flashed in 1 attempt dc->write_kernel_rsp(kernel_rsp_commit_flash_buffer,rxbuf,1); } break; case kernel_rsp_commit_flash_buffer: if (!kernel_verify_command_length(datalen,1)) break; l->print(log_densoecu,"kernel response commit flash buffer OK (%d pulses)\n",rxbuf[0]); break; case kernel_cmd_validate_flash_buffer: if (!kernel_verify_command_length(datalen,4)) break; crc = byte_to_int32(rxbuf); l->print(log_densoecu,"kernel validate flash buffer crc:%08X\n",crc); // verify crc if (crc != crc32(page4k,szpage4k)) { if (!listenmode) dc->write_kernel_rsp(kernel_rsp_error_bad_crc,NULL,0); break; } if (!listenmode) { delay(330); dc->write_kernel_rsp(kernel_rsp_validate_flash_buffer,NULL,0); } break; case kernel_rsp_validate_flash_buffer: if (!kernel_verify_command_length(datalen,0)) break; l->print(log_densoecu,"kernel response validate flash buffer OK )\n"); break; case kernel_cmd_blank_16k_page: if (!kernel_verify_command_length(datalen,3)) break; addr = byte_to_int24(rxbuf); l->print(log_densoecu,"kernel blank page addr:%06X \n",addr); if (kernel_flash_enabled) memset(rom+addr,0xFF,szpage); if (!listenmode) { delay(330); if (!kernel_flash_enabled) dc->write_kernel_rsp(kernel_rsp_error_programming_failure,NULL,0); else { rxbuf[0] = 1; // blanked in 1 attempt dc->write_kernel_rsp(kernel_rsp_blank_16k_page,rxbuf,1); } } break; case kernel_rsp_blank_16k_page: if (!kernel_verify_command_length(datalen,1)) break; l->print(log_densoecu,"kernel response blank page OK (%d pulses)\n",rxbuf[0]); break; default: if (!listenmode) dc->write_kernel_rsp(kernel_rsp_error_bad_command,NULL,0); break; } return true; }