/* ********************************************************************************************************* * FLASH MEMORY READ * * Description: This function is used to read the main memory of the flash * * Arguments : addr: memory address where to store the data * array: pointer to the stored data * len: the length of the data to be stored * * Returns : none * * write by : Wen Jianjun * * data : 0722 2008 * ********************************************************************************************************* */ void FlashMemoryRead(INT32U addr,void *array,INT16U len) { char i; char *Dest; Dest =(char *)array; FlashSendPrepare(); //very important for msp430 //_BIC_SR(GIE); FLASH_ENABLE; /*send command*/ FlashSendByte(CONTINUOUS_MREAD); /*send address 3 bytes*/ for(i=0;i<3;i++) { FlashSendByte((char)((addr>>(8*(2-i)))&0x000000ff)); } /*read a dummy byte*/ Delay_N_mS(20); FlashReadByte(0); /*read data from flash*/ while(len--) { *Dest++ = FlashReadByte(0); } //_BIS_SR(GIE); Delay_N_mS(20); FLASH_DISABLE; }
/******************************************************************** 函数功能:读取状态寄存器。 入口参数:无。 返 回:无。 备 注:FLASH操作状态。 ********************************************************************/ uint8 FlashReadStatus(void) { uint8 Status; FlashWriteCommand(0x70); //写查询命令 FlashReadByte(Status); //读回状态 return Status; }
/******************************************************************** 函数功能:从FLASH中读出一扇区数据保存到缓冲区中。 入口参数:Addr: 字节地址;pBuf:保存数据的缓冲区;Remain:预计接下来还需要读多少扇区 返 回:读取的状态。0:成功。非0:失败。 备 注:当Remain不为0时,将保存当前地址以备后面的继续读当前页,当不为0时, 设置当前读地址为无效,从而下次读时必须重新使用读命令将数据从flash中读入到页缓存。 ********************************************************************/ uint32 FlashReadOneSector(uint32 Addr, uint8 * pBuf, uint32 Remain) { uint32 i; FlashClrCe(); //选中芯片 if(Addr>FLASH_MAX_SECTOR_ADDR)return 1; //如果地址超出范围,则返回失败代码1,越界 Addr=FlashAddrRemap(Addr); //重新影射地址 if((Addr&(~(FLASH_PAGE_SIZE-1))) !=(FlashCurrentReadSectorAddr&(~(FLASH_PAGE_SIZE-1)))) //如果跨page { //如果跨页的,则写读数据命令 FlashWriteCommand(0x00); FlashWriteAddr4Byte(Addr); FlashWriteCommand(0x30); FlashWait(); //等待数据读回 } else { //如果没有跨页,则可以直接读 FlashWriteCommand(0x05); FlashWriteAddr2Byte(Addr); FlashWriteCommand(0xE0); FlashWait(); //等待数据读回 } for(i=0;i<FLASH_SECTOR_SIZE;i++) { FlashReadByte(pBuf[i]); //读一字节数据 } FlashCurrentReadSectorAddr=Addr; //保存当前操作的地址 if(Remain==0) //如果不会接着读,那么就设置当前读过的地址为无效值 { FlashCurrentReadSectorAddr=-1; } FlashSetCe(); //释放总线 return 0; }
/* ********************************************************************************************************* * FLASH BUFFER READ * * Description: This function is used to read the data from the buffers of the flash * * Arguments : addr: memory address where to read the data * array: pointer to the stored data * len: the length of the data to read * buff: indicate that which buffer to read from(the value should be one * of these:FLASHBUFFER1,FLASHBUFFER2) * * Returns : none * * write by : Wen Jianjun * * data : 0722 2008 * ********************************************************************************************************* */ void FlashBufferRead(INT32U addr,void *array,INT16U len,INT8U buff) { char i; char *Dest; Dest =(char *)array; FlashSendPrepare(); //very important for msp430 //_BIC_SR(GIE); FLASH_ENABLE; /*send command*/ //while(!(IFG2&UTXIFG1)); if(buff==FLASHBUFFER1) { FlashSendByte(BUFFER1_READ); //U1TXBUF =BUFFER1_READ; } else { FlashSendByte(BUFFER2_READ); //U1TXBUF =BUFFER2_READ; } /*send address 3 bytes*/ for(i=0;i<3;i++) { FlashSendByte((char)((addr>>(8*(2-i)))&0x000000ff)); } /*send one don't care byte*/ //while(!(IFG2&UTXIFG1)); //U1TXBUF =0; /*receive a dummy byte*/ FlashReadByte(0); /*read data from flash*/ while(len--) { *Dest++ = FlashReadByte(0); } //_BIS_SR(GIE); FLASH_DISABLE; }
void main(void) { uint8_t ui1; start_main: LCD_init(); DELAY(100); LCD_cmd(LCD_CMD_CUR_10); DELAY(100); LCD_WR_LINE(0, 0, "Hello World 1"); DELAY(100); FlashWriteByte (0xF000, 0x1); FlashWriteByte (0xF001, 0x2); FlashWriteByte (0xF002, 0x3); FlashWriteByte (0xF003, 0x4); ui1 = FlashReadByte(0xF000); LCD_WR("Hello World "); LCD_wrchar('0'+ui1); DELAY(10); ui1 = FlashReadByte(0xF001); LCD_WR("Hello World "); LCD_wrchar('0'+ui1); DELAY(10); ui1 = FlashReadByte(0xF002); LCD_WR("Hello World "); LCD_wrchar('0'+ui1); DELAY(10); ui1 = FlashReadByte(0xF003); LCD_WR("Hello World "); LCD_wrchar('0'+ui1); DELAY(10); goto start_main; }
/******************************************************************** 函数功能:读FLASH的ID号。 入口参数:Buf:保存ID号的缓冲区。 返 回:无。 备 注:无。 ********************************************************************/ void FlashReadId(uint8 *Buf) { uint8 i; FlashClrCe(); FlashWriteCommand(0x90); FlashSetAle(); //ALE置高,选择为地址 FlashSetPortAsOut(); //设置端口为输出状态 FlashWriteByte(0); //写一字节数据 FlashSetPortAsIn(); //设置端口为输入 FlashClrAle(); //ALE置低 for(i=0;i<5;i++) //读5字节的ID { FlashReadByte(Buf[i]); } FlashSetCe(); }
uint8_t ti89t_get_byte(uint32_t adr) { // RAM access if(IN_BOUNDS(0x000000, adr, 0x03ffff) || IN_BOUNDS(0x200000, adr, 0x23ffff) || IN_BOUNDS(0x400000, adr, 0x43ffff)) { return get_b(tihw.ram, adr, 0x03ffff); } // FLASH access else if(IN_BOUNDS(0x800000, adr, 0xbfffff)) { return FlashReadByte(adr); } // memory-mapped I/O else if(IN_BOUNDS(0x600000, adr, 0x6fffff)) { return io_get_byte(adr); } // memory-mapped I/O (hw2) else if(IN_RANGE(adr, 0x700000, IO2_SIZE_TI89T)) { return io2_get_byte(adr); } // memory-mapped I/O (hw3) else if(IN_RANGE(adr, 0x710000, IO3_SIZE_TI89T)) { return io3_get_byte(adr); } return 0x14; }
/******************************************************************** 函数功能:从FLASH的特定位置加载坏块表。 入口参数:无。 返 回:无。 备 注:无。 ********************************************************************/ void FlashLoadBadBlockTable(void) { uint32 i,j,k,Sum,Ok; uint8 Data; Ok=0; //设置为不成功 for(i=0;i<FLASH_BLOCKS_TABLE;i++) //查找没有准备擦除的块 { //从该块中最后一页读回第一字节,看是否为0xFF,如果为0xFF,表示该块没有准备擦除 FlashWriteCommand(0x00); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*(i+1) - FLASH_PAGE_SIZE); FlashWriteCommand(0x30); FlashWait(); //等待数据读回 FlashReadByte(Data); if(Data==0xFF) //表示该块数据还未准备擦除 { //从该块中倒数第二页读回第一字节,看是否为0,如果为0,表示该块已经写入了数据 FlashWriteCommand(0x00); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*(i+1) - 2*FLASH_PAGE_SIZE); FlashWriteCommand(0x30); FlashWait(); //等待数据读回 FlashReadByte(Data); if(Data==0) //表示数据有效 { FlashReadByte(Data); //读出校验和 Sum=Data; FlashReadByte(Data); //读出校验和 Sum=(Sum<<8)+Data; FlashReadByte(Data); //读出校验和 Sum=(Sum<<8)+Data; FlashReadByte(Data); //读出校验和 Sum=(Sum<<8)+Data; //从该块开始位置读 FlashWriteCommand(0x00); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i); FlashWriteCommand(0x30); FlashWait(); //等待数据读回 //检查第1字节是否为0 FlashReadByte(Data); if(Data!=0)continue; //检查第2字节是否为0x55 FlashReadByte(Data); if(Data!=0x55)continue; //检查第3字节是否为0xAA FlashReadByte(Data); if(Data!=0xAA)continue; //检查第4字节是否为0xFF FlashReadByte(Data); if(Data!=0xFF)continue; Sum+=0x1FE; //读坏块数量 FlashReadByte(Data); FlashBadBlocksCount=Data; Sum+=Data; FlashReadByte(Data); FlashBadBlocksCount=(FlashBadBlocksCount<<8)+Data; Sum+=Data; FlashReadByte(Data); FlashBadBlocksCount=(FlashBadBlocksCount<<8)+Data; Sum+=Data; FlashReadByte(Data); FlashBadBlocksCount=(FlashBadBlocksCount<<8)+Data; Sum+=Data; j=8; //读回坏块表 for(k=0;k<sizeof(FlashBadBlockTable[0][0])*FLASH_BAD_BLOCKS_REMAP*2;k++) { if(0==(j&(FLASH_PAGE_SIZE-1))) //如果超过了页,则需要重新读新页 { FlashWriteCommand(0x00); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i+j); FlashWriteCommand(0x30); FlashWait(); //等待数据读回 } FlashReadByte(Data); Sum+=Data; //求校验和 ((uint8 *)FlashBadBlockTable)[k]=Data; //读回一字节到坏块表中 j++; } //读回重影射区的状态表 for(k=0;k<sizeof(FlashRemapBlockStatus[0])*FLASH_BAD_BLOCKS_REMAP;k++) { if(0==(j&(FLASH_PAGE_SIZE-1))) //如果超过了页,则需要重新读新页 { FlashWriteCommand(0x00); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i+j); FlashWriteCommand(0x30); FlashWait(); //等待数据读回 } FlashReadByte(Data); Sum+=Data; //求校验和 ((uint8 *)FlashRemapBlockStatus)[k]=Data; //读回一字节到重影射区状态表中 j++; } if(Sum==0) //如果校验成功,则说明数据正确 { Ok=0xFF; //设置为成功 break; //并退出循环 } } } } if(Ok==0) //如果在已写入的表中找不到好的坏块表,再去准备擦除的中去找 { for(i=0;i<FLASH_BLOCKS_TABLE;i++) //查找准备擦除的块 { //从该块中最后一页读回第一字节,看是否为0,如果为0,表示该块已经准备擦除了 FlashWriteCommand(0x00); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*(i+1) - FLASH_PAGE_SIZE); FlashWriteCommand(0x30); FlashWait(); //等待数据读回 FlashReadByte(Data); if(Data==0x00) //表示该块数据准备擦除 { //从该块中倒数第二页读回第一字节,看是否为0,如果为0,表示该块已经写入了数据 FlashWriteCommand(0x00); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*(i+1) - 2*FLASH_PAGE_SIZE); FlashWriteCommand(0x30); FlashWait(); //等待数据读回 FlashReadByte(Data); if(Data==0) //表示数据有效 { FlashReadByte(Data); //读出校验和 Sum=Data; FlashReadByte(Data); //读出校验和 Sum=(Sum<<8)+Data; FlashReadByte(Data); //读出校验和 Sum=(Sum<<8)+Data; FlashReadByte(Data); //读出校验和 Sum=(Sum<<8)+Data; //从该块开始位置读 FlashWriteCommand(0x00); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i); FlashWriteCommand(0x30); FlashWait(); //等待数据读回 //检查第1字节是否为0 FlashReadByte(Data); if(Data!=0)continue; //检查第2字节是否为0x55 FlashReadByte(Data); if(Data!=0x55)continue; //检查第3字节是否为0xAA FlashReadByte(Data); if(Data!=0xAA)continue; //检查第4字节是否为0xFF FlashReadByte(Data); if(Data!=0xFF)continue; Sum+=0x1FE; //读坏块数量 FlashReadByte(Data); FlashBadBlocksCount=Data; Sum+=Data; FlashReadByte(Data); FlashBadBlocksCount=(FlashBadBlocksCount<<8)+Data; Sum+=Data; FlashReadByte(Data); FlashBadBlocksCount=(FlashBadBlocksCount<<8)+Data; Sum+=Data; FlashReadByte(Data); FlashBadBlocksCount=(FlashBadBlocksCount<<8)+Data; Sum+=Data; j=8; //读回坏块表 for(k=0;k<sizeof(FlashBadBlockTable[0][0])*FLASH_BAD_BLOCKS_REMAP*2;k++) { if(0==(j&(FLASH_PAGE_SIZE-1))) //如果超过了页,则需要重新读新页 { FlashWriteCommand(0x00); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i+j); FlashWriteCommand(0x30); FlashWait(); //等待数据读回 } FlashReadByte(Data); Sum+=Data; //求校验和 ((uint8 *)FlashBadBlockTable)[k]=Data; //读回一字节到坏块表中 j++; } //读回重影射区的状态表 for(k=0;k<sizeof(FlashRemapBlockStatus[0])*FLASH_BAD_BLOCKS_REMAP;k++) { if(0==(j&(FLASH_PAGE_SIZE-1))) //如果超过了页,则需要重新读新页 { FlashWriteCommand(0x00); FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i+j); FlashWriteCommand(0x30); FlashWait(); //等待数据读回 } FlashReadByte(Data); Sum+=Data; //求校验和 ((uint8 *)FlashRemapBlockStatus)[k]=Data; //读回一字节到重影射区状态表中 j++; } if(Sum==0) //如果校验成功,则说明数据正确 { FlashSaveBadBlockTable(); //将其保存到FLASH中 Ok=0xFF; //设置为成功 break; //并退出循环 } } } } } if(Ok==0) //如果还是没找到,那么只好重新初始化了 { FlashBadBlocksCount=0; //坏块数设置为0 for(i=0;i<FLASH_BAD_BLOCKS_REMAP;i++) { //所有影射块都设置为好块 FlashRemapBlockStatus[i]=FLASH_BLOCK_OK; //所有影射关系设置为-1 FlashBadBlockTable[0][i]=-1; FlashBadBlockTable[1][i]=-1; } //设置好之后保存起来 FlashSaveBadBlockTable(); } //设置当前访问过的地址为无效值 FlashLastAccessAddr=-1; }