📄 bl78k0_kx2_fdec.c
字号:
//==============================================================================
// PROJECT = Bootloader
// MODULE = bl78k0_kx2_fdec.c
// SHORT DESC. = File decoder module
// DEVICE = 78K0/Kx2
// VERSION = 1.0
// DATE = 05.12.2006
// LAST CHANGE =
// =============================================================================
// By: NEC Electronics (Europe) GmbH
// Arcadiastrasse 10
// D-40472 Duesseldorf
// =============================================================================
#include "io78f0547_80.h"
#include "bl78k0_kx2_user.h"
#include "bl78k0_kx2_fdec.h"
#include <intrinsics.h>
__saddr u08 rec_state; // record states
__saddr u08 nibble_count; // combine one byte from two ASCII bytes
__saddr u08 r_byte; // reseived byte(combined of two ASCII bytes)
__saddr u08 temp_sum; // temporary sum
__saddr u08 sum; // sum for calculate CHKSUM
__saddr u08 r_data_count; // byte count in record
__saddr u16 offset; // Offset in the record
__saddr u08 rec_type; // record type
__saddr u08 eof_bit; // eof bit
__saddr u16 ext_lin_add; // extended linear address
__saddr u16 ext_seg_add; // extended segmented address
__saddr union union_addr union_data_addr; // union address
__saddr union union_addr temp_addr; // temp union address
__saddr u32 last_decode_addr; // last decoded address
__saddr u08 addr_nibble_switch; // addr. nibble switch
//*****************************************************************************
// Function: decodeReceivedBytes
// Parameter: u08 -> this byte will be decode
// Return: 01: Hex file error
// 02: byte analysed, don't write in dbuffer, give me the next byte
// 03: write the analysed byte into the data buffer
//
// Description: This function decodes the received bytes from Intel-Hex file
//*****************************************************************************
__callt u08 decodeReceivedBytes(u08 rx_byte)
{
u08 ascii2hex = 0;
if( rec_state > 1 ) // is record state > 1
{
if( nibble_count == 1 ) // is first nibble?
{
nibble_count = 2; // set first nibble processed
ascii2hex = asciiDecode( rx_byte ); // convert ASCII -> HEX
r_byte = ascii2hex << 4; // save MSB nibble
return 2; // ready, give me the next byte
}
else // is second nibble!
{
nibble_count = 1; // set next nibble is first nibble
ascii2hex = asciiDecode( rx_byte ); // convert ASCII -> HEX
r_byte = r_byte | ascii2hex; // save LSB nibble to MSB Nibble
temp_sum = temp_sum + r_byte; // add as temporary sum for checksum calc.
}
if( ascii2hex == 255 ) // is an error occured on ASCII decode?
{
if( rec_state != 8 ) // isn't lf cr state?
{
return 1; // error occurs!
}
}
}
if( rec_state == 1) // is first record state(start character ':')?
{
if( rx_byte == ':' ) // is ':' received?
{
rec_state = 2; // set record state on "read data length"
sum = 0; // clear sum for checksum calc.
}
else // isn't ':' received!
{
return 1; // error occured on decode ':'
}
}
else if( rec_state == 2 ) // is "read data length" state?
{
r_data_count = r_byte; // save record data count
rec_state = 3; // set record state on "read offset MSB"
}
else if( rec_state == 3 ) // is "read offset MSB" state?
{
offset = ( (u16)r_byte ) << 8; // save 8 Bit MSB offset
rec_state = 4; // set record state on "read offset LSB"
}
else if( rec_state == 4 ) // is "read offset LSB" state?
{
offset = offset | r_byte; // save 8 Bit LSB offset
rec_state = 5; // set record state on "read type"
}
else if( rec_state == 5 ) // is "read type" state?
{
sum = temp_sum; // save temp_sum to sum
rec_type = r_byte; // save record type
rec_state = r_data_count > 0 ? 6 : 7; // if record data count > 0 set record state on "read data"
// if record data count == 0 set record state on 7
if( rec_type == 0 ) // is it data record?
{
// the folows instructions are optimized, because a u32 addition will bind a library function.
// Here we can assume that hex-file work without addr. overflow. This means that an addition
// of ext_seg_add and offset couldn't get a carry. And if the hex file is incorrect, so the
// write to buffer function will catch this exception, because an smaller address will be.
union_data_addr.u32_access = 0; // reset addr.
union_data_addr.u16_access.U16_2 = ext_lin_add; // add ext. lin. address
union_data_addr.u16_access.U16_2 += ext_seg_add >> 12; // save ext. seg. addr.
union_data_addr.u16_access.U16_1 += offset; // add offset
temp_addr.u32_access = union_data_addr.u32_access; // save temporary the address
}
else // isn't data record!
{
if( rec_type == 1 ) // is record type EOF?
{
eof_bit = 1; // set EOF bit
}
}
}
else if( rec_state == 6 ) // is "read data" state?
{
sum = temp_sum; // save temp_sum to sum
if( rec_type == 0 ) // is data record?
{
if( r_data_count == 1 ) // is last data?
{
rec_state = 7; // set record state on 7(CHKSUM)
}
r_data_count--; // decrement record data count
union_data_addr.u32_access = temp_addr.u32_access; // save addr. for this byte
if( last_decode_addr > union_data_addr.u32_access )// is current addr. < last addr.?
return 1; // error
last_decode_addr = union_data_addr.u32_access; // save current addr. as last addr
temp_addr.u16_access.U16_1++; // inc. addr. for next byte
return 3; // return -> write in data buffer
}
else if( rec_type == 2 ) // is rec. type == ext. segment addr.?
{
if( addr_nibble_switch == 0 ) // is MSB addr. byte?
{
addr_nibble_switch = 1; // set next state is LSB addr. byte
ext_seg_add = r_byte << 8; // save MSB addr.
}
else // it is LSB addr. byte
{
addr_nibble_switch = 0;
ext_seg_add = r_byte | ext_seg_add; // save LSB addr. byte
rec_state = 7; // set record state on 7(CHKSUM)
nibble_count = 1; // set nibble count is 1
// -> data count can be odd
}
}
else if( rec_type == 3 ) // is rec. type "start addr. seg. rec."
{
if( r_data_count == 1 ) // is last data byte?
{
rec_state = 7; // set record state on 7(CHKSUM)
}
r_data_count--; // decrement record data count
}
else if( rec_type == 4 ) // is rec. type "ext. lin. addr."?
{
if( addr_nibble_switch == 0 ) // is MSB addr. byte?
{
addr_nibble_switch = 1; // set next state is LSB addr. byte
ext_lin_add = r_byte << 8; // save MSB addr.
}
else // it is LSB addr. byte
{
addr_nibble_switch = 0;
ext_lin_add = r_byte | ext_lin_add; // save LSB addr. byte
rec_state = 7; // set record state on 7(CHKSUM)
}
}
else if( rec_type == 5 ) // is rec. type "start linear addr. rec."?
{
if( r_data_count == 1 ) // is last data?
{
rec_state = 7; // set record state on 7(CHKSUM)
}
r_data_count--; // decrement record data count
}
else // unknown state
{
return 1; // error
}
}
else if( rec_state == 7 ) // is record state "CHKSUM"?
{
if( !(calculateCHKSUM(sum) == r_byte) ) // isn't received CHECKSUM equal to calc?
{
return 1; // error
}
rec_state = 8; // set record state on 8(LF, CR)
}
else if( rec_state == 8 ) // is record state (LF, CR)?
{ // LF, CR
resetAfterRecord(); // reset all after received record
}
else // unknown state
{
return 1; // error
}
return 2; // ready, next byte please
}
//*****************************************************************************
// Function: resetAfterRecord
// Parameter: None
// Return: None
// Description: Reset needfully variables after successful record receive
//*****************************************************************************
void resetAfterRecord(void)
{
rec_state = 1; // reset record state
nibble_count = 1; // reset nibble count
temp_sum = 0; // reset temporary sum
sum = 0; // reset sum
}
//*****************************************************************************
// Function: resetFileDecoder
// Parameter: None
// Return: None
// Description: Reset all variables from file decoder
//*****************************************************************************
__callt void resetFileDecoder(void)
{
rec_state = 1; // record state
nibble_count = 1; // reset nibble count
r_byte = 0; // reset received byte
temp_sum = 0; // reset temporary sum
sum = 0; // reset sum
r_data_count = 0; // reset data count
offset = 0; // reset offset
rec_type = 0; // reset record type
eof_bit = 0; // reset eof bit
ext_lin_add = 0; // reset ext. lin. address
ext_seg_add = 0; // reset ext. seg. address
union_data_addr.u32_access = 0; // reset addr. union
temp_addr.u32_access = 0; // reset temp addr. union
addr_nibble_switch = 0; // reset address nibble switch
last_decode_addr = 0; // reset last decode address
}
//*****************************************************************************
// Function: isEOF
// Parameter: None
// Return: u08
// 0: isn't EOF
// 1: EOF
// Description: For EOF request
//*****************************************************************************
u08 isEOF(void)
{
return eof_bit; // return eof bit
}
//*****************************************************************************
// Function: getAddress
// Parameter: None
// Return: u32 -> address from received byte
// Description: For byte address request
//*****************************************************************************
u32 getAddress(void)
{
return union_data_addr.u32_access; // return byte address
}
//*****************************************************************************
// Function: getWriteByte
// Parameter: None
// Return: u08 -> byte to write into data buffer
// Description: -
//*****************************************************************************
u08 getWriteByte(void)
{
return r_byte; // return decoded byte
}
//*****************************************************************************
// Function: asciiDecode
// Parameter: u08 -> ASCII character
// Return: u08
// 0 - 15 -> digit
// 255 -> ERROR
// Description: Convert ASCII to DIGIT
//*****************************************************************************
__callt u08 asciiDecode(u08 ascii)
{
if( (ascii > 0x2F) && (ascii < 0x3A) ) // is 0 - 9
{
return (ascii & 0x0F); // clear 4 Bit MSB and return
}
else if( (ascii > 0x40) && (ascii < 0x47) ) // is A - F
{
return (ascii - 0x37); // ascii - 0x37 and return
}
else
{
return 255; // error
}
}
//*****************************************************************************
// Function: calculateCHKSUM
// Parameter: u08 -> calculated sum on record
// Return: u08 -> CHECKSUM
//
// Description: This function will calculate two's complement on the param. sum
//*****************************************************************************
u08 calculateCHKSUM(u08 sum_bytes)
{
sum_bytes = ~sum_bytes; // invert sum
sum_bytes += 1; // add 1
return sum_bytes; // return CHKSUM
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -