360trev
Full Member
Karma: +68/-2
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: +68/-2
Offline
Posts: 235
|
|
« Reply #16 on: November 12, 2020, 06:54:24 AM »
|
|
|
As promised here's a BSL (Boot Strap Loader) to understand.. ;---------------------------------------------------------------------------------------------------------------------- ; 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: +68/-2
Offline
Posts: 235
|
|
« Reply #17 on: November 12, 2020, 06:57:32 AM »
|
|
|
Hope this mini tutorial was useful to someone Source code will be uploaded soon to GitHub..
|
|
|
Logged
|
|
|
|
gremlin
|
|
« 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... ; 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: +68/-2
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
|
|
« 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.htmlAs 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: +68/-2
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 . 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
|
|
« 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
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
|
|
« 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 guideECUx PlotME7Sum checksumTrim heatmap toolPlease 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 ex
|
|
|
360trev
Full Member
Karma: +68/-2
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 And yes I can take a look soon...
|
|
|
Logged
|
|
|
|
nyet
|
|
« 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 guideECUx PlotME7Sum checksumTrim heatmap toolPlease 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 ex
|
|
|
360trev
Full Member
Karma: +68/-2
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
|
|
« 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 guideECUx PlotME7Sum checksumTrim heatmap toolPlease 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 ex
|
|
|
360trev
Full Member
Karma: +68/-2
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
|
|
|
|
|