⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hex.c

📁 In-system Programming with C51 MCU and External Flash
💻 C
字号:
/*C**************************************************************************
* NAME: hex.c 
*----------------------------------------------------------------------------
* PURPOSE: 
* HEX file decoder: extracts HEX file information, retrieve data and program
* the FLASH memory on the fly.
*****************************************************************************/

/*_____ I N C L U D E S ____________________________________________________*/
#include "config.h"
#include "isp.h"
#include <ctype.h>

/*_____ M A C R O S ________________________________________________________*/
/* State definition of the HEX file decoder state machine */
#define REC_MARK    0x01
#define REC_LEN_1   0x02
#define REC_LEN_2   0x03
#define OFFSET_1    0x04	
#define OFFSET_2    0x05
#define OFFSET_3    0x06
#define OFFSET_4    0x07
#define REC_TYP_1   0x08	
#define REC_TYP_2   0x09
#define DATA_1      0x0A
#define DATA_2      0x0B
#define CHEKSUM_1   0x0C	
#define CHEKSUM_2   0x0D

/*_____ D E C L A R A T I O N ______________________________________________*/
Uchar hex_decoder(Uchar hex_data);

/*F**************************************************************************
* NAME: hex_parser
*----------------------------------------------------------------------------
* PARAMS:  
* return: Exit status of the HEX file parser: OK or bad CRC encountered. 
*----------------------------------------------------------------------------
* PURPOSE: 
* Monitors the HEX file Rx buffer and call the HEX decoder as soon as data
* are available.
*****************************************************************************/
Uchar hex_parser(void)
{  
  Uchar hex_data, status;

  status = HEX_DEC_OK;
  
  while (status == HEX_DEC_OK)  /* Processes while hex decoder status is OK */ 
  {    
    if(nb_rx_data != 0)  
    {
      hex_data = rx_buffer_rd();
      status = hex_decoder(hex_data);
    }
  }         
  return status;      
}

/*F**************************************************************************
* NAME: hex_decoder
*----------------------------------------------------------------------------
* PARAMS:  
* hex_data: data from the HEX file to decode    
* return: Hex decoder exit status: OK or bad CRC encountered.
*----------------------------------------------------------------------------
* PURPOSE: 
* Decodes all HEX file records on a byte per byte basis: analyse HEX record, 
* extracts data for FLASH programming and verifies the checksum.
*****************************************************************************
* NOTE: 
* HEX data are ASCII data format. Each byte is made of 2 ASCII form digits
* that needed to be converted. Conversion uses toint which is not a ANSI
* C function. One should use strtol when available (not in Keil C lib).
*****************************************************************************/
Uchar hex_decoder(Uchar hex_data)
{
  static state = REC_MARK;  
  static Uchar length, type, nb_byte, data_value, sum, sum_1, sum_2;
  static Uint16 offset;

  Uchar status;

  status = HEX_DEC_OK;  

  switch(state)
  {		
    case REC_MARK:            /* Start of a new record */ 			  
	  {
      if (hex_data == ':')    /* Check if the right character */
        {                     
          state = REC_LEN_1;  /* If ok, next step: get the 1st lenght char */
          nb_byte=0; 
        }
        else  
          state = REC_MARK;   /* If ko, spurious char and skip */
      break;
    }
		
    case REC_LEN_1:           /* Get the 1st digit of the length byte */ 
    { 
      length = toint(hex_data) * 16; 
	    state = REC_LEN_2;         
      break;  
    }
       
    case REC_LEN_2:           /* Get the 2nd digit of the lenght byte */ 
    {              
	    length = length + toint(hex_data); 
      state = OFFSET_1;       
      break;  
    }
      
    case OFFSET_1:            /* Get the 1st digit of the adress byte */
    {
	    offset = toint(hex_data) * 4096; 
      state = OFFSET_2;       
      break;  
    }
       
    case OFFSET_2:            /* Get the 2nd digit of the adress byte */
    {
	    offset = offset + toint(hex_data) * 256;
     	sum_1= offset / 256;   
	    state = OFFSET_3;        
      break;  
    }

    case OFFSET_3:            /* Get the 3rd digit of the adress byte */
    {         
      offset = offset + toint(hex_data) * 16; 
	    state = OFFSET_4; 
      break;    
    }

    case OFFSET_4:            /* Get the 4th digit of the adress byte */
    {
	     offset = offset + toint(hex_data); 
	     sum_2 = offset - sum_1 * 256;       
       state = REC_TYP_1; 
       break;  
    }
                          
    case REC_TYP_1:           /* Get the 1st digit of the record type */
    {           
       type = toint(hex_data) * 16; 
	     state =REC_TYP_2; 
       break;  
    }

    case REC_TYP_2:           /* Get the 2nd digit of the record type */
    {     
      type = type + toint(hex_data); 
      sum = length + sum_1 + sum_2 + type;     
      if (length==0x00)       
        state=CHEKSUM_1;      /* If no data, go to checksum computation */
      else 
        state = DATA_1;       /* Otherwise next is data record acquisition */
      break;  
    }

    case DATA_1:              /* Get the 1st digit of one data */
    {                        
      data_value = toint(hex_data) * 16 ;        
	    state = DATA_2; 
      break;  
    }

    case DATA_2:              /* Get the 2nd digit of one data */
    { 
	    data_value = data_value + toint(hex_data); 
	    sum = sum + data_value;
                  
      flash_prog(offset + nb_byte, data_value);
      
      nb_byte++;      
      if (nb_byte == length) 
       state = CHEKSUM_1;     /* If end of data block, go to checksum */
      else
       state = DATA_1;        /* Otherwise, get the next data in the block */
      break;                         
     }

     case CHEKSUM_1:          /* Get 1st digit of the checksum */
     {           
       sum_1 = toint(hex_data) * 16;
	     sum = (~sum) + 1;      /* Checksum 2 complement */
       state = CHEKSUM_2; 
       break;  
     }

     case CHEKSUM_2:          /* Get 2nd digit of the checksum */
     {     
       sum_1 = sum_1 + toint(hex_data);
       if (sum_1 != sum) 
         status = HEX_DEC_CSERR;
              
       state = REC_MARK;      /* Ready for next record */
       if(type==0x01)   
         status = HEX_DEC_END; /*  end of transmission */ 
       break;  
    }
  }     
  return status;  
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -