Results 1 to 15 of 511

Thread: Corvette CCM Reverse Engineering Anyone?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Fuel Injected! -=Jeff=-'s Avatar
    Join Date
    Jun 2013
    Location
    Chicago Suburbs
    Age
    51
    Posts
    222
    Quote Originally Posted by NomakeWan View Post
    Think of "SYS" like the Service Engine Soon light, except for the CCM instead of the ECM.
    Yeah I should probably fix that, I know a few resistors will fix it, same error occurs (HVAC LED CIRCUIT OPEN) with an aftermarket radio and C60 HVAC.

    I bought a 1991 CCM today, I have some other ideas for it, but will need to find the VATS code on it.

    Back to the 1992 CCM and the MEGA Arduino code. I did a quick look and did not see and F0, but I agree that it must have worked. However, I would have expected to see the data not be ZERO on the cluster, maybe it will not show because of the SYS light

    I may have time to mess with it tonight as I really want to try and get the VATS info.

    Looked at your code again.. it is only processing the 0x40 and 0x41 messaging. I would need to add the F0 message wouldn't I? If so, where is that info.. that code is Polling, but it looks like we need the 'master request'?
    Last edited by -=Jeff=-; 10-04-2022 at 04:48 PM.
    -=Jeff=-
    1990 Corvette ZR-1
    Black/Red Interior

  2. #2
    Fuel Injected!
    Join Date
    Jul 2019
    Location
    Orange, CA
    Posts
    757
    Quote Originally Posted by -=Jeff=- View Post
    Yeah I should probably fix that, I know a few resistors will fix it, same error occurs (HVAC LED CIRCUIT OPEN) with an aftermarket radio and C60 HVAC.

    I bought a 1991 CCM today, I have some other ideas for it, but will need to find the VATS code on it.

    Back to the 1992 CCM and the MEGA Arduino code. I did a quick look and did not see and F0, but I agree that it must have worked. However, I would have expected to see the data not be ZERO on the cluster, maybe it will not show because of the SYS light

    I may have time to mess with it tonight as I really want to try and get the VATS info.

    Looked at your code again.. it is only processing the 0x40 and 0x41 messaging. I would need to add the F0 message wouldn't I? If so, where is that info.. that code is Polling, but it looks like we need the 'master request'?
    F0 is "CCM is requesting the presence of external devices" and is the "heartbeat" call for connecting to a Corvette data bus. The CCM makes this call by itself. If you reply to this F0 call with an F1 call ("External device requesting control of CCM"), that gets you in business.

    On the Corvette, the only interaction the CCM has with the ECM as far as data goes is a call/response for specific pieces of data. The CCM makes a $40 call, which is a request to the ECM for that specific datagram (on the 90 it is literally just 40 55 6B, which is Datagram-Length-Checksum; on the 92-96 there is also a handshake that we do not fully understand added). If the ECM is online, it accepts this $40 call and responds with $41, which is the datagram containing all the information the CCM wants. It is this $41 call that my code is able to emulate. I detect the incoming call and respond accordingly.

    My code is designed to work properly on a 1994-1996 CCM the way it was written. If you are using it on a 1992 CCM, please be sure that all the appropriate values have been changed per the instructions in the header. The 1992-1993 CCM uses a shorter response than the 1994-1995 does, but listens for the same handshake. The 90 of course has a shorter handshake it listens for, and a shorter $41 response.
    1990 Corvette (Manual)
    1994 Corvette (Automatic)
    1995 Corvette (Manual)

  3. #3
    Fuel Injected! -=Jeff=-'s Avatar
    Join Date
    Jun 2013
    Location
    Chicago Suburbs
    Age
    51
    Posts
    222
    Quote Originally Posted by NomakeWan View Post
    F0 is "CCM is requesting the presence of external devices" and is the "heartbeat" call for connecting to a Corvette data bus. The CCM makes this call by itself. If you reply to this F0 call with an F1 call ("External device requesting control of CCM"), that gets you in business.
    Looking through this thread again i found that too..

    Quote Originally Posted by NomakeWan View Post
    On the Corvette, the only interaction the CCM has with the ECM as far as data goes is a call/response for specific pieces of data. The CCM makes a $40 call, which is a request to the ECM for that specific datagram (on the 90 it is literally just 40 55 6B, which is Datagram-Length-Checksum; on the 92-96 there is also a handshake that we do not fully understand added). If the ECM is online, it accepts this $40 call and responds with $41, which is the datagram containing all the information the CCM wants. It is this $41 call that my code is able to emulate. I detect the incoming call and respond accordingly.
    so then if I understand correctly, went the F0 is sent, the ECM is not responding with F1, it just does the 41 response to the 40 from the CCM

    Quote Originally Posted by NomakeWan View Post
    My code is designed to work properly on a 1994-1996 CCM the way it was written. If you are using it on a 1992 CCM, please be sure that all the appropriate values have been changed per the instructions in the header. The 1992-1993 CCM uses a shorter response than the 1994-1995 does, but listens for the same handshake. The 90 of course has a shorter handshake it listens for, and a shorter $41 response.
    Yes I have it modified, here it is if you would be so kind to double check it

    Code:
    /* CCM Interaction Test Sketch for Arduino Mega 2560
    This sketch pretends to be the PCM for a 1994 to 1995 Chevrolet Corvette.
    It listens for the CCM poll request bytes (40 57 XX XX Checksum),
    then sends the appropriate diagnostic string upon receipt.
    The diagnostic string is idle values except for coolant temp,
    which is either static (236F) or variable (based on ADC0 input).
    
    This sketch works on the 1994 to 1995 Corvette. It may work for 1996.
    
    1990-1991 Corvettes use shorter polls (40 55 6B) and have shorter responses.
    To use for a 1990-1991 Corvette, change the sliding window to 3 bytes
    and just use the following match code without checksum ifs:
    ((window[0] == 0x40) && (window[1] == 0x55) && (window[2] == 0x6B))
    Then comment out the top lines with output[21] and use the ones
    with output[15]. If using dynamic CTS, change output[20] in the
    last line of code to output[14].
    
    The 1992-1993 Corvettes use the same poll as the 94-96, but their response
    is shorter. To use for a 92-93 Corvette, just comment out the top
    lines with output[21] and use the ones with output[18]. If using
    dynamic CTS, change output[20] in the last line of code to output[17].
    
    This sketch only works on the Arduino Mega 2560 family.
    This is because we're using Serial1, UCSR1B, RXEN1, RXCIE1.
    If you want to try it on a different board, change these accordingly.
    */
    
    #include <avr/io.h>
    #include <wiring_private.h>
    #include <FastLED.h>
    
    byte window[5]; //define the 5-byte-wide sliding window
    //byte output[21]= {0x41, 0x67, 0x02, 0xF5, 0x00, 0xCD, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x48, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x40}; //define the static CTS message
    //byte output[21]= {0x41, 0x67, 0x02, 0xF5, 0x00, 0x87, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x48, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x86}; //define the dynamic CTS message
    byte output[18]= {0x41, 0x64, 0x01, 0xF3, 0x00, 0xCD, 0x60, 0x01, 0x00, 0x6F, 0x0F, 0xD6, 0x83, 0x00, 0x51, 0xFF, 0xFF, 0x13}; //define 1992-1993 Corvette static CTS message
    //byte output[18]= {0x41, 0x64, 0x01, 0xF3, 0x00, 0x5A, 0x60, 0x01, 0x00, 0x6F, 0x0F, 0xD6, 0x83, 0x00, 0x51, 0xFF, 0xFF, 0x86}; //define 1992-1993 Corvette dynamic CTS message
    //byte output[15]= {0x41, 0x61, 0x00, 0xEC, 0x00, 0xCD, 0x39, 0x01, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x39, 0x45}; //define 1990-1991 Corvette static CTS message
    //byte output[15]= {0x41, 0x61, 0x00, 0xEC, 0x00, 0x39, 0x39, 0x01, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x39, 0x12}; //define 1990-1991 Corvette dynamic CTS message
    
    void setup() {
      analogReference(DEFAULT); //Switch to default reference explicitly
      pinMode(A0, INPUT); //Make sure A0 is an input explicitly
      bitSet (DIDR0, ADC0D); //Disable digital buffer on A0
      bitSet (DIDR0, ADC1D); //Disable digital buffer on A1
      bitSet (DIDR0, ADC2D); //Disable digital buffer on A2
      bitSet (DIDR0, ADC3D); //Disable digital buffer on A3
      bitSet (DIDR0, ADC4D); //Disable digital buffer on A4
      bitSet (DIDR0, ADC5D); //Disable digital buffer on A5
      bitSet (DIDR0, ADC6D); //Disable digital buffer on A6
      bitSet (DIDR0, ADC7D); //Disable digital buffer on A7
      bitSet (DIDR1, AIN0D); //Disable digital buffer on AIN0
      bitSet (DIDR1, AIN1D); //Disable digital buffer on AIN1
      bitSet (DIDR2, ADC8D); //Disable digital buffer on A8
      bitSet (DIDR2, ADC9D); //Disable digital buffer on A9
      bitSet (DIDR2, ADC10D); //Disable digital buffer on A10
      bitSet (DIDR2, ADC11D); //Disable digital buffer on A11
      bitSet (DIDR2, ADC12D); //Disable digital buffer on A12
      bitSet (DIDR2, ADC13D); //Disable digital buffer on A13
      bitSet (DIDR2, ADC14D); //Disable digital buffer on A14
      bitSet (DIDR2, ADC15D); //Disable digital buffer on A15
      analogRead(0); //Burn an analog reading on A0
        Serial1.begin(8192); //Open UART1 at 8192 baud
        UBRR1H = (uint8_t)(121>>8); //Switch to 8192 baud at 1x
        UBRR1L = (uint8_t)121; //Switch to 8192 baud at 1x
        cbi(UCSR1A, U2X0); //disable 2x mode
        cbi(UCSR1A, MPCM0); //disable multi-processor mode
        cbi(UCSR1B, TXEN1); //disable transmitter for now
        cbi(UCSR1B, TXCIE1); //disable transmit interrupts for now
        FastPin<18>::setInput(); //tri-state TX1
    }
    
    void loop() {
        if (Serial1.available()) {
            // Slide the 5-byte window
            for (uint8_t i = 0; i < 4; i++) {
                window[i] = window[i + 1];
            }
            // Add new bytes as they come in
            window[4] = Serial1.read();
    
            // Check the first two bytes for a match
            if ((window[0] == 0x40) && (window[1] == 0x57)) {
                // Calculate the checksum byte
                byte cs = 0;
                for (uint8_t i = 0; i < 4; i++) {
                    cs += window[i];
                }
                cs = 0xFF - cs;
                cs += 0x01;
                // If checksum byte matches, send diagnostic data
                if (cs == window[4]) {
                    cbi(UCSR1B, RXEN1); //disable receiver
                    cbi(UCSR1B, RXCIE1); //disable receive interrupts
                    window[0] = 0x00; //poison the sliding window
                    delay(2); //delay to allow ALDL line to settle
                    FastPin<18>::setOutput(); //reenable TX1 as Output
                    sbi(UCSR1B, TXEN1); //enable transmitter
                    sbi(UCSR1B, TXCIE1); //enable transmit interrupts
                    Serial1.write(output, sizeof(output)); //write the PCM diagnostic message
                    Serial1.flush(); //wait until transmit completes
                    cbi(UCSR1B, TXEN1); //disable transmitter
                    cbi(UCSR1B, TXCIE1); //disable transmit interrupts
                    FastPin<18>::setInput(); //tri-state TX1
                    sbi(UCSR1B, RXEN1); //reenable receiver
                    sbi(UCSR1B, RXCIE1); //reenable receive interrupts
                }
            }
        }
        //Read A0 to check status of potentiometer, save to cts byte
        //output[5] = analogRead(0)>>2;
        //Calculate new checksum and save to checksum byte
        byte checksum = 0;
        for (uint8_t i = 0; i < 20; i++) {
          checksum += output[i];
        }
        checksum = 0xFF - checksum;
        checksum += 0x01;
        output[17] = checksum;
    }
    EDIT.. I think this line is wrong and I missed the modification specifically the 20
    for (uint8_t i = 0; i < 20; i++)

    it should be:
    for (uint8_t i = 0; i < 17; i++)
    Last edited by -=Jeff=-; 10-04-2022 at 08:56 PM.
    -=Jeff=-
    1990 Corvette ZR-1
    Black/Red Interior

  4. #4
    Fuel Injected!
    Join Date
    Jul 2019
    Location
    Orange, CA
    Posts
    757
    Quote Originally Posted by -=Jeff=- View Post
    so then if I understand correctly, went the F0 is sent, the ECM is not responding with F1, it just does the 41 response to the 40 from the CCM
    Correct. ECMs do not request the ability to control the CCM. Frankly, when running the engine they're far too busy to be worrying about that. The CCM only needs a few pieces of data from the ECM for use with the digital dash and HVAC, so that's why the $40/$41 calls exist. It's these calls that fail when people do engine swaps or use aftermarket ECUs, which was why I created that code.

    Quote Originally Posted by -=Jeff=- View Post
    EDIT.. I think this line is wrong and I missed the modification specifically the 20
    for (uint8_t i = 0; i < 20; i++)

    it should be:
    for (uint8_t i = 0; i < 17; i++)
    Actually it should be entirely commented out. You're using the static message, and that stuff at the bottom is only for the dynamic message (connecting a potentiometer to A0 and outputting the potentiometer value to the Coolant Temp Sensor byte). The static message types already have the correct lengths ready to go.
    1990 Corvette (Manual)
    1994 Corvette (Automatic)
    1995 Corvette (Manual)

  5. #5
    Fuel Injected! -=Jeff=-'s Avatar
    Join Date
    Jun 2013
    Location
    Chicago Suburbs
    Age
    51
    Posts
    222
    Yeah I though that too ( entire thing) but if if I left it, it would just keep churning the same Checksum over and over. Now if I do change to dynamic, I will re enable it.

    for now, I will disable and try it tonight again
    -=Jeff=-
    1990 Corvette ZR-1
    Black/Red Interior

  6. #6
    Fuel Injected!
    Join Date
    Jul 2019
    Location
    Orange, CA
    Posts
    757
    Quote Originally Posted by -=Jeff=- View Post
    Yeah I though that too ( entire thing) but if if I left it, it would just keep churning the same Checksum over and over. Now if I do change to dynamic, I will re enable it.

    for now, I will disable and try it tonight again
    The checksum is part of the ALDL protocol specification and is merely there so that both ends of the conversation can be sure that the message they just received is not corrupted. It has nothing to do with security or authentication or handshakes.

    It is perfectly fine for the checksum to remain the same if the message remains the same. The CCM expects this to be the case. That is the entire point of the static messages I included--they can be used to quickly and easily demo the code to show it working without any extra hardware or wiring.
    1990 Corvette (Manual)
    1994 Corvette (Automatic)
    1995 Corvette (Manual)

  7. #7
    Fuel Injected! -=Jeff=-'s Avatar
    Join Date
    Jun 2013
    Location
    Chicago Suburbs
    Age
    51
    Posts
    222
    Quote Originally Posted by NomakeWan View Post
    The checksum is part of the ALDL protocol specification and is merely there so that both ends of the conversation can be sure that the message they just received is not corrupted. It has nothing to do with security or authentication or handshakes.

    It is perfectly fine for the checksum to remain the same if the message remains the same. The CCM expects this to be the case. That is the entire point of the static messages I included--they can be used to quickly and easily demo the code to show it working without any extra hardware or wiring.
    yes understood, but with dynamic, if any value in the message changes the checksum changes.. we are good and on the same page
    -=Jeff=-
    1990 Corvette ZR-1
    Black/Red Interior

Similar Threads

  1. car bogs down when switching into reverse/D
    By CAMMED LT1 in forum GM EFI Systems
    Replies: 4
    Last Post: 09-27-2021, 12:34 AM
  2. 12212156 code reverse engineering project in Ghidra
    By dzidaV8 in forum OBDII Tuning
    Replies: 8
    Last Post: 01-13-2020, 11:04 AM
  3. Help!! 93 Lt1 6M Reverse lockout
    By noeysuarez in forum GM EFI Systems
    Replies: 3
    Last Post: 09-14-2017, 08:17 AM
  4. 4l60e reverse boost valve location and procedure
    By JTodd in forum Introductions
    Replies: 1
    Last Post: 04-19-2013, 01:20 AM
  5. T56 reverse lockout options with TBI PCM
    By CDeeZ in forum GM EFI Systems
    Replies: 1
    Last Post: 02-26-2013, 05:06 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •