I have a CEM MCU frequency alignment code in my private branch, it increases sensitivity even for L-shaped P2. I'll polish the code and post it later for testing.
Unfortunately, brick-shaped P2 is still not cracking.
I have a CEM MCU frequency alignment code in my private branch, it increases sensitivity even for L-shaped P2. I'll polish the code and post it later for testing.
Code: Select all
limit = TSC + 2 * 1000 * clockCyclesPerMicrosecond();Code: Select all
limit = TSC + 2 * 1000 * clockCyclesPerMicrosecond() / 4;Code: Select all
[ 05 -- -- -- -- -- ]: 1 442 0 175 0 22 0 2 0 0 0 0 0 0 0 0 0 0 0 0 : latency 139384; std 40.36
Average latency: 147
73 : 2
108 : 1
126 : 1
132 : 1
134 : 8
136 : 69
137 : 1
138 : 275
139 : 1
140 : 442
142 : 175
144 : 22
146 : 2Code: Select all
[ 05 -- -- -- -- -- ]: 37 0 31 0 31 0 38 0 26 0 29 0 31 0 32 0 33 0 35 0 : latency 140313; std 12.29
Average latency: 138
106 : 17
108 : 31
110 : 26
111 : 1
112 : 28
114 : 23
116 : 5
118 : 37
120 : 33
122 : 35
124 : 17
126 : 35
128 : 29
130 : 37
132 : 31
134 : 31
136 : 38
138 : 26
140 : 29
142 : 31
144 : 32
146 : 33
148 : 35
150 : 19
152 : 28
154 : 16
156 : 51
158 : 37
160 : 34
162 : 29
164 : 27
166 : 26
168 : 23
170 : 23
172 : 29
174 : 18Yes, the limit is the total timeout for CAN reply, while the body of the function measures the longest pause on CAN bus. Because, unlike the synchronous or almost synchronous MCP2515 design, the Teensy code is not in control of when the CAN request will be sent out, reducing the limit to 500 us (which is more than enough for all known CEMs to reply) may/will affect the measurement, since a good chunk of time will be spent waiting for TX to complete.sirloins wrote: ↑18 Feb 2022, 09:04 So reducing the limit by 4x from 2ms to 0.5ms gives more variation in the returned latencies, and also some higher ones? The only thing I can think of is that without my change we hit the CAN Interrupt before the limit, and with my change, we hit the limit first? What do you guys think?
Edit: I confirmed that with the default code, it hits the CAN interrupt first before the TSC limit, every time. With my change, it is hitting the TSC limit every time.
Full logs where I took the above data from are attached.
limit = TSC + 2 * 1000 * clockCyclesPerMicrosecond() / 4; // TSC Limit now 0.5ms
...
while (!intr && TSC < limit) .....
...
// We exit out of the while loop due to TSC now > limit
// Wait for CAN interrupt so we don't hit the delay(1) in canMsgReceive()
do{}while(!intr);
/* see if anything came back from the CEM */
canMsgReceive(CAN_HS, &id, reply, 1000, verbose);
// Add 1ms delay to simulate the canMsgReceive having to wait
delay(1);
Try this?sirloins wrote: ↑18 Feb 2022, 10:52 I pulled the changes, but it did not work. I will run it with more logging but I am still trying to better understand why my change works. If I take your change, and just add the "limit = TSC + 2 * 1000 * clockCyclesPerMicrosecond() / 4;" then it works...
As I mentioned, with my change. We exit out of that while loop in cemUnlock from the TSC > limit instead of the CAN interrupt. After the loop it then calls canMsgReceive with a 1000ms timeout. Since the interrupt hasn't triggered, there are no messages available and it hits the delay(1) within canMsgReceive (1ms delay). This is also why my change makes the pin/sec much slower than normal.
Code: Select all
diff --git a/volvo-cem-cracker.ino b/volvo-cem-cracker.ino
index d0e9129..25b182c 100644
--- a/volvo-cem-cracker.ino
+++ b/volvo-cem-cracker.ino
@@ -368,6 +368,8 @@ bool cemUnlock (uint8_t *pin, uint8_t *pinUsed, uint32_t *latency, bool verbose)
/* maximum time to collect our samples */
+ delay(1);
+
limit = TSC + 2 * 1000 * clockCyclesPerMicrosecond();
intr = false;
What I did during my initial investigation year+ ago is toggling IO pin when something important happens, like timeout or detection of the longer reply latency, and collecting this pin with logic analyzer, along with CAN lanes. I have a cheap $10 knock-off of Saleae Logic. Then it was clear what is happening on the bus and how the sw reacts to the bus events.
Code: Select all
@@ -375,6 +375,7 @@ bool cemUnlock (uint8_t *pin, uint8_t *pinUsed, uint32_t *latency, bool verbose)
canMsgSend (CAN_HS, 0xffffe, unlockMsg, verbose);
start = end = TSC;
+ cli();
while (!intr && TSC < limit) {
/* if the line is high, the CAN bus is either idle or transmitting a bit */
@@ -393,6 +394,7 @@ bool cemUnlock (uint8_t *pin, uint8_t *pinUsed, uint32_t *latency, bool verbose)
start = end;
}
+ sei();