AW60 EEPROM Emulation in assembler

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

AW60 EEPROM Emulation in assembler

ソリューションへジャンプ
5,722件の閲覧回数
mylim
Contributor IV
Hi, I've seen a lot of EEPROM emulation example in C. I'm trying to do it in assembler.
I'm currently using CodeWarrior 6.0 on MS Windows Vista platform & the MCU i am using is AW60.
I'm trying to write the flash emulation routine above based on the flow chart show on MC9S08AW60 reference manual page 53. I've attached my code as below.
 
Code:
BLANKCHK    equ    $05BYTEPG      equ    $20BYTEBURSTPG equ    $25PAGEERASE   equ    $40MASSERASE   equ    $41;OK          equ    $00;ERR         equ    $01FADDR       equ    $8000CARDADR     ds     1FLCMD       ds     1 ;--------------------;Flash Erase/Program;--------------------;acca = adr; accx = cmdflash       psha            pshx            brclr  FSTAT_FACCERR,FSTAT,flash1       ;FACCERR = 0—            bset   FSTAT_FACCERR,FSTAT              ;clr errorflash1      bset   FSTAT_FCBEF,FSTAT                ;set FCBEF            lda    CARDADR                          ;load buffer adr & data            sta    FADDR             ldx    FLCMD                            ;write cmd to FCMD            sta    FCMD             nop                                     ;wait 7 cycle            nop            nop            nop            nop            nop            nop            bset   FSTAT_FCBEF,FSTAT                ;set FCBEF             nop                                     ;wait 7 cycle            nop            nop            nop            nop            nop            nop            brset  FSTAT_FACCERR,FSTAT,flashend     ;if FPVIOL = 1 –            brset  FSTAT_FPVIOL,FSTAT,flashend      ;if FACCERR = 1 ˜            feed_watchdog            brclr  FSTAT_FCCF,FSTAT,*               ;if FCCF = 0 ™                      flashend    pulx            pula            rts

 

Could you please advise on my code?
Thanks.
 
Regards,
MY
ラベル(1)
タグ(1)
0 件の賞賛
返信
1 解決策
2,111件の閲覧回数
bigmac
Specialist III
Hello MY,
 
There appears to be numerous issues with your posted code.  The main ones appear to be that you are attempting to use bit manipulation instructions for high page registers.  The bit manipulation instructions are applicable only to zero page registers, so alternative "bit mask" methods will need to be used.
 
Additionally, you do not appear to be running critical code associated with erase and programming operations, from within RAM.  This is necessary because the flash array become inaccessible during the erase and programming procedure.  Two alternatives are possible - to use the stack for the special code, or to use a fixed RAM location.  The attached code uses the latter method.
 
This code has been adapted from both the following recent posts, but is presented as relocatable assembler code, rather than using inline assembly within C code.
 
Regards,
Mac
 
Note that the attached file has been updated from that originally posted.
 



Message Edited by bigmac on 2008-03-17 05:14 PM

S08_Flash_ASM.zip

Message Edited by t.dowe on 2009-10-22 09:32 AM

元の投稿で解決策を見る

0 件の賞賛
返信
20 返答(返信)
2,112件の閲覧回数
bigmac
Specialist III
Hello MY,
 
There appears to be numerous issues with your posted code.  The main ones appear to be that you are attempting to use bit manipulation instructions for high page registers.  The bit manipulation instructions are applicable only to zero page registers, so alternative "bit mask" methods will need to be used.
 
Additionally, you do not appear to be running critical code associated with erase and programming operations, from within RAM.  This is necessary because the flash array become inaccessible during the erase and programming procedure.  Two alternatives are possible - to use the stack for the special code, or to use a fixed RAM location.  The attached code uses the latter method.
 
This code has been adapted from both the following recent posts, but is presented as relocatable assembler code, rather than using inline assembly within C code.
 
Regards,
Mac
 
Note that the attached file has been updated from that originally posted.
 



Message Edited by bigmac on 2008-03-17 05:14 PM

S08_Flash_ASM.zip

Message Edited by t.dowe on 2009-10-22 09:32 AM
0 件の賞賛
返信
2,111件の閲覧回数
mylim
Contributor IV
Hi Bigmac,
Thanks for the sample code.
It makes them clearer to me.
I have another question, I tried on my AW60 board, it seems to keep resetting.
Is it due to the RomStart location?
Am i able to reallocate another location instead of using RomStart?
Thanks.
 
Regards,
mingyee
0 件の賞賛
返信
2,111件の閲覧回数
bigmac
Specialist III
Hello mingyee,
 
I chose the ROMStart location for the NV data storage, to keep it below the start position for the code. This means that the data storage location can remain unprotected, while the flash above, including the program code, can be write protected.  However, another page can be used by changing the NV_DATA equate to another address, and suitably modifying the .prm file.
 
Did you substitute the project.prm file generated by the project wizard, with the one that I attached?  The modified one makes allowance for the NV_DATA position, so that the code does not overlap. It also specifies a block of RAM for the RAM based sub-routine.
 
Check the .map file for the project to confirm that the code is suitably positioned.above the NV_DATA flash page, and that no variables overlap the RAM sub-routine.
 
Note that the main.asm file, used as an example, is not complete.  There is no I/O initialisation, and the ICG module will need to be initialised.  Once the bus frequency is determined, this figure will be required to correctly setup the flash clock frequency.  If you are using the FLASH_CLOCK equate for this purpose (as shown in the sample code), the BUS_CLOCK equate within the file S08_Flash.inc will need to be ammended for the actual bus frequency in use.
 
If resets still occur after you have checked, and if necessary made any corrections, you will need to ascertain their cause by examining the SRS register during debug, and attempting to identify the code where the reset occurs..
 
Regards,
Mac
 
0 件の賞賛
返信
2,111件の閲覧回数
mylim
Contributor IV
Hi Bigmac,
I've change the project.prm file to they one attached.
This time i get this error message;

Link Error : L1119: Vector allocated at absolute address 0xFFFE overlaps with sections placed in segment .absSeg2


 I've done my code as below.

I've gone through the help file & i found this example.

Code:
 ERROR: Vector allocated at absolute address 0xFFFE overlaps with sections placed in segment ROM_2
 LINK  fibo.abs
 NAMES fibo.o startup.o END

 SEGMENTS
   MY_RAM = READ_WRITE 0x800 TO 0x80F;
   MY_ROM = READ_ONLY 0x810 TO 0xAFF;
   MY_STK = READ_WRITE 0xB00 TO 0xBFF;
   ROM_2 = READ_ONLY 0xFF00 TO 0xFFFF;
 END
 PLACEMENT
   .text  INTO MY_ROM;
   .data  INTO MY_RAM;
   .stack INTO MY_STK;
   .rodata INTO ROM_2;
 END

/* Set reset vector on _Startup */
 VECTOR ADDRESS 0xFFFE _Startup

*********************************************************************
 LINK  fibo.abs
 NAMES fibo.o startup.o END

 SEGMENTS
   MY_RAM = READ_WRITE 0x800 TO 0x80F;
   MY_ROM = READ_ONLY 0x810 TO 0xAFF;
   MY_STK = READ_WRITE 0xB00 TO 0xBFF;
   ROM_2 = READ_ONLY 0xC00 TO 0xCFF;
 END
 PLACEMENT
   .text  INTO MY_ROM;
   .data  INTO MY_RAM;
   .stack INTO MY_STK;
   .rodata INTO ROM_2;
 END

/* Set reset vector on _Startup */
 VECTOR ADDRESS 0xFFFE _Startup



 

I tried playing aroound with the ROM2 it still show the same error message.

Please advise.

Thanks.

 

Regards,MY

Flash_S08.zip

Message Edited by t.dowe on 2009-10-22 09:31 AM
0 件の賞賛
返信
2,111件の閲覧回数
bigmac
Specialist III
Hello mingyee,
 
This error suggests that you have defined the contents of the reset vector somewhere within your code.  This is OK, but you will need to remove (comment out) the similar definition from the last line of the .PRM file.  There must be only a single definition.
 
Additionally, the MY_ROM segment now specifies a range within RAM.  This is wrong.
 
Again, I would suggest that you double check the map file for the project, to verify that every subroutine and every variable is located at an appropriate address, and does not overlap either the RAM used for the RAM based sub-routine, or the flash block used for non-volatile data.
 
Regards,
Mac
 


Message Edited by bigmac on 2008-03-18 06:33 PM
0 件の賞賛
返信
2,111件の閲覧回数
mylim
Contributor IV
Hi Bigmac,
After I comment out the last line in the .prm file it works.
//VECTOR 0 _Startup
It's able to compile & able to erase the Flash but still unable to program the Flash.
 
As for the MY_ROM part, I dont quite understand.
You are still refering to the project.prm file?
 
$0000 - $006F direct page register
$0070 - $086F RAM
$0870 - $17FF Flash
$1800 - $185F High Page Register
$1860 - $FFFF Flash
Code:
    Z_RAM        =  READ_WRITE   0x0070 TO 0x00FF;    RAM1         =  READ_WRITE   0x0100 TO 0x010F; /* Reserve for RAM based code */    RAM          =  READ_WRITE   0x0110 TO 0x081F;    SSTACK       =  READ_WRITE   0x0820 TO 0x086F; /* Reserve for stack */    NVDATA       =  READ_ONLY    0x1860 TO 0x19FF; /* Reserve for NV data */    ROM          =  READ_ONLY    0x1A00 TO 0xFFAF;    ROM1         =  READ_ONLY    0x0870 TO 0x17FF;    ROM2         =  READ_ONLY    0xFFC0 TO 0xFFCB;

 
As the given memory allocation, it seems they fall in the correct location.
 
As the project.map portion, 
Code:
*********************************************************************************************SECTION-ALLOCATION SECTIONSection Name                    Size  Type     From       To       Segment---------------------------------------------------------------------------------------------MY_ZEROPAGE                      103   R/W       0x70       0xD6   Z_RAMMCUinit.asm__ORG00001              1     R     0xFFBD     0xFFBD   .absSeg0MCUinit.asm__ORG00002              1     R     0xFFBF     0xFFBF   .absSeg1MCUinit.asm__ORG00003             52     R     0xFFCC     0xFFFF   .absSeg2.init                            101     R     0x1A00     0x1A64   ROMCODE_SECT                        372     R     0x1A65     0x1BD8   ROMDEFAULT_CODE                     103     R     0x1BD9     0x1C3F   ROM.stack                            80   R/W      0x820      0x86F   SSTACKSummary of section sizes per section type:READ_ONLY (R):         276 (dec:      630)READ_WRITE (R/W):       B7 (dec:      183)

 There are not address fall into the RAM section except the ZEROPAGE.
I'm really confused.
 
Thanks.
 
regards,
MY
 
0 件の賞賛
返信
2,111件の閲覧回数
bigmac
Specialist III
Hello mingyee,
 
The reason nothing is allocated within the RAM segment is due to the fact that all your variables have been assigned to the Z_RAM segment, as you specified.
 
How do you know that the erase routine is working?  If you start out with contents 0xFF the erased state, and finish with contents 0xFF, this doesn't prove anything.  I am not clear about your initialisation of the ICG module, and what bus frequency you actually have.  Are you making use of the FLASH_CLOCK equate within your initialisation code?
 
Within my simple test code, I did not check for the occurrence of errors at the conclusion of the erase and programming routines.  So it would be a good idea to place a break point at the termination of each subroutine, in turn, and check the state of the accumulator at this point.  A non-zero value would indicate that an error has occurred.
 
Perhaps you should post a .zip of the whole CW project as it currently stands.  For an assembly only project, having the compiler/assembler generate a listing file is often very useful.
 
Regards,
Mac
 


Message Edited by bigmac on 2008-03-18 10:03 PM
0 件の賞賛
返信
2,111件の閲覧回数
mylim
Contributor IV
Hi Bigmac,
The CPU clock is set to external osc 13.56MHz & internal bus clock at 1.695MHz.
My bus clock is 1695000Hz.
I've attached my code as a zip file.
Coiuld you advise wut i 've left out.
Thanks.
 
Regards,MY
Message Edited by t.dowe on 2009-10-22 09:30 AM
0 件の賞賛
返信
2,111件の閲覧回数
bigmac
Specialist III
Hello MY,
 
When I first attempted to compile your project, there were errors within the MCUInit sub-routine.  It appears that some of the register names, for the ADC module, had been altered to non-standard ones.  PE would have initially used the correct names.
 
Once this problem was corrected, I could see no specific issue with the operation of the code.  Some of the code following _Startup is now redundant, since MCUinit already has initialised the FCDIV register, and enabled interrupts.  So you now do not need to call the FLASH_INIT sub-routine.  The flash clock frequency is probably a little low (for optimum speed), but within the specified limits.
 
The ICG module setup pertains to the use of an oscillator module, rather than a crystal.  Is this your situation?  When you tested the code, I assume that you programmed the code into the actual hardware - you cannot test the flash programming using simulation.
 
If you are still having problems, you will need to examine the error status, upon exit from each sub-routine, as I previously outlined.
 
Regards,
Mac
 
0 件の賞賛
返信
2,111件の閲覧回数
mylim
Contributor IV
Hi Bigmac,
i'm using an external crystal. There shouldnt be any concern i presume?
Previously I tested in simulation mode.
Meaning it will not work on simulation mode?
I will only be able to get my AW60 board either today or tomorrow.
I will be testing with them once i get them.
Thanks.
 
Regards,
MY
0 件の賞賛
返信
2,111件の閲覧回数
bigmac
Specialist III
Hello MY,
 
Your code is currently setup for an external oscillator module (with a single clock input pin to the MCU).  If you require to use an external crystal, the ICG initialisation code, within MCUInit sub-routine, will need to be altered.
 
Regards,
Mac
 
0 件の賞賛
返信
2,111件の閲覧回数
mylim
Contributor IV
Hi Bigmac,
I've altered my MCU_init as follow.
MCU_init:
  ; ### MC9S08AW60_64 "Cpu" init code ...
  ; Common initialization of the write once registers
        ; SOPT: COPE=0,COPT=1,STOPE=0
        LDA     #$53
        STA     SOPT                                              
        ; SPMSC1: LVDF=0,LVDACK=0,LVDIE=0,LVDRE=1,LVDSE=1,LVDE=1,BGBE=0
        LDA     #$1C
        STA     SPMSC1                                              
        ; SPMSC2: LVWF=0,LVWACK=0,LVDV=0,LVWV=0,PPDF=0,PPDACK=0,PPDC=0
        CLRA
        STA     SPMSC2                                              
        ; SMCLK: MPE=0,MCSEL=0
        LDA     SMCLK
        AND     #$E8
        STA     SMCLK
  ;  System clock initialization
        ; ICGC1: HGO=1,RANGE=1,REFS=1,CLKS1=1,CLKS0=1,OSCSTEN=1,LOCD=1
        MOV     #$FE,ICGC1                                       
        ; ICGC2: LOLRE=0,MFD2=0,MFD1=0,MFD0=0,LOCRE=0,RFD2=0,RFD1=1,RFD0=1
        MOV     #$03,ICGC2                                       
        ; ICGTRM: Initialize internal clock trim from a non volatile memory
        LDA     $FF
        STA     ICGTRM

I've changed my ICGC1 & ICGC2 according.
However, I can't init my crystal to 13.56MHz in device initialisation. I'll have to configure to 10MHz.
I'm still able to program into my AW60.
 
The code is able to copy to the RAM (0x100 - 0x10F).
I'm not sure hot to determine whether the SSTACK at the flash is erased.
I couldnt program into the flash either.
I've attached my lastest code for your reference.
Please advise.
 
 
Regards,
MY







Message Edited by mingyee on 2008-03-20 10:19 AM

RAM_Code_After1.jpg

ICGC1_13_56MHz1.jpg

ICGC1_10MHz1.jpg

PAGE_ERASE.jpg

PROG_BYTE_FAILED.jpg

AW60_flash.zip

Message Edited by t.dowe on 2009-10-22 09:27 AM
0 件の賞賛
返信
2,111件の閲覧回数
bigmac
Specialist III
Hello,
 
You now have invalid settings for the ICG module - you are now attempting to use a 13.56 MHz crystal in FEE mode, which is outside the allowable range for the FLL (40 MHz maximum DCO frequency).  In all probability, the flash clock will also be outside its allowable range for flash operations.
 
I would suggest that you carefully examine the data sheet for the AW60 to see how the ICGC1 and ICGC2 registers should be set up to achieve the operation that you requre.  Once you know the bus frequency that you will actually have, you can then work out the setting for the FDIV register to give a flash clock frequency somewhere between 150 and 200 kHz.  Anything outside this range will mean that the flash operations within your program will not work.
 
To test whether the flash erase routine is working, you need to pre-load some data into the NV data block, to be included within the S19 file that is used for programming the device in the first instance.  Since this block has an absolute address, a suitable ORG directive can be used, followed by one or more DC.B directives and an associated list of arbitrary byte values to represent this initial data.
 
Regards,
Mac
 


Message Edited by bigmac on 2008-03-20 10:54 PM
0 件の賞賛
返信
2,111件の閲覧回数
mylim
Contributor IV
Hi Bigmac,
I re-configured the ICG to internal clock (ICGC1 = 0x4c & ICGC2 = 0x52).
I also pre-loaded some data into address 0x1860 - 0x186F.
Then i tried to erase.
I've gone thru step by step but still couldn't get it erased.
I've taken printscreen of the steps.
Could you please help me to look at it see if I've done anything mistake?
Thanks.
 
Regards,MY
Message Edited by t.dowe on 2009-10-22 09:23 AM
0 件の賞賛
返信
2,111件の閲覧回数
bigmac
Specialist III
Hello MY,
 
I could not see any specific problem with your current code.  You appear to be getting an access error early within the erase function, and this will prevent the erase from completing.  You will need to investigate the cause of this error.  Look in the datasheet for all the causes of this error, and eliminate them one by one.
 
I suspect the problem may be the way you are monitoring the operation of the function, with extra register reads occuring during the BDM process.
 
Regards,
Mac
 
0 件の賞賛
返信
2,111件の閲覧回数
mylim
Contributor IV
Hi Bigmac,
I've finally managed to get it work.
You are right about the way i monitor the operation.
I shouldnt place the breakpoint in the flash routine.
In that case, how do i monitor the operation step by step?
Thanks.
 
Regards,
mingyee
 
0 件の賞賛
返信
2,111件の閲覧回数
bigmac
Specialist III
Hello MY,
 
I'm glad you were able to get the code to work.
 
When dealing with MCU hardware registers, there will be instances where it is not possible to single step the code, and this is one of them.  Another instance is where a flag is cleared by the process of reading one or more registers.
 
If the code works as intended, there is really no reason to single step into the function.
 
Regards,
Mac
 
0 件の賞賛
返信
2,111件の閲覧回数
alex1
Contributor I

hello bigmac We are developing an ECU for the seat of a car using MC9S08AC16 We are using 2 sectors of Flash (512 bytes each) as emulated EEPROM. After that, we have a 16 byte gap before the Program area. About the Problem: During sector swapping, the ECU resets due to watchdog time-out. (We did not use the callback function because we are not using internal watchdog, we use external watchdog from SBC80A6624 Atmel) (This problem was solved later on the succeeding software releases by disabling the watchdog prior to writing. Problem might be 99% solved ) When this happens, 2 resulting problems might happen: 1) EEPROM data loss 2) overwriting 1 byte at start of Program area, making the ECU non-functional. atached file is the eeprom driver source code. any suggestion would be a great help.. thank you

Message Edited by alex1 on 2008-05-17 04:38 AM

ee4.zip

Message Edited by t.dowe on 2009-10-22 09:33 AM
0 件の賞賛
返信
2,111件の閲覧回数
bigmac
Specialist III
Hello,
 
Firstly on the reset issue -
 
A sector erase will take 25-35 milliseconds, depending on the flash clock frequency.  If your external watchdog does not have a greater timeout period, you would normally need to reset the watchdog timer within the wait loop of your HighVoltage sub-routine.  Temporarily disabling the watchdog should also work, but resetting the watchdog within the loop should be simpler.
 
For the case of a MCU with a single flash array, as you are using, I think it is rather dangerous to have any possibility of a non-specific "call back" routine executing from within the HighVoltage routine, even it can be disabled with a null address.  Personally, I would totally remove the code from the routine (which will also reduce the size of this RAM based routine).  The wait loop can be further simplified by using a single test to see whether any one of the three FSTAT flags is set, and exiting the routine if so.  Whether the exit was due to an error condition can then be determined from outside this sub-routine.  The error flags would also be cleared from outside.  The following code should considerably reduce the amount of RAM storage required.
 
HighVoltage:
            ldhx  #SGF_FSTAT  ; load FSTAT address
            lda   #SGF_FSTAT_FCBEF ; A <- $80
            sta   ,x          ; launch command
waitFCCF:   reset_watchdog    ; Macro for external watchdog reset
            lda   ,x          ; check flags in FSTAT
            bit   #(SGF_FSTAT_FCCF|SGF_FSTAT_FPVIOL|SGF_FSTAT_ACCERR)
            beq   waitFCCF       
            rts               ; Current FSTAT value returned in ACC
 
But this probably does not help with your current problem.
 
I do not pretend to understand the complexities of your EEPROM emulation process.  However the primary contender for the write problem is probably where indexed addressing has been used to define a flash address location, and you have a wayward H-register value.  It is quite possible that the H-regiister is being corrupted only one percent of the time.  You will need to double check your code for this possibility.
 
I assume that, for the code over-write to occur, that you do not have this portion of flash write protected.  Whenever using flash routines within a program, it is essential that the remainder of the flash containing the program code be write protected.
 
Regards,
Mac
 


Message Edited by bigmac on 2008-05-18 12:34 PM
0 件の賞賛
返信
2,111件の閲覧回数
mylim
Contributor IV
Hi Bigmac,
The AW60 board i was given has a 13.56MHz crytal on it.
I will be skip that & use internal clock instead.
I have initialise the system clock as follow;
Code:
  ;  System clock initialization         ; ICGC1: HGO=0,RANGE=1,REFS=0,CLKS1=0,CLKS0=1,OSCSTEN=1,LOCD=0         MOV     #$4C,ICGC1                                                ; ICGC2: LOLRE=0,MFD2=1,MFD1=0,MFD0=1,LOCRE=0,RFD2=0,RFD1=1,RFD0=0         MOV     #$52,ICGC2                                                ; ICGTRM: Initialize internal clock trim from a non volatile memory         LDA     $FFBE        STA     ICGTRM
  ; ### Init_FLASH init code
        ; FCDIV: DIVLD=0,PRDIV8=1,DIV5=0,DIV4=0,DIV3=0,DIV2=0,DIV1=1,DIV0=0
        LDA     #$42                   ; 162kHz
        STA     FCDIV                  ; Set clock divider
  ; ###
        CLI                            ; Enable interrupts
        RTS
I will test it when i get the board tomorrow.
Thanks.
 
Regards,
mingyee


Message Edited by mingyee on 2008-03-21 04:00 PM
0 件の賞賛
返信