SSM2 via CAN

Link to page: SSM2 via CAN


3 responses to “SSM2 via CAN

  1. Those addresses are writable.
    Hope this helps.
    0x00 (read_memory_disable???)
    0x60(ecu reset)
    0x6f(ignition retard)
    0x70(idle speed)
    0x71(idle speed aircon)
    0x89(address index byte_0???)
    0x8A(address index byte_1???)
    0xe8(ecu soft rest???)

    ROM:0002C33E ; =============== S U B R O U T I N E =======================================
    ROM:0002C33E SSM_WRITE_@060_RESET: ;
    ROM:0002C33E mov.w @(h’72,pc), r2 ; [0002C3B4] = h’FFFFAF28
    ROM:0002C340 mov.l @(h’80,pc), r1 ; [0002C3C4] = (loc_AA54+1) ; / AA55 -> r1
    ROM:0002C342 mov.b r4, @r2
    ROM:0002C344 mov.w @r2, r3
    ROM:0002C346 extu.w r3, r3
    ROM:0002C348 cmp/eq r1, r3
    ROM:0002C34A bt/s SSM_WRITE_@060_1
    ROM:0002C34C nop
    ROM:0002C34E mov.l @(h’78,pc), r3 ; [0002C3C8] = Mark_RAM_Invalid
    ROM:0002C350 jmp @r3 ; Mark_RAM_Invalid
    ROM:0002C352 nop
    ROM:0002C354 ; —————————————————————————
    ROM:0002C354 SSM_WRITE_@060_1: ;
    ROM:0002C354 rts
    ROM:0002C356 nop
    ROM:0002C356 ; End of function SSM_WRITE_@060_RESET
    ROM:0002C358 ; —————————————————————————
    ROM:0002C358 SSM_WRITE_@06F_IGN_RETARD: ;
    ROM:0002C358 sts.l pr, @-r15
    ROM:0002C35A fldi0 fr5
    ROM:0002C35C mov.l @(h’6C,pc), r3 ; [0002C3CC] = sub_25F8
    ROM:0002C35E jsr @r3 ; sub_25F8
    ROM:0002C360 fldi1 fr4
    ROM:0002C362 mov.w @(h’50,pc), r2 ; [0002C3B6] = h’FFFFAF1C
    ROM:0002C364 lds.l @r15+, pr
    ROM:0002C366 rts
    ROM:0002C368 fmov.s fr0, @r2
    ROM:0002C36A ; —————————————————————————
    ROM:0002C36A SSM_WRITE_@070_IDLE: ;
    ROM:0002C36A sts.l pr, @-r15
    ROM:0002C36C mova @(h’60,pc), r0 ; [0002C3D0] = h’FFFFC548
    ROM:0002C36E fmov.s @r0, fr5
    ROM:0002C370 mova @(h’60,pc), r0 ; flt_2C3D4 ; / 25
    ROM:0002C372 mov.l @(h’58,pc), r3 ; [0002C3CC] = sub_25F8
    ROM:0002C374 jsr @r3 ; sub_25F8
    ROM:0002C376 fmov.s @r0, fr4
    ROM:0002C378 mov.w @(h’3C,pc), r2 ; [0002C3B8] = h’FFFFAF20
    ROM:0002C37A lds.l @r15+, pr
    ROM:0002C37C rts
    ROM:0002C37E fmov.s fr0, @r2
    ROM:0002C380 ; —————————————————————————
    ROM:0002C380 SSM_WRITE_@071_IDLE_AIRCON: ;
    ROM:0002C380 sts.l pr, @-r15
    ROM:0002C382 mova @(h’4C,pc), r0 ; [0002C3D0] = h’FFFFC548
    ROM:0002C384 mov.l @(h’44,pc), r3 ; [0002C3CC] = sub_25F8
    ROM:0002C386 fmov.s @r0, fr5
    ROM:0002C388 mova @(h’48,pc), r0 ; flt_2C3D4 ; /25
    ROM:0002C38A jsr @r3 ; sub_25F8
    ROM:0002C38C fmov.s @r0, fr4
    ROM:0002C38E mov.w @(h’28,pc), r2 ; [0002C3BA] = h’FFFFAF24
    ROM:0002C390 lds.l @r15+, pr
    ROM:0002C392 rts
    ROM:0002C394 fmov.s fr0, @r2
    ROM:0002C396 ; —————————————————————————
    ROM:0002C396 SSM_WRITE_@089_FFFFB014: ;
    ROM:0002C396 mov.w @(h’22,pc), r3 ; [0002C3BC] = h’FFFFB014
    ROM:0002C398 rts
    ROM:0002C39A mov.b r4, @r3
    ROM:0002C39C ; —————————————————————————
    ROM:0002C39C SSM_WRITE_@08A_FFFFB015: ;
    ROM:0002C39C mov.w @(h’1E,pc), r3 ; [0002C3BE] = h’FFFFB015
    ROM:0002C39E rts
    ROM:0002C3A0 mov.b r4, @r3
    ROM:0002C3A2 ; —————————————————————————
    ROM:0002C3A2 SSM_WRITE__@0E8_FFFF80D8_SOFT_RESET ???: ;
    ROM:0002C3A2 sts.l pr, @-r15
    ROM:0002C3A4 mov.l @(h’30,pc), r3 ; [0002C3D8] = MAKE_1BYTE_CHECK_R4_R0
    ROM:0002C3A6 jsr @r3 ; MAKE_1BYTE_CHECK_R4_R0
    ROM:0002C3A8 nop
    ROM:0002C3AA mov.w @(h’12,pc), r2 ; [0002C3C0] = h’FFFF80D8
    ROM:0002C3AC lds.l @r15+, pr
    ROM:0002C3AE rts
    ROM:0002C3B0 mov.w r0, @r2


    • Hi Sasha_A80,
      thanks for the write addresses overview.
      The additional write limitation meant in the blog post affects SSM2 over CAN.
      I’ve checked gasoline ECU ROM and found it, too. Like Diesel, only 0x60 is allowed using CAN.
      Basically that means one cannot do maintenance jobs via CAN (other than ECU reset), we have to use serial communication instead.

      Concrete example: 2011 STi
      Hex file is posted on
      Following is a quick diassembly, may contain errors!

      CAN-handler sub for B8-WriteAddress-command:

      ROM:000927B4 ; r4: length after cmd byte
      ROM:000927B4 ; Attributes: noreturn
      ROM:000927B4 CanHandlerB8_927B4: ; DATA XREF: ROM:00093C98#o
      ROM:000927B4 ; ROM:00093D34#o
      ROM:000927B4 mov.l r14, @-r15
      ROM:000927B6 sts.l pr, @-r15
      ROM:000927B8 add #-h'28, r15
      ROM:000927BA mov #-1, r2
      ROM:000927BC mov #h'1C, r0
      ROM:000927BE mov.b r2, @(r0,r15)
      ROM:000927C0 extu.w r4, r6 ; r6 = length after cmd byte
      ROM:000927C2 mov r6, r0
      ROM:000927C4 cmp/eq #4, r0 ; must be 4: Address[3] + Byte[1]
      ROM:000927C6 bt/s Length_Ok_loc_927CE
      ROM:000927C8 mov #0, r14
      ROM:000927CA bra CheckErrR14_loc_92838
      ROM:000927CC mov #h'13, r14
      ROM:000927CE ; ---------------------------------------------------------------------------
      ROM:000927CE Length_Ok_loc_927CE: ; CODE XREF: CanHandlerB8_927B4+12#j
      ROM:000927CE mov r15, r5
      ROM:000927D0 mov.l off_928C4, r2 ; CopyPacketBytes_9546E
      ROM:000927D2 mov #-h'48, r4
      ROM:000927D4 jsr @r2 ; CopyPacketBytes_9546E
      ROM:000927D6 extu.b r4, r4
      ROM:000927D8 mov.b @r15, r2
      ROM:000927DA extu.b r2, r4
      ROM:000927DC shll16 r4
      ROM:000927DE mov.b @(1,r15), r0
      ROM:000927E0 extu.b r0, r2
      ROM:000927E2 shll8 r2
      ROM:000927E4 add r2, r4
      ROM:000927E6 mov.b @(2,r15), r0
      ROM:000927E8 extu.b r0, r2
      ROM:000927EA add r2, r4 ; r4: SSM2Address
      ROM:000927EC mov.w word_928C0, r2 ; h'350
      ROM:000927EE cmp/hs r2, r4 ; address >= 0x350 ?
      ROM:000927F0 bt/s Err22_loc_92836
      ROM:000927F2 mov.l r4, @(h'20,r15) ; store address
      ROM:000927F4 bsr IsSsmWriteAddressInvalid_9289C ; Argument r4: Ssm2Address
      ROM:000927F4 ; Returns r0: bool
      ROM:000927F6 ; ---------------------------------------------------------------------------
      ROM:000927F6 nop
      ROM:000927F8 extu.b r0, r2 ; r2 = result
      ROM:000927FA tst r2, r2 ; result == 0 ?
      ROM:000927FC bf Err22_loc_92836 ; if (result) return err 0x22
      ROM:000927FE mov.l @(h'20,r15), r2 ; r2 = saved address
      ROM:00092800 shll2 r2 ; *4
      ROM:00092802 mov.l r2, @(h'24,r15)
      ROM:00092804 mov.l off_928C8, r4 ; SSM2WRITEVECTOR_616D0

      So above sub calls this sub “IsSsmWriteAddressInvalid”:

      ROM:0009289C ; Argument r4: Ssm2Address
      ROM:0009289C ; Returns r0: bool
      ROM:0009289C ; Attributes: noreturn
      ROM:0009289C IsSsmWriteAddressInvalid_9289C: ; CODE XREF: CanHandlerB8_927B4+40#p
      ROM:0009289C mov r4, r7 ; r7 = address
      ROM:0009289E mov #1, r1 ; r1 = count = 1; also default return value = true
      ROM:000928A0 mov #0, r5
      ROM:000928A2 bra CheckLoopCondition_loc_928B8
      ROM:000928A4 mov r5, r4 ; r4 = 0
      ROM:000928A6 ; ---------------------------------------------------------------------------
      ROM:000928A6 Do_loc_928A6: ; CODE XREF: IsSsmWriteAddressInvalid_9289C+1E#j
      ROM:000928A6 mov.l off_928E8, r6 ; SsmAllowedWriteAddressesTable_94E28
      ROM:000928A8 mov r4, r0
      ROM:000928AA mov.l @(r0,r6), r2
      ROM:000928AC cmp/eq r7, r2 ; addressFromTable == address ?
      ROM:000928AE bf Next_loc_928B4
      ROM:000928B0 bra RetR1_loc_928BC
      ROM:000928B2 mov #0, r1 ; return 0 = false meaning address is not invalid
      ROM:000928B4 ; ---------------------------------------------------------------------------
      ROM:000928B4 Next_loc_928B4: ; CODE XREF: IsSsmWriteAddressInvalid_9289C+12#j
      ROM:000928B4 add #1, r5 ; i++
      ROM:000928B6 add #4, r4 ; inc offset to next table value
      ROM:000928B8 CheckLoopCondition_loc_928B8: ; CODE XREF: IsSsmWriteAddressInvalid_9289C+6#j
      ROM:000928B8 cmp/hs r1, r5 ; i >= r1 ?
      ROM:000928BA bf Do_loc_928A6
      ROM:000928BC RetR1_loc_928BC: ; CODE XREF: IsSsmWriteAddressInvalid_9289C+14#j
      ROM:000928BC rts
      ROM:000928BE mov r1, r0 ; return r1
      ROM:000928BE ; End of function IsSsmWriteAddressInvalid_9289C

      Table only has one entry:
      ROM:00094E28 h'60

      Can you confirm that this limitation does exist in other ROMs, too?


  2. I am trying probably the first 32 bit (512 kB) ecu from JDM MY03 Forester not supported currently.

    A8/A0 commands allow 0-0x159 SSM data to be read thru lookup table,
    as well 0x60000-0x7FFFFF region with calibrations and RAM 0xFFFF8000-0xFFFFdFFF locations.

    B8 has a support just for mentioned above SSM address.

    B0 is able to write RAM 0xFFFF9000-0xFFFFdFFF locations.
    Learning values at 0xFFFF8000-0xFFFF8FFF are write protected.

    CAN is physically present and sends 0x410 CANID message (ecu is at the bench). I failed to upload initial and operating system bootloaders and do not see any CAN related code inside the ROM region I got.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s