WhyCan Forum

人过留名,雁过留声,感谢各位朋友不离不弃地支持。 QQ: 516333132 (挖坑网/填坑网) admin@whycan.cn

您尚未登录。

#1 2019-06-14 14:47:52

还能这么玩
会员
注册时间: 2019-04-14
累计积分: 105

N76E003 熔丝位(CONFIG) 总是不能设置成自己想要的

https://github.com/OpenNuvoton/N76E003-BSP/blob/master/Sample_Code/IAP_program_Config/Code/IAP_DATAFLASH.c


void Enable_WDT_Reset_Config(void)
{
    set_IAPEN;                                                                    // Enable IAP function
    IAPAL = 0x04;
    IAPAH = 0x00;
    IAPFD = 0x0F;
    IAPCN = BYTE_PROGRAM_CF;
    set_CFUEN;                                                                    // Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
        while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
}

CONFIG.4 熔丝位设置成 0x0F 倒是没什么问题


但是我设置成 0xFF, 就不行了。

离线

#2 2019-06-14 14:55:40

还能这么玩
会员
注册时间: 2019-04-14
累计积分: 105

Re: N76E003 熔丝位(CONFIG) 总是不能设置成自己想要的

发现无论 CONFIG.4 是 0xXF 什么, 都可以编程为 0x0F

如果原来是 0x0F, 就不能编程为 0xFF

看来有可能是需要先擦除, 才能写。

离线

#3 2019-06-14 14:58:54

还能这么玩
会员
注册时间: 2019-04-14
累计积分: 105

Re: N76E003 熔丝位(CONFIG) 总是不能设置成自己想要的

//擦除 CONFIG0/1/2/4
void Erase_All_Config(void)
{
    set_IAPEN;// Enable IAP function
    IAPAL = 0x00;
    IAPAH = 0x00;
    IAPFD = 0xFF;
    IAPCN = ERASE_ALL_CF;
    set_CFUEN;    // Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
   
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
}

//编程 CONFIG4
void Enable_WDT_Reset_Config(void)
{
    set_IAPEN;                // Enable IAP function
    IAPAL = 0x04;
    IAPAH = 0x00;
    IAPFD = 0x5F;
    IAPCN = BYTE_PROGRAM_CF;
    set_CFUEN;                    // Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
}


main 函数调用:

void main (void)
{   
    Erase_All_Config();
    Enable_WDT_Reset_Config();
    while(1);
}


这样先擦除, 再编程, 就OK, 想写多少就写多少, 编程前, 先把这四个熔丝位保存起来, 擦除后写回去。

离线

#4 2019-06-14 15:52:24

还能这么玩
会员
注册时间: 2019-04-14
累计积分: 105

Re: N76E003 熔丝位(CONFIG) 总是不能设置成自己想要的

UINT8 Read_Config(UINT8 cfg)
{
    UINT8 value = 0;
    set_IAPEN;                                                                    // Enable IAP function
    IAPAL = cfg;
    IAPAH = 0x00;   
    IAPCN = BYTE_READ_CF;
    set_CFUEN;                                                                    // Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
   
    value = IAPFD;
   
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
   
    return value;
}

void main (void)
{
    UINT8 cfg0, cfg1, cfg2, cfg4;
   
    cfg0 = Read_Config(0);
    cfg1 = Read_Config(1);
    cfg2 = Read_Config(2);
    cfg4 = Read_Config(4); 
}

这样可以把各熔丝位读出来了。



全部代码:

/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* Copyright(c) 2017 Nuvoton Technology Corp. All rights reserved.                                         */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/

//***********************************************************************************************************
//  Nuvoton Technoledge Corp. 
//  Website: http://www.nuvoton.com
//  E-Mail : MicroC-8bit@nuvoton.com
//  Date   : Apr/21/2017
//***********************************************************************************************************

//***********************************************************************************************************
//  File Function: N76E003 CONFIG program demo code
//***********************************************************************************************************

#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"

/*
	Since the DATAFLASH is in the APROM. Program command is same as program APROM
*/

#define     PAGE_ERASE_CF       0xE2
#define     BYTE_READ_CF        0xC0
#define     BYTE_PROGRAM_CF     0xE1
#define     ERASE_ALL_CF        0xE2

#define     ERASE_FAIL          0x70
#define     PROGRAM_FAIL        0x71
#define     IAPFF_FAIL          0x72
#define     IAP_PASS            0x00

		

/********************************************************************************************
 Following IAP command register is also define in SFR_Macro.h
 
	#define set_IAPEN   BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;CHPCON |= SET_BIT0 ;EA=BIT_TMP
	#define clr_IAPEN   BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;CHPCON &= ~SET_BIT0;EA=BIT_TMP
	#define set_CFUEN   BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;IAPUEN|=SET_BIT2;EA=BIT_TMP
	#define clr_CFUEN   BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;IAPUEN&=~SET_BIT2;EA=BIT_TMP
**********************************************************************************************/
void IAP_ERROR_LED(void)
{
	while (1)
	{
		clr_P03;
		Timer0_Delay1ms(100);
		set_P03;
		Timer0_Delay1ms(100);
	}

}

//-----------------------------------------------------------------------------------------------------------/
void Trigger_IAP(void)
{   
    set_IAPGO;																	//trigger IAP
    if((CHPCON&SET_BIT6)==SET_BIT6)             // if fail flag is set, toggle error LED and IAP stop
		{
			clr_IAPFF;
			IAP_ERROR_LED();
		}
}
/*
		WARNING:
	No matter read or writer, when IAPFF is set 1, 
	this step process is fail. DATA should be ignore.
*/
//-----------------------------------------------------------------------------------------------------------/

/*****************************************************************************************************************
Write CONFIG subroutine:
******************************************************************************************************************/		
void Erase_All_Config(void)
{
    set_IAPEN;																	// Enable IAP function
    IAPAL = 0x00;
    IAPAH = 0x00;
    IAPFD = 0xFF;
    IAPCN = ERASE_ALL_CF;
    set_CFUEN;																	// Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
    
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
}

UINT8 Read_Config(UINT8 cfg)
{
    UINT8 value = 0;
    set_IAPEN;																	// Enable IAP function
    IAPAL = cfg;
    IAPAH = 0x00;    
    IAPCN = BYTE_READ_CF;
    set_CFUEN;																	// Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
    
    value = IAPFD;
    
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
    
    return value;
}

void Enable_WDT_Reset_Config(void)
{
    set_IAPEN;																	// Enable IAP function
    IAPAL = 0x04;
    IAPAH = 0x00;
    IAPFD = 0x5F;
    IAPCN = BYTE_PROGRAM_CF;
    set_CFUEN;																	// Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
}

//-----------------------------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------------------------
void main (void) 
{
    UINT8 cfg0, cfg1, cfg2, cfg4;
    
    cfg0 = Read_Config(0);
    cfg1 = Read_Config(1);
    cfg2 = Read_Config(2);
    cfg4 = Read_Config(4);
    
    Set_All_GPIO_Quasi_Mode;
//---------toggle GPIO1---------	
	clr_GPIO1;
	Timer0_Delay1ms(100);
	set_GPIO1;
	Timer0_Delay1ms(100);
	clr_GPIO1;
	Timer0_Delay1ms(100);
	set_GPIO1;
	Timer0_Delay1ms(100);
//---------end toggle GPIO1---------
	
    Erase_All_Config();
    Enable_WDT_Reset_Config();
    while(1);
}
//-----------------------------------------------------------------------------------------------------------

离线

#5 2019-06-14 16:10:25

还能这么玩
会员
注册时间: 2019-04-14
累计积分: 105

Re: N76E003 熔丝位(CONFIG) 总是不能设置成自己想要的

/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* Copyright(c) 2017 Nuvoton Technology Corp. All rights reserved.                                         */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/

//***********************************************************************************************************
//  Nuvoton Technoledge Corp. 
//  Website: http://www.nuvoton.com
//  E-Mail : MicroC-8bit@nuvoton.com
//  Date   : Apr/21/2017
//***********************************************************************************************************

//***********************************************************************************************************
//  File Function: N76E003 CONFIG program demo code
//***********************************************************************************************************

#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"

/*
	Since the DATAFLASH is in the APROM. Program command is same as program APROM
*/

#define     PAGE_ERASE_CF       0xE2
#define     BYTE_READ_CF        0xC0
#define     BYTE_PROGRAM_CF     0xE1
#define     ERASE_ALL_CF        0xE2

#define     ERASE_FAIL          0x70
#define     PROGRAM_FAIL        0x71
#define     IAPFF_FAIL          0x72
#define     IAP_PASS            0x00

		

/********************************************************************************************
 Following IAP command register is also define in SFR_Macro.h
 
	#define set_IAPEN   BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;CHPCON |= SET_BIT0 ;EA=BIT_TMP
	#define clr_IAPEN   BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;CHPCON &= ~SET_BIT0;EA=BIT_TMP
	#define set_CFUEN   BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;IAPUEN|=SET_BIT2;EA=BIT_TMP
	#define clr_CFUEN   BIT_TMP=EA;EA=0;TA=0xAA;TA=0x55;IAPUEN&=~SET_BIT2;EA=BIT_TMP
**********************************************************************************************/
void IAP_ERROR_LED(void)
{
	while (1)
	{
		clr_P03;
		Timer0_Delay1ms(100);
		set_P03;
		Timer0_Delay1ms(100);
	}

}

//-----------------------------------------------------------------------------------------------------------/
void Trigger_IAP(void)
{   
    set_IAPGO;																	//trigger IAP
    if((CHPCON&SET_BIT6)==SET_BIT6)             // if fail flag is set, toggle error LED and IAP stop
		{
			clr_IAPFF;
			IAP_ERROR_LED();
		}
}
/*
		WARNING:
	No matter read or writer, when IAPFF is set 1, 
	this step process is fail. DATA should be ignore.
*/
//-----------------------------------------------------------------------------------------------------------/

/*****************************************************************************************************************
Write CONFIG subroutine:
******************************************************************************************************************/		
void Erase_All_Config(void)
{
    set_IAPEN;																	// Enable IAP function
    IAPAL = 0x00;
    IAPAH = 0x00;
    IAPFD = 0xFF;
    IAPCN = ERASE_ALL_CF;
    set_CFUEN;																	// Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
    
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
}

UINT8 Read_Config(UINT8 cfg)
{
    UINT8 value = 0;
    set_IAPEN;																	// Enable IAP function
    IAPAL = cfg;
    IAPAH = 0x00;    
    IAPCN = BYTE_READ_CF;
    set_CFUEN;																	// Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
    
    value = IAPFD;
    
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
    
    return value;
}

void Write_Config(UINT8 cfg, UINT8 value)
{
    set_IAPEN;																	// Enable IAP function
    IAPAL = cfg;
    IAPAH = 0x00;
    IAPFD = value;
    IAPCN = BYTE_PROGRAM_CF;
    set_CFUEN;																	// Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
}

//-----------------------------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------------------------
void main (void) 
{
    UINT8 cfg0, cfg1, cfg2, cfg4;
    
    //读熔丝位
    cfg0 = Read_Config(0);
    cfg1 = Read_Config(1);
    cfg2 = Read_Config(2);
    cfg4 = Read_Config(4);
    
	//擦除熔丝位
    Erase_All_Config();
    
    //编程熔丝位
    Write_Config(0, cfg0);
    Write_Config(1, cfg1);
    Write_Config(2, cfg2);
    Write_Config(4, 0x0F);
    
    
    while(1);
}
//-----------------------------------------------------------------------------------------------------------

void Erase_All_Config(void)
{
    set_IAPEN;                                                                    // Enable IAP function
    IAPAL = 0x00;
    IAPAH = 0x00;
    IAPFD = 0xFF;
    IAPCN = ERASE_ALL_CF;
    set_CFUEN;                                                                    // Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
   
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
}

UINT8 Read_Config(UINT8 cfg)
{
    UINT8 value = 0;
    set_IAPEN;                                                                    // Enable IAP function
    IAPAL = cfg;
    IAPAH = 0x00;   
    IAPCN = BYTE_READ_CF;
    set_CFUEN;                                                                    // Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
   
    value = IAPFD;
   
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
   
    return value;
}

void Write_Config(UINT8 cfg, UINT8 value)
{
    set_IAPEN;                                                                    // Enable IAP function
    IAPAL = cfg;
    IAPAH = 0x00;
    IAPFD = value;
    IAPCN = BYTE_PROGRAM_CF;
    set_CFUEN;                                                                    // Enable CONFIG writer bit
    set_IAPGO;                                  //trigger IAP
    while((CHPCON&SET_BIT6)==SET_BIT6);          //check IAPFF (CHPCON.6)
    clr_CFUEN;
    clr_IAPEN;
}


void main (void)
{
    UINT8 cfg0, cfg1, cfg2, cfg4;
   
    //读熔丝位
    cfg0 = Read_Config(0);
    cfg1 = Read_Config(1);
    cfg2 = Read_Config(2);
    cfg4 = Read_Config(4);
   
    //擦除熔丝位
    Erase_All_Config();
   
    //编程熔丝位
    Write_Config(0, cfg0);
    Write_Config(1, cfg1);
    Write_Config(2, cfg2);
    Write_Config(4, 0x0F);
   
   
    while(1);
}

终于把狗屎一样的 SDK 改好看一点了

离线

页脚