Beispiel #1
0
/*----------------------------------------------------------------------------*/
int nxp_verify_hex(ASerialPort_t* aPort, ADeviceNXP_t* aDevice)
{
	int test, loop, wait, count, index = 0, length = 0;
	char hexchk[COUNT_HEXSTR_BUFF];
	/* no need to check end-of-record line! */
	if(aDevice->linehex->type==0x01)
		return 0;
	aDevice->command = NXP_ISP_CHECK;
	aDevice->subcommand = CHECK_DATA;
	aDevice->beg_hi = aDevice->linehex->address;
	aDevice->end_lo = aDevice->linehex->address+aDevice->linehex->count-1;
	count = aDevice->linehex->count*2;
	wait = NXP_CHECK_EQ_INDEX+1+NXP_CHECK_BUFF_EXT+count;
	/* send data read command */
	test = nxp_check_data(aPort, aDevice);
	if(test) return HEX_ERROR_GENERAL;
	/* wait for data */
	test = nxp_get_wait(aPort,hexchk,COUNT_HEXSTR_BUFF,wait);
	if(test) return HEX_ERROR_ACK;
	/* get length */
	while(hexchk[length]) length++;
	if(length<NXP_CHECK_EQ_INDEX+1) return HEX_ERROR_LENGTH;
#ifdef MY1DEBUG
	printf("[DEBUG0] {%s},{%s}\n",hexchk,aDevice->linehex->hexstr);
#endif
	/* check address */
	test = get_hexword(&hexchk[index]);
	if(test!=aDevice->linehex->address) return HEX_ERROR_INVALID;
	/* check '=' sign */
	if(hexchk[NXP_CHECK_EQ_INDEX]!='=') return HEX_ERROR_INVALID;
	/* check data */
	index=NXP_CHECK_EQ_INDEX+1;
	if((length-index)<count) return HEX_ERROR_LENGTH;
#ifdef MY1DEBUG
	printf("[DEBUGX] ");
#endif
	count = 0; /* now, count error */
	for(loop=0;loop<aDevice->linehex->count;loop++)
	{
		test = get_hexbyte(&hexchk[index]);
		if(test!=aDevice->linehex->data[loop])
			count++;
		index += 2;
#ifdef MY1DEBUG
		printf("([%02X|%02X]{%d})",test,aDevice->linehex->data[loop],count);
#endif
	}
#ifdef MY1DEBUG
	printf("\n");
#endif
	return count;
}
Beispiel #2
0
/* ========================================================================= */
uint8 check_checksum(uint8 *hex, uint8 reclen)
{
    uint8 checksum = 0;
    uint8 i;

    // add all byte values, incl. checksum!
    for (i=0; i <= (reclen + HEX_HEADER_LEN); i++)
    {
        checksum += get_hexbyte(hex);
        hex += 2;
    }

    // checksum is zero if checksum is correct
    return (checksum);
}
Beispiel #3
0
/*----------------------------------------------------------------------------*/
int nxp_check_hex(char* hexstr, ALineHEX_t* linehex)
{
	int length = 0, loop = 0, type;
	int count, address, checksum, test, temp;
	/* find length, filter newline! */
	while(hexstr[length])
	{
		linehex->hexstr[length] = hexstr[length];
		if(hexstr[length]=='\n'||hexstr[length]=='\r')
		{
			hexstr[length] = 0x0;
			linehex->hexstr[length] = 0x0;
			break;
		}
		length++;
		if(length>COUNT_HEXSTR_CHAR)
			return HEX_ERROR_LENGTH;
	}
	/* check valid length */
	if(length<9)
		return HEX_ERROR_LENGTH;
	/* check first char */
	if(hexstr[loop++]!=':')
		return HEX_ERROR_NOCOLON;
	/* get data count */
	count = get_hexbyte(&hexstr[loop]);
	checksum = count&0x0FF;
	loop += 2;
	/* get address - highbyte */
	test = get_hexbyte(&hexstr[loop]);
	checksum += test&0xFF;
	loop += 2;
	address = (test&0xFF)<<8;
	/* get address - lowbyte */
	test = get_hexbyte(&hexstr[loop]);
	checksum += test&0xFF;
	loop += 2;
	address |= (test&0xFF);
	/* get record type for checksum calc */
	type = get_hexbyte(&hexstr[loop]);
	checksum += type&0xFF;
	loop += 2;
	/* check EOF type? */
	if(type!=0x00&&type!=0x01)
		return HEX_ERROR_NOTDATA;
	/* save data if requested */
	if(linehex)
	{
		linehex->count = count;
		linehex->type = type;
		linehex->address = address;
		linehex->lastaddr = address + count - 1 + type; /* count=0 @ type=1! */
	}
	/* get data */
	for(temp=0;temp<count;temp++)
	{
		if(loop>=(length-2))
			return HEX_ERROR_LENGTH;
		test = get_hexbyte(&hexstr[loop]);
		if(linehex)
			linehex->data[temp] = test&0xFF;
		checksum += test&0xFF;
		loop += 2;
	}
	/* get checksum */
	if(loop!=(length-2))
		return HEX_ERROR_LENGTH;
	test = get_hexbyte(&hexstr[loop]);
	/* calculate and verify checksum */
	checksum = ~checksum + 1;
	if((test&0xFF)!=(checksum&0xFF))
		return HEX_ERROR_CHECKSUM;
	/* returns record type */
	return type;
}
Beispiel #4
0
/* ========================================================================= */
void bootloader(void)
{
    uint32 addr;
    uint16 addr_low;
    uint8 addr_high = 0;
    uint8 reclen;
    uint8 rectype;
    uint8 idx;
    uint8 buffer[HEX_LINE_LEN_MAX];
    uint8 ch;
    bool hexend = 0;
    
    #if getenv("FLASH_ERASE_SIZE")>2
    uint16 next_addr = 0;
    #endif

    
    /* until end of HEX file */
    while(hexend == 0)
    {
        /* get one line of the HEX file via RS232 until we receive CR or */
        /* we reached the end of the buffer */
        idx = 0;
        do
        {
             /* get one byte */
             ch = getch();
             /* save to buffer */
             buffer[idx] = ch;
             /* increment buffer index */
             idx++;
        }
        while(ch != 0x0A);


        /* get record length */
        reclen = get_hexbyte(&buffer[HEX_LEN_START]);

        /* check for proper checksum */
        if (check_checksum(&buffer[HEX_LEN_START], reclen) != 0)
        {
            /* checkum error - send negative acknowledge */
            putc(NAK);
        }
        else
        {
            /* checkum ok */

            /* get address */
            addr_low = make16(get_hexbyte(&buffer[HEX_ADDR_START]),
                              get_hexbyte(&buffer[HEX_ADDR_START+2]));

            /* make 32 bit address */
            addr = make32(addr_high, addr_low);

            /* get record type */
            rectype = get_hexbyte(&buffer[HEX_TYPE_START]);
            
            if (rectype == HEX_DATA_REC)
            {
                /* only program code memory */
                if ((addr_high < 0x30) && (addr >= RESET_VECTOR))
                {
                    for (idx=0; idx < reclen; idx++)
                    {
                        buffer[idx] = get_hexbyte(&buffer[HEX_DATA_START+(idx*2)]);
                    }

                    #if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
                    #if defined(__PCM__)
                    if ((addr_low!=next_addr)&&(addr_low&(getenv("FLASH_ERASE_SIZE")-1)!=0))
                    #else
                    if ((addr_low!=next_addr)&&(addr_low&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))
                    #endif
                        erase_program_eeprom(addr);
                    next_addr = addr_low + 1;
                    #endif
                    write_program_memory(addr, buffer, reclen);
                }
            }
            else if (rectype == HEX_EOF_REC)
            {
                hexend = 1;
            }
            else if (rectype == HEX_EXTADDR_REC)
            {
                /* to save resources, only take lower byte - this */
                /* allows 24 bit addresses => enough for PIC18F */
                //addr_high = make16(get_hexbyte(&buffer[HEX_DATA_START]),
                //                   get_hexbyte(&buffer[HEX_DATA_START+2]));
                addr_high = get_hexbyte(&buffer[HEX_DATA_START+2]);
            }
            
            /* send positive acknowledge */
            putc(ACK);
        }
    }
}