Página 1 de 1

[Resolvido] Memória não volátil - MC9S08SH4

MensagemEnviado: 15 Jan 2012 19:16
por [Daniel]
Olá,

Gostaria de saber como os Sr's fazem para salvar dados com o freescale do título do tópico, pois não encontrei eeprom interna nele, existe alguma outra maneira de salvar os dados, afim de que quando eu religar o uC os dados anteriores sejam restaurados?

Obrigado

MensagemEnviado: 15 Jan 2012 21:28
por Red Neck Guy
Você pode reservar uma página da memória flash para guardar os teus dados. Mas como a granularidade de apagamento da memória flash é de uma página, sempre que você for escrever em alguma posição dessa tua área de dados que já foi previamente utilizada, terás que apagar toda essa página novamente.
Por essa razão, será necessário sempre copiar o conteúdo para a ram, apagar a pagina e depois escrever o conteúdo na flash.
Para as operações de escrita na flash existem alguns registradores que controlam isso, não lembro agora, mas tá lá no datasheet.

MensagemEnviado: 17 Jan 2012 22:16
por [Daniel]
Aquino, muito obrigado pela sua colaboração. Já estava olhando algumas coisa lá sim, mas eu não compreendi muito bem ainda, afinal iniciei os estudos com freescale no final do ano passado, não fiz muito coisa até agora.

Não queria ser muito abusado mas alguém teria algum tipo de exemplo? Só pra tirar uma base.

thanks

MensagemEnviado: 18 Jan 2012 11:37
por mastk
Procure o AN3942, acredito que tenha tudo o que procura.

MensagemEnviado: 18 Jan 2012 12:36
por hcarcaro
Olá Daniel, já trabalho a algum tempo com esta família S08, segue usando o device initialization:

- Se estiver usando clock interno, alterar o registrador FCDIV para 28 (decimal). Este registrador esta no quadro de perifericos, item IntFLASH.
- Copiar o codigo abaixo no começo do soft:

volatile unsigned int temp;
volatile unsigned char PGM[59] = {
0x87,0xC6,0x18,0x25,0xA5,0x10,0x27,0x08,0xC6,0x18,0x25,0xAA,0x10,0xC7,0x18,0x25,
0x9E,0xE6,0x01,0xF7,0xA6,0x20,0xC7,0x18,0x26,0x45,0x18,0x25,0xF6,0xAA,0x80,0xF7,
0x9D,0x9D,0x9D,0x9D,0x45,0x18,0x25,0xF6,0xF7,0xF6,0xA5,0x30,0x27,0x04,0xA6,0xFF,
0x20,0x07,0xC6,0x18,0x25,0xA5,0x40,0x27,0xF9,0x8A,0x81};
#define Page_Erase PGM[21]=0x40; temp = ((unsigned char(*)(unsigned int))(PGM))
#define Program_Byte PGM[21]=0x20; temp = ((unsigned char(*)(unsigned int, unsigned char))(PGM))


- No LINKER FILES o arquivo Project.prm deve ser alterado:
de:
Z_RAM = READ_WRITE 0x0060 TO 0x007F;
RAM = READ_WRITE 0x0080 TO 0x015F;
ROM = READ_ONLY 0xF000 TO 0xFFA9;
ROM1 = READ_ONLY 0xFFC0 TO 0xFFCF;
para:
Z_RAM = READ_WRITE 0x0060 TO 0x007F;
RAM = READ_WRITE 0x0080 TO 0x015F;
EEPROM = READ_ONLY 0xF000 TO 0xF1FF;
ROM = READ_ONLY 0xF200 TO 0xFFA9;
ROM1 = READ_ONLY 0xFFC0 TO 0xFFCF;

obs: neste caso estou usando o QD4, mas é só acrescentar o bloco de "e2prom" dentro da área de memoria flash do teu micro.

- Por fim para usar as funções de escrita e erase é necessário desabilitar temporariamente as interrupções :

DisableInterrupts;
Page_Erase(0xF000);
DELAY1mS(10);
Program_Byte(0xF000,0x66);
DELAY1mS(10);
EnableInterrupts;

ps1 - É importante lembrar que a função de erase apaga todo o conteúdo dentro da pagina de 512 bytes, mesmo que vc coloque o ultimo endereço da pagina. E sempre a gravação é byte por byte.

ps2 - No meu caso usei um delay de 1mS chamado 10x, foi tempo suficiente, faça testes com relação ao tempo de delay.

Espero ter ajudado.
Abraço.

MensagemEnviado: 26 Fev 2012 17:47
por [Daniel]
Colega hcarcaro,

O Sr. poderia de dar uma luz a respeito de como faz para:
*ler os dados por endereço por ex.
*onde salva a pagina para apenas modificar um dado no meio

Ou por favor, pelo menos me explique esse seu código, gostaria de entender como ele funciona, o que fazem esses #defines...

Obrigado

MensagemEnviado: 27 Fev 2012 09:24
por hcarcaro
Olá Daniel, para ler um dado é só carregar o valor diretamente do endereço.
Ex simples:
asm{
lda 0xFXXX
sta VARIAVEL
}

Para fazer a mudança de somente um dado no meio da pagina não é possível, uma vez que vc deve apagar toda a pagina para escrever novamente.
Para fazer o que vc esta querendo será necessário criar 2 paginas, dai vc pode copiar todo o conteúdo da primeira para a segunda, alterando somente o byte que vc quer.

Aqueles #defines pega todos aqueles dados dentro da matriz PGM[59] que na verdade são comandos em hexa e faz rodar o código diretamente da memoria RAM.

Espero ter ajudado.

MensagemEnviado: 28 Fev 2012 17:15
por [Daniel]
Olá,

Fiz vários testes, escrevi alguns códigos para testar, pelo que posso ver eu consegui obter o que esperava, demorou mas obtive resultados muito bons, ainda mais que freescale é novidade para mim. Usei também como base o livro do Fabio Pereira uCs HCS08 - teoria e pratica.

Estou grato aos Srs por toda ajuda, espero futuramente poder contribuir também da mesma forma.

Um MUITO OBRIGADO A TODOS!!
Tópico [Resolvido].

Daniel

MensagemEnviado: 28 Fev 2012 17:16
por [Daniel]
Olá,

Fiz vários testes, escrevi alguns códigos para testar, pelo que posso ver eu consegui obter o que esperava, demorou mas obtive resultados muito bons, ainda mais que freescale é novidade para mim. Usei também como base o livro do Fabio Pereira uCs HCS08 - teoria e pratica. Testei na placa DEMO9S08QG8.

Estou grato aos Srs por toda ajuda, espero futuramente poder contribuir também da mesma forma.

Um MUITO OBRIGADO A TODOS!!
Tópico [Resolvido].

Daniel

Re: [Resolvido] Memória não volátil - MC9S08SH4

MensagemEnviado: 01 Ago 2015 21:46
por egipts
Olá. Alguém conseguiu fazer a gravação da Flash no SH4 usando assembly? não estou conseguindo...

Eu adicionei o DoOnStack.h mas na hora de compilar ele apresentava erros em algumas diretivas do arquivo e tinha algumas referências a registradores que estava erradas.
Com o intuito de facilitar, copiei tudo no mesmo arquivo do meu programa e corrigi os nomes dos registradores que estavam errados. Mas não funcionou, quando chamo o Erase ele Reseta....

No AN3942 não fala sobre as mudanças no arquivo .prm, mas fiz de acordo com o livro HCS08 e conforme citado neste tópico mas também não resolveu. Alguém já encontrou esse problema?

Grato a todos.

Re: [Resolvido] Memória não volátil - MC9S08SH4

MensagemEnviado: 03 Ago 2015 11:14
por mastk
Ola Egipts, eu ja consegui, o problema eh que faz algum tempo, acho que o problema eh o DoOnStack.h, me lembro que tive que passar o ASM a limpo, preciso ate conferir os meus codigos antigos.

Re: [Resolvido] Memória não volátil - MC9S08SH4

MensagemEnviado: 04 Ago 2015 08:25
por egipts
Ok. Assim q resolver eu posto aqui...
Acho até que já vou deixar copiado na RAM logo no boot, pois sobra RAM no programa que estou fazendo. Assim é só chamar como uma subrotina, sem ter que copiar na ram toda vez...

Grato.

Re: [Resolvido] Memória não volátil - MC9S08SH4

MensagemEnviado: 04 Ago 2015 13:03
por mastk
Define uma regiao da flash com PRAGMA.
Nessa regiao coloque o codigo para escrever a FLASH.
Copie os dados da regiao reservada para a RAM.
Pule para ela e rode o programa.

Com a BDM da para ir passo a passo e ver os registros, se resolver me envia uma caixa de BIS.

Re: [Resolvido] Memória não volátil - MC9S08SH4

MensagemEnviado: 02 Set 2015 16:58
por egipts
Enfim consegui que funcionasse. O Eng. Marco Antônio da Siletec me enviou uma versão em assembly que era como eu queria.

Segue abaixo o programa exemplo enviado (SH4): main.asm


; Include derivative-specific definitions
INCLUDE 'derivative.inc'

; export symbols
XDEF _Startup, main
; we export both '_Startup' and 'main' as symbols. Either can
; be referenced in the linker .prm file or from C/C++ later on

XREF __SEG_END_SSTACK ; symbol defined by the linker for the end of the stack

EEPROM1_Start equ $F000
;EEPROM1_Start equ $B000
;EEPROM2_Start equ $FC00

RAM_Code equ $130
;RAM_Code equ $110
;ROMStart2 equ $E200
;ROMStart2 equ $F200

ORG $F000
DC.B $00
DC.B $00
DC.B $00


; variable/data section
MY_ZEROPAGE: SECTION SHORT ; Insert here your data definition

Address: DS.B 2 ; var com primeiro endereço do bloco de dados da Flash
DataSize: DS.B 1 ; variavel contendo tamanho em bytes do dado da RAM a ser gravado na Flash
DataPtr: DS.B 2 ; variavel contendo primeiro endereço do bloco de dados da RAM a ser gravado na Flash
DataBuff: DS.B 3 ; variavel que armazena dados da RAM a serem gravados na Flash


; code section
MyCode: SECTION
main:
_Startup:
LDHX #__SEG_END_SSTACK ; initialize the stack pointer
TXS
CLI ; enable interrupts

lda $ffaf ;calibração oscilador.
sta ICSTRM ;
; MCGTRM: Initialize internal clock trim from a non volatile memory
;LDA $FFAF
;STA MCGTRM
; MCGSC: Initialize internal clock trim from a non volatile memory
;LDA $FFAE
;STA MCGSC



entry_00:
LDHX #RAMEnd+1 ; deixa o stack pointer no final da memória RAM
TXS

lda #$02 ;
sta SOPT1 ;
; RESERVADO
lda #$00 ;
sta SOPT2 ;
lda #$14
sta SPMSC1
lda #$30
sta SPMSC2


mov #$04,ICSC1
mov #$48,ICSC2 ; HABILITEI OSC. INT. 31,25KHz E BUS=8MHz


; MCGC2: BDIV=1,RANGE=0,HGO=0,LP=0,EREFS=0,ERCLKEN=0,EREFSTEN=0
; MOV #$40,MCGC2 ; Set MCGC2 register
; MCGC1: CLKS=0,RDIV=0,IREFS=1,IRCLKEN=0,IREFSTEN=0
; MOV #$04,MCGC1 ; Set MCGC1 register
; MCGC3: LOLIE=0,PLLS=0,CME=0,VDIV=1
; MOV #$01,MCGC3 ; Set MCGC3 register
;while_Cpu0: ; Wait until FLL is locked
; BRCLR 6,MCGSC,while_Cpu0




;inicialização da FLASH

lda FSTAT ; limpa flag de erro
ora #mFSTAT_FACCERR
sta FSTAT
lda #46
sta FCDIV ; DE ACORDO COM BUS =8MHz, CONFIGUREI FCDIV
; PARA QUE CLOCK FLASH = 170kHz (VIDE DATASHEET)

lda $F000
;lda $B000
sta DataBuff ; ler últimos dados da Flash e salvá-los de volta à RAM

lda $F001
;lda $B001
sta DataBuff+1

lda $F002
;lda $B002
sta DataBuff+2

;lda $FC00
;sta DataBuff2 ; ler últimos dados da Flash e salvá-los de volta à RAM

;lda $E001
;lda $FC01
;sta DataBuff2+1

;lda $E002
;lda $FC02
;sta DataBuff2+2



sei ; disable interrupts
ldhx #EEPROM1_Start
sthx Address
jsr Flash_Erase ; apaga página de 512 bytes da Flash ($F000 a $F1FF)


; mov #$09,DataBuff
; mov #$0A,DataBuff+1
; mov #$0B,DataBuff+2

lda DataBuff
add #$05
sta DataBuff

lda DataBuff+1 ; incrementar dados da RAM antes de regravá-los na Flash
add #$05
sta DataBuff+1

lda DataBuff+2
add #$05
sta DataBuff+2

ldhx #EEPROM1_Start
sthx Address
ldhx #DataBuff
sthx DataPtr
mov #$03,DataSize
jsr Flash_Program


CLI ; enable interrupts


mainLoop:
; Insert your code here
NOP

;feed_watchdog
BRA mainLoop


Flash_Program:
ldhx #$48
FP_00:
lda Flash_Program_Code-1,x
sta RAM_Code-1,x
dbnzx FP_00

jmp RAM_Code

Flash_Program_Code:

sei
lda FSTAT ; limpa flag de erro
ora #mFSTAT_FACCERR
sta FSTAT

FPC_00: lda FSTAT
and #mFSTAT_FCBEF
beq FPC_00

ldhx DataPtr
lda ,x
ldhx Address
sta ,x

lda #$25
sta FCMD

lda FSTAT ;
ora #mFSTAT_FCBEF
sta FSTAT

ldhx DataPtr
aix #1
sthx DataPtr

ldhx Address
aix #1
sthx Address

lda FSTAT
and #(mFSTAT_FACCERR|mFSTAT_FPVIOL)
bne FPC_01

dbnz DataSize,FPC_00
FPC_02:
lda FSTAT
and #mFSTAT_FCCF
beq FPC_02

FPC_01: cli
rts
Flash_Program_Code_End:


Flash_Erase:

ldhx #$29
FE_00:
lda Flash_Erase_Code-1,x
sta RAM_Code-1,x
dbnzx FE_00

jmp RAM_Code

Flash_Erase_Code:
sei
lda FSTAT ; limpa flag de erro
ora #mFSTAT_FACCERR
sta FSTAT

ldhx Address
sta ,x

lda #$40
sta FCMD

lda FSTAT ;
ora #mFSTAT_FCBEF
sta FSTAT

lda FSTAT
and #(mFSTAT_FACCERR|mFSTAT_FPVIOL)
bne FEC_01

FEC_02:
lda FSTAT
and #mFSTAT_FCCF
beq FEC_02
FEC_01:
rts


Esse programa lê os dados da Flash e adiciona 5 a cada um dos 3 endereços exemplo. A cada reset ele repete essa operação, ele executa uma vez e fica em loop...
Note os detalhes no arquivo Project.prm a seguir:

/* This is a linker parameter file for the mc9s08sh4 */

NAMES END /* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your own files too. */

SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */
Z_RAM = READ_WRITE 0x0080 TO 0x00FF;
RAM = READ_WRITE 0x0100 TO 0x012F;/* $0130 to $017F reserved to FLASH PROGRAM ROUTINE*/
ROM = READ_ONLY 0xF200 TO 0xFFAD;/* $F000 to $F1FF reserved to data (first page of Flash) */
/* INTVECTS = READ_ONLY 0xFFC0 TO 0xFFFF; Reserved for Interrupt Vectors */
END

PLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */
DEFAULT_RAM, /* non-zero page variables */
INTO RAM;

_PRESTART, /* startup code */
STARTUP, /* startup data structures */
ROM_VAR, /* constant variables */
STRINGS, /* string literals */
VIRTUAL_TABLE_SEGMENT, /* C++ virtual table segment */
DEFAULT_ROM,
COPY /* copy down information: how to initialize variables */
INTO ROM;

_DATA_ZEROPAGE, /* zero page variables */
MY_ZEROPAGE INTO Z_RAM;
END

//STACKSIZE 0x30

STACKTOP 0X17F

VECTOR 0 _Startup /* Reset vector: this is the default entry point for an application. */


Note que ele reservou o final da RAM para deixar o programa da flash e acrescentou o comando "STACKTOP 0X17F ".

Agradeço a ajuda de todos.