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

📄 flash.c

📁 realview下的一个arm9的bootloader烧录器.支持norflash读写
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    
	    for( CurrenBlockNumber = 0; CurrenBlockNumber < NUM_BLOCKS-1; CurrenBlockNumber++ ) { //total 131: CurBlock = 0~130
	        if ((flash_offset>=BlockOffset[CurrenBlockNumber]) && (flash_offset<BlockOffset[CurrenBlockNumber+1]) ) {
	         ret_val = BlockOffset[CurrenBlockNumber];
	         break;
	         }
	    }
*/   	
//     ret_val = flash_offset & FLASH_BLOCK_SIZE;
    
    return ret_val;
}

unsigned int flash_block_unlock(unsigned int flash_offset,unsigned int lock_block)//flash_block_address
{
    unsigned int flash_block_address;
    unsigned int lock_status;
    
    if (lock_block != Correct_block)
    {
    	lock_block = flash_find_block_address(flash_offset,lock_block);
    	flash_block_address = BlockOffset[lock_block];
    }
    else if (lock_block == Correct_block)
    {
    	flash_block_address = flash_offset;
    }
//    flash_block_address <<= 1;
//    flash_block_address += FLASH_BASE;
    
    *( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_CONFIGURATION; 
    *( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_UNLOCK; 
    
    
    *( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_READ_ELECTRONIC_SIGNATURE; 
    lock_status = *( (unsigned short *)(flash_block_address) + 0x02 ); //flash_offset<-->flash_block_address
    
    if(lock_status != FLASH_BLOCK_PROTECTION_UNLOCKED)
    {
        //printf("%x unlock error!\n",flash_offset);
        //while(1);
    }

    *( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_READ;
    
    return lock_block;
}



unsigned int flash_block_lock(unsigned int flash_offset,unsigned int lock_block)
{
    unsigned int flash_block_address;
    unsigned int lock_status;
    
    if (lock_block != Correct_block)
    {
        lock_block = flash_find_block_address(flash_offset,lock_block);
        flash_block_address = BlockOffset[lock_block];
    }
    else if (lock_block == Correct_block)
    {
    	flash_block_address = flash_offset;
    }
//    flash_block_address <<= 1;
//    flash_block_address += FLASH_BASE;
    
    *( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_CONFIGURATION; 
    *( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_LOCK; 
    
    
    *( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_READ_ELECTRONIC_SIGNATURE; 
    lock_status = *( (unsigned short *)(flash_block_address) + 0x02 ); //flash_offset<-->flash_block_address
    
    if(lock_status != FLASH_BLOCK_PROTECTION_LOCKED)
    {
        //printf("%x lock error!\n",flash_offset);
        //while(1);
    }

    *( (unsigned short *)(flash_block_address) ) = (unsigned short)FLASH_CMD_READ;
    
    return lock_block;
}



void ghdi_flash_block_erase(UINT32 CurrenBlockOffset)
{
//    UINT32 CurrenBlockOffset=BlockOffset[BlockNumber]; //erase addr = CurrenBlockOffset;
    unsigned short flash_status_reg;
    unsigned int lock_block;
    
    lock_block = 0x20000000;
    /* Validate paratmers */
    if( ( CurrenBlockOffset == NULL ) ) /* Add flash parameter checking later */
    {
        while(1);
    }
    
        lock_block = flash_block_unlock(CurrenBlockOffset,lock_block);
        *( (unsigned short *)CurrenBlockOffset) = (unsigned short)FLASH_CMD_BLOCK_ERASE; 
        *( (unsigned short *)CurrenBlockOffset) = (unsigned short)FLASH_CMD_UNLOCK; 
        
        do
        {
            flash_status_reg = *( (unsigned short *)(CurrenBlockOffset));
        }
        while( (flash_status_reg & SR7) == 0);
        
        if( ( (flash_status_reg & SR3) == SR3 ) ||
            ( ( (flash_status_reg & SR4) == SR4 ) && ( (flash_status_reg & SR5) == SR5 ) ) ||
            ( (flash_status_reg & SR5) == SR5 ) ||
            ( (flash_status_reg & SR1) == SR1 ) )
        {
            //printf("Erase error! block: %x\n",CurrenBlockOffset);
            //while(1);
        }
        lock_block = flash_block_lock(CurrenBlockOffset,lock_block);
       
}


/* API added by WBH, 20071106 */

unsigned int flash_get_block_addr_base(unsigned int sys_addr_within_block)
{
    unsigned int ret_val;
    unsigned int flash_block_addr_mask;

    ASSERT( sys_addr_within_block >= FLASH_BASE );
    ASSERT( sys_addr_within_block <  (FLASH_BASE + FLASH_SIZE) );

    /* Within parameter blocks range */
    if( ( sys_addr_within_block >= FLASH_BASE + FLASH_NORMAL_BLOCK_SIZE *FLASH_NORMAL_BLOCK_NUM ) && 
        ( sys_addr_within_block <  FLASH_BASE + (FLASH_NORMAL_BLOCK_SIZE *FLASH_NORMAL_BLOCK_NUM) + (FLASH_PARAMETER_BLOCK_SIZE *FLASH_PARAMETER_BLOCK_NUM) ) 
      )
    {
        flash_block_addr_mask = (FLASH_PARAMETER_BLOCK_SIZE - 1);
    }
    /* Within normal blocks range */
    else
    {
        flash_block_addr_mask = (FLASH_NORMAL_BLOCK_SIZE - 1);
    }

    ret_val = sys_addr_within_block & ~flash_block_addr_mask;

    return ret_val;
}


unsigned int flash_get_block_addr_base_from_id(unsigned int block_id)
{
    unsigned int ret_val;


    ASSERT( block_id <= FLASH_TOTAL_BLOCK_NUM );

    /* Within parameter blocks range */
    if( ( block_id >= FLASH_NORMAL_BLOCK_NUM ) && 
        ( block_id <  FLASH_NORMAL_BLOCK_NUM + FLASH_PARAMETER_BLOCK_NUM )
      )
    {
    	ret_val = FLASH_BASE + 
    	          (FLASH_NORMAL_BLOCK_SIZE    * FLASH_NORMAL_BLOCK_NUM ) + 
    	          (FLASH_PARAMETER_BLOCK_SIZE * (block_id - FLASH_NORMAL_BLOCK_NUM ) ) ;
    }
    /* Within normal blocks range */
    else
    {
    	ret_val = FLASH_BASE + 
    	          (FLASH_NORMAL_BLOCK_SIZE * block_id);
    }

    return ret_val;
}


unsigned int flash_get_block_size_from_id(unsigned int block_id)
{
    unsigned int ret_val;


    ASSERT( block_id <= FLASH_TOTAL_BLOCK_NUM );

    /* Within parameter blocks range */
    if( ( block_id >= FLASH_NORMAL_BLOCK_NUM ) && 
        ( block_id <  FLASH_NORMAL_BLOCK_NUM + FLASH_PARAMETER_BLOCK_NUM )
      )
    {
    	ret_val = FLASH_PARAMETER_BLOCK_SIZE;
    }
    /* Within normal blocks range */
    else
    {
    	ret_val = FLASH_NORMAL_BLOCK_SIZE;
    }

    return ret_val;
}


/* Block lock/unlock/lock-down function */
unsigned int flash_block_cntl(unsigned int sys_addr_within_block, unsigned int operation)
{
    unsigned int block_base_address;
    unsigned int lock_status;
    unsigned int ret_val = 1;
    static const unsigned short flash_op_cmd_set[2]            = {FLASH_CMD_LOCK, 
                                                                  FLASH_CMD_UNLOCK};

    static const unsigned short flash_op_expected_state_set[2] = {FLASH_BLOCK_PROTECTION_LOCKED, 
                                                                  FLASH_BLOCK_PROTECTION_UNLOCKED};
    unsigned int flash_op_cmd, flash_op_expexted_state;

    /* Validate parameters */
    ASSERT(sys_addr_within_block >= FLASH_BASE );
    ASSERT(sys_addr_within_block <  (FLASH_BASE + FLASH_SIZE) );
    ASSERT(operation < FLASH_OPERATION_MAX);
    
    flash_op_cmd            = flash_op_cmd_set[operation];
    flash_op_expexted_state = flash_op_expected_state_set[operation];

    /* Get block base address with respect to the system memory space */
    block_base_address = flash_get_block_addr_base(sys_addr_within_block);
    
    *( (unsigned short *)(block_base_address) ) = (unsigned short)FLASH_CMD_CONFIGURATION; 
    *( (unsigned short *)(block_base_address) ) = (unsigned short)flash_op_cmd; 
    
    
    *( (unsigned short *)(block_base_address) ) = (unsigned short)FLASH_CMD_READ_ELECTRONIC_SIGNATURE; 
    lock_status = *( (unsigned short *)(block_base_address) + 0x02 ); //flash_offset<-->flash_block_address
    
    ASSERT(lock_status == flash_op_expexted_state);

    *( (unsigned short *)(block_base_address) ) = (unsigned short)FLASH_CMD_READ;
    
    return ret_val;
}



/*******************************************************************************
 *
 *  Function name: nor_flash_write
 *  --------------
 *  Description:   Write word data to flash
 *  ------------
 *  Parameters:    addr:   the location of flash where the data will be written to.
 *  -----------    length: how long the data is. The lenght unit is 16 bits.
 *                 *data:  The pointer to the written data.
 *
 *  Returns:       None
 *  --------
 *
 ******************************************************************************/
void nor_flash_write (unsigned int addr, unsigned short *data, unsigned int length)
{
    int i, fail_count, max_fail_count;
    unsigned int flash_write_starting_address;   
    unsigned short flash_status_reg;

    ASSERT( addr >= FLASH_BASE );
    ASSERT( (addr + ( length << 1 ) ) < (FLASH_BASE + FLASH_SIZE) );

    fail_count = 0;
    max_fail_count = 10000000; /* Just a large number for waiting */        flash_write_starting_address = addr;

    for(i=0; i<length; i++)
    {
        flash_block_cntl((flash_write_starting_address) + (i << 1) , FLASH_OPERATION_UNLOCK);
        *( (unsigned short *)(flash_write_starting_address) + i) = (unsigned short)FLASH_CMD_WRITE; 
        *( (unsigned short *)(flash_write_starting_address) + i) = *(data+i); 
       
        do
        {
            flash_status_reg = *( (unsigned short *)(flash_write_starting_address) + i);

            if(fail_count > max_fail_count)
            {
                /* erase failed */
                ASSERT(FALSE);
            }
            else
            {
                fail_count++;
            }
        }
        while( (flash_status_reg & SR7) == 0);
        
        ASSERT( (flash_status_reg & SR3) != SR3 ); /* Vpp invalid, abort */
        ASSERT( (flash_status_reg & SR4) != SR4 ); /* Program error */
        ASSERT( (flash_status_reg & SR1) != SR1 ); /* Program/erase on protected block, abort */

        flash_block_cntl((flash_write_starting_address) + (i << 1) , FLASH_OPERATION_LOCK);
    }
}

/*******************************************************************************
 *
 *  Function name: nor_flash_sector_erase
 *  --------------
 *  Description:   Erase the whole content of a sector.
 *  ------------
 *  Parameters:    addr: the address within this sector.
 *  -----------
 *  Returns:       Status (1: success, -1: fail)
 *  --------
 *
 ******************************************************************************/
int nor_flash_sector_erase (unsigned int addr)
{
    int status = 1; //Assume ok by default
    UINT32 fail_count, max_fail_count;
    unsigned short flash_status_reg;
    unsigned int block_base_address;
    
    /* Validate paratmers */
    ASSERT( addr >= FLASH_BASE );

    fail_count = 0;
    max_fail_count = 300; 

    block_base_address = flash_get_block_addr_base(addr);    flash_block_cntl(block_base_address, FLASH_OPERATION_UNLOCK);

    *( (unsigned short *)block_base_address) = (unsigned short)FLASH_CMD_BLOCK_ERASE; 
    *( (unsigned short *)block_base_address) = (unsigned short)FLASH_CMD_UNLOCK; 
    
    do
    {
        flash_status_reg = *( (unsigned short *)(block_base_address));

        if(fail_count > max_fail_count)
        {
            status = -1; /* erase failed */
            break;
        }
        else
        {
            //NU_Sleep(10);//10 ticks = 10 * 10ms = 0.1 sec
            gpt_sleep_us(10*1000);
            fail_count++;
        }
    }
    while( (flash_status_reg & SR7) == 0);
    
    ASSERT( (flash_status_reg & SR3) != SR3 );
    ASSERT( ( (flash_status_reg & SR4) != SR4 ) || ( (flash_status_reg & SR5) != SR5 ) );
    ASSERT( (flash_status_reg & SR5) != SR5 );
    ASSERT( (flash_status_reg & SR1) != SR1 );

    flash_block_cntl(addr, FLASH_OPERATION_LOCK);

    return status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -