Pages: 1 [2] 3
Author Topic: Fully open source ME7 EEPROM tool :)  (Read 31497 times)
360trev
Full Member
***

Karma: +66/-2
Offline Offline

Posts: 235


« Reply #15 on: November 12, 2020, 06:33:40 AM »

Forgot to mention the minimon stuff is entirely MCU architecture (Micro-controller) related. It has nothing to do with Bosch. You can use this approach on ANY C16x derived architecture including ST derivatives etc.
Logged
360trev
Full Member
***

Karma: +66/-2
Offline Offline

Posts: 235


« Reply #16 on: November 12, 2020, 06:54:24 AM »

As promised here's a BSL (Boot Strap Loader) to understand..

Code:
;----------------------------------------------------------------------------------------------------------------------
; Siemens C16x - Stage #1 Boot Strap Loader
;----------------------------------------------------------------------------------------------------------------------
; Warning: Hardware dictates cannot exceed 32 bytes!
;
; This simple boot strap loader simply sets up serial port
; and waits for data (393 bytes) before jumping straight into
; that code.
;----------------------------------------------------------------------------------------------------------------------

bslEntrypoint:  mov     S0TBUF, #1                              ; setup serial

_wait_ir1:      jnb     S0RIR, _wait_ir1                        ; wait forever until we get an serial interrupt
                mov     r0, #entrypoint_2ndStage_start_of_rom   ; setup destination ram address for incoming bytes
;
;-------------- main copy loop
;
_copy_ir_loop:  bclr    S0RIR                                   ; clear the interrupt
_wait_ir2:      jnb     S0RIR, _wait_ir2                        ; wait forever until we get an serial interrupt

                movb    [r0], S0RBUF                            ; receive byte from serial port

                cmpi1   r0, #entrypoint_2ndStage_end_of_rom ; have we got 393 bytes yet?
                jmpr    cc_NZ, _copy_ir_loop ; if not clear irq and wait for another byte
;
;-------------- now jump into entrypoint
;
                jmpa    cc_UC, entrypoint_2ndStage_start_of_rom ; finally lets transfer control to 2nd stage boot loader...

;
;--------------- new 393 byte boot loader will be copied directly after our code...
;
entrypoint_2ndStage_start_of_rom:ds 393                 
entrypoint_2ndStage_end_of_rom:
Logged
360trev
Full Member
***

Karma: +66/-2
Offline Offline

Posts: 235


« Reply #17 on: November 12, 2020, 06:57:32 AM »

Hope this mini tutorial was useful to someone Smiley

Source code will be uploaded soon to GitHub..

Logged
gremlin
Hero Member
*****

Karma: +179/-7
Offline Offline

Posts: 568


« Reply #18 on: November 12, 2020, 07:19:07 AM »

I have reverse engineered ArgDub's driver and yes indeed a lot of that code is recognizable...

Why going such a long and difficult way?
18 years ago it takes me half hour to patch free source code example for X25160 eepom from minimon driver directory and compile new driver for 95040.
Now I looked for  and found it in my archive...
Code:
; My driver to work with SPI EEPROM in ECUs
; 512-byte EEPROM sampling line - P4.7
; The driver is written rather carelessly, it is
; a rewritten version of the driver from the MiniMon kit, in which
; I added a group write function to EEPROM from RAM, using
; script-and this will be done much faster than rather curves
; operations of working with flash by means of the Minimon itself (by byte it works
; extremely slowly).

$SEGMENTED
$MOD167
$NoPaging
           assume  DPP3:system

; Driver function codes

_WriteSPI  equ     00h     ; programming one byte
_ReadSPI   equ     36h     ; read block
_WriteAll  equ     37h     ; block record
_GetState  equ     06h     ; read state

; SPI EEPROM Commands

_EEWrite   equ     02h     ; Write
_EERead    equ     03h     ; Read
_EEState   equ     05h     ; Read Status Register
_EEWREN    equ     06h     ; Enable Write

; MCU registers

P3         defr    0FFC4h          ; port P3
DP3        defr    0FFC6h          ; its direction lines
P6         defr    0FFC8h          ; port P4
DP6        defr    0FFCAh          ; its direction lines
SSCRIC     defr    0FF74h
SSCCON     defr    0FFB2h          ; SSC configuration register
SSCTB      defr    0F0B0h          ; SSC transmit register
SSCRB      defr    0F0B2h          ; SSC receive register
SSCBR      defr    0F0B4h          ; SSC baudrate
SSCRIR     equ     SSCRIC.7        ; exchange completion flag
SPI_CS     equ     P6.3            ; CS line
SPI_CS_PD  equ     DP6.3           ; port direction control

DriverC    section code at 0FD00h

; ------------------------------------------------- ---------------------
; The beginning of the driver itself - initializing ports
; r8 - operation code;
; r9 - block length in bytes;
; r10 - low bytes of the RAM address;
; r13 - low bytes of the EEPROM address;
; r15 - return code on exit
; ------------------------------------------------- ---------------------

DriverP    proc    far

; Deselect EEPROM

           bset    SPI_CS          ; -CS=1
   nop
           bset    SPI_CS_PD       ; and switch the line to output

; SPI init

           extr    #1
           mov     SSCBR,#000Bh    ; baudrate speed in the ECU firmware
           mov     SSCCON,#0C037h  ; configuration
           bfldh   P3,#023h,#23h   ; Set MRST=1, MTSR=1, SCLK=1
           bfldh   DP3,#023h,#22h  ; Set MRST=input, MTSR=output, SCLK=output
           callr   Delay

; ------------------------------------------------- ---------------------
; Programming one byte
; r8 - opcode
; r9 - block length in bytes (for programming - 1, byte!);
; r10 - low bytes of the source block address
; r13 - low bytes of the address in the EEPROM
; r15 - return code on exit
; ------------------------------------------------- ---------------------

           cmp     r8,#_WriteSPI   ; write byte?
           jmp     cc_ne,Cmd1      ; no
           mov     r8,#_WriteAll   ; block write command
           mov     r9,#1           ; and the explicit length is 1 byte
           xor     r10,r13         ; addresses in registries r10 and r13
           xor     r13,r10         ; swapping
           xor     r10,r13

; ------------------------------------------------- ---------------------
; Writing a block from RAM to EEPROM
; r8 - operation code;
; r9 - block length in bytes (for programming - 1, byte!);
; r10 - EEPROM address
; r13 - RAM address
; r15 - return code on exit
; ------------------------------------------------- ---------------------

Cmd1:
           cmp     r8,#_WriteAll   ; block recording?
           jmp     cc_ne,Cmd2      ; no
Block:
           bclr    SPI_CS          ; -CS

           mov     r3,#_EEState
           callr   SendRecSSC       status register read command

           callr   SendRecSSC      ; send dummy byte, receive data byte
           bset    SPI_CS          ; remove the sample
           and     r4,#01h         ; WIP control
           jmp     cc_nz,Block     ; busy ?

           exts    #0,#1
           movb    rl5,[r13]       ; byte of data from RAM

           bclr    SPI_CS          ; EEPROM selection
           mov     r3,#_EEWREN     ; recording enable
           callr   SendRecSSC
           bset    SPI_CS          ; switch off EEPROM selection

           callr   Delay

           bclr    SPI_CS          ; EEPROM selection
           mov     r6,r10          ; EEPROM address
           and     r6,#0700h       ; A8,A9,A10
           shr     r6,#5           ; shift
           mov     r3,#_EEWrite
           or      r3,r6           ; add A8 in command
           callr   SendRecSSC
           mov     r3,r10          ; transmit byte
           callr   SendRecSSC      ; address

           mov     r3,r5           ; data to write in low byte r5
           callr   SendRecSSC      ;
           bset    SPI_CS          ; switch off EEPROM selection

           add     r13,#1          ; next byte in RAM
           add     r10,#1          ; next EEPROM address
           sub     r9,#1
           jmp     cc_nz,Block
           mov     r15,#0          ; completion code
           rets

; ------------------------------------------------- ---------------------
; Reading SPI EEPROM to buffer
; r8 - operation code;
; r9 is the length of the read block;
; r10 - address in EEPROM;
; r13 - buffer address;
; r15 - return code on exit
; ------------------------------------------------- ---------------------

Cmd2:      cmp     r8,#_ReadSPI    ; reading a block?
           jmp     cc_ne,Cmd3      ; no

           bclr    SPI_CS          ; -CS
           
           mov     r3,#_EERead
           callr   SendRecSSC      ; read command

           mov     r3,r10          ; MSB of byte address
   ror    r3,#8
           callr   SendRecSSC

           mov     r3,r10          ; LSB of byte address
           callr   SendRecSSC

           sub     r9,#1
;          mov     r5,#0F200h      ; fixed buffer addr=F200
           mov     r5,r13          ; buffer addr
           addc    r5,r10          ; + offset
ReadLoop:
           callr   SendRecSSC      ; read byte
           exts    #0,#1
           movb    [r5],rl4        ; store byte in buffer
           add     r5,#1           ; next address
           cmpd1   r9,#0
           jmpr    cc_ugt,ReadLoop ; until r9 > 0

           bset    SPI_CS          ; switch off EEPROM selection
           mov     r15,#0          ; completion code
           rets

; ------------------------------------------------- ---------------------
; Reading EEPROM status, r9 returns status value
; ------------------------------------------------- ---------------------

Cmd3:
;      cmp     r8,#_GetState
;           jmp     cc_ne,CmdC
;
Read_S:
           bclr    SPI_CS          ; -CS
           mov     R3,#_EEState
           callr   SendRecSSC      ; status register read command
           
           callr   SendRecSSC      ; send dummy byte, receive data byte
           mov     r9,r4           ; in r9

           bset    SPI_CS          ; switch off EEPROM selection
           mov     r15,#0          ; completion code
           rets

; ------------------------------------------------- ---------------------
; Unrecognized command, exit c r15 = 1
; ------------------------------------------------- ---------------------
CmdC:      mov     r15,#1
           rets

DriverP    endp

;----------------------------------------------------------------------
; Small delay ...
;----------------------------------------------------------------------

Delay      proc    near
           nop
           nop
           nop
           nop
           ret
Delay      endp

; ------------------------------------------------- ---------------------
; SSC work program - data reception and transmission
; r3 - transmitted value; r4 - received value
; ------------------------------------------------- ---------------------

SendRecSSC proc    near

           bclr    SSCRIR          ; reset flag
           mov     SSCTB,r3        ; transmission start

SSCWait:
           jnb     SSCRIR,SSCWait  ; waiting for completion
           mov     r4,SSCRB        ; received data
           ret

SendRecSSC endp

;----------------------------------------------------------------------

DriverC    ends

           end

Logged
360trev
Full Member
***

Karma: +66/-2
Offline Offline

Posts: 235


« Reply #19 on: November 12, 2020, 07:32:36 AM »

All you guys looking at this when it was new had access to the a lot of the manufacturer SDK's and documentations, source-codes, etc. I didn't spot that code! Most of this is rapidly dissappearing off the web as these 16-bit cpu's have long reached end of life. Any source-code contributions are indeed welcome. Finding stuff on these older mcu's isn't so easy these days and yet they are still quite capable processors and good for teaching.

I thought it would be a good example for people to work through from 1st principals. I.e. understand exactly all the details by actually building code that runs on the actual microcontroller.
I've built my own assembler, dissassembler and C compiler for the C16x series now too. (Yes I know others exist) and soon I plan to integrate the Arduino IDE so that you can build apps which can manipulate the gpio's etc. directly from the ide...

I took a look quick look at your driver, the only recommendation I would have would be to use a hardware timer for your delay as running on a 20MHz vs 40MHz device will yield different times for your nop's...
« Last Edit: November 12, 2020, 07:36:18 AM by 360trev » Logged
gremlin
Hero Member
*****

Karma: +179/-7
Offline Offline

Posts: 568


« Reply #20 on: November 12, 2020, 08:29:22 AM »

All you guys looking at this when it was new had access to the a lot of the manufacturer SDK's and documentations, source-codes, etc. I didn't spot that code!

When I was working on this driver, I did not have any non-public documents or special access to professional ide / sdk.
Only minimon, which has not disappeared anywhere and is still freely available on the Internet.
All sources texts present now.
http://www.perschl.at/minimon.html
As for the driver's optimality, was say that this is a "five-minute soup" and no one bothers to improve it.

In my opinion, the time for such a program has gone like the last train. Everything has already been done and more than once.
It can be interesting only for educational purposes.

Logged
360trev
Full Member
***

Karma: +66/-2
Offline Offline

Posts: 235


« Reply #21 on: November 12, 2020, 08:58:15 AM »

I hear you...

There are still however millions of cars on the road with these ecu's inside them and millions more in scrap yards. There is still value there if you care to look hard enough.

The concepts of these old obsolete 16-bit microcontroller are still alive and kicking and found in modern applications. Even modern cars can still use them, just likely with a different instruction set driving them which is probably arm based. Your soft close door locks on a 2020 MY car very likely have a modernized NXP 16-bit MCU driving them. SPI, I2C, PWM, GPIO, Serial, CAN, DMA, etc. all used today in pretty much same way except hidden behind layers of API's. If you extrapolate away from bare metal assembly you find you can still write a lot of the code in a portable way in C, then that inself can be transferred across to current soc's like infineon tricore's and such via cross compilation (even in the eeprom is now emulated in flash Smiley. The biggest problem with these obscure instruction sets like C16x is lack of good tooling, the code optimization of those proprietary (very old GCC based!) C compilers is frankly shocking, no wonder so much was written in assembly at the time...

-T
Logged
Blazius
Hero Member
*****

Karma: +89/-40
Offline Offline

Posts: 1277



« Reply #22 on: November 12, 2020, 10:04:58 AM »

Terrific job! Thanks for all your contributions.
Logged
DT
Full Member
***

Karma: +20/-1
Offline Offline

Posts: 184


« Reply #23 on: November 12, 2020, 12:43:36 PM »

Thank you for this write up. Always nice to see custom code.
Logged

nyet
Administrator
Hero Member
*****

Karma: +604/-166
Offline Offline

Posts: 12232


WWW
« Reply #24 on: November 12, 2020, 03:05:29 PM »

Amazing. Any chance I can get you to finish the bootmode flash stuff in the nef flasher?

or even better, integrate eeprom access into the nef flasher?
Logged

ME7.1 tuning guide (READ FIRST)
ECUx Plot
ME7Sum checksum checker/corrrector for ME7.x

Please do not ask me for tunes. I'm here to help people make their own.

Do not PM me technical questions! Please, ask all questions on the forums! Doing so will ensure the next person with the same issue gets the opportunity to learn from your experience.
360trev
Full Member
***

Karma: +66/-2
Offline Offline

Posts: 235


« Reply #25 on: November 12, 2020, 04:19:10 PM »

Nyet, DT and Blazius,

Thank you so much for the nice comments. I was beginning to think nobody cared anymore.

I'm determined to get an Arduino IDE running on Bosch ME7 hardware, it will be called the ME7duino  Smiley

And yes I can take a look soon...
Logged
nyet
Administrator
Hero Member
*****

Karma: +604/-166
Offline Offline

Posts: 12232


WWW
« Reply #26 on: November 12, 2020, 05:02:59 PM »

While im here, the nef flasher shouldn't require ftdi cables anymore either... its been on my list to fix but i dont have a functional non-ftdi cable to test on.

I assume none of your routines strictly depend on the ftdi dll either.
Logged

ME7.1 tuning guide (READ FIRST)
ECUx Plot
ME7Sum checksum checker/corrrector for ME7.x

Please do not ask me for tunes. I'm here to help people make their own.

Do not PM me technical questions! Please, ask all questions on the forums! Doing so will ensure the next person with the same issue gets the opportunity to learn from your experience.
360trev
Full Member
***

Karma: +66/-2
Offline Offline

Posts: 235


« Reply #27 on: November 12, 2020, 05:34:39 PM »

Nothing that's talking over K-Line serial alone requires anything at USB level.

I've written a Serial UART abstraction api, this means you can indeed cross compile all the higher level code to run across any OS. I.e. on OSX, Linux and any other embedded mcu. Technically you can re-flash or read eeprom from a simple microcontroller with an SD card attached or Wifi connection to your mobile hotspot.

Your not strictly limited to just UART serial as a means of communication either, as long as you software bridge the connection api's you can even re-direct read/writes over tcp/ip (internet) and on the device side flash receive data over CAN at 1Mbps. Its something I would like to implement a driver for along with differential flashing capability, so if you've previously flashed the same image and want to make incremental changes to just some maps like KFZW, checksums etc. your "update" is going to be pretty much instantaneous rather than minutes. The bottleneck for boot flashing is the relatively slow uart uplink speed.




Logged
nyet
Administrator
Hero Member
*****

Karma: +604/-166
Offline Offline

Posts: 12232


WWW
« Reply #28 on: November 12, 2020, 05:44:45 PM »

Differential flashing still sucks in Nef because you have to erase/write the whole affected block.

It is already implemented.

back on topic: the only reason it used the ftdi dll was for licensing against fdti serial number, which is no longer a requirement. In this case (coincidentally) on the topic of differential flashing.

Or are you talking about bootmode differential flashing? Because that would be amazing. Still, it suffers from the block issue.
Logged

ME7.1 tuning guide (READ FIRST)
ECUx Plot
ME7Sum checksum checker/corrrector for ME7.x

Please do not ask me for tunes. I'm here to help people make their own.

Do not PM me technical questions! Please, ask all questions on the forums! Doing so will ensure the next person with the same issue gets the opportunity to learn from your experience.
360trev
Full Member
***

Karma: +66/-2
Offline Offline

Posts: 235


« Reply #29 on: November 12, 2020, 06:28:00 PM »


Yes I'm talking about differential flashing in bootmode and also download of the data via high speed CAN driver.

This obviously means you cannot just have a dumb K-Line serial to uart IC. You also need a CAN ic too. These however are less than $1 these days and the big benefit is dramatically faster downloads. The flashing isn't really the slowest part, its the download speeds, 1mbps is multiple times quicker than serial uart can do it.

Did you know on these AMD flash devices that even if you don't erase a sector you can still write to it too? You can just OR each byte. @Fluke9 explained the trick to me. You can flip the bit to a high in a write but never to a low, so you can do bitwise changes and not disturb the whole byte.

Logged
Pages: 1 [2] 3
  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Page created in 0.025 seconds with 16 queries. (Pretty URLs adds 0s, 0q)