RomRaider Logo

RomRaider

Open Source ECU Tools
 FAQ •  Register •  Login 

RomRaider

Documentation

Community

Developers

It is currently Sat Dec 27, 2025 1:33 pm

All times are UTC - 5 hours [ DST ]





Post new topic Reply to topic  [ 12 posts ] 
Author Message
 Post subject: Trying to talk Subaru with freediag / nisprog
PostPosted: Fri Apr 29, 2022 6:55 am 
Offline
Experienced

Joined: Fri Aug 21, 2020 6:05 am
Posts: 315
Been trying to talk to a Subaru ECU (on the bench) with freediag / nisprog. Bench setup confirmed to work using RR logger, so its not a physical connection issue.

nisprog npconn - doesn't connect
diag connect - doesn't connect with l2protocol set to ISO14230
diag connect - does connect with l2protocol set to RAW (see below)
diag sendreq 0x80 0x10 0xF0 0x01 0xBF 0x40 - this is ECU Init command - no response received (see below)

Connection settings are set as per the SSM page and ECU Register settings: https://romraider.com/index.php/RomRaider/SsmProtocol

I've become fairly familiar with nisprog code and operation, but I haven't yet looked deeply into freediag so I may be using it incorrectly. Any suggestions on how to get this working? Note that the Subaru comms protocol is quite close to ISO14230, but not exactly the same. In particular, Subaru assumes all headers are 4 bytes long (format, destination, source, length). I also tried diag with ISO9141 but no luck.

Thanks!

Here's the debug output...
Code:
nisprog> set show
interface: using DUMB
Connect speed: 4800
display: metric units
testerid: using 0xF0
addrtype: physical addressing
destaddr: using 0x10
l1protocol: Layer 1 (H/W) protocol to use ISO14230
l2protocol: Layer 2 protocol to use RAW
initmode: Initmode to use with above protocol is FAST
L0 options:
        port=\\.\COM1
        dumbopts=   72
nisprog> diag connect
diag_l2.c:234:  l2_open Generic dumb serial interface on 007f3768, L1proto=2
diag_l1.c:99:  diag_l1_open(0x007f3768, l1 proto=2
diag_l0_dumb.c:208:  open port \\.\COM1 L1proto 2
diag_tty_win.c:61:  Device \\.\COM1 opened, fd 00000158
diag_tty_win.c:341:  tty_read: ttyh=007f3c98, fd=00000158, len=1024, t=30
diag_l2.c:345:  _startCommunications dl0d=007f3768 L2proto 0 flags=0x1 4800bps target=0x10 src=0xF0
diag_l2.c:596:  diag_l2_ioctl 007f3ce8 cmd 0x2101
diag_tty_win.c:163:  dev 00000158; 4800bps 8,1,3
diag_l2.c:452:  diag_l2_StartComms returns 007f3ce8
Connection to ECU established!
nisprog> diag sendreq 0x80 0x10 0xF0 0x01 0xBF 0x40
diag_l2.c:507:  diag_l2_send 007f3ce8 msg 0063ef34 msglen 6 called
diag_l2_raw.c:91:  diag_l2_send 007f3ce8, msg 0063ef34 len 6 called
diag_l1.c:155:  _send: len=6 P4=5 l0flags=0x101B; 0x80 0x10 0xF0 0x01 0xBF 0x40
diag_l0_dumb.c:662:  l0_send dl0d=007f3768 len=1; 0x80
diag_l0_dumb.c:690:  _recv dl0d=007f3768 req=1 bytes timeout=200
diag_tty_win.c:341:  tty_read: ttyh=007f3c98, fd=00000158, len=1, t=200
diag_l0_dumb.c:701:  Got 0x80
diag_l0_dumb.c:662:  l0_send dl0d=007f3768 len=1; 0x10
diag_l0_dumb.c:690:  _recv dl0d=007f3768 req=1 bytes timeout=200
diag_tty_win.c:341:  tty_read: ttyh=007f3c98, fd=00000158, len=1, t=200
diag_l0_dumb.c:701:  Got 0x10
diag_l0_dumb.c:662:  l0_send dl0d=007f3768 len=1; 0xF0
diag_l0_dumb.c:690:  _recv dl0d=007f3768 req=1 bytes timeout=200
diag_tty_win.c:341:  tty_read: ttyh=007f3c98, fd=00000158, len=1, t=200
diag_l0_dumb.c:701:  Got 0xF0
diag_l0_dumb.c:662:  l0_send dl0d=007f3768 len=1; 0x01
diag_l0_dumb.c:690:  _recv dl0d=007f3768 req=1 bytes timeout=200
diag_tty_win.c:341:  tty_read: ttyh=007f3c98, fd=00000158, len=1, t=200
diag_l0_dumb.c:701:  Got 0x01
diag_l0_dumb.c:662:  l0_send dl0d=007f3768 len=1; 0xBF
diag_l0_dumb.c:690:  _recv dl0d=007f3768 req=1 bytes timeout=200
diag_tty_win.c:341:  tty_read: ttyh=007f3c98, fd=00000158, len=1, t=200
diag_l0_dumb.c:701:  Got 0xBF
diag_l0_dumb.c:662:  l0_send dl0d=007f3768 len=1; 0x40
diag_l0_dumb.c:690:  _recv dl0d=007f3768 req=1 bytes timeout=200
diag_tty_win.c:341:  tty_read: ttyh=007f3c98, fd=00000158, len=1, t=200
diag_l0_dumb.c:701:  Got 0x40
diag_l2.c:567:  diag_l2_recv 007f3ce8 timeout 300 called
diag_l1.c:253:  _recv request len=1024, timeout=300;diag_l0_dumb.c:690:  _recv dl0d=007f3768 req=1024 bytes timeout=300
diag_tty_win.c:341:  tty_read: ttyh=007f3c98, fd=00000158, len=1024, t=300
diag_l2.c:577:  diag_l2_recv returns -8
No data received


Top
 Profile  
 
 Post subject: Re: Trying to talk Subaru with freediag / nisprog
PostPosted: Fri Apr 29, 2022 8:33 am 
Offline
Experienced
User avatar

Joined: Wed Jan 08, 2014 11:07 pm
Posts: 652
a few things :

- debug L1 0x8c is what I find the most useful for troubleshooting. I rarely want to see what's going on at L0 or tty, it's mostly noise
- set l2 proto to 14230 as well, so it knows how to init and read keybytes. Make sure that it sends the correct init message. [EDIT - ignore this, see later posts]
- SSM : I just thought, didn't I read somewhere that ssm doesn't need the 25+25ms break/wakeup pattern ? You may need to play with initmodes ... [EDIT - ignore this]

- try diag connect a few times in a row (with a few seconds gap) to rule out irregular timing. Sometimes it just won't work on the first try [EDIT - probably not the problem]
- if you do manage to connect (with the correct L2proto), 'diag sendreq' needs only data bytes, not headers nor checksums .

_________________
If you like nisprog + npkern, you can support me via https://liberapay.com/fenugrec/
For sending me encrypted/secure messages, use PGP key 0xBAC61AEB3A3E6531 available from pool.sks-keyservers.net


Top
 Profile  
 
 Post subject: Re: Trying to talk Subaru with freediag / nisprog
PostPosted: Fri Apr 29, 2022 8:46 am 
Offline
RomRaider Developer

Joined: Wed May 20, 2009 9:49 pm
Posts: 7314
Location: Canada eh!
We use ISO9141 with SSM, 4800 baud n, 8, 1. No wakeup or anything just straight out query/response.
I can use Freediag against my ECU without issue, have you tried it? Maybe it will shed some light on the issue.
Also:
P1_MAX: 2
P3_MIN: 0
P4_MIN: 0


Top
 Profile  
 
 Post subject: Re: Trying to talk Subaru with freediag / nisprog
PostPosted: Fri Apr 29, 2022 9:02 am 
Offline
Experienced
User avatar

Joined: Wed Jan 08, 2014 11:07 pm
Posts: 652
dschultz wrote:
No wakeup or anything just straight out query/response.


Ah there you go. Then disregard what I said about inits. Being able to run with L2proto=14230 would still be useful to get headers & checksums for free, but it might only be possible with a custom build of freediag / nisprog to manually set the keybytes, since there is no init to supply them. Unfortunately there's no way to configure this at runtime. Nisprog would be easier to modify IMO. I would look at cmd_npconn() in np_cli.c

_________________
If you like nisprog + npkern, you can support me via https://liberapay.com/fenugrec/
For sending me encrypted/secure messages, use PGP key 0xBAC61AEB3A3E6531 available from pool.sks-keyservers.net


Top
 Profile  
 
 Post subject: Re: Trying to talk Subaru with freediag / nisprog
PostPosted: Tue May 03, 2022 9:07 am 
Offline
Experienced

Joined: Fri Aug 21, 2020 6:05 am
Posts: 315
Thanks for the tips fenugrec and dschultz. Been chipping away at this. Took some time to figure out how to get CMake compiler settings right to compile nisprog, but got it working eventually.

freediag / nisprog will connect if both l1protocol and l2protocol are set to RAW. This allows successful SSM communication, but requires manual construction of headers and checksum. As fenugrec suggested, made some edits to npconn() to change a RAW connection into an ISO14230 connection. This seemed to work. There is a timeout that I probably need to fix. Next step is to check if npdisc needs similar edits and then start changing SIDs from Nissan specific to Subaru specific.
Code:
nisprog> set show
interface: using DUMB
Connect speed: 4800
display: metric units
testerid: using 0xF0
addrtype: physical addressing
destaddr: using 0x10
l1protocol: Layer 1 (H/W) protocol to use RAW
l2protocol: Layer 2 protocol to use RAW
initmode: Initmode to use with above protocol is FAST
L0 options:
        port=\\.\COM1
        dumbopts=     72
nisprog> npconn
L2 RAW detected, changing to L2 ISO14230
Change to ISO14230 successful
Connected to ECU !
diag_l2.c:542: Read/Write timeout.
Couldn't get ECUID ? Verify settings, connection mode etc.
nisprog> debug l1 0x8c
L1 debug is 0x8C: READ WRITE DATA
nisprog> diag sr 0xBF
diag_l1.c:155:  _send: len=6 P4=0 l0flags=0x1000; 0x80 0x10 0xF0 0x01 0xBF 0x40
diag_l1.c:252:  _recv request len=1024, timeout=300;got 62 bytes; 0x80 0xF0 0x10 0x39 0xFF 0xA2 0x10 0x02 0x45 0x52 0x16 0x42 0x06 0xF3 0xFA 0xCB 0x84 0x23 0x86 0x02 0xAC 0x00 0x00 0x00 0xE0 0xCE 0xD4 0xFD 0xB8 0x60 0x00 0x0F 0x20 0x00 0x00 0x00 0x00 0x00 0xDC 0x00 0x00 0x5D 0x1F 0x30 0x80 0xF0 0x24 0x00 0x00 0x40 0xFB 0x00 0xE1 0x00 0x00 0x00 0x00 0x00 0x00 0xC1 0xF0 0xA3
diag_l1.c:252:  _recv request len=962, timeout=23;diag_l1.c:252:  _recv request len=1024, timeout=50;msg 00 src=0x10 dest=0xF0
msg 00 data: 0xFF 0xA2 0x10 0x02 0x45 0x52 0x16 0x42 0x06 0xF3 0xFA 0xCB 0x84 0x23 0x86 0x02 0xAC 0x00 0x00 0x00 0xE0 0xCE 0xD4 0xFD 0xB8 0x60 0x00 0x0F 0x20 0x00 0x00 0x00 0x00 0x00 0xDC 0x00 0x00 0x5D 0x1F 0x30 0x80 0xF0 0x24 0x00 0x00 0x40 0xFB 0x00 0xE1 0x00 0x00 0x00 0x00 0x00 0x00 0xC1 0xF0


These are the npconn() edits, happy to hear if I should be doing something differently:
Code:
   //MODFLAG: at this point if we have a valid ISO14230 connection then apply Nissan modeflags, else
   //we could have a valid RAW connection. If so, we now need to update d_conn manually to change to ISO14230.
   //The general initialisation would have set d_conn->diag_link, ->l2proto, ->diag_l2_type, ->diag_l2_srcaddr, ->diag_l2_destaddr,
   //->diag_l2_p1 2 2e 3 4 min max, ->tinterval, ->tlast, ->diag_l2_state
   //The RAW initialisation would have set diag_serial_settings and d_conn->diag_l2_destaddr and ->diag_l2_srcaddr
   //
   //If we have a valid Iso14230 connection, then apply the modeflags for Nissan
   if (global_cfg.L2proto == DIAG_L2_PROT_ISO14230) {
      printf("L2 ISO14230 detected\n");
      struct diag_l2_14230 * dlproto;   // for bypassing headers
      dlproto = (struct diag_l2_14230 *)global_l2_conn->diag_l2_proto_data;
      if (dlproto->modeflags & ISO14230_SHORTHDR) {
         dlproto->modeflags &= ~ISO14230_LONGHDR;   //deactivate long headers
      } else {
         printf("Short headers not supported by ECU ! Have you \"set addrtype phys\" ?"
               "Some stuff will not work.");
      }
   } else {
   // if we have a valid RAW connection, then change to ISO14230
      if (global_cfg.L2proto == DIAG_L2_PROT_RAW) {
         printf("L2 RAW detected, changing to L2 ISO14230\n");
         struct diag_l2_14230 *dp;
         const struct diag_l2_proto *dl2p;
         int i, rv;

         global_cfg.L2proto = DIAG_L2_PROT_ISO14230;
         
         for (i=0; l2proto_list[i] ; i++) {
            dl2p = l2proto_list[i];   
            if (dl2p->diag_l2_protocol == global_cfg.L2proto) {
               d_conn->l2proto = dl2p;
               break;
            }
         }      

         rv = diag_calloc(&dp, 1);
         if (rv != 0) return CMD_FAILED;         

         d_conn->diag_l2_proto_data = (void *)dp;

         dp->srcaddr = global_cfg.src;
         dp->dstaddr = global_cfg.tgt;
         dp->first_frame = 0;
         dp->monitor_mode = 0;
         d_conn->diag_l2_kb1 = 0x8F;
         d_conn->diag_l2_kb2 = 0xEA; //length byte required, address bytes required (ie) 4 byte headers
         d_conn->diag_l2_physaddr = global_cfg.src;
         dp->state = STATE_ESTABLISHED;
         dp->modeflags = 6; //length byte required, address bytes required (ie) 4 byte headers
         printf("Change to ISO14230 successful\n");
      } else {
         printf("incorrect L2 protocol ! try \"set l2protocol\"\n");
         return CMD_FAILED;
      }
   }
   //end MODFLAG


Top
 Profile  
 
 Post subject: Re: Trying to talk Subaru with freediag / nisprog
PostPosted: Tue May 03, 2022 9:30 am 
Offline
Experienced
User avatar

Joined: Wed Jan 08, 2014 11:07 pm
Posts: 652
Code:
nisprog> diag sr 0xBF
...
msg 00 data: 0xFF 0xA2 0x10 0x02 0..


Cool ! Good work. Isn't it nice not having to compute headers & checksums manually P )

For your mods to nisprog : I recommend adding functions as much as possible instead of modifying nissan-specific stuff. For instance you could add to the function table : duplicate + rename + modify cmd_npconn, add it to the command table in nisprog.c/h etc. It will be easier to maintain, whether we eventually merge into nisprog or generate a separate subaru build from the same codebase. Otherwise as you can see it adds a lot of conditionals to the code, and will be a lot more complex to debug as well.

_________________
If you like nisprog + npkern, you can support me via https://liberapay.com/fenugrec/
For sending me encrypted/secure messages, use PGP key 0xBAC61AEB3A3E6531 available from pool.sks-keyservers.net


Top
 Profile  
 
 Post subject: Re: Trying to talk Subaru with freediag / nisprog
PostPosted: Wed May 04, 2022 8:39 am 
Offline
Experienced

Joined: Fri Aug 21, 2020 6:05 am
Posts: 315
Thanks again for the suggestions. I thought I saw a question about ISO14230 having limited packet sizes. Perhaps this only comes into play when uploading a new kernel... and the ROM imposes a max length anyway of 132 bytes per transferData in its response to SID 0x34 (requestDownload), so I'm hoping any length restriction in ISO14230 isn't a factor.

I have recut the code to isolate changes in new functions / commands. "spconn" establishes the connection (RAW first then switches to ISO14230), executes SID 0x81 (startCommunications) because that is a pre-requisite for other functions and finally gets the ECU ID using an SSM command. "sprunkernel" isn't yet complete... so far it completes Seed / Key exchange with the ECU. Getting near the pointy end now...

Code:
nisprog> spconn
L2 RAW detected, changing to L2 ISO14230
Change to ISO14230 successful
diag_l1.c:155:  _send: len=6 P4=0 l0flags=0x1000; 0x80 0x10 0xF0 0x01 0x81 0x02
diag_l1.c:252:  _recv request len=1024, timeout=60;got 8 bytes; 0x80 0xF0 0x10 0x03 0xC1 0xEF 0x8F 0xC2
diag_l1.c:252:  _recv request len=1016, timeout=23;diag_l1.c:252:  _recv request len=1024, timeout=50;
Connected to ECU and ready for SSM or SID Commands
diag_l1.c:155:  _send: len=22 P4=0 l0flags=0x1000; 0x80 0x10 0xF0 0x11 0xA8 0x00 0x00 0x00 0x01 0x00 0x00 0x02 0x00 0x00 0x03 0x00 0x00 0x04 0x00 0x00 0x05 0x48
diag_l1.c:252:  _recv request len=1024, timeout=60;got 11 bytes; 0x80 0xF0 0x10 0x06 0xE8 0x45 0x52 0x16 0x42 0x06 0x63
diag_l1.c:252:  _recv request len=1013, timeout=23;diag_l1.c:252:  _recv request len=1024, timeout=50;
ECUID: 45 52 16 42 06
nisprog> sprunkernel
diag_l1.c:155:  _send: len=7 P4=0 l0flags=0x1000; 0x80 0x10 0xF0 0x02 0x27 0x01 0xAA
diag_l1.c:252:  _recv request len=1024, timeout=60;got 11 bytes; 0x80 0xF0 0x10 0x06 0x67 0x01 0x40 0x35 0xE0 0x5F 0xA2
diag_l1.c:252:  _recv request len=1013, timeout=23;diag_l1.c:252:  _recv request len=1024, timeout=50;
Seed obtained: 40 35 e0 5f
Key generated: 4 87 5e e8

diag_l1.c:155:  _send: len=11 P4=0 l0flags=0x1000; 0x80 0x10 0xF0 0x06 0x27 0x02 0x04 0x87 0x5E 0xE8 0x80
diag_l1.c:252:  _recv request len=1024, timeout=60;got 8 bytes; 0x80 0xF0 0x10 0x03 0x67 0x02 0x34 0x20
diag_l1.c:252:  _recv request len=1016, timeout=23;diag_l1.c:252:  _recv request len=1024, timeout=50;
SID27 Access achieved !!
nisprog> exit
diag_l1.c:155:  _send: len=6 P4=0 l0flags=0x1000; 0x80 0x10 0xF0 0x01 0x82 0x03
diag_l1.c:252:  _recv request len=1024, timeout=60;


Top
 Profile  
 
 Post subject: Re: Trying to talk Subaru with freediag / nisprog
PostPosted: Tue May 10, 2022 7:05 am 
Offline
Experienced

Joined: Fri Aug 21, 2020 6:05 am
Posts: 315
Making progress... code now does SIDs 0x81 (startCommunications), 0x27 (securityAccess), 0x10 (startDiagnosticSession), 0x34 (requestDownload) and 0x36 (transferData including encryption). Next step is SID 0x31 (RAM Jump).

A couple of things it would be good to get some input on:
1. SID 0x36 does not always seem to be reliable, and I wonder whether it is speed related because after SID 0x10 the ROM increases the bitrate to 15,625 bit/s. I have been using a 32 byte *.txt file as a test file. The original nisprog code uses diag_l2_send() and diag_l1_recv() but when I used those functions, the data that arrived in the ROM was pretty random. I then tried diag_l2_request() and that was better but not perfect. The first time I tried it the ROM data appeared random. The second time I tried it (with only 1 bit difference in the first byte), the data arrived in the ROM all perfectly except for the last 2 bytes. And on the third and fourth tries it worked perfectly. Should I be doing anything differently at these bit rates? Here is the relevant code:
Code:
   for (; len > 0; len -= 32, blockno += 1) {
      
      blockaddr = dataaddr + blockno * 32;
      txdata[1] = (uint8_t) (blockaddr >> 16) & 0xFF;
      txdata[2] = (uint8_t) (blockaddr >> 8) & 0xFF;
      txdata[3] = (uint8_t) blockaddr & 0xFF;

      memcpy(&txdata[4], buf, 32);
      buf += 32;

      rxmsg=diag_l2_request(global_l2_conn, &nisreq, &errval);
      
      if ((rxmsg->len != 1) || rxmsg->data[0] != 0x76) {
         printf("got bad SID 0x36 dataTransfer response : ");
         diag_data_dump(stdout, rxmsg->data, rxmsg->len);
         printf("\n");
         diag_freemsg(rxmsg);
         return -1;
      }
      printf("\rSID36 block 0x%04X/0x%04X done",
            (unsigned) blockno, (unsigned) maxblocks);

   }


2. Seeing as I'm almost ready for the kernel, I'm wondering what sort of edits might be required to the nisprog kernel to make it Subaru compatible? Seeing as the kernel is pretty self-contained, I'm hoping the edits are pretty minimal. From skimming the code, I am wondering whether these changes might be required:
- The Subaru ROMs require the payload to be loaded into 0xFFFF3000 to 0xFFFF5000. Upon SID 0x31 (RAM Jump), execution jumps to 0xFF3004 so this is where the start of the kernel needs to go. I think Nissan ROMs assume the payload goes to 0xFFFF6000 (or was it 0xFFFF8000?). Any kernel changes required here?
- The Subaru ROM requires the kernel to have a 16bit checksum of 0x5AA5, is there some way to configure the nisprog kernel so it has a set checksum? I wonder whether that is why execution starts at 0xFFFF3004.... because it leaves 4 bytes to make sure the checksum is right...?
- What about the Stack Pointer? In normal operation, the Subaru SP is at 0xFFBFA0. Should this be set somewhere else in the kernel?
- The Subaru ROM sends a '1' over PB15 when the WDT overflows every 6.6ms. Does this need to be adjusted in the nisprog kernel?
- Any other changes? I see in the code FL_ERASE_BASE and FL_WRITE_BASE at certain RAM addresses - not sure what these are?

Note: this Subaru ROM is a SH7058. Lots of questions, but I'd rather get the kernel close to perfect before taking the RAM Jump leap!

Thanks!


Top
 Profile  
 
 Post subject: Re: Trying to talk Subaru with freediag / nisprog
PostPosted: Tue May 10, 2022 10:12 am 
Offline
Experienced
User avatar

Joined: Wed Jan 08, 2014 11:07 pm
Posts: 652
Quote:
the data that arrived in the ROM was pretty random.

What do you mean by "arrived in the ROM" ? Assuming a typo and you mean RAM, how are you verifying this ?

As for speed, on Nissan + npkern the speed is set to 62500 bps without problems. So I don't think you're running into physical speed limits.

That said, maybe your stock ECU firmware can't handle 15k; you could try increasing inter-byte spacing (P4min) to give it a few extra ms to process incoming data.

Subaru kernel : do you have access to a factory kernel ? That would answer many questions. Like what is in those four bytes at ffff3000 to 3004.


Quote:
- payload destination

One challenge with Nissans is that the SID36 copy-to-RAM doesn't always use the same destination address, although always in the area around ffff 8438. So npkern is designed to run from ffff 8100; to make this work I have a small bit of tricky code early in npkern that moves the whole kernel up to ffff8100. I.e. no matter where it's loaded, as long as it's after ffff8100 + a small margin, it'll move itself to the right place and run there. This happens in start_705x.s .

If you're certain Subaru always loads to the same address, then that process could be simplified. You would need a different lkr_7058.ld file for sure, as well as a new start_705x.s
Open a ticket on the github repo, we can discuss the details there.

My first kernel tests were simple sanity checks. First just freeze/crash the ECU to confirm I was gaining control; then generate a recognizable but valid pulse train on the keepalive pin (PB15 on yours) to validate that the kernel is staying operational. These tests are low risk; a cold reboot of the ECU reverts it to normal.

Quote:
- The Subaru ROM requires the kernel to have a 16bit checksum of 0x5AA5

First, determine exactly the crc algorithm. If its an actual CRC16, try pycrc , https://www.lammertbies.nl/comm/info/crc-calculation , or other methods, to make sure you have the right polynomial and parameters.

Then, there is a trick where if you compute crc on a block, append that crc to the block, then compute again a crc on the concatenated {block+crc}, you obtain a fixed number. This is probably what they're doing.
IMO once you figure this out, the easiest place to compute it would be in nisprog. I do something similar for Nissan: it needs a checksum in the SID37 request after transfering the kernel.


Quote:
- What about the Stack Pointer? In normal operation, the Subaru SP is at 0xFFBFA0.

Um, that address looks invalid for 7058... In npkern it's defined via _stackinit in the .ld file, and r15 is set in start_705x.s


Quote:
- The Subaru ROM sends a '1' over PB15 when the WDT overflows every 6.6ms. Does this need to be adjusted in the nisprog kernel?

yes. see wdt_tog()

Quote:
- Any other changes? I see in the code FL_ERASE_BASE and FL_WRITE_BASE at certain RAM addresses


See the ROM chapter in the 7058 datasheet. These need to point to free RAM areas for the cpu to load its own built-in flash "microcode". If you need to change these, the FTDAR_* values also need adjusting.

_________________
If you like nisprog + npkern, you can support me via https://liberapay.com/fenugrec/
For sending me encrypted/secure messages, use PGP key 0xBAC61AEB3A3E6531 available from pool.sks-keyservers.net


Top
 Profile  
 
 Post subject: Re: Trying to talk Subaru with freediag / nisprog
PostPosted: Tue May 10, 2022 6:46 pm 
Offline
RomRaider Developer

Joined: Wed May 20, 2009 9:49 pm
Posts: 7314
Location: Canada eh!
For the SH7058 Subaru sets the SP to 0xFFFFBFA0.
RAM starts at 0xFFFF0000 and is 0xC000 in length, so the SP it at the top of this range.


Top
 Profile  
 
 Post subject: Re: Trying to talk Subaru with freediag / nisprog
PostPosted: Tue May 10, 2022 7:53 pm 
Offline
Experienced

Joined: Fri Aug 21, 2020 6:05 am
Posts: 315
Thanks again for the suggestions, I'll keep chipping away at it. In the interim, some clarifications...
Quote:
What do you mean by "arrived in the ROM" ? Assuming a typo and you mean RAM, how are you verifying this ?

Apologies, I meant RAM. Verifying it is a bit cumbersome. The Subaru ROM does not seem to have a SID 0x37 to exit the dataTransfer process, so I power cycle the ECU, reconnect and then use 'diag sr' along with the SSM 'Block Read' command to tell me the RAM contents at 0xFFFF3000.
Quote:
maybe your stock ECU firmware can't handle 15k

The ECU sets the speed via the BRR register. Maybe it's the cheapo VAG Com cable / CH340 chipset. To expand on comms speed, the Subaru ROM has two comms modes. The first is for dealing with 'normal' comms like reading data, SSM commands etc. In this mode, bitrate is 4800. The second mode is for loading a kernel and is triggered by SID 0x10 at which point execution jumps high up in the ROM, the bitrate is increased to 15,625 and execution settles into an endless loop (with no exit) with only the WDT issuing a '1' on PB15 and TX/RX on SCI2 for comms. Took a little while to figure out that the speed change was why the ECU seemed to go silent after SID 0x10.
Quote:
Subaru kernel : do you have access to a factory kernel ? That would answer many questions. Like what is in those four bytes at ffff3000 to 3004.

Unfortunately not. Not sure where I would get one... Would I get one if I somehow downloaded the EEPROM contents?
Quote:
First, determine exactly the crc algorithm.

It's a simple 32bit summation of each byte in the address range set by the preceeding SID 0x34, and then (just before executing the RAM Jump) it checks that the lower 16bits of the checksum equal 0x5AA5.
Quote:
Um, that address looks invalid for 7058

Oops, I was using my shorthand for RAM addresses where I ignore the extra 'FF'
Quote:
yes. see wdt_tog()

I get that the WDT is a form of ECU protection, but I'm wondering how the pin signal is used? Is there something in the PCB circuit outside the ECU that requires a regular signal on the pin? I couldn't see anything inside the ROM code using this signal. I thought that it might be using the interrupt triggered by the WDT overflow, but the VBR being used in this part of the ROM isn't long enough to have a separate subroutine for a WDT interrupt.
Quote:
See the ROM chapter in the 7058 datasheet

Ah yes, I see FTDAR settings now. Looks like this is the same regardless of Nissan/Subaru

One other question... I see npkern uses SCI1 for TX/RX. Should this change to SCI2 because that's how the Subaru ECU communicates? Or won't it matter once the kernel is in charge?


Top
 Profile  
 
 Post subject: Re: Trying to talk Subaru with freediag / nisprog
PostPosted: Tue May 10, 2022 9:18 pm 
Offline
Experienced
User avatar

Joined: Wed Jan 08, 2014 11:07 pm
Posts: 652
rimwall wrote:
I power cycle the ECU, reconnect and then use 'diag sr' along with the SSM 'Block Read' command to tell me the RAM contents at 0xFFFF3000.


Ah I see. Note, power cycling may affect RAM contents in unpredictable ways. Grounding NRST temporarily to cause a cpu reset may be more useful.


Quote:
maybe your stock ECU firmware can't handle 15k

What I meant was, maybe it can't handle data coming with no gap between bytes?. Doubtful, but the only explanation I have.

Quote:
Quote:
Subaru kernel : do you have access to a factory kernel ?

Unfortunately not. Not sure where I would get one... Would I get one if I somehow downloaded the EEPROM contents?

No. You would have to look at factory J2534 software and ROM update files.

Quote:
It's a simple 32bit summation of each byte in the address range set by the preceeding SID 0x34, and then (just before executing the RAM Jump) it checks that the lower 16bits of the checksum equal 0x5AA5.

Hah ! Excellent, very simple. I'd definitely throw that in nisprog : first, append two 0 bytes to kernel payload, calculate sum, and adjust those two filler bytes. Then if required, pad kernel with more 0 bytes (e.g. Nissan needs the payload size to be a multiple of 32)

Quote:
I get that the WDT is a form of ECU protection, but I'm wondering how the pin signal is used?

Right - there's WDT and there's WDT. I get lazy with wording. wdt_tog() refers to the "external WDT", so to speak : I fully expect an independant IC in the ecu monitoring that PB15 pin for the "heartbeat" signal.

It's possible to use the 705x's internal WDT peripheral as a generic periodic timer, but it's typically meant to reset the cpu under certain conditions.

Quote:
Ah yes, I see FTDAR settings now. Looks like this is the same regardless of Nissan/Subaru

Correct, just make sure the FTDAR settings doesn't clobber the same ffff3000 block that you want to use for the kernel.

Quote:
Should this change to SCI2 because that's how the Subaru ECU communicates?

Absolutely. SCI1 and SCI2 are on different cpu pins entirely.

_________________
If you like nisprog + npkern, you can support me via https://liberapay.com/fenugrec/
For sending me encrypted/secure messages, use PGP key 0xBAC61AEB3A3E6531 available from pool.sks-keyservers.net


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC - 5 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Style based on FI Subsilver by phpBBservice.nl