flash_28fxxx.inl
来自「eCos操作系统源码」· INL 代码 · 共 767 行 · 第 1/2 页
INL
767 行
goto bad; } *BA = FLASH_Write_Buffer; } *BA = FLASHWORD(wc-1); // Count is 0..N-1 for (i = 0; i < wc; i++) { addr_v = FLASH_P2V(addr_p++); *addr_v = *data_p++; } *BA = FLASH_Confirm; ROM[0] = FLASH_Read_Status; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { res = FLASH_ERR_DRV_TIMEOUT; goto bad; } } } }#endif // CYGHWR_DEVS_FLASH_INTEL_BUFFERED_WRITES while (len > 0) { addr_v = FLASH_P2V(addr_p++); ROM[0] = FLASH_Program; *addr_v = *data_p; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { res = FLASH_ERR_DRV_TIMEOUT; goto bad; } } if (stat & FLASH_ErrorMask) { if (!(stat & FLASH_ErrorProgram)) res = FLASH_ERR_HWR; // Unknown error else { if (stat & FLASH_ErrorLowVoltage) res = FLASH_ERR_LOW_VOLTAGE; else if (stat & FLASH_ErrorLocked) res = FLASH_ERR_PROTECT; else res = FLASH_ERR_PROGRAM; } break; } ROM[0] = FLASH_Clear_Status; ROM[0] = FLASH_Reset; if (*addr_v != *data_p++) { res = FLASH_ERR_DRV_VERIFY; break; } len -= sizeof( flash_data_t ); } // Restore ROM to "normal" mode bad: ROM[0] = FLASH_Reset; CYGHWR_FLASH_WRITE_DISABLE(); // Ideally, we'd want to return not only the failure code, but also // the address/device that reported the error. return res;}#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING//----------------------------------------------------------------------------// Lock blockintflash_lock_block(void* block){ volatile flash_data_t *ROM; int res = FLASH_ERR_OK; flash_data_t state; int timeout = 5000000; volatile flash_data_t* b_p = (flash_data_t*) block; volatile flash_data_t *b_v; cyg_bool bootblock; int len, len_ix = 1; if (!flash_dev_info->locking) return res;#ifdef DEBUG d_print("flash_lock_block %08x\n", block);#endif ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask); // Is this the boot sector? bootblock = (flash_dev_info->bootblock && (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM))); if (bootblock) { len = flash_dev_info->bootblocks[len_ix++]; } else { len = flash_dev_info->block_size; } CYGHWR_FLASH_WRITE_ENABLE(); while (len > 0) { b_v = FLASH_P2V(b_p); // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Set lock bit *b_v = FLASH_Set_Lock; *b_v = FLASH_Set_Lock_Confirm; // Confirmation while(((state = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { res = FLASH_ERR_DRV_TIMEOUT; break; } } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; // Go to next block b_p += len / sizeof( flash_data_t ); len = 0; if (FLASH_ErrorLock == (state & FLASH_ErrorLock)) res = FLASH_ERR_LOCK; if (res != FLASH_ERR_OK) break; if (bootblock) len = flash_dev_info->bootblocks[len_ix++]; } CYGHWR_FLASH_WRITE_DISABLE(); return res;}//----------------------------------------------------------------------------// Unlock blockintflash_unlock_block(void* block, int block_size, int blocks){ volatile flash_data_t *ROM; int res = FLASH_ERR_OK; flash_data_t state; int timeout = 5000000; volatile flash_data_t* b_p = (flash_data_t*) block; volatile flash_data_t *b_v;#if (defined(CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4) || defined(CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_95) ) // The Sharp device follows all the same rules as the Intel 28x part, // except that the unlocking mechanism unlocks all blocks at once. This // is the way the Strata part seems to work. I will replace the // flash_unlock_block function with one similar to the Strata function. // As the Sharp part does not have the bootlock characteristics, I // will ignore them.//// The difficulty with this operation is that the hardware does not support// unlocking single blocks. However, the logical layer would like this to// be the case, so this routine emulates it. The hardware can clear all of// the locks in the device at once. This routine will use that approach and// then reset the regions which are known to be locked.//#define MAX_FLASH_BLOCKS (flash_dev_info->block_count * CYGNUM_FLASH_SERIES) unsigned char is_locked[MAX_FLASH_BLOCKS]; int i; // Get base address and map addresses to virtual addresses#ifdef DEBUG d_print("\nNow inside low level driver\n");#endif ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE; block = FLASH_P2V(block); // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Get current block lock state. This needs to access each block on // the device so currently locked blocks can be re-locked. b_p = ROM; for (i = 0; i < blocks; i++) { b_v = FLASH_P2V( b_p ); *b_v = FLASH_Read_ID; if (b_v == block) { is_locked[i] = 0; } else { if(b_v[2]){ /* it is possible that one of the interleaved devices * is locked, but others are not. Coming out of this * function, if one was locked, all will be locked. */ is_locked[i] = 1; }else{ is_locked[i] = 0; } }#ifdef DEBUG#endif b_p += block_size / sizeof(*b_p); } ROM[0] = FLASH_Reset;#ifdef DEBUG for (i = 0; i < blocks; i++) { d_print("\nblock %d %s", i, is_locked[i] ? "LOCKED" : "UNLOCKED"); } d_print("\n");#endif // Clears all lock bits ROM[0] = FLASH_Clear_Lock; ROM[0] = FLASH_Clear_Lock_Confirm; // Confirmation timeout = 5000000; while(((state = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } // Restore the lock state b_p = ROM; for (i = 0; i < blocks; i++) { b_v = FLASH_P2V( b_p ); if (is_locked[i]) { *b_v = FLASH_Set_Lock; *b_v = FLASH_Set_Lock_Confirm; // Confirmation timeout = 5000000; while(((state = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0){ res = FLASH_ERR_DRV_TIMEOUT; break; } } if (FLASH_ErrorLock == (state & FLASH_ErrorLock)) res = FLASH_ERR_LOCK; if (res != FLASH_ERR_OK) break; } b_p += block_size / sizeof(*b_p); } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; return res;#else // not CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4 cyg_bool bootblock; int len, len_ix = 1; if (!flash_dev_info->locking) return res; ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask);#ifdef DEBUG d_print("flash_unlock_block dev %08x block %08x size %08x count %08x\n", ROM, block, block_size, blocks);#endif // Is this the boot sector? bootblock = (flash_dev_info->bootblock && (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM))); if (bootblock) { len = flash_dev_info->bootblocks[len_ix++]; } else { len = flash_dev_info->block_size; } CYGHWR_FLASH_WRITE_ENABLE(); while (len > 0) { b_v = FLASH_P2V(b_p); // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Clear lock bit *b_v = FLASH_Clear_Lock; *b_v = FLASH_Clear_Lock_Confirm; // Confirmation while(((state = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { res = FLASH_ERR_DRV_TIMEOUT; break; } } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; // Go to next block b_p += len / sizeof( flash_data_t ); len = 0; if (FLASH_ErrorLock == (state & FLASH_ErrorLock)) res = FLASH_ERR_LOCK; if (res != FLASH_ERR_OK) break; if (bootblock) len = flash_dev_info->bootblocks[len_ix++]; } CYGHWR_FLASH_WRITE_DISABLE(); return res; // FIXME: Unlocking need to support some other parts in the future // as well which take a little more diddling.#if 0//// The difficulty with this operation is that the hardware does not support// unlocking single blocks. However, the logical layer would like this to// be the case, so this routine emulates it. The hardware can clear all of// the locks in the device at once. This routine will use that approach and// then reset the regions which are known to be locked.//#define MAX_FLASH_BLOCKS (flash_dev_info->block_count * CYGNUM_FLASH_SERIES) unsigned char is_locked[MAX_FLASH_BLOCKS]; // Get base address and map addresses to virtual addresses ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)block ); block = FLASH_P2V(block); // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Get current block lock state. This needs to access each block on // the device so currently locked blocks can be re-locked. bp = ROM; for (i = 0; i < blocks; i++) { bpv = FLASH_P2V( bp ); *bpv = FLASH_Read_Query; if (bpv == block) { is_locked[i] = 0; } else { is_locked[i] = bpv[2]; } bp += block_size / sizeof(*bp); } // Clears all lock bits ROM[0] = FLASH_Clear_Locks; ROM[0] = FLASH_Clear_Locks_Confirm; // Confirmation timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } // Restore the lock state bp = ROM; for (i = 0; i < blocks; i++) { bpv = FLASH_P2V( bp ); if (is_locked[i]) { *bpv = FLASH_Set_Lock; *bpv = FLASH_Set_Lock_Confirm; // Confirmation timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } } bp += block_size / sizeof(*bp); } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset;#endif#endif // #CYGHWR_DEVS_FLASH_SHARP_LH28F016SCT_Z4}#endif // CYGHWR_IO_FLASH_BLOCK_LOCKING#endif // CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?