📄 isp_iap.c
字号:
/* Check count validity first as mapping check requires count */
rc = param_check(param_buf[ISP_PARAM_2],(unsigned *)&count,COUNT,count);
if(rc == 0)
{
rc = param_check(param_buf[ISP_PARAM_1],&dst,RAM_ADDRESS,count);
if (rc == SRC_ADDR_NOT_MAPPED)
{
rc = ADDR_NOT_MAPPED;
}
if (rc == SRC_ADDR_ERROR)
{
rc = ADDR_ERROR;
}
}
/* Do not allow write to ISP RAM variable area */
if( (crp_after_reset == CRP1) )
{
if( ( dst < (RAM_START) ) )
{
rc = CODE_READ_PROTECTION_ENABLED;
}
}
/* Print command result on serial channel */
sendline_crlf(i_to_a(rc,param_buf[ISP_PARAM_0],PARAM_SIZE));
/* execute command only if parameters are ok */
if(rc != CMD_SUCCESS)
{
return;
}
/* Initialize checksum related variables */
checksum = 0;
line_ctr = 0;
last_dst = dst;
last_cnt = count;
while(count>0)
{
if(getline(cmd_buf,CMD_SIZE,&char_cnt) != CMD_SUCCESS)
{
/* Abort command */
break;
}
/* Keep track of number of lines decoded. Need to verify checksum
once the LINE_CHECKSUM lines are receieved */
if(char_cnt != 0) /* Ignore empty lines */
{
line_ctr++;
checksum = checksum + uudecode(cmd_buf,(char *)dst,&decode_count);
dst = dst + decode_count;
count = count - decode_count;
}
/* Need checksum handshake ? */
if( ((line_ctr == LINE_CHECKSUM) || (count == 0)) )
{
char_cnt = 0;
/* Get checksum string (ASCII decimal) from host */
while(char_cnt == 0)
{
rc = getline(cmd_buf,CMD_SIZE,&char_cnt);
}
if( rc != CMD_SUCCESS)
{
break;
}
/* No error check while conversion to integer. If there is an error
it will be trapped by wrong checksum */
a_to_i(cmd_buf,&recvd_checksum);
if( checksum == recvd_checksum)
{
last_cnt = count;
last_dst = dst;
sendline_crlf((char *)ok);
}
else
{
count = last_cnt;
dst = last_dst;
sendline_crlf((char *)resend);
}
/* line counter and checksum has to be reset anyway */
line_ctr = 0;
checksum = 0;
}
}/* While loop */
} /* write_to_ram */
void read(void)
{
unsigned src,checksum,last_src,line_ctr;
int count,encode_count,last_cnt;
unsigned rc;
/* Check count validity first as address mapping check requires count */
rc = param_check(param_buf[ISP_PARAM_2],(unsigned *)&count,COUNT,NUL);
if(rc == 0)
{
rc = param_check(param_buf[ISP_PARAM_1],&src,RAM_OR_FLASH_ADDRESS,count);
}
/* Print command result on serial channel */
sendline_crlf(i_to_a(rc,param_buf[ISP_PARAM_0],PARAM_SIZE));
/* execute command only if parameters are ok */
if(rc != CMD_SUCCESS)
{
return;
}
/* Initialize checksum related variables */
checksum = 0;
line_ctr = 0;
last_src = src;
last_cnt = count;
while(count > 0)
{
if(count > UU_LINE)
{
encode_count = UU_LINE;
}
else
{
encode_count = count;
}
checksum = checksum + uuencode((char *)src,cmd_buf,encode_count);
if(sendline_crlf(cmd_buf) != 0)
{
/* Abort command */
break;
}
/* Keep track of number of lines encoded. Need to send checksum
once the LINE_CHECKSUM lines are transmitted */
line_ctr++;
src = src + encode_count;
count = count - encode_count;
if( ((line_ctr == LINE_CHECKSUM) || (count == 0)) )
{
/* Tranmitt checksum string (ASCII decimal) to host */
sendline_crlf(i_to_a(checksum,cmd_buf,PARAM_SIZE));
/* Read host response */
rc = getline(cmd_buf,CMD_SIZE,NUL);
if( rc != CMD_SUCCESS)
{
break;
}
if(str_cmp(cmd_buf,(char *)ok) == 0)
{
last_cnt = count;
last_src = src;
}
else
{
count = last_cnt;
src = last_src;
}
/* line counter and checksum has to be reset anyway */
line_ctr = 0;
checksum = 0;
}
} /* while count > 0 */
} /* read */
void go_cmd(void)
{
unsigned rc;
void (*go)(void);
if(lock == FALSE)
{
rc = CMD_SUCCESS;
}
else
{
rc = CMD_LOCKED;
}
if(rc == CMD_SUCCESS)
{
/* Convert and check Go addres */
rc = param_check(param_buf[ISP_PARAM_1],(unsigned *)&go, \
RAM_OR_FLASH_ADDRESS,NUL);
}
if(rc == CMD_SUCCESS)
{
/* Check for processor mode switch */
if( ((*(param_buf[ISP_PARAM_2]) == 'T') || (*(param_buf[ISP_PARAM_2]) == 'A')) )
{
if(*(param_buf[ISP_PARAM_2]) == 'T')
{
/* ARM Thumb compiler generates BX instruction when pointer
to a function is used. Set last bit of the address to 1
to prevent mode switch to ARM */
go = (void(*)(void))( ((unsigned)(go) | 0x1) );
}
/* else For ARM mode leave last bit of the address 0 */
}
else
{
/* Mode parameter is not specified or incorrect */
rc = PARAM_ERROR;
}
}
/* Print command result on serial channel */
sendline_crlf(i_to_a(rc,param_buf[ISP_PARAM_1],PARAM_SIZE));
/* execute command only if all the parameters are ok */
if(rc == CMD_SUCCESS)
{
go();
}
} /* go */
void unlock(void)
{
int u_code;
unsigned rc;
rc = param_check(param_buf[ISP_PARAM_1],(unsigned *)&u_code,NO_PARAM_CHECK,NUL);
/* execute command only if parameters are ok */
if(rc == 0)
{
if(u_code == unlock_code)
{
lock = FALSE;
}
else
{
rc = INVALID_CODE;
}
}
/* Print command result on serial channel */
sendline_crlf(i_to_a(rc,param_buf[ISP_PARAM_1],PARAM_SIZE));
} /* unlock */
void prepare_sector(void)
{
/* Convert ascii string to integer. Do not validate sector numbers as it is
done in IAP prepare sector for write. Parameter type is deliberately
set to NO_PARAM_CHECK so that param_check function just converts ascii
to integer
*/
result_table[IAP_STAT_CODE] = param_check(param_buf[ISP_PARAM_1], \
¶m_table[IAP_PARAM_0],NO_PARAM_CHECK,NUL);
if( result_table[IAP_STAT_CODE] == CMD_SUCCESS )
{
result_table[IAP_STAT_CODE] = param_check(param_buf[ISP_PARAM_2], \
¶m_table[IAP_PARAM_1],NO_PARAM_CHECK,NUL);
}
if( result_table[IAP_STAT_CODE] == CMD_SUCCESS )
{
param_table[IAP_CMD_CODE] = PREPARE_SECTOR_FOR_WRITE;
iap_entry(param_table,result_table);
}
sendline_crlf(i_to_a(result_table[IAP_STAT_CODE],param_buf[ISP_PARAM_1], \
PARAM_SIZE));
} /* prepare_sector */
void copy(void)
{
if(lock == TRUE)
{
sendline_crlf(i_to_a(CMD_LOCKED,param_buf[ISP_PARAM_1],PARAM_SIZE));
}
else
{
/* Convert ascii string to integer. Do not validate sector numbers as it is
done in IAP copy RAM to FLASH.Parameter type is deliberately
set to NO_PARAM_CHECK so that param_check function just converts ascii to integer
*/
result_table[IAP_STAT_CODE] = param_check(param_buf[ISP_PARAM_1], \
¶m_table[IAP_PARAM_0],NO_PARAM_CHECK,NUL);
if( result_table[IAP_STAT_CODE] == CMD_SUCCESS )
{
result_table[IAP_STAT_CODE] = param_check(param_buf[ISP_PARAM_2], \
¶m_table[IAP_PARAM_1],NO_PARAM_CHECK,NUL);
}
if( result_table[IAP_STAT_CODE] == CMD_SUCCESS )
{
result_table[IAP_STAT_CODE] = param_check(param_buf[ISP_PARAM_3], \
¶m_table[IAP_PARAM_2],NO_PARAM_CHECK,NUL);
}
/* Do not allow write to USER Start sector */
if( (crp_after_reset == CRP1) )
{
if( (param_table[IAP_PARAM_0] < (USER_START_SECTOR_ADDRESS+USER_START_SECTOR_SIZE)) )
{
result_table[IAP_STAT_CODE] = CODE_READ_PROTECTION_ENABLED;
}
}
if( result_table[IAP_STAT_CODE] == CMD_SUCCESS )
{
param_table[IAP_CMD_CODE] = COPY_RAM_TO_FLASH;
param_table[IAP_PARAM_3] = fcclk_KHz;
iap_entry(param_table,result_table);
}
sendline_crlf(i_to_a(result_table[IAP_STAT_CODE],param_buf[ISP_PARAM_1], \
PARAM_SIZE));
}
} /* copy */
void erase(void)
{
if(lock == TRUE)
{
sendline_crlf(i_to_a(CMD_LOCKED,param_buf[ISP_PARAM_1],PARAM_SIZE));
}
else
{
/* Convert ascii string to integer. Do not validate sector numbers as it is
done in IAP erase sector. Parameter type is deliberately
set to NO_PARAM_CHECK so that param_check function just converts ascii to integer
*/
result_table[IAP_STAT_CODE] = param_check(param_buf[ISP_PARAM_1], \
¶m_table[IAP_PARAM_0],NO_PARAM_CHECK,NUL);
if( result_table[IAP_STAT_CODE] == CMD_SUCCESS )
{
result_table[IAP_STAT_CODE] = param_check(param_buf[ISP_PARAM_2], \
¶m_table[IAP_PARAM_1],NO_PARAM_CHECK,NUL);
}
/* If code read protection level 2 or 3 is enabled allow erase command only when
all sectors are selected for erase */
if( (crp_after_reset == CRP2) || \
(crp_after_reset == CRP3)
)
{
if( (param_table[IAP_PARAM_0] != USER_START_SECTOR) || \
(param_table[IAP_PARAM_1] != USER_END_SECTOR)
)
{
result_table[IAP_STAT_CODE] = CODE_READ_PROTECTION_ENABLED;
}
}
/* If code read protection level 1 is enabled allow erase command only when
user start sector is NOT selected for erase */
else if( (crp_after_reset == CRP1) )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -