📄 s29jl064h.c
字号:
/* Write a block of bytes to Flash *//* *//* This routine will be registered as the MTD vol.write routine *//* *//* Parameters: *//* vol : Pointer identifying drive *//* address : Card address to write to *//* buffer : Address of data to write *//* length : Number of bytes to write *//* overwrite : TRUE if overwriting old Flash contents *//* FALSE if old contents are known to be erased *//* *//* Returns: *//* FLStatus : 0 on success, failed otherwise *//*----------------------------------------------------------------------*/static FLStatus am29lv160dMTDWrite(FLFlash vol, CardAddress address, const void FAR1 *buffer, int length, FLBoolean overwrite){ int cLength; FlashWPTR flashPtr, unlockAddr1, unlockAddr2; unsigned long offset; #define bFlashPtr flashPtr #define bBuffer ((const unsigned short int FAR1 *) buffer) #ifdef DEBUG_PRINT DEBUG_PRINT("MTDWrite : address = 0x%lx, length = %d\n",address, length);#endif if (flWriteProtected(vol.socket)) { return flWriteProtect; } flashPtr = mapBase(&vol, address, &offset, length); unlockAddr1 = (FlashWPTR) (FLASH_TFFS_BASE) + 0x555; unlockAddr2 = (FlashWPTR) (FLASH_TFFS_BASE) + 0x2AA; flashPtr = (FlashWPTR) flAddLongToFarPointer((void FAR0 *)flashPtr, offset); cLength = length; while (cLength > 0) { *((volatile UINT16 *)FLASH_TFFS_BASE + 0x555) = 0xAA; *((volatile UINT16 *)FLASH_TFFS_BASE + 0x2AA) = 0x55; *((volatile UINT16 *)FLASH_TFFS_BASE + 0x555) = 0xA0; *bFlashPtr = *bBuffer; cLength = cLength - 2; bBuffer++; bFlashPtr++; printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); } flashPtr -= (length/2); bBuffer -= (length/2); if (tffscmp((void FAR0 *) flashPtr,buffer,length)) { /* verify the data */ printf("write failed in AMD MTD on verification.\n"); return flWriteFault; } return flOK;}/*----------------------------------------------------------------------*//* am29lv160dMTDErase *//* *//* Erase one or more contiguous Flash erasable blocks *//* *//* This routine will be registered as the MTD vol.erase routine *//* *//* Parameters: *//* vol : Pointer identifying drive *//* firstErasableBlock : Number of first block to erase *//* numOfErasableBlocks: Number of blocks to erase *//* *//* Returns: *//* FLStatus : 0 on success, failed otherwise *//*----------------------------------------------------------------------*/static FLStatus am29lv160dMTDErase(FLFlash vol, int firstErasableBlock, int numOfErasableBlocks){ int iBlock; int eraseaddr; #ifdef DEBUG_PRINT DEBUG_PRINT("Enter am29lv160dMTDErase routine\n"); DEBUG_PRINT("firstErasableBlock = %d\n", firstErasableBlock); DEBUG_PRINT("numOfErasableBlocks = %d\n", numOfErasableBlocks);#endif for (iBlock = firstErasableBlock; iBlock < firstErasableBlock + numOfErasableBlocks; iBlock++) { eraseaddr = 0x010000 * iBlock;#ifdef DEBUG_PRINT DEBUG_PRINT("Sector %d at 0x%x will be erased!\n", iBlock, eraseaddr); #endif *((volatile UINT16 *)FLASH_TFFS_BASE+0x555) = 0xAA; *((volatile UINT16 *)FLASH_TFFS_BASE+0x2AA) = 0x55; *((volatile UINT16 *)FLASH_TFFS_BASE+0x555) = 0x80; *((volatile UINT16 *)FLASH_TFFS_BASE+0x555) = 0xAA; *((volatile UINT16 *)FLASH_TFFS_BASE+0x2AA) = 0x55; *((volatile UINT16 *)(FLASH_TFFS_BASE+eraseaddr)) = 0x30; taskDelay (sysClkRateGet () * 8); }#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Leave am29lv160dMTDErase routine.\n");#endif return flOK;}/*****************************************************************//* FLASH AM29LV160 Drivers*//*Architecture: -------------------------------------------------------- Operations Layer ***Op -------------------------------------------------------- Command Sequences Layer ***Cmd -------------------------------------------------------- Hardware read and write Layer HalRead HalWrite --------------------------------------------------------*//**************Definitions for drivers***************************//* Data Bus Configurations */#define DEVICE_TYPE_MASK (0x000F)#define X8_DEVICE (0x0001)#define X16_DEVICE (0x0002)#define X8X16_DEVICE (0x0004)#define DATA_WIDTH_MASK (0x00F0)#define X8_DATA (0x0010)#define X16_DATA (0x0020)/* device/bus width configurations */#define X8X16_AS_X8 (X8X16_DEVICE | X8_DATA)#define X8X16_AS_X16 (X8X16_DEVICE | X16_DATA)/* Address/Command Info */#define NOR_UNLOCK_ADDR1_X8 (0xAAA)#define NOR_UNLOCK_ADDR2_X8 (0x555)#define NOR_UNLOCK_ADDR1_X8_X16 (0x555)#define NOR_UNLOCK_ADDR2_X8_X16 (0x2AA)#define NOR_UNLOCK_DATA1 (0xAAAAAAAA)#define NOR_UNLOCK_DATA2 (0x55555555)#define NOR_RESET_CMD (0xF0F0F0F0)#define NOR_AUTOSELECT_CMD (0x90909090)#define NOR_PROGRAM_CMD (0xA0A0A0A0)#define NOR_ERASE_SETUP_CMD (0x80808080)#define NOR_CHIP_ERASE_CMD (0x10101010)#define NOR_SECTOR_ERASE_CMD (0x30303030)#define NOR_SUSPEND_CMD (0xB0B0B0B0)#define NOR_RESUME_CMD (0x30303030)#define NOR_CFI_QUERY_CMD (0x98989898)#define NOR_UNLOCK_BYPASS_ENTRY_CMD (0x20202020)#define NOR_UNLOCK_BYPASS_PROGRAM_CMD (0xA0A0A0A0)#define NOR_UNLOCK_BYPASS_RESET_CMD1 (0x90909090)#define NOR_UNLOCK_BYPASS_RESET_CMD2 (0x00000000)#define NOR_SECSI_SECTOR_ENTRY_CMD (0x88888888)#define NOR_SECSI_SECTOR_EXIT_SETUP_CMD (0x90909090)#define NOR_SECSI_SECTOR_EXIT_CMD (0x00000000)/* data masks */#define DQ0_BIT_MASK (0x01) /* select DQ0 */#define DQ1_BIT_MASK (0x02) /* select DQ1 */#define DQ2_BIT_MASK (0x04) /* select DQ2 */#define DQ5_BIT_MASK (0x20) /* select DQ5 */#define DQ6_BIT_MASK (0x40) /* select DQ6 */#define DQ7_BIT_MASK (0x80) /* select DQ7 *//* polling routine options */#define POLL_PGM (0x0001)#define POLL_WRT_BUF_PGM (0x0002)#define POLL_SEC_ERS (0x0003)#define POLL_CHIP_ERS (0x0004)#define POLL_RESUME (0x0005)typedef enum { dev_status_unknown = 0, dev_not_busy, dev_busy, dev_exceeded_time_limits, dev_suspend, dev_write_buffer_abort} DEVSTATUS;/* Operation Return Values */#define AM29LV160_OK (0) /* good status */#define AM29LV160_ERROR (-1) /* bad status *//* Flash Drivers Error Codes */#define NO_ERROR (0x00000000)#define FLASH_INTERNAL_TIMEOUT (0x00000001)#define WRITE_BUFFER_LOAD_ERROR (0x00000020)#define INVALID_PARAMETER (0x00000040)#define VERIFY_ERROR (0x00000080)#define INTERNAL_ERROR (0x00000100)#define HAL_ERROR (0x00000200)/*Delay for program*/#define WAIT_4us_FOR_DATA_POLLING_BITS_TO_BECOME_ACTIVE#define DELAY_4us 1/*Debug*/#define FLASH_DEBUG_PRINT printf/**************Global variables for drivers***************************/UINT8 *fpb_g;UINT16 *fpw_g;typedef enum { BYTE_8bits = 0, WORD_16bits = 1} FLASH_DATABUS_WIDTH;FLASH_DATABUS_WIDTH bus_width_g = WORD_16bits;/**************Internal Data Type***************************/typedef UINT32 ADDRESS;typedef UINT32 PARAM;typedef UINT32 FLASHDATA;/**************Functions for drivers***************************//* private functions *//**********************************************************/void hal_PointerInit(UINT8 *byte_ptr, UINT16 *word_ptr){ fpb_g = byte_ptr; fpw_g = word_ptr; return;}/******************************************************************************/UINT32 GetUnitReadMask(PARAM data_cfg){ switch (data_cfg) { case X8X16_AS_X8: return 0xFF; case X8X16_AS_X16: return 0xFFFF; default: return 0xFFFFFFFF; }}/******************************************************************************//* ActiveMaskInit Philosophy: * 1.) identify which devices have DQ6 toggling * and clean out bits other than DQ6 * 2.) identify which devices have DQ2 toggling * and clean out bits other than DQ2 * 3.) Shift the DQ6 bits over to the "DQ0" position (e.g. 0x40 --> 0x01) * and store the result in the "active_mask" variable. * 4.) Shift the DQ2 bits over to the "DQ0" position (e.g. 0x04 --> 0x01) * (for suspended devices) * and OR-in the result to the "active_mask" variable. * * Example: * -------- * X8_AS_X32 configuration DQ6 toggling on device 0 * and DQ2 toggling on device 3: 0x0200 0040 * active mask after DQ6 shift: 0x0000 0001 * active mask after DQ2 shift: 0x0100 0001 * active mask after multiplying by 0xFF: 0xFF00 00FF * */int ActiveMaskInit(FLASHDATA* active_mask_ptr, FLASHDATA data1, FLASHDATA data2, PARAM data_cfg, PARAM polling_type, PARAM* err_code_ptr, char* err_buf ){ FLASHDATA active_mask_tmp = 0; FLASHDATA read_mask = 0xFFFF; FLASHDATA toglbit1_mask = DQ6_BIT_MASK; FLASHDATA toglbit2_mask = DQ2_BIT_MASK; FLASHDATA dq6togl_active = 0; FLASHDATA dq2togl_active = 0; FLASHDATA combined_togl_mask = 0; int status = AM29LV160_ERROR; #if 0 status = ToggleBit1MaskInit(&toglbit1_mask, data_cfg, err_code_ptr, err_buf); if (status != AM29LV160_OK) return status; status = ToggleBit2MaskInit(&toglbit2_mask, data_cfg, err_code_ptr, err_buf); if (status != AM29LV160_OK) return status; #endif dq6togl_active = (data1 ^ data2) & toglbit1_mask; dq2togl_active = (data1 ^ data2) & toglbit2_mask; combined_togl_mask = (data1 ^ data2) & (toglbit1_mask | toglbit2_mask); /* when called from lld_EraseResumeCmd, we do not want lld_StatusGet */ /* to return dev_busy when simply erase suspended. */ if (polling_type == POLL_RESUME) { #if 0 /* indirectly determine the number of devices (interleaving) */ status = ReadMaskInit(&read_mask, data_cfg, err_code_ptr, err_buf); if (status != AM29LV160_OK) return status; #endif /* determine the size of an individual device */ switch(GetUnitReadMask(data_cfg)) { case 0xFF: switch(read_mask) /* if erase suspended, make it not active */ { case 0xFF: if (combined_togl_mask == toglbit2_mask) dq2togl_active = 0; break; case 0xFFFF: if ((combined_togl_mask & 0xFF) == (toglbit2_mask & 0xFF)) dq2togl_active &= 0xFF00; if ((combined_togl_mask & 0xFF00) == (toglbit2_mask & 0xFF00)) dq2togl_active &= 0x00FF; break; case 0xFFFFFFFF: if ((combined_togl_mask & 0x000000FF) == (toglbit2_mask & 0x000000FF)) dq2togl_active &= 0xFFFFFF00; if ((combined_togl_mask & 0x0000FF00) == (toglbit2_mask & 0x0000FF00)) dq2togl_active &= 0xFFFF00FF; if ((combined_togl_mask & 0x00FF0000) == (toglbit2_mask & 0x00FF0000)) dq2togl_active &= 0xFF00FFFF; if ((combined_togl_mask & 0xFF000000) == (toglbit2_mask & 0xFF000000)) dq2togl_active &= 0x00FFFFFF; break; } break; case 0xFFFF: switch(read_mask) { case 0xFFFF: if (combined_togl_mask == toglbit2_mask) dq2togl_active = 0; break; case 0xFFFFFFFF: if ((combined_togl_mask & 0x0000FFFF) == (toglbit2_mask & 0x0000FFFF)) dq2togl_active &= 0xFFFF0000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -