dongnanxibei 发表于 2025-5-26 17:37

CM1003使用I2C/UART实现ISP



dongnanxibei 发表于 2025-5-26 17:38

/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* SPDX-License-Identifier: Apache-2.0                                                                     */
/* Copyright(c) 2024 Nuvoton Technology Corp. All rights reserved.                                       */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/
#include "numicro_8051.h"
#include "isp_uart0.h"

#if defined __C51__
xdata uint16_t start_address,u16_addr;
#elif defined __ICC8051__
__xdata uint16_t start_address,u16_addr;
#elif defined __SDCC__
__xdata uint16_t start_address,u16_addr;
#endif

uint8_tvo8temp;
uint16_t vo16temp;
uint32_t vo32temp;

/****************************************
* @brief   UART interrupt subroutine.
* @param None.
* @return    None.
****************************************/
#if defined __C51__
void Serial_ISR(void) interrupt 4
#elif defined __ICC8051__
#pragma vector=0x23
__interrupt void UART0_ISR(void)
#elif defined __SDCC__
void Serial_ISR(void) __interrupt (4)
#endif
{
    uint8_tvotemp;
   
    if (RI == 1)
    {
      votemp = SBUF;
      uart_rcvbuf =votemp;
      clr_SCON_RI;                                       // Clear RI (Receive Interrupt).
    }
    if (TI == 1)
    {
      clr_SCON_TI;                                       // Clear TI (Transmit Interrupt).
    }
    if (bufhead == 1)
    {
      g_timer1Over = 0;
      g_timer1Counter = 90; //for check uart timeout using
    }
    if (bufhead == 64)
    {
      bUartDataReady = TRUE;
      g_timer1Counter = 0;
      g_timer1Over = 0;
      bufhead = 0;
    }
}

/****************************************
* @brief   Timer0 interrupt subroutine.
* @param None.
* @return    None.
****************************************/
#if defined __C51__
void Timer0_ISR(void) interrupt 1
#elif defined __ICC8051__
#pragma vector=0x0B
__interrupt void Timer0_ISR(void)
#elif defined __SDCC__
void Timer0_ISR(void) __interrupt (1)
#endif
{
    if (g_timer0Counter)
    {
      g_timer0Counter--;
      if (!g_timer0Counter)
      {
            g_timer0Over = 1;
      }
    }
    if (g_timer1Counter)
    {
      g_timer1Counter--;
      if (!g_timer1Counter)
      {
            g_timer1Over = 1;
      }
    }
}


/******************************
* @brief   Main loop.
* @param None.
* @return    None.
******************************/
void main (void)
{

    set_CHPCON_IAPEN;
    MODIFY_HIRC_24();
#ifdefisp_with_wdt
    TA=0x55;TA=0xAA;WDCON=0x07;
#endif
//uart initial for ISP programmer GUI, always use 115200 baudrate
UART0_ini_115200_24MHz();
TM0_ini();

g_timer0Over=0;
g_timer0Counter=Timer0Out_Counter;
g_programflag=0;

while(1)
{
      if(bUartDataReady == TRUE)
      {
          EA=0; //DISABLE ALL INTERRUPT
          if(g_programflag==1)
          {
            for(count=8;count<64;count++)
            {
            IAPCN = BYTE_PROGRAM_AP;          //program byte
            IAPAL = flash_address&0xff;
            IAPAH = (flash_address>>8)&0xff;
            IAPFD=uart_rcvbuf;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
         
            IAPCN = BYTE_READ_AP;            //program byte verify
            vo8temp = uart_rcvbuf;
            if(IAPFD!=vo8temp)
            while(1);                        
            if (CHPCON==0x43)            //if error flag set, program error stop ISP
            while(1);

            g_totalchecksum += vo8temp;
            flash_address++;
            vo16temp = AP_size;
            if(flash_address==vo16temp)
            {
               g_programflag=0;
               g_timer0Over =1;
               goto END_2;
            }
            }
END_2:
            Package_checksum();
            uart_txbuf=g_totalchecksum&0xff;
            uart_txbuf=(g_totalchecksum>>8)&0xff;
            Send_64byte_To_UART0();
          }
            
          switch(uart_rcvbuf)
          {
            case CMD_CONNECT:
            case CMD_SYNC_PACKNO:
            {
            Package_checksum();
            Send_64byte_To_UART0();   
            g_timer0Counter=0; //clear timer 0 for no reset
            g_timer0Over=0;
            break;
            }

            case CMD_GET_FWVER:
            {
            Package_checksum();
            uart_txbuf=FW_VERSION;
            Send_64byte_To_UART0();
            break;
            }
            
            case CMD_RUN_APROM:
            {
            goto _APROM;
            break;
            }

            //please for ISP programmer GUI, ID always use following rule to transmit.
            case CMD_GET_DEVICEID:
            {
            READ_ID();
            Package_checksum();
            uart_txbuf=DID_lowB;
            uart_txbuf=DID_highB;
            uart_txbuf=PID_lowB;
            uart_txbuf=PID_highB;
            Send_64byte_To_UART0();
            break;
            }

            case CMD_ERASE_ALL:
            {
            set_IAPUEN_APUEN;
            IAPFD = 0xFF;          //Erase must set IAPFD = 0xFF
            IAPCN = PAGE_ERASE_AP;
            for(flash_address=0x0000;flash_address<APROM_SIZE/PAGE_SIZE;flash_address++)
            {      
                IAPAL = LOBYTE(flash_address*PAGE_SIZE);
                IAPAH = HIBYTE(flash_address*PAGE_SIZE);
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
            }
            Package_checksum();
            Send_64byte_To_UART0();
            break;
            }

            case CMD_READ_CONFIG:
            {
            READ_CONFIG();
            Package_checksum();
            uart_txbuf=CONF0;
            uart_txbuf=CONF1;
            uart_txbuf=CONF2;
            uart_txbuf=0xff;
            uart_txbuf=CONF4;
            uart_txbuf=0xff;
            uart_txbuf=0xff;
            uart_txbuf=0xff;
            Send_64byte_To_UART0();
            break;
            }
            
            case CMD_UPDATE_CONFIG:
            {
            recv_CONF0 = uart_rcvbuf;
            recv_CONF1 = uart_rcvbuf;
            recv_CONF2 = uart_rcvbuf;
            recv_CONF4 = uart_rcvbuf;

            set_IAPUEN_CFUEN;                  /*Erase CONFIG */
            IAPCN = PAGE_ERASE_CONFIG;
            IAPAL = 0x00;
            IAPAH = 0x00;
            IAPFD = 0xFF;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
            IAPCN = BYTE_PROGRAM_CONFIG;      /*Program CONFIG*/
            IAPFD = recv_CONF0;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
            IAPFD = recv_CONF1;
            IAPAL = 0x01;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
            IAPAL = 0x02;
            IAPFD = recv_CONF2;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
            IAPAL = 0x04;
            IAPFD = recv_CONF4;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
            clr_IAPUEN_CFUEN;

            READ_CONFIG();                        /*Read new CONFIG*/
            Package_checksum();
            uart_txbuf=CONF0;
            uart_txbuf=CONF1;
            uart_txbuf=CONF2;
            uart_txbuf=0xff;
            uart_txbuf=CONF4;
            uart_txbuf=0xff;
            uart_txbuf=0xff;
            uart_txbuf=0xff;
            Send_64byte_To_UART0();
            break;
            }

            case CMD_UPDATE_APROM:
            {
            set_IAPUEN_APUEN;
            IAPFD = 0xFF;          //Erase must set IAPFD = 0xFF
            IAPCN = PAGE_ERASE_AP;
            
            start_address = 0;
            start_address = uart_rcvbuf;
            start_address |= ((uart_rcvbuf<<8)&0xFF00);
            AP_size = 0;
            AP_size = uart_rcvbuf;
            vo8temp = uart_rcvbuf;
            AP_size |= ((vo8temp<<8)&0xFF00);

            u16_addr = start_address + AP_size;
            flash_address = (start_address&0xFF00);

            while(flash_address< u16_addr)
            {
                IAPAL = LOBYTE(flash_address);
                IAPAH = HIBYTE(flash_address);
#ifdef isp_with_wdt
                set_IAPTRG_IAPGO_WDCLR;
#else
                trig_IAPGO;
#endif
                flash_address += PAGE_SIZE;
            }
            
            g_totalchecksum = 0;
            flash_address = start_address;
            g_programflag = 1;

            for(count=16;count<64;count++)
            {
                IAPCN = BYTE_PROGRAM_AP;
                IAPAL = flash_address&0xff;
                IAPAH = (flash_address>>8)&0xff;
                IAPFD = uart_rcvbuf;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
                IAPCN = BYTE_READ_AP;                //program byte verify
                trig_IAPGO;
                vo8temp = uart_rcvbuf;
                if(IAPFD!=vo8temp)
                while(1);
                if (CHPCON==0x43)                //if error flag set, program error stop ISP
                while(1);

                g_totalchecksum += vo8temp;
                flash_address++;
                vo16temp = AP_size;
                if(flash_address==vo16temp)
                {
                  g_programflag=0;
                   goto END_1;
                }
            }
END_1:               
            Package_checksum();
            uart_txbuf=g_totalchecksum&0xff;
            uart_txbuf=(g_totalchecksum>>8)&0xff;
            Send_64byte_To_UART0();
            break;
            }
          }
          bUartDataReady = FALSE;
          bufhead = 0;

          EA=1;
      }
      /*For connect timer out   */
      if(g_timer0Over==1)
      {
      CALL_NOP;
      goto _APROM;
      }
      
      /*for uart time out or buffer error*/
       if(g_timer1Over==1)
      {
       if((bufhead<64)&&(bufhead>0)||(bufhead>64))
         {
             bufhead=0;
         }
      }
}   

_APROM:
    MODIFY_HIRC_16();
    clr_CHPCON_IAPEN;
    TA = 0xAA; TA = 0x55; CHPCON = 0x80;                   //software reset enable boot from APROM
    /* Trap the CPU */
    while(1);
}




dongnanxibei 发表于 2025-5-26 17:39

/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* SPDX-License-Identifier: Apache-2.0                                                                     */
/* Copyright(c) 2024 Nuvoton Technology Corp. All rights reserved.                                       */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/
#include "numicro_8051.h"
#include "isp_i2c.h"

//#define   isp_with_wdt   /* if enable WDT function. Uncomment this line*/


/******************************
* @brief   Main loop.
* @param None.
* @return    None.
******************************/
void main (void)
{
    uint8_t   vo8temp;
    uint16_tvo16temp;
   
    bI2CDataReady=0;
    set_CHPCON_IAPEN;

    Init_I2C();

    TM0_ini();
    g_timer0Over=0;
    g_timer0Counter=5000;


    g_progarmflag=0;

while(1)
{
      //if(bUartDataReady == TRUE)
      if(bI2CDataReady == TRUE)
      {
          EA=0; /* Disable all interrupt */
          if(g_progarmflag==1)
          {
            for(count=8;count<64;count++)
            {
            IAPCN = BYTE_PROGRAM_AP;          //program byte
            IAPAL = flash_address&0xff;
            IAPAH = (flash_address>>8)&0xff;
            IAPFD=rx_buf;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
         
            IAPCN = BYTE_READ_AP;            //program byte verify
            set_IAPTRG_IAPGO;
            vo8temp = rx_buf;
            if(IAPFD!=vo8temp)
            while(1);                        
            if (CHPCON==0x43)            //if error flag set, program error stop ISP
            while(1);
            
            g_totalchecksum += vo8temp;
            flash_address++;
            vo16temp = AP_size;
            if(flash_address==vo16temp)
            {
                g_progarmflag=0;
                                g_timer0Over =1;
               goto END_2;         
            }
            }
END_2:               
            Package_checksum();
            tx_buf=g_totalchecksum&0xff;
            tx_buf=(g_totalchecksum>>8)&0xff;

            bISPDataReady = 1;
          }
            
          switch(rx_buf)
          {               
            case CMD_CONNECT:
            case CMD_SYNC_PACKNO:
            {
            Package_checksum();

            bISPDataReady = 1;            
            g_timer0Counter=0; //clear timer 0 for no reset
            g_timer0Over=0;
            break;
            }
                        
            case CMD_GET_FWVER:            
            {
            Package_checksum();
            tx_buf=FW_VERSION;

            bISPDataReady = 1;
            break;
            }
            
            case CMD_RUN_APROM:
            {
            goto _APROM;
            break;
            }
   
            //please for ISP programmer GUI, ID always use following rule to transmit.
            case CMD_GET_DEVICEID:            
            {
            READ_ID();
            Package_checksum();
            tx_buf=DID_lowB;
            tx_buf=DID_highB;
            tx_buf=PID_lowB;
            tx_buf=PID_highB;

            bISPDataReady = 1;
            break;
            }
            case CMD_ERASE_ALL:
            {
            set_CHPCON_IAPEN;
            set_IAPUEN_APUEN;
            IAPFD = 0xFF;          //Erase must set IAPFD = 0xFF
            IAPCN = PAGE_ERASE_AP;
            
            for(flash_address=0x0000;flash_address<APROM_SIZE/PAGE_SIZE;flash_address++)
            {      
                IAPAL = LOBYTE(flash_address*PAGE_SIZE);
                IAPAH = HIBYTE(flash_address*PAGE_SIZE);
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
            }
            
            Package_checksum();
            bISPDataReady = 1;
            break;
            }
            case CMD_READ_CONFIG:
            {
            READ_CONFIG();
            Package_checksum();
            tx_buf=CONF0;
            tx_buf=CONF1;
            tx_buf=CONF2;
            tx_buf=0xff;
            tx_buf=CONF4;
            tx_buf=0xff;
            tx_buf=0xff;
            tx_buf=0xff;
            bISPDataReady = 1;
            break;
            }
            
            case CMD_UPDATE_CONFIG:
            {
            recv_CONF0 = rx_buf;
            recv_CONF1 = rx_buf;
            recv_CONF2 = rx_buf;
            recv_CONF4 = rx_buf;
/*Erase CONFIG */            
            set_CHPCON_IAPEN;
            set_IAPUEN_CFUEN;
            IAPCN = PAGE_ERASE_CONFIG;
            IAPAL = 0x00;
            IAPAH = 0x00;
            IAPFD = 0xFF;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif

/*Program CONFIG*/
            IAPCN = BYTE_PROGRAM_CONFIG;
            IAPFD = recv_CONF0;
            set_IAPTRG_IAPGO;
            IAPFD = recv_CONF1;
            IAPAL = 0x01;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
            IAPAL = 0x02;
            IAPFD = recv_CONF2;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
            IAPAL = 0x04;
            IAPFD = recv_CONF4;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
            clr_IAPUEN_CFUEN;
/*Read new CONFIG*/
            READ_CONFIG();
            
            Package_checksum();
            tx_buf=CONF0;
            tx_buf=CONF1;
            tx_buf=CONF2;
            tx_buf=0xff;
            tx_buf=CONF4;
            tx_buf=0xff;
            tx_buf=0xff;
            tx_buf=0xff;
            bISPDataReady = 1;
            break;
            }
            
            case CMD_UPDATE_APROM:
            {
            set_CHPCON_IAPEN;
            set_IAPUEN_APUEN;
            IAPFD = 0xFF;          //Erase must set IAPFD = 0xFF
            IAPCN = PAGE_ERASE_AP;

            for(flash_address=0x0000;flash_address<APROM_SIZE/PAGE_SIZE;flash_address++)
            {      
                IAPAL = LOBYTE(flash_address*PAGE_SIZE);
                IAPAH = HIBYTE(flash_address*PAGE_SIZE);
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
            }

            g_totalchecksum=0;
            flash_address=0;
            AP_size=0;
            AP_size=rx_buf;
            vo8temp=rx_buf;
            AP_size|=(vo8temp<<8);
            g_progarmflag=1;

            for(count=16;count<64;count++)
            {
                IAPCN = BYTE_PROGRAM_AP;
                IAPAL = flash_address&0xff;
                IAPAH = (flash_address>>8)&0xff;
                IAPFD=rx_buf;
                clr_CHPCON_IAPFF;
#ifdef isp_with_wdt
            set_IAPTRG_IAPGO_WDCLR;
#else
            trig_IAPGO;
#endif
      
                IAPCN = BYTE_READ_AP;                //program byte verify
                set_IAPTRG_IAPGO;
                vo8temp = rx_buf;
                if(IAPFD!=vo8temp)
                while(1);
                if (CHPCON==0x43)                //if error flag set, program error stop ISP
                while(1);
               
                g_totalchecksum+=vo8temp;
                flash_address++;
                vo16temp = AP_size;
                if(flash_address==vo16temp)
                {
                  g_progarmflag=0;
                   goto END_1;
                }
            }
END_1:               
            Package_checksum();
            tx_buf=g_totalchecksum&0xff;
            tx_buf=(g_totalchecksum>>8)&0xff;

            bISPDataReady = 1;
            break;
            }
          }
          bI2CDataReady = FALSE;
          EA=1;
      }
      //For connect timer out
      if(g_timer0Over==1)
      {      
       goto _APROM;
      }
}   


_APROM:
    EA = 0;
    clr_CHPCON_IAPEN;
    TA = 0xAA;
    TA = 0x55;
    CHPCON = 0x00;                  //set boot from AP
    TA = 0xAA;
    TA = 0x55;
    CHPCON = 0x80;                   //software reset enable

    /* Trap the CPU */
    while(1);
}


xiaoaibjd 发表于 2025-5-28 09:05

单片机MCU技术交流群 679013663

彩虹捕手 发表于 2025-5-28 09:48

看起来你上传了一个关于CM1003使用I2C/UART实现ISP的文件,这对于需要进行嵌入式编程的开发者来说非常有用。如果有任何具体问题,欢迎随时提问。

梦境摆渡人 发表于 2025-5-28 16:20

感谢分享ISP的实现方法,我正需要这个资料来完成我的项目。请问这个文件包含具体的实现步骤和代码吗?

绝影孤狼 发表于 2025-5-28 18:03

这个ISP.rar文件包含了CM1003使用I2C/UART实现ISP的相关资料,有需要的朋友可以下载查看。

梦境摆渡人 发表于 2025-5-28 20:33

这个文件看起来包含了具体的实现方法和代码,对于需要通过I2C/UART实现ISP的朋友来说非常有用。

时光贩卖机 发表于 2025-5-28 21:05

感谢分享!请问这个ISP.rar文件包含了哪些具体内容?是代码示例还是配置文件?
页: [1]
查看完整版本: CM1003使用I2C/UART实现ISP