Results 1 to 15 of 511

Thread: Corvette CCM Reverse Engineering Anyone?

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #11
    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

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
  •