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

📄 isp_iap.c

📁 ARM系列LPC2378使用ethernet进行codeloader下载更新的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    
    /* 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], \
    &param_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], \
        &param_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], \
        &param_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], \
            &param_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], \
            &param_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], \
        &param_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], \
            &param_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 + -