This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Erasing a sector from the internal memory block

Hello,

I have a problem when erasing the internal memory block on an XC167CS-32F microcontroller.

I can erase sectors 0, 1, 2, and 3 OK. Sector 4 fails to erase, but then sectors 5, 6, and 7 erase OK.

I can write to all of the sectors (with the exception of sector 3).

The Keil uVision 'Flash->Erase' instruction DOES manage to do the erase correctly, so I know that my device is OK - it is just down to something that I am doing wrong.

Is it possible that one of the sectors (sector 4) has become 'protected', and if so, how do I go about reseting things so that the sector is no longer protected !

Thanks for you help,

Simon May

Parents
  • I am not sure what is going on your setup. I made some code to erase and I don't see the same issue. The sector erase only takes about 220 msec to complete. I also preprogrammed the complete sector with a pattern of 0x55AA.

    You can use a hardware timer without interrupts. You just need to poll the ready flag.

      src = (U16 huge *)0xC08000;
      ResetToRead();
      ClearStatus();
      FlashErase(src);
      flashStatus = *(U16 huge *)(0xFFF000);
    

    With the FlashErase routine:

      T2CON     DEFR  0FF40H
      T2        DEFR  0FE40H
      T2IC      DEFR  0FF60H
      T2R       BIT   T2CON.6
      T2IC_IR   BIT   T2IC.7
    
    TIMEOUT_1SEC EQU 19531
    
    ;*****************************************************************************
    ;
    ; Function    :  void far FlashErase(unsigned int huge * src)
    ;
    ;             :  sector base address passed in registers 'R8/R9'
    ;******************************************************************************
      FlashErase  PROC  FAR
      PUBLIC  FlashErase
    
      MOV   T2,#TIMEOUT_1SEC
      BCLR  T2IC_IR
    
    ; *(unsigned int huge *) (0xC000AA) = 0x0080;
      MOV   R4,#080H
      EXTS  R9,#1
      MOV   000AAH,R4
    
    ; *(unsigned int huge *) (0xC00054) = 0x00AA;
      MOV   R4,#0AAH
      EXTS  R9,#1
      MOV   00054H,R4
    
    ; *src = 0x0033;
      MOV   R4,#033H
      EXTS  R9,#1
      MOV   [R8],R4
    
    FlashEraseActive:
      NOP
      NOP
      NOP
      NOP   ; delays to make sure Flash state machine starts
      EXTS  #0FFH,#1
      MOV   R4,0F000H
      JNB   R4.2,FlashEraseExit
    
      BSET  T2R ; start timer
    
    ;  wait for flash operation to finish or timeout
    FlashEraseDone:
      JB    T2IC_IR,FlashEraseExit ; jump on timeout
      EXTS  #0FFH,#1
      MOV   R4,0F000H
      AND   R4,#5
      JMP   cc_NZ,FlashEraseDone  ; wait for command to finsih
    
    FlashEraseExit:
      BCLR  T2R     ; stop timer
      RETS
    
      FlashErase  ENDP
    

Reply
  • I am not sure what is going on your setup. I made some code to erase and I don't see the same issue. The sector erase only takes about 220 msec to complete. I also preprogrammed the complete sector with a pattern of 0x55AA.

    You can use a hardware timer without interrupts. You just need to poll the ready flag.

      src = (U16 huge *)0xC08000;
      ResetToRead();
      ClearStatus();
      FlashErase(src);
      flashStatus = *(U16 huge *)(0xFFF000);
    

    With the FlashErase routine:

      T2CON     DEFR  0FF40H
      T2        DEFR  0FE40H
      T2IC      DEFR  0FF60H
      T2R       BIT   T2CON.6
      T2IC_IR   BIT   T2IC.7
    
    TIMEOUT_1SEC EQU 19531
    
    ;*****************************************************************************
    ;
    ; Function    :  void far FlashErase(unsigned int huge * src)
    ;
    ;             :  sector base address passed in registers 'R8/R9'
    ;******************************************************************************
      FlashErase  PROC  FAR
      PUBLIC  FlashErase
    
      MOV   T2,#TIMEOUT_1SEC
      BCLR  T2IC_IR
    
    ; *(unsigned int huge *) (0xC000AA) = 0x0080;
      MOV   R4,#080H
      EXTS  R9,#1
      MOV   000AAH,R4
    
    ; *(unsigned int huge *) (0xC00054) = 0x00AA;
      MOV   R4,#0AAH
      EXTS  R9,#1
      MOV   00054H,R4
    
    ; *src = 0x0033;
      MOV   R4,#033H
      EXTS  R9,#1
      MOV   [R8],R4
    
    FlashEraseActive:
      NOP
      NOP
      NOP
      NOP   ; delays to make sure Flash state machine starts
      EXTS  #0FFH,#1
      MOV   R4,0F000H
      JNB   R4.2,FlashEraseExit
    
      BSET  T2R ; start timer
    
    ;  wait for flash operation to finish or timeout
    FlashEraseDone:
      JB    T2IC_IR,FlashEraseExit ; jump on timeout
      EXTS  #0FFH,#1
      MOV   R4,0F000H
      AND   R4,#5
      JMP   cc_NZ,FlashEraseDone  ; wait for command to finsih
    
    FlashEraseExit:
      BCLR  T2R     ; stop timer
      RETS
    
      FlashErase  ENDP
    

Children
  • I forgot to mention that the FlashErase routine is loaded from Flash to PSRAM and executed out of PSRAM.

  • Chris,

    Once again many thanks for your time and effort in answering my questions.

    I will not be able to get around to trying out the code that you suggest until Monday, now, but I did want to say thank you.

    All the best,

    Simon

  • Tues 29th Jan, 2008 - an update

    I have built a project with the code that Chris has shown, above.

    The project is built to work with the XC161CS-32F microcontroller with 256KBytes of internal flash ROM.

    The project works great when the flash ROM sector has been filled with data which is written to it by the application.

    In the case where we have a source code module which contains a constant definition which we load into the flash ROM sector, the erase continues to fail to work.

    From a simple point of view it would seem that the erase routine should not care whether the data in the sector to be erased has been put there by the application writing to it or by the initial programming of the flash ROM module by the Keil IDE via the JTAG ULINK box.

    Is it, however, the case that there IS a difference ?

    Any thoughts ?!?!

    Thanks,

    Simon May

  • Weds 30th January, 2008 - an update

    To recap :

    Code written which is loaded onto the internal flash ROM module of an XC161CS-32F microcontroller.

    Erase routines have been written which are stored in ROM but copied from ROM to RAM and executed from RAM.

    The erase routines work on sectors which have small amounts of data in.

    In the MAIN module, include a const declaration :

    const  char  A_str [ 100 ] = "this is a string" ;
    

    With the memory model, 'small', selected, this const gets located to address 0xC04000.

    When the erase routines are executed, they work fine.

    If the const declaration is changed to :

    const  char  A_str [ 200 ] = "this is a string" ;
    

    ie: if the size is changed from 100 to 200, the erase routines execute, cause no FSR error, but do not actually erase the sector.

    I am somewhat perplexed !

    Any thoughts are much appreciated,

    Thanks,

    Simon May

  • This issue has now been resolved.

    It turns out that the code that I have been using from the start HAS been working.

    The reason that I thought that it was NOT working was that the UVision debugger memory window was showing me that the flash ROM module contained data.

    I eventually used the Infineon memtool to download the contents of the internal flash ROM module and when I looked at the resultant data files, I could see that the internal flash ROM module HAD in fact been erased.

    Simon May