fome-fw/firmware/config/engines/vw_b6.lua

476 lines
11 KiB
Lua

strncpy(config->luaScript, R"(
AIRBAG = 0x050
-- 1088
TCU_1 = 0x440
-- 1344
TCU_2 = 0x540
-- 1440
BRAKE_2 = 0x5A0
VWTP_OUT = 0x200
VWTP_IN = 0x202
VWTP_TESTER = 0x300
-- 640
MOTOR_1 = 0x280
-- 644
MOTOR_BRE = 0x284
-- 648
MOTOR_2 = 0x288
-- 896
MOTOR_3 = 0x380
-- 1152
MOTOR_5 = 0x480
-- 1160
MOTOR_6 = 0x488
-- 1386
ACC_GRA = 0x56A
-- 1408 the one with variable payload
MOTOR_INFO = 0x580
-- 1416
MOTOR_7 = 0x588
TCU_BUS = 1
fakeTorque = 0
hexstr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F" }
function toHexString(num)
if num == 0 then
return '0'
end
local result = ""
while num > 0 do
local n = num % 16
result = hexstr[n + 1] ..result
num = math.floor(num / 16)
end
return result
end
function arrayToString(arr)
local str = ""
local index = 1
while arr[index] ~= nil do
str = str.." "..toHexString(arr[index])
index = index + 1
end
return str
end
function onTcu1(bus, id, dlc, data)
-- print("onTcu1")
end
function onTcu2(bus, id, dlc, data)
-- print("onTcu2")
end
motor5FuelCounter = 0
function setBitRange(data, totalBitIndex, bitWidth, value)
local byteIndex = totalBitIndex >> 3
local bitInByteIndex = totalBitIndex - byteIndex * 8
if (bitInByteIndex + bitWidth > 8) then
bitsToHandleNow = 8 - bitInByteIndex
setBitRange(data, totalBitIndex + bitsToHandleNow, bitWidth - bitsToHandleNow, value >> bitsToHandleNow)
bitWidth = bitsToHandleNow
end
mask = (1 << bitWidth) - 1
data[1 + byteIndex] = data[1 + byteIndex] & (~(mask << bitInByteIndex))
maskedValue = value & mask
shiftedValue = maskedValue << bitInByteIndex
data[1 + byteIndex] = data[1 + byteIndex] | shiftedValue
end
function setTwoBytes(data, offset, value)
data[offset + 1] = value % 255
data[offset + 2] = (value >> 8) % 255
end
shallSleep = Timer.new()
-- we want to turn on with hardware switch while ignition key is off
hadIgnitionEvent = false
function onAirBag(bus, id, dlc, data)
-- looks like we have ignition key do not sleep!
shallSleep : reset()
hadIgnitionEvent = true
end
function setTwoBytes(data, offset, value)
value = math.floor(value)
data[offset + 2] = value >> 8
data[offset + 1] = value & 0xff
end
function xorChecksum(data, targetIndex)
local index = 1
local result = 0
while data[index] ~= nil do
if index ~= targetIndex then
result = result ~ data[index]
end
index = index + 1
end
data[targetIndex] = result
return result
end
function getBitRange(data, bitIndex, bitWidth)
byteIndex = bitIndex >> 3
shift = bitIndex - byteIndex * 8
value = data[1 + byteIndex]
if (shift + bitWidth > 8) then
value = value + data[2 + byteIndex] * 256
end
mask = (1 << bitWidth) - 1
return (value >> shift) & mask
end
motor1Data = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
motorBreData = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
motor2Data = { 0x8A, 0x8D, 0x10, 0x04, 0x00, 0x4C, 0xDC, 0x87 }
motor2mux = {0x8A, 0xE8, 0x2C, 0x64}
canMotorInfo = { 0x00, 0x00, 0x00, 0x14, 0x1C, 0x93, 0x48, 0x14 }
canMotorInfo1= { 0x99, 0x14, 0x00, 0x7F, 0x00, 0xF0, 0x47, 0x01 }
canMotorInfo3= { 0x9B, 0x14, 0x00, 0x11, 0x1F, 0xE0, 0x0C, 0x46 }
canMotor3 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
motor5Data = { 0x1C, 0x08, 0xF3, 0x55, 0x19, 0x00, 0x00, 0xAD }
motor6Data = { 0x00, 0x00, 0x00, 0x7E, 0xFE, 0xFF, 0xFF, 0x00 }
motor7Data = { 0x1A, 0x66, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 }
accGraData = { 0x00, 0x00, 0x08, 0x00, 0x1A, 0x00, 0x02, 0x01 }
setTickRate(100)
everySecondTimer = Timer.new()
canMotorInfoCounter = 0
motorBreCounter = 0
--accGraCounter = 0
counter16 = 0
motor2counter = 0
mafSensor = Sensor.new("maf")
mafCalibrationIndex = findCurveIndex("mafcurve")
canMotorInfoTotalCounter = 0
function onAccGra(bus, id, dlc, data)
print("onAccGra")
end
canRxAdd(AIRBAG, onAirBag)
canRxAdd(TCU_1, onTcu1)
canRxAdd(TCU_2, onTcu2)
-- canRxAdd(BRAKE_2)
-- canRxAdd(1, ACC_GRA, onAccGra)
function onMotor1(bus, id, dlc, data)
rpm = getSensor("RPM") or 0
tps = getSensor("TPS1") or 0
fakeTorque = interpolate(0, 6, 100, 60, tps)
engineTorque = fakeTorque * 0.9
innerTorqWithoutExt = fakeTorque
torqueLoss = 20
requestedTorque = fakeTorque
motor1Data[2] = engineTorque / 0.39
setTwoBytes(motor1Data, 2, rpm / 0.25)
motor1Data[5] = innerTorqWithoutExt / 0.4
motor1Data[6] = tps / 0.4
motor1Data[7] = torqueLoss / 0.39
motor1Data[8] = requestedTorque / 0.39
-- print ('MOTOR_1 fakeTorque ' ..fakeTorque)
-- print ('MOTOR_1 engineTorque ' ..engineTorque ..' RPM ' ..rpm)
-- print ('MOTOR_1 innerTorqWithoutExt ' ..innerTorqWithoutExt ..' tps ' ..tps)
-- print ('MOTOR_1 torqueLoss ' ..torqueLoss ..' requestedTorque ' ..requestedTorque)
txCan(TCU_BUS, MOTOR_1, 0, motor1Data)
end
function onMotor3(bus, id, dlc, data)
iat = getSensor("IAT") or 0
tps = getSensor("TPS1") or 0
desired_wheel_torque = fakeTorque
canMotor3[2] = (iat + 48) / 0.75
canMotor3[3] = tps / 0.4
canMotor3[5] = 0x20
setBitRange(canMotor3, 24, 12, math.floor(desired_wheel_torque / 0.39))
canMotor3[8] = tps / 0.4
txCan(TCU_BUS, MOTOR_3, 0, canMotor3)
end
motorBreCounter = 0
function onMotorBre(bus, id, dlc, data)
motorBreCounter = (motorBreCounter + 1) % 16
setBitRange(motorBreData, 8, 4, motorBreCounter)
xorChecksum(motorBreData, 1)
txCan(TCU_BUS, MOTOR_BRE, 0, motorBreData)
end
motor2counter = 0
function onMotor2(bus, id, dlc, data)
motor2counter = (motor2counter + 1) % 16
minTorque = fakeTorque / 2
-- todo: add CLT
motor2Data[7] = math.floor(minTorque / 0.39)
--print ( "brake " .. getBitRange(data, 16, 2) .. " " .. rpm)
brakeBit = rpm < 2000 and 1 or 0
setBitRange(motor2Data, 16, 1, brakeBit)
index = math.floor(motor2counter / 4)
motor2Data[1] = motor2mux[1 + index]
txCan(TCU_BUS, MOTOR_2, 0, motor2Data)
end
motor5FuelCounter = 0
function onMotor5(bus, id, dlc, data)
setBitRange(motor5Data, 5, 9, motor5FuelCounter)
xorChecksum(motor5Data, 8)
txCan(TCU_BUS, MOTOR_5, 0, motor5Data)
end
counter16 = 0
function onMotor6(bus, id, dlc, data)
counter16 = (counter16 + 1) % 16
-- engineTorque = getBitRange(data, 8, 8) * 0.39
-- actualTorque = getBitRange(data, 16, 8) * 0.39
-- feedbackGearbox = getBitRange(data, 40, 8) * 0.39
engineTorque = fakeTorque * 0.9
actualTorque = fakeTorque
feedbackGearbox = 255
motor6Data[2] = math.floor(engineTorque / 0.39)
motor6Data[3] = math.floor(actualTorque / 0.39)
motor6Data[6] = math.floor(feedbackGearbox / 0.39)
setBitRange(motor6Data, 60, 4, counter16)
xorChecksum(motor6Data, 1)
txCan(TCU_BUS, MOTOR_6, 0, motor6Data)
end
accGraCounter = 0
function onAccGra(bus, id, dlc, data)
accGraCounter = (accGraCounter + 1) % 16
setBitRange(accGraData, 60, 4, accGraCounter)
xorChecksum(accGraData, 1)
txCan(TCU_BUS, id, 0, accGraData)
-- txCan(TCU_BUS, id, 0, data)
end
canMotorInfoCounter = 0
function onMotorInfo(bus, id, dlc, data)
canMotorInfoTotalCounter = canMotorInfoTotalCounter + 1
canMotorInfoCounter = (canMotorInfoCounter + 1) % 16
-- canMotorInfoCounter = getBitRange(data, 0, 4)
baseByte = canMotorInfoTotalCounter < 6 and 0x80 or 0x90
canMotorInfo[1] = baseByte + (canMotorInfoCounter)
canMotorInfo1[1] = baseByte + (canMotorInfoCounter)
canMotorInfo3[1] = baseByte + (canMotorInfoCounter)
mod4 = canMotorInfoCounter % 4
if (mod4 == 0 or mod4 == 2) then
txCan(TCU_BUS, MOTOR_INFO, 0, canMotorInfo)
elseif (mod4 == 1) then
txCan(TCU_BUS, MOTOR_INFO, 0, canMotorInfo1)
else
txCan(TCU_BUS, MOTOR_INFO, 0, canMotorInfo3)
end
end
function onMotor7(bus, id, dlc, data)
txCan(TCU_BUS, MOTOR_7, 0, motor7Data)
end
local tcuId = 0
function onCanHello(bus, id, dlc, data)
-- here we handle 201 packets
print('Got Hello Response ' ..arrayToString(data))
tcuId = data[6] * 256 + data[5]
print('From TCU ' ..tcuId)
txCan(1, tcuId, 0, { 0xA0, 0x0F, 0x8A, 0xFF, 0x32, 0xFF })
end
local sendCounter = 2
local packetCounter = 1
local payLoadIndex = 0
local groups = { 10 }
-- todo: smarter array size calculation?
local groupsSize = 1
local groupIndex = 1
function onCanTester(bus, id, dlc, data)
-- here we handle 300 packets
-- print('Got from tester ' ..arrayToString(data))
if data[1] == 0xA3 then
-- print ("Keep-alive")
txCan(1, tcuId, 0, { 0xA1, 0x0F, 0x8A, 0xFF, 0x4A, 0xFF })
groupIndex = groupIndex + 1
if groupIndex > groupsSize then
groupIndex = 1
end
groupId = groups[groupIndex]
print (groupIndex .." " ..groupId)
reqFirst = 0x10 + sendCounter
print("Requesting next group " ..groupId .." with counter " ..sendCounter)
txCan(1, tcuId, 0, { reqFirst, 0x00, 0x02, 0x21, groupId })
sendCounter = sendCounter + 1
if sendCounter == 16 then
sendCounter = 0
end
return
end
if data[1] == 0xA1 then
print ("Happy 300 packet")
txCan(1, tcuId, 0, { 0x10, 0x00, 0x02, 0x10, 0x89 })
return
end
if data[1] == 0xA8 then
print ("They said Bye-Bye")
return
end
if data[1] == 0x10 and dlc == 5 then
ackPacket = 0xB0 + packetCounter
print ("Sending ACK B1 " ..ackPacket)
txCan(1, tcuId, 0, { ackPacket })
-- request first group from array
txCan(1, tcuId, 0, { 0x11, 0x00, 0x02, 0x21, groups[1] })
return
end
top4 = math.floor(data[1] / 16)
if top4 == 0xB then
-- print("Got ACK")
return
end
if top4 == 2 or top4 == 1 then
print ("Looks like payload index " ..payLoadIndex ..": " ..arrayToString(data))
if groupId == 2 and payLoadIndex == 0 then
L7 = data[7]
H9 = data[8]
V = 256 * H9 + L7
print("V 0 " ..V)
end
if groupId == 2 and payLoadIndex == 1 then
L3 = data[3]
H4 = data[4]
V = 256 * H4 + L3
print("V 1 " ..V)
end
if groupId == 2 and payLoadIndex == 2 then
L2 = data[2]
H3 = data[3]
V = 256 * H3 + L2
print("V 2 " ..V)
end
payLoadIndex = payLoadIndex + 1
packetCounter = packetCounter + 1
if packetCounter > 15 then
packetCounter = 0
end
if top4 == 1 then
ackPacket = 0xB0 + packetCounter
print ("Sending payload ACK " ..ackPacket)
txCan(1, tcuId, 0, { ackPacket })
payLoadIndex = 0
end
return
end
print('Got unexpected ' ..arrayToString(data))
end
canRxAdd(VWTP_IN, onCanHello)
txCan(1, VWTP_OUT, 0, { 0x02, 0xC0, 0x00, 0x10, 0x00, 0x03, 0x01 })
function onTick()
freqValue = getSensor("AuxSpeed1") or 0
mafValue = curve(mafCalibrationIndex, 5)
-- print(freqValue .. " mafValue=" .. mafValue)
mafSensor : set(mafValue)
counter16 = (counter16 + 1) % 16
rpm = getSensor("RPM") or 0
vbat = getSensor("BatteryVoltage") or 0
if rpm == 0 then
canMotorInfoTotalCounter = 0
end
onMotor1(0, 0, 0, nil)
onMotor3(0, 0, 0, nil)
onMotorBre(0, 0, 0, nil)
onMotor2(0, 0, 0, nil)
onMotor5(0, 0, 0, nil)
onMotor6(0, 0, 0, nil)
onMotor7(0, 0, 0, nil)
onAccGra(0, 0, 0, nil)
local timeToTurnOff = shallSleep : getElapsedSeconds() > 2
local connectedToUsb = vbat < 4
if hadIgnitionEvent and timeToTurnOff then
-- looks like ignition key was removed
-- mcu_standby()
end
if everySecondTimer : getElapsedSeconds() > 1 then
everySecondTimer : reset()
motor5FuelCounter = motor5FuelCounter + 20
onMotorInfo(0, 0, 0, nil)
end
end
)", efi::size(config->luaScript));