CPU 用的是2812,FLASH为AM29LV160DT(一片)
#define WRITE_FLASH(addr,data) *((volatile INT16U*)(addr)) = (INT16U)data
/* --------------------------------------------------------------------- * 函 数 名: waitForOperationEnd * 函数描述: 等待操作结束 * ----------------------------------------------------------------------*/ BOOL waitForOperationEnd(void) { INT32U addr; BOOL finish** = FALSE; INT16U dq5Counter = 0; volatile INT16U oldStatus,newStatus;
addr = 0x101000;
/* 根据DQ6 和DQ5 判断操作是否完成*/ oldStatus = *((volatile INT16U *)addr); while(1) { newStatus = *((volatile INT16U *)addr); if( (oldStatus & 0x40) == (newStatus & 0x40) ) { finish** = TRUE; break; } else { if( (newStatus & 0x20) != 0) { if(dq5Counter ++ >= 1) { finish** = FALSE; break; } } oldStatus = newStatus; } }
return(finish**); } /* --------------------------------------------------------------------- * 函 数 名: addrConvert * 函数描述: 将0~1m的虚拟地址转化为实际地址 * ----------------------------------------------------------------------*/ INT32U addrConvert(INT32U virtualAddr) { INT32U realAddr;
if(virtualAddr < 0x80000) { GpioDataRegs.GPFDAT.bit.GPIOF14 = 0; realAddr = virtualAddr + 0x100000; } else if(virtualAddr <0x100000) { GpioDataRegs.GPFDAT.bit.GPIOF14 = 1; realAddr = virtualAddr + 0x100000 - 0x80000; } /* 大于1m 则取1m 对应的实际地址*/ else { GpioDataRegs.GPFDAT.bit.GPIOF14 = 1; realAddr = 0x17ffff; } return(realAddr); }
/* --------------------------------------------------------------------- * 函 数 名: wordRead * 函数描述: 从flash 指定地址中读字 * ----------------------------------------------------------------------*/ INT16U wordRead(INT32U virtualAddr) { INT32U addr; addr = addrConvert(virtualAddr); return( *((volatile unsigned int *)(addr)) ); } /* --------------------------------------------------------------------- * 函 数 名: wordWrite * 函数描述: 向flash 指定地址中写字 * ----------------------------------------------------------------------*/ BOOL wordWrite ( INT32U virtualAddr, INT16U data) { INT32U addr; BOOL finish** = FALSE; INT16U a19Status = 0; addr = addrConvert(virtualAddr); a19Status = GpioDataRegs.GPFDAT.bit.GPIOF14 ; GpioDataRegs.GPFDAT.bit.GPIOF14 = 0; WRITE_FLASH(0x555+0x100000, 0xAA); WRITE_FLASH(0x2AA+0x100000, 0x55); WRITE_FLASH(0x555+0x100000, 0xA0);
GpioDataRegs.GPFDAT.bit.GPIOF14 = a19Status; WRITE_FLASH(addr, data); finish** = waitForOperationEnd(); return(finish**); } /* --------------------------------------------------------------------- * 函 数 名: sectorErase * 函数描述: 擦除指定扇区 * ----------------------------------------------------------------------*/ BOOL sectorErase(INT32U virtualSectorAddr) { INT32U sectorAddr; INT16U a19Status = 0; BOOL finish** = FALSE;
sectorAddr = addrConvert(virtualSectorAddr); a19Status = GpioDataRegs.GPFDAT.bit.GPIOF14 ; GpioDataRegs.GPFDAT.bit.GPIOF14 = 0; WRITE_FLASH(0x555+0x100000, 0xAA); WRITE_FLASH(0x2AA+0x100000, 0x55); WRITE_FLASH(0x555+0x100000, 0x80); WRITE_FLASH(0x555+0x100000, 0xAA); WRITE_FLASH(0x2AA+0x100000, 0x55); GpioDataRegs.GPFDAT.bit.GPIOF14 = a19Status; WRITE_FLASH(sectorAddr, 0x30); finish** = waitForOperationEnd(); return(finish**); } /* --------------------------------------------------------------------- * 函 数 名: chipErase * 函数描述: 擦除整片 * ----------------------------------------------------------------------*/ BOOL chipErase(void) { BOOL finish** = FALSE; GpioDataRegs.GPFDAT.bit.GPIOF14 = 0; WRITE_FLASH(0x555+0x100000, 0xAA); WRITE_FLASH(0x2AA+0x100000, 0x55); WRITE_FLASH(0x555+0x100000, 0x80); WRITE_FLASH(0x555+0x100000, 0xAA); WRITE_FLASH(0x2AA+0x100000, 0x55); WRITE_FLASH(0x555+0x100000, 0x10);
finish** = waitForOperationEnd(); return(finish**); } /* --------------------------------------------------------------------- * 函 数 名: pointSector * 函数描述: 找到virtualAddr 所在的扇区地址 * ----------------------------------------------------------------------*/ INT32U pointSector(INT32U virtualAddr) { INT32U sectorAddr = 0;
if(virtualAddr < 0xF8000) { sectorAddr = (virtualAddr >> 15) << 15; } else if(virtualAddr < 0xFC000) { sectorAddr = 0xF8000; } else if(virtualAddr < 0xFD000) { sectorAddr = 0xFC000; } else if(virtualAddr < 0xFE000) { sectorAddr = 0xFD000; } else { sectorAddr = 0xFE000; } return(sectorAddr); }
|