Página 1 de 1
Problemas na FLASH como EEPROM do QG08

Enviado:
19 Ago 2007 20:34
por Budzinski
Olá Pessoal,
Estou com dificuldades para gravar na FLASH do QG08. Estou tentando usar a flash como EEPROM, pelo exemplo do livro do Fábio não consegui rodar. Quando adiciono o arquivo doonstack.h o compilador gera um erro no linker por faltar definição para a rotina FlashProg. Se adiciono o arquivo doonstack.ASM gera outros erros na compilação... Onde posso estar errando?
Valeu !!!

Enviado:
20 Ago 2007 10:04
por Fábio Pereira
Que outros erros de compilação ?
Eu utilizo há bastante tempo estas funções e funcionam muito bem.
Outra coisa: você está utilizando o CW 6.0 ? Se estiver, tem de alterar algumas coisas (comentar os dois símbolos no início do arquivo ASM):
;mPageErase equ $40
;mByteProg equ $20
Até +

Enviado:
20 Ago 2007 10:14
por Budzinski
Isso mesmo, estou usando o Code 6... Talvez seja isso então, os erros são esses:


Enviado:
20 Ago 2007 13:32
por Budzinski
Pelo que acompanhei no DEBUG, o bit FACCERR está indo para nivel lógico 1 quando faz uma escrita ou apagamento... Ou seja, o procedimento doonstack não está correto...
Que saudade dos HC08 !!! rsrsrsrsrsrs

Enviado:
21 Ago 2007 09:50
por Fábio Pereira
Eu não tenho saudade nenhuma ...
Uma dúvida: você tem um main.c e um main.asm. Porquê ?
T+

Enviado:
22 Ago 2007 08:42
por Budzinski
Eu tinha criado um projeto C com realocate asm... Só para teste, porém não ajudou muito...
Os erros de compilação eu arrumei, porém o bit FACCERR vai para 1 logo que roda as instruções do doonstack. Ou seja, a sequencia de programação não está correta!!!
Segue o doonstack.asm como ficou:
;**************************************************************
;* This stationery is meant to serve as the framework for a *
;* user application. For a more comprehensive program that *
;* demonstrates the more advanced functionality of this *
;* processor, please see the demonstration applications *
;* located in the examples subdirectory of the *
;* Metrowerks Codewarrior for the HC08 Program directory *
;**************************************************************
; export symbols
XDEF DoOnStack
XDEF FlashErase
XDEF FlashProg
; we use export 'Entry' as symbol. This allows us to
; reference 'Entry' either in the linker .prm file
; or from C/C++ later on
; include derivative specific macros
Include 'mc9s08qg8.inc'
; variable/data section
MY_ZEROPAGE: SECTION SHORT
; Insert here your data definition. For demonstration, temp_byte is used.
; temp_byte ds.b 1
; code section
MyCode: SECTION
;**************************************************************
; this assembly routine is called the C/C++ application
DoOnStack: pshx
pshh ;save pointer to flash
psha ;save command on stack
ldhx #SpSubEnd ;point at last byte to move to stack;
SpMoveLoop: lda ,x ;read from flash
psha ;move onto stack
aix #-1 ;next byte to move
cphx #SpSub-1 ;past end?
bne SpMoveLoop ;loop till whole sub on stack
tsx ;point to sub on stack
tpa ;move CCR to A for testing
and #$08 ;check the I mask
bne I_set ;skip if I already set
sei ;block interrupts while FLASH busy
lda SpSubSize+6,sp ;preload data for command
jsr ,x ;execute the sub on the stack
cli ;ok to clear I mask now
bra I_cont ;continue to stack de-allocation
I_set: lda SpSubSize+6,sp ;preload data for command
jsr ,x ;execute the sub on the stack
I_cont: ais #SpSubSize+3 ;deallocate sub body + H:X + command ;H:X flash pointer OK from SpSub
lsla ;A=00 & Z=1 unless PVIOL or ACCERR
rts ;to flash where DoOnStack was called
;**************************************************************
SpSub: ldhx LOW(SpSubSize+4),sp ;get flash address from stack
sta 0,x ;write to flash; latch addr and data
lda SpSubSize+3,sp ;get flash command
sta FCMD ;write the flash command
lda #FSTAT_FCBEF ;mask to initiate command
sta FSTAT ;[pwpp] register command
nop ;[p] want min 4~ from w cycle to r
ChkDone: lda FSTAT ;[prpp] so FCCF is valid
lsla ;FCCF now in MSB
bpl ChkDone ;loop if FCCF = 0
SpSubEnd: rts ;back into DoOnStack in flash
SpSubSize: equ (*-SpSub)
;**************************************************************
FlashErase: psha ;adjust sp for DoOnStack entry
lda #(FSTAT_FPVIOL+FSTAT_FACCERR) ;mask
sta FSTAT ;abort any command and clear errors
lda #mPageErase ;mask pattern for page erase command
bsr DoOnStack ;finish command from stack-based sub
ais #1 ;deallocate data location from stack
rts
;**************************************************************
FlashProg: psha ;temporarily save entry data
lda #(FSTAT_FPVIOL+FSTAT_FACCERR) ;mask
sta FSTAT ;abort any command and clear errors
lda #mByteProg ;mask pattern for byte prog command
bsr DoOnStack ;execute prog code from stack RAM
ais #1 ;deallocate data location from stack
rts
;**************************************************************
Att.
Vicente

Enviado:
22 Ago 2007 11:25
por Fábio Pereira
E o seu programa em C, como está ?
T+

Enviado:
24 Ago 2007 08:23
por Budzinski
Segue o código em C:
- Código: Selecionar todos
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "main_asm.h" /* interface to the assembly module */
#include "hcs08.h"
#include "doonstack.h" // inclui as funções para manipulação da memória FLASH
/* FCDIV: DIVLD=0,PRDIV8=0,DIV5=1,DIV4=0,DIV3=0,DIV2=1,DIV1=1,DIV0=1 */
FCDIV = 0x27;
const char PROTECAO[1] @0xFFBD=0b11100010;
void Start_MCU();
// lê um endereço da memória FLASH
unsigned char flash_read(unsigned int endereco)
{
unsigned char *ponteiro;
ponteiro = (char*) endereco;
return (*ponteiro);
}
// escreve em um endereço da memória FLASH
unsigned char flash_write(unsigned int endereco, unsigned char dado)
{
unsigned char *ponteiro;
// guarda o endereço da memória em um ponteiro
ponteiro = (char*) endereco;
// verifica e apaga flag de erro de acesso a FLASH
if (FSTAT_FACCERR) FSTAT_FACCERR=1;
// chama a função de programação da FLASH
FlashProg(ponteiro,dado);
// se houve erro, retorna 1 caso contrário, retorna 0
if (FSTAT_FACCERR || FSTAT_FPVIOL) return(1); else return(0);
}
// apaga uma página da memória FLASH
unsigned char flash_page_erase(unsigned int endereco)
{
unsigned char *ponteiro;
// guarda o endereço da memória em um ponteiro
ponteiro = (char*) endereco;
// verifica e apaga flag de erro de acesso a FLASH
if (FSTAT_FACCERR) FSTAT_FACCERR=1;
// chama a função de apagamento da FLASH
FlashErase(ponteiro);
// se houve erro, retorna 1 caso contrário, retorna 0
if (FSTAT_FACCERR || FSTAT_FPVIOL) return(1); else return(0);
}
/*
** ===================================================================
** CONFIGURA MCU
** ===================================================================
*/
void Start_MCU()
{
asm
{
lda 0x0000FFAF
sta ICSTRM
}
//ICSTRM = 166; // para 8Mhz
SOPT1 = 0b00000010; // CONFIG 1
/* |||||||+-- RSTPE = PINO RESET HABILITADO ???
||||||+--- BKGDPE = HABILITA BDM ???
|||||+---- ?????? = NULL
||||+----- ?????? = NULL
|||+------ ?????? = NULL
||+------- STOPE = HABILITA MODO STOP ???
|+-------- COPT = CONTAGEM COP 0=8192 OU 1=262144
+--------- COPE = HABILITA COP ???
*/
SOPT2 = 0b10000000; // CONFIG 2
/* |||||||+-- ACIC = CONECTA COMPARADOR CANAL 0 ???
||||||+--- IICPS = I2C 0=SDA->PTA2 SCL->PTA3
|||||+---- ?????? = NULL
||||+----- ?????? = NULL
|||+------ ?????? = NULL
||+------- ?????? = NULL
|+-------- ?????? = NULL
+--------- COPCLKS = CLOCK COP 0=1KHZ 1=FBUS
*/
SPMSC1 =0b01010100; // REGISTRADOR BAIXA TENSÃO
/* |||||||+-- BGBE = HABILITA BUFFER ???
||||||+--- ?????? = NULL
|||||+---- LVDE = HABILITA LVD ???
||||+----- LVDSE = HABILITA LCD MODO STOP ???
|||+------ LVDRE = GERA RESET CASO LVD
||+------- LVDIE = GERA INTERRUPÇÃO CASO LVD
|+-------- LVDACK = 1 APAGA FLAG LVDF
+--------- LVDF = SINALIZA BAIXA TENSÃO
*/
IRQSC = 0b01000100; // INTERRUPÇÃO EXTERNA
/* |||||||+-- IRQMOD = MODO DE DISPARO
||||||+--- IRQIE = HABILITAÇÃO IRQ
|||||+---- IRQACK = 1 APAGA O FLAG IRQF
||||+----- IRQF = SINALIZA IRQ
|||+------ IRQPE = HABILITA PINO IRQ
||+------- IRQEDG = BORDA x NIVEL
|+-------- IRQDD = PULL-UP
+--------- ?????? = NULL
*/
ICSC2 = 0b00110100; // ICSC2
ICSC1 = 0b00000110;
/* |||||||+-- IREFSTEN= REFERENCIA MODO STOP
||||||+--- IRCLKEN = CLOCK INTERNO???
|||||+---- IREFS = REFENCIA INTERNA???
||||+----- RDIV = FATOR DE DIVISAO
|||+------ RDIV =
||+------- RDIV =
|+-------- IRQDD = PULL-UP
+--------- ?????? = NULL
*/
PTADD = 0b00000001; // DIREÇÃO DA PORTA A
/* |||||||+-- PTA0
||||||+--- PTA1
|||||+---- PTA2
||||+----- PTA3
|||+------ PTA4
||+------- PTA5
|+-------- PTA6
+--------- PTA7
*/
PTADS = 0b00000001; // MODO POTENCIA NA PORTA A
/* |||||||+-- PTA0
||||||+--- PTA1
|||||+---- PTA2
||||+----- PTA3
|||+------ PTA4
||+------- PTA5
|+-------- PTA6
+--------- PTA7
*/
PTBDD = 0b11110110; // DIREÇÃO DA PORTA B
/* |||||||+-- PTB0
||||||+--- PTB1
|||||+---- PTB2
||||+----- PTB3
|||+------ PTB4
||+------- PTB5
|+-------- PTB6
+--------- PTB7
*/
PTBDS = 0b11110110; // MODO POTENCIA NA PORTA B
/* |||||||+-- PTB0
||||||+--- PTB1
|||||+---- PTB2
||||+----- PTB3
|||+------ PTB4
||+------- PTB5
|+-------- PTB6
+--------- PTB7
*/
TPMSC = 0b01001000; // Configura TIM
TPMMOD = 798; // Timer 100uS
ADCSC2 = 0b00000000;
ADCCFG = 0b00001000;
if(FSTAT_FACCERR)
FSTAT_FACCERR=1;
FCDIV = vFCDIV;
DisableInterrupts;
// __asm CLI
}
void main(void)
{
volatile unsigned char va, vb, res;
Start_MCU();
va = 10;
vb = 20;
res = flash_page_erase(0xE000); // apaga a página da FLASH
va = flash_write(0xE000, va); // escreve o valor de va no endereço 0xE000
vb = flash_write(0xE001, vb); // escreve o valor de vb no endereço 0xE001
// neste ponto, as variáveis res, va e vb devem estar com o valor 0
// lê as posições 0xE000 e 0xE001 da FLASH e guarda em va e vb
va = flash_read(0xE000);
vb = flash_read(0xE001);
// se va igual a 10 e vb igual a 20, acende o led
if (va==10 && vb==20) PTBD_PTBD6 = 0;
while (1); // fim do programa
}

Enviado:
24 Ago 2007 08:57
por KrafT
Vicente, arrumei o código pra vc, para que fique mais legivel.. blz?

Enviado:
24 Ago 2007 11:27
por Fábio Pereira
Você modificou o arquivo PRM para que o linker não utilize a página em 0xE000 para armazenar código ?
Os símbolos mFACCERR, mFPVIOL e mFCBEF estão definidos aonde ? Não encontrei eles no seu doonstack.asm.
Até +

Enviado:
24 Ago 2007 22:21
por Budzinski
Sim,
Mudei para 0xE400, os simbolos símbolos mFACCERR, mFPVIOL e mFCBEF estão definidos no arquivo QG08.h do codewarrior...