TODOPIC

Otros Microcontroladores / Dispositivos programables => Microcontroladores ARM => Mensaje iniciado por: aismirlian en 15 de Octubre de 2008, 12:44:17

Título: Flash Como EEprom HCS08
Publicado por: aismirlian en 15 de Octubre de 2008, 12:44:17
Hola. Tengo un problema, a ver si alguien ya lo resolvió:
Tengo que guardar 3 bytes de datos no volátiles, y como estoy trabajando con un HCS08 no tengo memoria EEprom interna, por lo tanto tengo dos opciones que debido a la capacidad de almacenamiento que necesito elijo la de utilizar 3 bytes de la Flash como EEprom. Como para escribir en la flash no puedo hacerlo desde la misma flash para estos micros, hice una función que me copia a otra función en la RAM para que luego ejecutándola desde la RAM pueda escribir en la Flash.
Mi problema reside en la función que escribe en la flash, según la hoja de datos y el diagrama de flujo que muestra, arme la siguiente función:

void far Flash_Write (void)
{
  DisableInterrupts;
  //FCDIV=0x44; SUPUESTAMENTE NO HACE FALTA PORQUE LO HACE EN EL RESET
  FSTAT=0xC4;//LIMPIO TODOS LOS FLAGS DE ERROR

  FPROT_FPDIS=1;//SACO PROTECCION DE FLASH

  if(FSTAT_FACCERR)
  FSTAT_FACCERR=0;
 
  *DIRECCION=DATO_FLASH;//ASIGNO A LA DIRECCIÓN 0xF000 UN DATO CUALQUIERA

  FCMD=0x20;
 
  FSTAT_FCBEF=1;

  asm
  {
  NOP
  NOP
  NOP
  NOP
  NOP
  }
 
  if(FSTAT_FACCERR|FSTAT_FPVIOL)
  ERROR_FLASH=1;

  while (!FSTAT_FCCF);
}
Todo esto esta armado según el diagrama de flujo del Datasheet del M9S08QG8, en la seccion 4.5.

Cuando llamo a la función desde la RAM, la ejecuta lo mas bien, pero no me graba el valor que le dije en la Flash. No se a que se debe, si alguien tiene idea agradezco la ayuda.

Saludos.
Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 15 de Octubre de 2008, 16:49:47
Código: C
  1. /* Flash access function must be allocated in RAM */
  2. #pragma MESSAGE DISABLE C1805
  3. #define Page_Erase   PGM[21] = 0x40; temp = (( byte (*)( word ))( PGM ))
  4. #define Program_Byte PGM[21] = 0x20; temp = (( byte (*)( word, byte ))( PGM ))
  5.  
  6. /* Array of opcode instructions of the Erase/Program function in the HCS08 family */
  7. volatile unsigned char PGM[64]  =
  8. {  
  9.         0x87,0xC6,0x18,0x25,0xA5,0x10,0x27,0x08,0xC6,0x18,0x25,0xAA,0x10,0xC7,0x18,0x25,
  10.         0x9E,0xE6,0x01,0xF7,0xA6,0x20,0xC7,0x18,0x26,0x45,0x18,0x25,0xF6,0xAA,0x80,0xF7,
  11.         0x9D,0x9D,0x9D,0x9D,0x45,0x18,0x25,0xF6,0xF7,0xF6,0xA5,0x30,0x27,0x04,0xA6,0xFF,
  12.         0x20,0x07,0xA6,0xFF,0xC7,0x18,0x00,0xC6,0x18,0x25,0xA5,0x40,0x27,0xF4,0x8A,0x81
  13. };
  14. /*  The opcode above represents this set of instructions  
  15.     if ( FSTAT & 0x10 )
  16.                 {
  17.                   // Check to see if FACCERR is set
  18.                         FSTAT = FSTAT | 0x10;    // write a 1 to FACCERR to clear
  19.     }
  20.     (*((volatile unsigned char *)(Address))) = data;  //write to somewhere in flash
  21.     FSTAT = FSTAT | 0x80;      //Put FCBEF at 1.
  22.     _asm NOP;                  //Wait 4 cycles
  23.     _asm NOP;
  24.     _asm NOP;
  25.     _asm NOP;
  26.     if ( FSTAT & 0x30 )
  27.                 {  
  28.                   //check to see if FACCERR or FVIOL are set
  29.                         return 0xFF;             //if so, error.
  30.     }
  31.     while (( FSTAT & 0x40 )== 0 )
  32.                 {
  33.                         // Kick the dog
  34.                         _asm LDA 0xFF
  35.                         _asm STA 0x1800
  36.     }
  37.    */
  38. bool FlashErase( word Dest )
  39. {
  40.         byte temp;
  41.         bool Result = TRUE;
  42.  
  43.         /* In this routine is not allowed access to flash */
  44.         Cpu_DisableInt();
  45.  
  46.         temp = Page_Erase( Dest );
  47.  
  48.         if ( temp == 0xFF )
  49.         {
  50.                 /* Signal Error */
  51.                 Result = FALSE;
  52.         }
  53.  
  54.         Cpu_EnableInt();
  55.  
  56.         /* Signal Ok */
  57.         return( Result );
  58. }
  59. /*-----------------------------------------------------------------------------
  60. ** Function Name : FlashWrite
  61. ** Description   : Write a block of data in internal Flash
  62. ** Input         : Address, Source and length
  63. ** Output        : Result of operations
  64. ** Notes         :
  65. -----------------------------------------------------------------------------*/
  66. byte FlashWrite( word Address, byte *Source, byte Len )
  67. {
  68.         byte Index, temp;
  69.         bool Result = TRUE;
  70.  
  71.         /* In this routine is not allowed access to flash */
  72.         Cpu_DisableInt();
  73.  
  74.         for ( Index = 0; Index < Len; Index ++ )
  75.         {
  76.                 temp = Program_Byte( Address + Index, ( byte ) *( Source + Index ));
  77.  
  78.                 /* Execute Program routine */
  79.                 if ( temp == 0xFF )
  80.                 {
  81.                         /* Signal Error */
  82.                         Result = FALSE;
  83.                         break;
  84.                 }
  85.         }
  86.  
  87.         Cpu_EnableInt();
  88.  
  89.         /* Signal Ok */
  90.         return( Result );
  91. }
Estas dos funciones las tengo funcionando sin problemas, la diferencia con la que planteas vos, es que en vez de subir la función a RAM, directamente el array PGM contiene todos los opcodes necesarios para la ejecución de la misma.

Saludos !
Título: Re: Flash Como EEprom HCS08
Publicado por: aismirlian en 16 de Octubre de 2008, 12:40:31
Antes que nada muchas gracias, pero al ver tu codigo me surgen un par de dudas:
Nunca vi esta declaracion en C:

#define Page_Erase   PGM[21] = 0x40; temp = (( byte (*)( word ))( PGM ))
#define Program_Byte PGM[21] = 0x20; temp = (( byte (*)( word, byte ))( PGM ))

O sea se entiende que para Borrar FCMD=0x40 y para Escribir un Byte FCMD=0x20. Lo que no entiendo es que función cumple temp y como es que esta declarado.

Otra cosa, en la parte que esta comentada, que vendría a ser lo mismo que escribiste en PGM, no veo la parte donde le asignas el valor a FCMD.

Gracias nuevamente.
Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 16 de Octubre de 2008, 14:29:14
Hola, vamos por partes...

Las declaraciones de Page_Erase corresponde a la declaración de un puntero a función, en este caso PGM ( un array en memoria RAM ) que devuleve un byte y que recibe un word como parametro, de manera similar Program_Byte.
temp esta puesto de esa manera para forzar al compilador a asignar el resultado de la función, porque Program_Byte se traduce primero a PGM[21] = 0x40.
El FCMD se encuentra en el address 0x1826, y justamente se hace con la asignacion PGM[21]...si te fijas a partir de la dirección 20 del PGM dice
0xA6,0x20,0xC7,0x18,0x26 --> Cargar A con 0x20 y descargar A en 0x1826, por eso se pisa PGM[21]

Espero haber sido claro.

Saludos !


Título: Re: Flash Como EEprom HCS08
Publicado por: aismirlian en 17 de Octubre de 2008, 09:50:55
Okay, entiendo, esta muy claro.
Ahora, cuando ejecuto el codigo, hice un .C aparte con este codigo, y llamo a estas funciones desde el main, de la siguiente manera:

if(FlashErase(DIRECCION))
ERROR_FLASH=FlashWrite(DIRECCION,&DATO_FLASH,1);

Donde DIRECCION=0xE382 y DATO_FLASH=0x65, pero como vi que hay que pasarle el puntero, le pase la direccion de DATO_FLASH, y cuando ejecuto, va a la RAM y lo ejecuta lo mas bien todo el codigo, pero cuando despues voy a ver la direccion 0xE382, aparece 0xFF y no 0x65.

Tenes idea a que se puede deber? tene en cuenta que como las definiciones de WORD, BYTE, las definiciones del temp las hice asi:
temp = (( byte (*)( word ))( PGM )) ------->  temp = (( int (*)( int ))( PGM ))
temp = (( byte (*)( word, byte ))( PGM )) -------> temp = (( int (*)( int, char ))( PGM ))

Igual no creo que eso este impidiendo que me escriba el byte en la flash.
Título: Re: Flash Como EEprom HCS08
Publicado por: aismirlian en 17 de Octubre de 2008, 10:00:55
Ah y otra cosa que no se como es en tu codigo, es el Cpu_DisableInt(); y el Cpu_EnableInt(); yo los reemplace por DisableInterrupts() y EnableInterrupts() que lo unico que hacen en habilitar y deshabilitar las interrupciones generales, quiza en las tuyas hacen algo mas que quiza en las mias no lo hago y por eso no funciona.
Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 17 de Octubre de 2008, 10:39:01
Hola, vamos por partes, con respecto a las funciones  Cpu_DisableInt() y el Cpu_EnableInt() solamente apagan y prenden las interrpciones, porque cuando se graba la flash nadie puede acceder a la misma.
Con respecto a la traducción de la macro no esta bien hecho, tene en cuenta la importancia de los signos y el sizeof de los tipos, la traduccion de estos typedefs en tipos nativos del lenguaje son:

El código de ejemplo es correcto, yo las uso de la misma manera, proba como te dije y fijate que onda.

Saludos !

PD: Agradecer no biene mal....
Título: Re: Flash Como EEprom HCS08
Publicado por: aismirlian en 17 de Octubre de 2008, 16:11:00
Gracias Man, esta muy bien explicado.

Esto sirve bastante para cuando neceistas guardar un par de datos no volatiles y no hay necesidad de poner una memoria externa, mas si sobran bytes en la Flash.

Muchas gracias nuevamente.

Saludos.
Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 17 de Octubre de 2008, 16:19:15
Hola, si totalemnte cierto seria como un reemplazo de los micros que traian EEPROM, esta tecnologia ( SUPER FLASH ) se la compro FreeScale a ST y creo que a cambio le pasaron la arquitectura de los micros tipo 680x, sino fijate los data sheet de ST y vas a ver que son unos 6800 mejorados. Con que modelo de la familia HCS08 trabajas ?
Con respecto a las funciones no son 100 % mias, buzzeando buzzaendo junte conceptos y código snippeado y los meti todos juntos...

Saludos !
Título: Re: Flash Como EEprom HCS08
Publicado por: aismirlian en 17 de Octubre de 2008, 16:40:19
Si igual que yo, primero empece con el datasheet solamente, pero para terminar de entenderlo necesite complementar con otros codigos.

Estoy trabajando con MC9S08QG8, el problema como ya dije era que tenia que guardar 3 variables no volatiles, con esto lo soluciono, pero vale aclarar que solamente con esto no alcanza, me refiero a que es  peligroso escribir en la flash sin saber bien donde estoy parado, conviene para esto bloquear la flash:

Primero hay que tener en cuenta que me conviene (para este micro) mover todo el programa al final de la parte de memoria de programa (llegando a 0xFFFF), esto es debido a que existe un registro FPROT que te permite bloquear la programacion y borrado de la flash en tiempos de ejecucion, dandole como parametro 7bits, los cuales van a ser el inicio de proteccion de flash, y de ahi para abajo, de esta forma me aseguro que el programa no me haga cagadas como escrbir donde no debe.

Espero que sirva el comentario.

Saludos.
Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 18 de Octubre de 2008, 08:32:41
Me parece muy buena la idea.  8)

Saludos !
Título: Re: Flash Como EEprom HCS08
Publicado por: elotrogonzalo en 08 de Marzo de 2014, 01:00:57
Hola RICHI777! que gran aporte! ya estoy implementando estas rutinas para probarlas! solo tengo una duda con respecto a la función tipo booleana, cómo defino éste tipo de datos en el codewarrior por que no tengo agregado el typedef bool (el tipo booleano no lo tengo en mi CW).

O puedo reemplazarlo por un unsigned char?


Muchas gracias!!!
Saludos!
Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 08 de Marzo de 2014, 15:24:12
Código: C
  1. /* No include in CodeWarrior compiler */
  2. #ifndef __HIWARE__
  3.   /* Types definition */
  4.   typedef unsigned char byte;
  5.   typedef unsigned short int word;
  6.   typedef unsigned long dword;
  7. #else
  8.   /* Types definition */
  9.   typedef unsigned char byte;
  10.   typedef unsigned int word;
  11.   typedef unsigned long dword;
  12. #endif
  13.  
  14.  
  15. typedef unsigned char bool;
  16.  
  17. #ifndef FALSE
  18.   #define FALSE 0                    
  19. #endif
  20. #ifndef TRUE
  21.   #define TRUE  !FALSE              
  22. #endif
Título: Re: Flash Como EEprom HCS08
Publicado por: elotrogonzalo en 08 de Marzo de 2014, 15:25:59
Que bueno gracias!
Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 08 de Marzo de 2014, 15:42:28
Lo ideal que esas definiciones las incluyas en un archivo header ( *.h  )  y que sea incluidos en todos los archivos fuentes.

Saludos !
Título: Re: Flash Como EEprom HCS08
Publicado por: elotrogonzalo en 11 de Marzo de 2014, 09:17:44
Claro, se entiende! muchas gracias. Sospechaba que ese bool era en realidad un unsigned char. Ahora esta rutina la puedo utilizar para cualquier hcs08? o solo es válida para el QG8?
Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 11 de Marzo de 2014, 16:33:29
Hola, si podes utilizarla para toda la familia HCs08, lo único que tenes que tener en cuenta es el registro que programa la velocidad de clock del oscilador que maneja la grabación de los datos en Flash, no recuerdo el nombre. Este valor tiene que ver con la velocidad de clock de tu micro.

Saludos !
Título: Re: Flash Como EEprom HCS08
Publicado por: elotrogonzalo en 12 de Marzo de 2014, 00:19:11
Muchas gracias, pero que gran aporte la verdad. Muy bueno. Estas rutinas siempre son necesarias y útiles pero no son fáciles de hacer ni conseguir.
Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 23 de Abril de 2014, 16:53:40
Muchas gracias, pero que gran aporte la verdad. Muy bueno. Estas rutinas siempre son necesarias y útiles pero no son fáciles de hacer ni conseguir.

De nada !
Título: Re: Flash Como EEprom HCS08
Publicado por: alex1961 en 08 de Septiembre de 2014, 09:50:20
hola a todos en especial al RICHI777 que puso el codigo original
hice mi version:


RAM: section ($100)
fshcode:   rmb         64         ; ram, no pagina zero
*
* flash a grabar
*
addeep      equ          $C000         ;
fstab         equ          $1825
fcmd         equ          $1826
srs            equ          $1800 ; depende del micro ya esta definido en el inc

*
*       $87,$C6,$18,$25,$A5,$10,$27,$08,$C6,$18,$25,$AA,$10,$C7,$18,$25   ;
*   
*       $9E,$E6,$01,$F7,$A6,$20,$C7,$18,$26,$45,$18,$25,$F6,$AA,$80,$F7   ;
*
*        $9D,$9D,$9D,$9D,$45,$18,$25,$F6,$F7,$F6,$A5,$30,$27,$04,$A6,$FF   ;
*
*       $20,$07,$A6,$FF,$C7,$18,$00,$C6,$18,$25,$A5,$40,$27,$F4,$8A,$81   ;
*
*
* rutina de grabar un byte en $F000, $5A
*      
wrikm:
       sei                     ; no irq
*   
        ldhx           #$C000            ;
                sthx          fshadd            ;
       lda      #$C3            ;
       sta      fshdat            ;
      lda      #$40            ;
      sta      fshcmd            ;
      jsr      fwrite            ; erase
*
       ldhx           #$C000            ;
       sthx           fshadd            ;   
       lda      #$C3            ;
      sta      fshdat            ;
      lda      #$20            ;
      sta      fshcmd            ;
       jsr      fwrite            ; write
*
       clrh                  ;
       cli                     ;
       rts                     ;   
*
* ingresa hx=dir
*         a=dato
* 21,x en ram es $20 graba $40 borra
*   
* ingresa:
*   fshadd=direccion a grabar/borrar (1bloque)
*   fshdat=dato a grabar
*    fshcmd=comando $20 graba, $40 borra
*   fshcode=lugar en ram donde se ejecuta
*   
fwrite:
                ldhx      #(f_wr_fin - f_wr_com)      ;numero de bytes a copiar, H=0
                                           ;copia funcion de GRABACION a RAM
fwr010:
                lda       (f_wr_com-1),x              ;
                sta       (fshcode-1),x              ;(-1 porque X= ultimo..1)
                dbnzx   fwr010                  ;
*
                sta       srs                        ;resetea COP
*
      lda      fshcmd                  ;
      sta      fshcode+21               ;
                ldhx          fshadd                  ;carga address del bloque a grabar/borrar
      lda      fshdat                  ;
                jmp          fshcode                  ;ejecuta codigo en RAM, sale por RTS
*
* rutina de write/erase
*
f_wr_com:
*      
write:
       psha               ;
      lda      fstat         ;
      bit      #$10         ; 0001 0000 FACCERR
      beq      wri010         ;
      lda      fstat         ;
      ora      #$10         ; IF FACCERR=1, clear it
      sta      fstat         ;
wri010:
      lda      1,sp         ; tomo dato a grabar
      sta      ,x            ; grabo donde quiero
      lda      #$20         ;
      sta      fcmd         ; comando $20
      ldhx          #$1825         ;
      lda      ,x            ;
      ora      #$80         ; FCBEF=1
                sta      ,x            ;
      nop                  ;
      nop                  ;
      nop                  ;
      nop                  ;
      ldhx           #fstat         ;
      lda      ,x            ;
      sta      ,x            ;
      lda      ,x            ;
      bit      #$30         ; FPVIOL y FACCERR
      beq      wri020         ; (04)
      lda      #$FF         ; 2
      bra      wri030         ; 2 (07)
wri020:
      lda      #$FF         ; 2
      sta      srs            ; 3 watchdog
      lda      fstat         ;
      bit      #$40         ;
      beq      wri020         ; $F4
wri030:   
      pulh               ;
      rts                  ;
*
f_wr_fin:
   
wrikm: primero borra un bloque y luego graba un byte en $C000 con $5A
lo que hice fue insertar el codigo propuesto en binario en RAM y ejecutarlo. (fwrite)
lo diferente fue que es codigo ASSEMBLER puro.
pase el binario en una rutina la cual esta en write.

lo unico que encontre que un byte no me coincidio ya que el salto ultimo me da $20 $0C y no $20 $07, lo probe
y me grabo lo mas bien.
saludos a todos, el foro me ayudo muchisimo!!!

utilizo codewarrior, assembler puro, con micro MC9S08AC16CFB
Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 08 de Septiembre de 2014, 12:00:13
Excelente !!!, yo hace unos años que estoy alejado de estos micros. Sugerencia, no copies el código directamente, encerralos en estos tags, queda mas lindo.
"
Código: [Seleccionar]
tu codigo"

Saludos !
Título: Re: Flash Como EEprom HCS08
Publicado por: alex1961 en 08 de Septiembre de 2014, 12:48:28
bueno a pedido, cambie el formato, gracias nuevamente RICHI777
ahora agregue las rutinas de comparacion y grabado de n bytes, super completa. funciona ok.
yo suelo grabar entre 1 y 32 datos de configuracion o cuando se corta la energia.


Excelente !!!, yo hace unos años que estoy alejado de estos micros. Sugerencia, no copies el código directamente, encerralos en estos tags, queda mas lindo.

Código: [Seleccionar]
*
* -------------------------------------------------------
*
* comparo datos entre EEPROM y RAM
*
* flash: addeep
* ram:   cuenta+0,1 ...
* sale   a=$00 OK
*        a=$FF mal
*
* -------------------------------------------------------
*
cmpkm:
        ldx     #ctebre         ; cantidad de datos
cmk010:
        sta     srs             ;
        lda     addeep,x        ;
        cmp     cuenta,x        ;
        bne     cmk080          ;
        decx                    ;
        bpl     cmk010          ;
*
* comparo ok!
*
        clra                    ;
        bra     cmk090          ;
cmk080:
        clra                    ;
        coma                    ;
cmk090:
        rts                     ;
*
* -------------------------------------------------------
*
* rutina de escritura en FLASH de datos en cuenta+0,1 ...
* intento cterei veces grabacion
* sale:
*       a=$00 todo bien
*       a=$FF mal
*
* -------------------------------------------------------
*
wrikm:
        mov     #cterei,ayurei      ;
wkm010:
        jsr     wrieep          ;
        jsr     cmpkm           ;
        tsta                    ;
        beq     wkm100          ;
*
        dbnz    ayurei,wkm010   ;
wkm090:
        lda     #$FF            ;
wkm100:
        clrh                    ;
        bclr    4,flag0         ; ya grabe
*
        rts                     ;
*
* -------------------------------------------------------
*
* rutina de grbacion datos en EEPROM
*
* ingresa:
*       fshadd=direccion a grabar/borrar (1bloque)
*       fshdat=dato a grabar
*       fshcmd=comando $20 graba, $40 borra (21,x)
*       fshcode=lugar en ram donde se ejecuta
*
* anulo irq's
*
* -------------------------------------------------------
*
wrieep:
        clr     ayucnt          ;
        sei                     ; no timer
        bset    1,irqsc         ; no irq ext
*       
        ldhx    #$C000          ;
        sthx    fshadd          ;
        lda     #$FF            ;
        sta     fshdat          ;
        lda     #cmdera         ; cmd erase
        sta     fshcmd          ;
        jsr     fwrite          ; erase
wrp010:
        clrh                    ;
        ldx     ayucnt          ;
        lda     cuenta,x        ;
        sta     fshdat          ; data
        lda     #cmdwri         ;
        sta     fshcmd          ; write
        jsr     fwrite          ;
*
        inc     fshadd+1        ; add=+1
        inc     ayucnt          ;
        lda     ayucnt          ;
        sta     srs             ;
        cmp     #ctebre+1       ;
        bne     wrp010          ;
*
        clrh                    ;
        cli                     ;
        bclr    1,irqsc         ; si irq ext
*
        rts                     ;
*
* db    $87,$C6,$18,$25,$A5,$10,$27,$08,$C6,$18,$25,$AA,$10,$C7,$18,$25 ;
*   
* db    $9E,$E6,$01,$F7,$A6,$20,$C7,$18,$26,$45,$18,$25,$F6,$AA,$80,$F7 ;
*
* db    $9D,$9D,$9D,$9D,$45,$18,$25,$F6,$F7,$F6,$A5,$30,$27,$04,$A6,$FF ;
*
* db    $20,$07,$A6,$FF,$C7,$18,$00,$C6,$18,$25,$A5,$40,$27,$F4,$8A,$81 ;
*
*
* ingresa hx=dir
*         a=dato
* 21,x en ram es $20 graba $40 borra
*
* ingresa:
* fshadd=direccion a grabar/borrar (1bloque)
* fshdat=dato a grabar
* fshcmd=comando $20 graba, $40 borra
* fshcode=lugar en ram donde se ejecuta
*
fwrite:
        ldhx    #(f_wr_fin - f_wr_com) ;numero de bytes a copiar, H=0
                                        ;copia funcion de GRABACION a RAM
fwr010:
        lda     (f_wr_com-1),x          ;
        sta     (fshcode-1),x    ;(-1 porque X= ultimo..1)
        dbnzx   fwr010 ;
*
        sta     srs             ;resetea COP
*
lda fshcmd          ;
sta fshcode+21 ;
        ldhx    fshadd ;carga address del bloque a grabar/borrar
lda fshdat ;
        jmp     fshcode ;ejecuta codigo en RAM, sale por RTS
*
* rutina de write/erase
*
f_wr_com:
*
write:
  psha ;
lda fstat ;
bit #$10 ; 0001 0000 FACCERR
beq wri010 ;
lda fstat ;
ora #$10 ; IF FACCERR=1, clear it
sta fstat ;
wri010:
lda 1,sp ; tomo dato a grabar
sta ,x ; grabo donde quiero
lda #$20 ;
sta fcmd ; comando $20
ldhx #$1825 ;
lda ,x ;
ora #$80 ; FCBEF=1
      sta ,x ;
nop ;
nop ;
nop ;
nop ;
ldhx #fstat ;
lda ,x ;
sta ,x ;
lda ,x ;
bit #$30 ; FPVIOL y FACCERR
beq wri020 ;
lda #$FF ;
bra wri030 ;
wri020:
lda #$FF ;
sta srs ; watchdog
lda fstat ;
bit #$40 ;
beq wri020 ; $F4
wri030:
pulh ;
rts ;
*
f_wr_fin:

Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 08 de Septiembre de 2014, 13:10:21
Excelente !!! Así es mucho mas legible.

bueno a pedido, cambie el formato, gracias nuevamente RICHI777
ahora agregue las rutinas de comparacion y grabado de n bytes, super completa. funciona ok.
yo suelo grabar entre 1 y 32 datos de configuracion o cuando se corta la energia.


Excelente !!!, yo hace unos años que estoy alejado de estos micros. Sugerencia, no copies el código directamente, encerralos en estos tags, queda mas lindo.

Código: [Seleccionar]
*
* -------------------------------------------------------
*
* comparo datos entre EEPROM y RAM
*
* flash: addeep
* ram:   cuenta+0,1 ...
* sale   a=$00 OK
*        a=$FF mal
*
* -------------------------------------------------------
*
cmpkm:
        ldx     #ctebre         ; cantidad de datos
cmk010:
        sta     srs             ;
        lda     addeep,x        ;
        cmp     cuenta,x        ;
        bne     cmk080          ;
        decx                    ;
        bpl     cmk010          ;
*
* comparo ok!
*
        clra                    ;
        bra     cmk090          ;
cmk080:
        clra                    ;
        coma                    ;
cmk090:
        rts                     ;
*
* -------------------------------------------------------
*
* rutina de escritura en FLASH de datos en cuenta+0,1 ...
* intento cterei veces grabacion
* sale:
*       a=$00 todo bien
*       a=$FF mal
*
* -------------------------------------------------------
*
wrikm:
        mov     #cterei,ayurei      ;
wkm010:
        jsr     wrieep          ;
        jsr     cmpkm           ;
        tsta                    ;
        beq     wkm100          ;
*
        dbnz    ayurei,wkm010   ;
wkm090:
        lda     #$FF            ;
wkm100:
        clrh                    ;
        bclr    4,flag0         ; ya grabe
*
        rts                     ;
*
* -------------------------------------------------------
*
* rutina de grbacion datos en EEPROM
*
* ingresa:
*       fshadd=direccion a grabar/borrar (1bloque)
*       fshdat=dato a grabar
*       fshcmd=comando $20 graba, $40 borra (21,x)
*       fshcode=lugar en ram donde se ejecuta
*
* anulo irq's
*
* -------------------------------------------------------
*
wrieep:
        clr     ayucnt          ;
        sei                     ; no timer
        bset    1,irqsc         ; no irq ext
*       
        ldhx    #$C000          ;
        sthx    fshadd          ;
        lda     #$FF            ;
        sta     fshdat          ;
        lda     #cmdera         ; cmd erase
        sta     fshcmd          ;
        jsr     fwrite          ; erase
wrp010:
        clrh                    ;
        ldx     ayucnt          ;
        lda     cuenta,x        ;
        sta     fshdat          ; data
        lda     #cmdwri         ;
        sta     fshcmd          ; write
        jsr     fwrite          ;
*
        inc     fshadd+1        ; add=+1
        inc     ayucnt          ;
        lda     ayucnt          ;
        sta     srs             ;
        cmp     #ctebre+1       ;
        bne     wrp010          ;
*
        clrh                    ;
        cli                     ;
        bclr    1,irqsc         ; si irq ext
*
        rts                     ;
*
* db    $87,$C6,$18,$25,$A5,$10,$27,$08,$C6,$18,$25,$AA,$10,$C7,$18,$25 ;
*   
* db    $9E,$E6,$01,$F7,$A6,$20,$C7,$18,$26,$45,$18,$25,$F6,$AA,$80,$F7 ;
*
* db    $9D,$9D,$9D,$9D,$45,$18,$25,$F6,$F7,$F6,$A5,$30,$27,$04,$A6,$FF ;
*
* db    $20,$07,$A6,$FF,$C7,$18,$00,$C6,$18,$25,$A5,$40,$27,$F4,$8A,$81 ;
*
*
* ingresa hx=dir
*         a=dato
* 21,x en ram es $20 graba $40 borra
*
* ingresa:
* fshadd=direccion a grabar/borrar (1bloque)
* fshdat=dato a grabar
* fshcmd=comando $20 graba, $40 borra
* fshcode=lugar en ram donde se ejecuta
*
fwrite:
        ldhx    #(f_wr_fin - f_wr_com) ;numero de bytes a copiar, H=0
                                        ;copia funcion de GRABACION a RAM
fwr010:
        lda     (f_wr_com-1),x          ;
        sta     (fshcode-1),x    ;(-1 porque X= ultimo..1)
        dbnzx   fwr010 ;
*
        sta     srs             ;resetea COP
*
lda fshcmd          ;
sta fshcode+21 ;
        ldhx    fshadd ;carga address del bloque a grabar/borrar
lda fshdat ;
        jmp     fshcode ;ejecuta codigo en RAM, sale por RTS
*
* rutina de write/erase
*
f_wr_com:
*
write:
  psha ;
lda fstat ;
bit #$10 ; 0001 0000 FACCERR
beq wri010 ;
lda fstat ;
ora #$10 ; IF FACCERR=1, clear it
sta fstat ;
wri010:
lda 1,sp ; tomo dato a grabar
sta ,x ; grabo donde quiero
lda #$20 ;
sta fcmd ; comando $20
ldhx #$1825 ;
lda ,x ;
ora #$80 ; FCBEF=1
      sta ,x ;
nop ;
nop ;
nop ;
nop ;
ldhx #fstat ;
lda ,x ;
sta ,x ;
lda ,x ;
bit #$30 ; FPVIOL y FACCERR
beq wri020 ;
lda #$FF ;
bra wri030 ;
wri020:
lda #$FF ;
sta srs ; watchdog
lda fstat ;
bit #$40 ;
beq wri020 ; $F4
wri030:
pulh ;
rts ;
*
f_wr_fin:

Título: Re: Flash Como EEprom HCS08
Publicado por: RICHI777 en 11 de Septiembre de 2014, 21:44:20
Hace mucho tiempo que no toco estas rutinas, pero encontré algunas mejoras. Capaz que sirva de algo ...

Código: C
  1. #define KPGM_ADDRESS            0x1860   /* Flash routine RODATA */
  2.  
  3.  
  4. /* Array of opcode instructions of the Erase/Program function in the HCS08 family */
  5. const byte KPGM[11] @KPGM_ADDRESS =
  6. {  
  7.   0xF7,               // STA ,X  FSTAT  
  8.   0x44,               // LSRA -  Delay and convert to FCCF bit
  9.   0xA6,0xFF,          // LDA FFh   - Watch dog reset
  10.   0xC7,0x18,0x00,     // STA 1800h
  11.   0xF5,               // BIT ,X  FSTAT
  12.   0x27,0xF8,          // BEQ *-1
  13.   0x81                // RTS
  14. };
  15.  
  16. #pragma DATA_SEG _DATA_ZEROPAGE
  17. byte PGM[11];
  18.  
  19. /* Si se produjo un IPL es necesario volver a iniciar las rutinas de RAM para Flash */
  20.   FlashInit();
  21.  
  22.  
  23. void FlashInit( void )
  24. {
  25.   /* Se inicia byte a byte para no crear dependencias con otro funciones */
  26.   PGM[0] = KPGM[0];
  27.   PGM[1] = KPGM[1];
  28.   PGM[2] = KPGM[2];
  29.   PGM[3] = KPGM[3];
  30.   PGM[4] = KPGM[4];
  31.   PGM[5] = KPGM[5];
  32.   PGM[6] = KPGM[6];
  33.   PGM[7] = KPGM[7];
  34.   PGM[8] = KPGM[8];
  35.   PGM[9] = KPGM[9];
  36.   PGM[10] = KPGM[10];
  37. }
  38.  
  39. #pragma CODE_SEG FLASH_ERASE_CODE_SEG
  40. byte FlashErase( word Address )
  41. {
  42.   asm
  43.   {
  44.       TPA                       ; Get status to A      
  45.       PSHA                      ; Save current status        
  46.       SEI                       ; Disable interrupts      
  47.       LDA  #0x30                ;    
  48.       STA  FSTAT                ; Clear FACCERR & FPVIOL flags      
  49.       LDHX Address              ;      
  50.       STA  ,X                   ; Save the data      
  51.       LDA  #$40                 ; Erase command      
  52.       STA  FCMD                 ;
  53.       LDA  #FSTAT_FCBEF_MASK    ;  
  54.       LDHX @FSTAT               ;
  55.       JSR  PGM                  ;
  56.       PULA                      ; Restore previous status      
  57.       TAP                       ;            
  58.   }  
  59.  
  60.   return ( FSTAT & 0x30 );  
  61. }
  62.  
  63. #pragma CODE_SEG FLASH_PRG_BYTE_CODE_SEG
  64. byte FlashProgramByte( word Address, byte Data )
  65. {
  66.   asm
  67.   {
  68.     TPA                         ;
  69.     PSHA                        ; Save current status        
  70.     SEI                         ; Disable interrupts      
  71.     LDA  #0x30                  ;
  72.     STA  FSTAT                  ; Clear FACCERR & FPVIOL flags      
  73.     LDHX Address                ;      
  74.     LDA  Data                   ;
  75.     STA  ,X                     ; Save the data      
  76.     LDA  #$20                   ; Burn command      
  77.     STA  FCMD                   ;
  78.     LDA  #FSTAT_FCBEF_MASK      ;
  79.     LDHX @FSTAT                 ;
  80.     JSR  PGM                    ;
  81.     PULA                        ; Restore previous status      
  82.     TAP    
  83.   }
  84.  
  85.   return ( FSTAT & 0x30 );                                                              
  86. }
  87.  
  88. #pragma CODE_SEG FLASH_WRITE_CODE_SEG
  89. byte FlashWrite( word Address, byte *Source, word Len )
  90. {
  91.   word Index;
  92.  
  93.   for ( Index = 0; Index < Len; Index ++ )
  94.   {
  95.     if ( FlashProgramByte( Address + Index, ( byte ) *( Source + Index )))
  96.     {
  97.       /* Signal Error */
  98.       return( 0xFF );
  99.     }
  100.   }
  101.  
  102.         /* Signal Ok */
  103.         return( 0 );
  104. }


El código esta pegado, pero son las dos funciones que se precisan borrar y escribir. Estas funciones trabajan bien en equipos que hace años que estan funcionando en la calle.

Saludos !
Título: Re:Flash Como EEprom HCS08
Publicado por: turkosale en 01 de Febrero de 2016, 10:55:51
Buenos días gente, les consulto estas rutinas funcionan ok tanto con oscilador interno como cristal??? ya que las estoy probando y no puedo hacer que graben con un micro MC9S08SH8.

saludos
Título: Re:Flash Como EEprom HCS08
Publicado por: KILLERJC en 01 de Febrero de 2016, 12:14:55
Buenos días gente, les consulto estas rutinas funcionan ok tanto con oscilador interno como cristal??? ya que las estoy probando y no puedo hacer que graben con un micro MC9S08SH8.

saludos

En el datasheet te dice como hacerlo, y sobre tu pregunta de oscilador interno o cristal

Citar
Before any program or erase command can be accepted, the FLASH clock divider register (FCDIV) must be written to set the internal clock for the FLASH module to a frequency (fFCLK) between 150 kHz and 200 kHz (see Section 4.7.1, “FLASH Clock Divider Register (FCDIV)”)

Debe ser ejecutado en el reset, y limpiar todos los errores antes de hacerlo.