Página 1 de 1
[Resolvido] Memória não volátil - MC9S08SH4

Enviado:
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

Enviado:
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.

Enviado:
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

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

Enviado:
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.

Enviado:
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

Enviado:
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.

Enviado:
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

Enviado:
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

Enviado:
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

Enviado:
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

Enviado:
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

Enviado:
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

Enviado:
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.