DZ60 - Problem flashing some adresses

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

DZ60 - Problem flashing some adresses

跳至解决方案
2,305 次查看
PierreAFD
Contributor II

Hi, I am currently porting my bootloader to the MC9S08D60.

I've been using this bootloader on 9S08AW60, 9S08AC60, 9S08AC96.

 

So I wasn't expecting what happend....

I have changed the page size from 512 to 768 bytes (datasheet), I also have noticed that the erased page is not a multiple of 768 (experiment), and that burst programming works only for 32 consecutive bytes, starting at a multiple of 32.

 

Here is a list  of related topics I found :

S08 Flash question programming, strange results

https://community.freescale.com/message/33624#33624

 

Here is what happends :

After blanking my page, I start programming is, say 32 bytes per 32.

During the first 256 bytes, all bytes are written.

From 256 to 511, I can flash the first byte, and get an access error when attempting to write the next byte.

From 512 to 767, all bytes are written again

 

Thats the same is I proceed 256 per 256 bytes, or 8 per 8 bytes.

 

You will find attached two S19, before and after flashing. The files should be the same (I suggest the use kdiff3 or winmerge to ease comparison).

The area to be programmed is 0x3100..0x33FF, here is a snapshot of the borders :

 

S123 31E0 EB37EAFCEABFEA81EA41E9FFE9BCE977E931E8E8E89DE84FE7FEE7ABE754E6FA5F
S123 3200 E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3

 

S123 32E0 04FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5
S123 3300 049B049A0499049904980498049704970496049504950494049404930493049204

 

Here is the assembly routine that I use. I think I found it some where around this forum :

 

ProgSub:            lda   #(mFSTAT_FPVIOL|mFSTAT_FACCERR) ;clear FSTAT[PVIOL,ACCERR]            ldhx  #FCNFG  ;load address of FCNFG            sta   2,x         ;double-write FSTAT ensures FSTAT[PVIOL,ACCERR] are cleared            sta   2,x            clr   ,x          ;write $00 to FCNFG to clear FCNFG[KEYACC]            clra              ;clear return code            psha              ;save to stack, used as return code and operation resultcheckSize:            lda   #1          ;set the stop function flag            ldhx  LEN        ;check if size is zero            beq   waitFCCF    ;if zero, wait FCCF set and terminate function            aix   #-1         ;sub size by 1            sthx  LEN            pula              ;remove previous operation result and ignore AwaitFCBEF:            lda   FSTAT   ;check if FSTAT[FCBEF] is high            bpl   waitFCBEF   ;new command can only be start if FSTAT[FCBEF] is high            ldhx   ADRR      lda    0,x      aix    #1      sthx   ADRR      ldhx    ADRS    ;get flash address      sta    0,x    ;write to flash; latch addr and data      aix    #1      sthx   ADRS            lda   #mBurstProg ;load A with burst program command            sta   FCMD         ;store burst program command to FCMD            lda   #mFSTAT_FCBEF ;launch command            sta FSTAT   ;4 bus cycle   nop   nop   nop   nop            lda   ,x          ;check error flags in FSTAT            and   #(mFSTAT_FPVIOL|mFSTAT_FACCERR) ;reserve FSTAT[PVIOL,ACCERR]            psha              ;return code and operation result in A; save to stack            beq   checkPAGEEND ;do the next program sequence if success            sta   ,x          ;clear FSTAT[PVIOL,ACCERR]            bra   waitFCCF    ;non zero in A will stop function after FSTAT[FCCF] setcheckPAGEEND:                 ;need to wait FSTAT[FCCF] set at page boundary            tsx            lda   9,x         ;high byte of dest            asra              ;lowest bit saved in carry bit            bcs   checkSize   ;not a page start if carry bit is set            lda   10,x        ;low byte of dest            bne   checkSize   ;not a page start if low byte is non zero,                              ;Zero in A. function continue after FSTAT[FCCF] setwaitFCCF:            psha              ;save stop flag            ldx   FSTAT   ;check if FSTAT[FCCF] is high            aslx              ;commands are finished if FSTAT[FCCF] is high            pula              ;retrieve stop flag            bpl   waitFCCF    ;wait until FSTAT[FCCF] is high            tsta              ;check if stop function            beq   checkSize            pula              ;retrieve return code from stack            ldhx STACK            txs            rtsProgSubEnd:ProgSubSize: equ (*-ProgSub)

 

I tried to add some more nop after starting programming, without succes.

 

Can Anyone help me to fix the problem ?

 

Regards,

 

Pierre

标签 (1)
0 项奖励
回复
1 解答
1,744 次查看
PierreAFD
Contributor II

I didn't notice on p65 that if the base block address is not a multiple of 768, the protected area size is always.

 

You were right : the line you pointed on my code

lda   ,x

is incorrect, since HX points to ADRS ...

 

I fixed my code by replacing this line by

lda FSTAT

 

The funny, and also worrying, fact is that this bug is on a bootloader that I use on all my freescale projects. So far, it has gone through all tests !

 

Thanks for your help.

 

Pierre

在原帖中查看解决方案

0 项奖励
回复
10 回复数
1,744 次查看
bigmac
Specialist III

Kef,

The 'DZ60, and related devices are different from most other HCS08 devices in that the flash sector size has been increased to 768 bytes.

 

Pierre,

I assume that you are actually using the "doonstack' method, with the data pre-loaded to the stack, followed by the ProgSub code.  But the stack usage for the data is not immediately evident from your code snippet.  Have you checked that the data being read is correct, and there is not a data indexing problem?

 

Keep in mind that, with the 'DZ60 there is an alternative approach, that would provide simpler code.  This is to place the ProgSub code permanently into EEPROM, and run the code from there.  EEPROM is a separate array from flash for this device, so is accessible during flash programming.

 

Also consider that, if you are erasing the non-volatile data sector immediately prior to the programming process, there is usually little justification to use burst programming mode, as the sector erase period will exceed the programming period for the data.  Byte-by-byte programming will occupy a marginally longer period, but should give somewhat simpler and much more straightforward code.  Burst programming is really only of value for time critical applications, where the sector has already been erased.

 

Some general comments about your code:

I would see little point in writing to FCNFG register, as you are not dealing with the backdoor key.  Indexing to this register has apparently caused some indexing errors later in the code.  I assume that the original code on which you based your code actually indexed to FSTAT.  I do not know why you would need to double write to FSTAT.

 

Regards,

Mac

 

0 项奖励
回复
1,744 次查看
PierreAFD
Contributor II

bigmac :

You are right : I use the "doonstack" method. But as far as I can remember, I didn't change a byte from the code I got, except the code section and a macro name. I join the full source file to this post.

 

I have checked that the pointers are correct, their values are ok, and so the pointed data.

 

I am about to place the code in the eeprom to ease debuging, but think in the end I will still have to use the flash code from ram since I want to keep the eeprom dedicated to the application.

 

What you say about burst/non burst programming is intersting, I didn't consider that point : I just wanted the fastest possible code !

 

kef also pointed some issues about fstat, I'll check that, and compare my code to the one provided in the bootloader application sample.

The double write to fstat was already there.

 

Also, is it realy necessary to program 32 bytes per 32 bytes ?  I tested with 256 bytes, and it was ok, for the 256 first and last bytes only.

 

Thanks for your help so far

 

Pierre

0 项奖励
回复
1,745 次查看
kef
Specialist I

Mac,

 

I'm using S08DZ and am sure sector/page size is 768. I disagree with Pierre's comment:

 

  •  I also have noticed that the erased page is not a multiple of 768 (experiment),

 

 

0 项奖励
回复
1,745 次查看
bigmac
Specialist III

Hello Kef,

 

Sorry, I misinterpreted your previous comment.

 

Regards,

Mac

 

0 项奖励
回复
1,745 次查看
kef
Specialist I

Page size is not 768 bytes? You must be wrong.

 

I see at least one problem in your code:

 

      ldhx    ADRS    ;get flash address      sta    0,x    ;write to flash; latch addr and data      aix    #1      sthx   ADRS            lda   #mBurstProg ;load A with burst program command            sta   FCMD         ;store burst program command to FCMD            lda   #mFSTAT_FCBEF ;launch command            sta FSTAT   ;4 bus cycle   nop   nop   nop   nop===> HX doesn't point to FSTAT!            lda   ,x          ;check error flags in FSTAT            and   #(mFSTAT_FPVIOL|mFSTAT_FACCERR) ;reserve FSTAT[PVIOL,ACCERR]

 

0 项奖励
回复
1,745 次查看
PierreAFD
Contributor II

Yes, I use a 768 byte page, but I made a mistake in my sentence.

 

What I wanted to say is :

"The starting adress of the erased page is not at a multiple of 768 bytes"

 

Considering these points, it comes to something logic :

- The flash starting adress is 0x1900, which is not a multiple of 768 bytes.

- In my example, when I set the erase adress to 0x3300 (which is a multiple of 768), the bytes effectively erased are from 0x3100 (which is a not multiple of 768) to 0x33FF.

I think this is due to the flash protection mechanism which still work on multiples of 512 bytes, if you look at the first protected bytes in the datasheet (cf datasheet table 4.14 page 65 ).

 

Thanks for your suggestion about HX not pointing to fstat, I must have a look !

 

Pierre

0 项奖励
回复
1,745 次查看
kef
Specialist I

Pierre,

 

Yes, 64k address space is not divisible by 0x300 (768). Since vectors are in top most addresses and flash has to be there, 0x300 bytes sectors are aligned not to the bottom of address space (address 0), but to the top of address space. The top most sector(page) is 0xFD00-FFFF, then 0xFA00-0xFCFF etc. In other words each sector starts at address

 

 (0x10000 % 0x300) + (N * 0x300) = 0x100, 0x400, 0x700 etc

 

Flash protection scheme works not on multiple of 512 bytes, but on multiple of two 768 sectors. See datasheet page 65. Flash Block Protection table. You can protect 0 kB, 1.5kB( 2x768), 3kB (4*768), 4.5kB etc.

 

 

(You may wonder why such odd sector size. Look at S08DE datasheet. With flash error correction (ECC) enabled, you have 512 bytes sectors, with ECC off you have 768 bytes sectors. Extra 256 bytes in the sector are used for errors correction. I guess DZ60 uses same flash arrays, just that the ECC feature is disabled.)

0 项奖励
回复
1,745 次查看
PierreAFD
Contributor II

I didn't notice on p65 that if the base block address is not a multiple of 768, the protected area size is always.

 

You were right : the line you pointed on my code

lda   ,x

is incorrect, since HX points to ADRS ...

 

I fixed my code by replacing this line by

lda FSTAT

 

The funny, and also worrying, fact is that this bug is on a bootloader that I use on all my freescale projects. So far, it has gone through all tests !

 

Thanks for your help.

 

Pierre

0 项奖励
回复
1,745 次查看
bigmac
Specialist III

Hello Pierre,

 

For comparison purposes, I have attached some code that uses an alternative method for byte-by-byte programming.  This code uses a fixed location in RAM for the RAM resident code, rather than using the stack.  This code size requrement is less than 20 bytes, is common to erase and programming routines, and could alternatively be programmed to EEPROM, for the 'DZ60.

 

Regards,

Mac

 

0 项奖励
回复
1,745 次查看
PierreAFD
Contributor II

Thanks, very compact !

 

I also have the SGF reference driver (copyright ... motorola !! ).

Bigger, but complete.

 

Pierre

0 项奖励
回复