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

📄 bl78k0_kx2_fdec.c

📁 NEC upd78f0300的自编程序样例
💻 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 + -