Newsgroup: it.hobby.elettronica.digitale
Titolo: colpa del micro?

ciao a tutti...
Sto realizzando un bootloader per il PIC24HJ128GP206.
Funziona tutto... ma non sempre.
Alcuni dispositivi durante la riprogrammazione vanno in uno strano stato 
in cui gli SFR assumono il valore di reset, ma il program counter non si 
muove da zero. Questo lo vedo con l'ICD2 ma anche programmandolo in 
definitivo, perlomeno da quello che posso osservare.
Alcuni dispositivi hanno questo problema una volta ogni 3-4 
riprogrammazioni. Altri dispositivi non hanno avuto problemi anche 
ripetendo la riprogrammazione centinaia di volte tramite procedure 
automatiche. Facendo le solite prove (cambia l'alimentatore, cambia la 
scheda, cambia i cavi etc) l'elemento che diciamo così si porta appresso 
il problema è il micro.
Ho preso un micro tra quelli problematici (i più tanti) e ho ridotto il 
bootloader ad un mero riscrittore ciclico di una sequenza di word in 
flash che riporto sotto, le cui funzioni di scrittura sono mutuate dalla 
AN1157 (l'application note su un bootloader per pic24f/h).
Bene, dopo un tempo apparentemente casuale, ma comunque inferiore al 
minuto, il micro entra nello stato indefinito descritto sopra. 
Analizzando il contenuto della flash dopo il blocco, ciò accade sempre 
durante la scrittura delle word e mai durante la cancellazione delle 
pagine di flash.
Qualche volta si pianta sulle prime word, qualche volta a metà, qualche 
volta in fondo, in una posizione casuale all'interno della pagina (che 
ne so, dopo aver scritto 11 word).
Ho provato a:
- portare i MIPS da 20 a 8 (senza risultati)
- rimuovere il PLL
- mettere pause tra una scrittura e l'altra
- togliere tutte le inizializzazioni che non servivano (vuoi mai che la 
uart o l'adc o che altro abbia qualche interferenza con la riprogrammazione)
ma non cambia nulla, si pianta regolarmente entro il primo minuto.
Per me, è colpa del micro, che tra l'altro:
- a 40MIPS (velocità permessa) occasionalmente non funziona bene (ho già 
tutto pronto per fare un ticket)
- diversamente da quanto scritto nel datasheet, il polling sulla uart 
richiede il test dell' rx-interrupt flag altrimenti il contenuto del 
frame error è inaffidabile (ho già tutto pronto per fare un ticket)
Il problema scompare se ometto la riga
BootWriteMem(BOOT_PM_WORD_WRITE);
nella funzione BootWriteInstruction().
Ora provo a scrivere a righe piuttosto che a singole word, ma temo che 
il problema sarebbe semplicemente demoltiplicato in termini di 
ricorrenza, ma ci sarebbe ancora.
Magari sono capitato in un lotto di micro sfigati, però che c***ni!
Se mi trovate un errore qua sotto, mi do del pirla, tiro un sospiro di 
sollievo e vi offro una birra!
/**************************************************************************************************
*	NOME	testflash.c
**************************************************************************************************/
/**************************************************************************************************
*	Include:	
**************************************************************************************************/
#include <p24hj128gp206.h>
/**************************************************************************************************
*	configuraion bits:
**************************************************************************************************/
_FOSCSEL(FNOSC_PRIPLL & IESO_OFF)
_FOSC(FCKSM_CSDCMD  & OSCIOFNC_ON & POSCMD_HS)
_FWDT(FWDTEN_OFF)
_FICD(COE_ON & JTAGEN_OFF & ICS_PGD3)
_FGS(GCP_ON)
/**************************************************************************************************
*	constants:
**************************************************************************************************/
#define PM_FLASH_SIZE				0x15800									//flash size in words
#define PM_PAGE_SIZE				0x400									//page size in words
//Self-write NVMCON opcodes	
#define BOOT_PM_PAGE_ERASE 			0x4042									//NVM page erase opcode
#define BOOT_PM_WORD_WRITE			0x4003									//NVM word write opcode
/**************************************************************************************************
*	Local functions declaration	
**************************************************************************************************/
int		main(void);
void 	BootErasePage(unsigned long address);
void 	BootWriteLatch(unsigned long address, unsigned long data);
void 	BootWriteMem(unsigned int cmd);
int  	BootWriteInstruction(unsigned long address, unsigned long data);
void 	BootVisStart(void);
void 	BootVisProgress(unsigned long addr);
/**************************************************************************************************
*	Files assignment
**************************************************************************************************/
/**************************************************************************************************
*	functions definition
**************************************************************************************************/
/**************************************************************************************************
*	int main(void)
**************************************************************************************************/
int main(void)
{
	unsigned long i;
	PLLFBD=30;																//fck=10MHz -> PLL: 30 0 1 --> 20 MIPS
	CLKDIVbits.PLLPRE=0;
	CLKDIVbits.PLLPOST=1;
	AD1PCFGL	=	0b1111111111111111;										//Init ADC
	AD1PCFGH	= 	0b1111111111111111;
	while(1)
	{
		BootVisStart();														//show "-   " on 4 7-segment displays
 
		for(i=0x1000;i<PM_FLASH_SIZE;i+=PM_PAGE_SIZE)						//delete all flash 
pages
			BootErasePage(i);												
 
		for(i=0x1000;i<PM_FLASH_SIZE;i++)									//starting from 0x1000
		{
			BootWriteInstruction(i,i);										//..write i at address i
			BootVisProgress(i);												//show "progress bar" on 4 7-segment 
displays
		}
	}
	return 1;
}
/**************************************************************************************************
*	void BootErasePage(unsigned long address)
**************************************************************************************************/
void BootErasePage(unsigned long address)
{
	unsigned int temp;	
	asm("clrwdt");
	temp = TBLPAG;
	TBLPAG = address>>16;
	NVMCON = BOOT_PM_PAGE_ERASE;
	__builtin_tblwtl(address & 0x0000ffff,address & 0x0000ffff);
	__builtin_write_NVM();
	while(NVMCONbits.WR == 1);
	TBLPAG = temp;
}
/**************************************************************************************************
*	void BootWriteLatch(unsigned long address, unsigned long data)
**************************************************************************************************/
void BootWriteLatch(unsigned long address, unsigned long data)
{	
	TBLPAG = address>>16;
	__builtin_tblwtl(address & 0x0000ffff, data & 0x0000ffff);
	__builtin_tblwth(address & 0x0000ffff, data >> 16);
}
/**************************************************************************************************
*	void BootWriteMem(unsigned int cmd)
**************************************************************************************************/
void BootWriteMem(unsigned int cmd)
{
	NVMCON = cmd;
	__builtin_write_NVM();
	while(NVMCONbits.WR == 1);
}
/**************************************************************************************************
*	int BootWriteInstruction(unsigned long address, unsigned long data)
**************************************************************************************************/
int BootWriteInstruction(unsigned long address, unsigned long data)
{
	asm("clrwdt");
	BootWriteLatch(address,data);
	BootWriteMem(BOOT_PM_WORD_WRITE);
	return 0;
}
/**************************************************************************************************
*	void BootVisStart(void)
**************************************************************************************************/
void  BootVisStart(void)
{
	TRISGbits.TRISG12=0;
 
	TRISGbits.TRISG6=0;
	LATGbits.LATG6=0;
	TRISGbits.TRISG7=0;
	LATGbits.LATG7=0;
	TRISDbits.TRISD11=0;
	LATDbits.LATD11=0;
	TRISDbits.TRISD10=0;
	LATDbits.LATD10=0;
	LATDbits.LATD10=1;
	LATGbits.LATG12=1;	//"-   "
}
/**************************************************************************************************
*	void BootVisProgress(unsigned long addr)
**************************************************************************************************/
void BootVisProgress(unsigned long addr)
{
	LATGbits.LATG6=0;
	LATGbits.LATG7=0;
	LATDbits.LATD11=0;
	LATDbits.LATD10=0;
	switch((addr >> 8) & 0x3)
	{
	case 0:
		LATGbits.LATG7=1;	//"  - "
		break;	
	case 1:
		LATGbits.LATG6=1;	//"   -"
		break;	
	case 2:
		LATDbits.LATD10=1;	//"-   "
		break;	
	case 3:
		LATDbits.LATD11=1;	//" -  "
		break;	
	}	
}

 
verificato, ed è così!
grrrr

 grrrr
Appero'! Buono a sapersi, evviva i PIC :-)

SilverLeo ha scritto:

già.....!