📄 hex.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 + -