Exemplo n.º 1
0
void ti89_put_byte(uint32_t adr, uint8_t arg) 
{
    // RAM access
	if(IN_BOUNDS(0x000000, adr, 0x1fffff))
	{
		put_b(tihw.ram, adr, RAM_SIZE_TI89 - 1, arg);
	}

    // FLASH access
	else if(IN_BOUNDS(0x200000, adr, 0x5fffff))
	{
		FlashWriteByte(adr, arg);
	}

	// memory-mapped I/O
    else if(IN_BOUNDS(0x600000, adr, 0x6fffff))
	{
		io_put_byte(adr, arg);
	}

	// memory-mapped I/O (hw2)
	else if(IN_RANGE(adr, 0x700000, IO2_SIZE_TI89))
	{
		io2_put_byte(adr, arg);
	}

    return;
}
Exemplo n.º 2
0
/********************************************************************
函数功能:FLASH写命令。
入口参数:Val:要写的命令值。
返    回:无。
备    注:没有片选,必须在其他更高层的函数负责片选。
********************************************************************/
void FlashWriteCommand(uint8 Cmd)
{
 FlashSetCle(); //选择为命令
 FlashSetPortAsOut();
 FlashWriteByte(Cmd);
 FlashSetPortAsIn();
 FlashClrCle();
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
/********************************************************************
函数功能:读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();
}
Exemplo n.º 5
0
/********************************************************************
函数功能:往FLASH写入二字节地址的函数。
入口参数:Addr:要写入的字节地址。
返    回:无。
备    注:没有片选,必须在其他更高层的函数负责片选。只写地址低位
********************************************************************/
void FlashWriteAddr2Byte(uint32 Addr)
{
 uint i;
 
 //只需要低11位
 Addr=Addr&(FLASH_PAGE_SIZE-1);

 FlashSetAle();  //ALE置高,选择为地址
 FlashSetPortAsOut(); //设置端口为输出状态
 for(i=0;i<2;i++)     //写入二字节的地址
 {
  FlashWriteByte(Addr);  //写一字节数据
  Addr>>=8;
 }
 FlashSetPortAsIn();  //设置端口为输入
 FlashClrAle();       //ALE置低
}
Exemplo n.º 6
0
/********************************************************************
函数功能:往FLASH写入二字节页地址的函数。
入口参数:Addr:要写入的字节地址。
返    回:无。
备    注:没有片选,必须在其他更高层的函数负责片选。
********************************************************************/
void FlashWritePageAddr(uint32 Addr)
{
 uint i;
 
 //计算页地址
 Addr/=FLASH_PAGE_SIZE;

 FlashSetAle();  //ALE置高,选择为地址
 FlashSetPortAsOut(); //设置端口为输出状态
 for(i=0;i<2;i++) //写入四字节的地址
 {
  FlashWriteByte(Addr); //写一字节数据
  Addr>>=8;
 }
 FlashSetPortAsIn(); //设置端口为输入
 FlashClrAle(); //ALE置低
}
Exemplo n.º 7
0
/********************************************************************
函数功能:往FLASH写入四字节地址的函数。
入口参数:Addr:要写入的字节地址。
返    回:无。
备    注:没有片选,必须在其他更高层的函数负责片选。注意地址中间的0。
********************************************************************/
void FlashWriteAddr4Byte(uint32 Addr)
{
 uint i;
 
 //注意:该FLASH的地址中间有5bit必须置0
 //并将高16位左移5位
 Addr=((Addr<<5)&(~0xFFFF))|(Addr&0x07FF);

 FlashSetAle();  //ALE置高,选择为地址
 FlashSetPortAsOut(); //设置端口为输出状态
 for(i=0;i<4;i++) //写入四字节的地址
 {
  FlashWriteByte(Addr); //写一字节数据
  Addr>>=8;
 }
 FlashSetPortAsIn(); //设置端口为输入
 FlashClrAle();  //ALE置低
}
Exemplo n.º 8
0
void WriteBufferRemainder(){
  //any data remaining in the output buffer is written 
  uint16_u outInt16;
  outInt16.val = currentRecordNumber;
  if (writeBufferIndex == 0){
    currentPageAddress -= 1;
    FlashWriteByte(currentPageAddress,0,WRITE_COMPLETE_REC_END);
    loggingState = UPDATE_FIRST_PAGE;
    return;
  }
  writeBuffer[0] = WRITE_STARTED_REC_END;
  writeBuffer[1] = outInt16.buffer[0];
  writeBuffer[2] = outInt16.buffer[1];
  for(uint16_t i = writeBufferIndex; i < 256; i++){
    writeBuffer[i] = 0xFF;
  }
  writeBufferIndex = 0;
  FlashWritePage(currentPageAddress,writeBuffer);
  loggingState = COMPLETE_LAST_PAGE;

}
Exemplo n.º 9
0
void ti89t_put_byte(uint32_t adr, uint8_t arg) 
{
	// RAM access
	if(IN_BOUNDS(0x000000, adr, 0x03ffff) ||
	   IN_BOUNDS(0x200000, adr, 0x23ffff) ||
	   IN_BOUNDS(0x400000, adr, 0x43ffff))
	{
		put_b(tihw.ram, adr, 0x03ffff, arg);
	}

	// FLASH access
    else if(IN_BOUNDS(0x800000, adr, 0xbfffff))
	{
		FlashWriteByte(adr, arg);
	}

	// memory-mapped I/O
    else if(IN_BOUNDS(0x600000, adr, 0x6fffff))			
	{
		io_put_byte(adr, arg);
	}

	// memory-mapped I/O (hw2)
	else if(IN_RANGE(adr, 0x700000, IO2_SIZE_TI89T))
	{
		io2_put_byte(adr, arg);
	}

	// memory-mapped I/O (hw3)
	else if(IN_RANGE(adr, 0x710000, IO3_SIZE_TI89T))
	{
		io3_put_byte(adr, arg);
	}

    return;
}
Exemplo n.º 10
0
/********************************************************************
函数功能:往FLASH中写一个扇区(FLASH_SECTOR_SIZE字节)。
入口参数:Addr: 字节地址;pBuf:保存数据的缓冲区;Remain:预计接下来还需要写多少扇区
返    回:写入的状态。0:成功。非0:失败。
备    注:当Remain不为0时,当前页以及该块内剩余部分将不会回写!
          如果数据传输结束,应该将Remain置0,将数据写回。
********************************************************************/
uint32 FlashWriteOneSector(uint32 Addr, uint8 * pBuf, uint32 Remain)
{
 uint32 i;
 uint32 SwapPageAddr;
 
 FlashClrCe(); //选中芯片
 if(Addr>FLASH_MAX_SECTOR_ADDR)return 1; //如果地址超出范围,则返回失败代码1,越界
 Addr=FlashAddrRemap(Addr); //重新影射地址
 if((Addr&(~(FLASH_PAGE_SIZE-1)))!=(FlashCurrentWriteSectorAddr&(~(FLASH_PAGE_SIZE-1)))) //如果跨page
 {
  if(FlashNeedWriteBack) //如果前面写了数据,则需要将当前读出的page写回
  {
   if(FlashWritePage()&0x01) //写入失败
   {
    Addr=FlashDealBadBlock(Addr-FLASH_PAGE_SIZE,3)+FLASH_PAGE_SIZE;  //坏块处理
   }
  }
  if((Addr&(~(FLASH_BLOCK_SIZE-1)))!=(FlashCurrentWriteSectorAddr&(~(FLASH_BLOCK_SIZE-1))))  //如果跨block,则需要擦除新的块,
  {
   //在擦除之前,要先将原来的块复制到交换区,并且将该块前面部分数据写回
   //该函数除了将整块数据复制到交换区以外,并且还将擦除掉原来的块,然后将前面部分复制回原来的块
   Addr=FlashCopyBlockToSwap(Addr);
  }
  //从交换区中读出对应的一页
  FlashWriteCommand(0x00);
  FlashWriteAddr4Byte(FlashGetCurrentSwapBlock()+(Addr&(FLASH_BLOCK_SIZE-1)));
  FlashWriteCommand(0x35);
  FlashWait();
  //随机写
  FlashWriteCommand(0x85);
  FlashWriteAddr4Byte(Addr); //写4字节地址
  FlashSetPortAsOut();  //总线设置为输出口
  for(i=0;i<FLASH_SECTOR_SIZE;i++)
  {
   FlashWriteByte(pBuf[i]);
  }
  FlashSetPortAsIn(); //总线设置为输入口
  FlashNeedWriteBack=1; //需要写回
 }
 else  //没有超过一页地址,则直接写数据
 {
  //随机写
  FlashWriteCommand(0x85);
  FlashWriteAddr2Byte(Addr);
  FlashSetPortAsOut();  //总线设置为输出口
  for(i=0;i<FLASH_SECTOR_SIZE;i++)
  {
   FlashWriteByte(pBuf[i]);
  }
  FlashSetPortAsIn(); //总线设置为输入口
  FlashNeedWriteBack=1; //需要写回
 }
 FlashCurrentWriteSectorAddr=Addr; //保存本次地址 
 if(Remain==0) //剩余扇区数为0,不会再写了,需要写回
 {
  if(FlashNeedWriteBack) //如果前面写了数据,则需要将当前读出的page写回
  {
   if(FlashWritePage()&0x01) //写入失败
   {
    Addr=FlashDealBadBlock(Addr,3);  //坏块处理
   }
  }
  //计算剩余页数
  Remain=(((Addr+FLASH_BLOCK_SIZE)&(~(FLASH_BLOCK_SIZE-1)))-(Addr&(~(FLASH_PAGE_SIZE-1))))/FLASH_PAGE_SIZE-1;
  //计算在交换块中的起始页地址
  SwapPageAddr=FlashGetCurrentSwapBlock()+(Addr&(FLASH_BLOCK_SIZE-1));
  
  for(i=0;i<Remain;i++)  //将该块内保存在交换块中剩余部分页的数据复制回该块
  {
   Addr+=FLASH_PAGE_SIZE;   //从下一页开始写
   SwapPageAddr+=FLASH_PAGE_SIZE;   
   if(0x01==(FlashCopyPage(SwapPageAddr,Addr)&0x01)) //如果复制失败
   {
    Addr=FlashDealBadBlock(Addr,2);  //处理坏块
   }
  }
  FlashNeedWriteBack=0; //清除需要写回标志
  FlashCurrentWriteSectorAddr=-1;
 }
 FlashSetCe(); //释放FLASH芯片
 return 0;
}
Exemplo n.º 11
0
/********************************************************************
函数功能:保存坏块表到FLASH的特定位置。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void FlashSaveBadBlockTable(void)
{
 uint32 i,j,k,Sum;
 
 for(i=0;i<FLASH_BLOCKS_TABLE;i++) //标志为准备擦除
 {
  FlashWriteCommand(0x80);
  FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*(i+1) - FLASH_PAGE_SIZE);
  FlashSetPortAsOut();  //总线设置为输出口
  FlashWriteByte(0x00);  //将第一字节设置为0,表示准备擦除
  //剩余字节写0xFF
  for(j=1;j<FLASH_PAGE_SIZE;j++)
  {
   FlashWriteByte(0xFF);
  }
  FlashWritePage(); //写页
 }
 
 for(i=0;i<FLASH_BLOCKS_TABLE;i++) //将坏块表写入这三块
 {
  FlashEraseBlock(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i); //擦除一块
  FlashWriteCommand(0x80);
  FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i); //写入第一块的开始位置
  FlashSetPortAsOut();  //总线设置为输出口
  FlashWriteByte(0x00);  //将第1字节设置为0
  FlashWriteByte(0x55);  //将第2字节设置为0x55
  FlashWriteByte(0xAA);  //将第3字节设置为0xAA
  FlashWriteByte(0xFF);  //将第4字节设置为0xFF
  Sum=0x1FE;
  //接着写坏块数量,并统计校验和
  FlashWriteByte((FlashBadBlocksCount>>24)&0xFF);
  Sum+=(FlashBadBlocksCount>>24)&0xFF;
  FlashWriteByte((FlashBadBlocksCount>>16)&0xFF);
  Sum+=(FlashBadBlocksCount>>16)&0xFF;
  FlashWriteByte((FlashBadBlocksCount>>8)&0xFF);
  Sum+=(FlashBadBlocksCount>>8)&0xFF;
  FlashWriteByte((FlashBadBlocksCount)&0xFF);
  Sum+=(FlashBadBlocksCount)&0xFF;
  j=8; //写了8字节
  //保存坏块表
  for(k=0;k<sizeof(FlashBadBlockTable[0][0])*FLASH_BAD_BLOCKS_REMAP*2;k++)
  {
   if(0==(j&(FLASH_PAGE_SIZE-1))) //如果超过了页,则需要重新写新页
   {
    FlashWritePage(); //写页
    FlashWriteCommand(0x80);
    FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i + j);
    FlashSetPortAsOut();  //总线设置为输出口
   }
   Sum+=((uint8 *)FlashBadBlockTable)[k]; //求校验和
   FlashWriteByte(((uint8 *)FlashBadBlockTable)[k]);  //写一字节
   j++;
  }
  //保存重影射区的状态表
  for(k=0;k<sizeof(FlashRemapBlockStatus[0])*FLASH_BAD_BLOCKS_REMAP;k++)
  {
   if(0==(j&(FLASH_PAGE_SIZE-1))) //如果超过了页,则需要重新写新页
   {
    FlashWritePage(); //写页
    FlashWriteCommand(0x80);
    FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*i + j);
    FlashSetPortAsOut();  //总线设置为输出口
   }
   Sum+=((uint8 *)FlashRemapBlockStatus)[k]; //求校验和
   FlashWriteByte(((uint8 *)FlashRemapBlockStatus)[k]);  //写一字节
   j++;
  }
  for(;0!=(j&(FLASH_PAGE_SIZE-1));j++) //将剩余部分写入0xFF
  {
   FlashWriteByte(0xFF);
  }
  FlashWritePage();   //写页
  
  //已完成写状态及校验和写入到该块的倒数第二页
  FlashWriteCommand(0x80);
  FlashWriteAddr4Byte(FLASH_BLOCK_TABLE_ADDR + FLASH_BLOCK_SIZE*(i+1) - 2*FLASH_PAGE_SIZE);
  FlashSetPortAsOut();  //总线设置为输出口
  FlashWriteByte(0x00);  //将第一字节设置为0,表示已经写入
  //将校验和取反加1,这样累加结果就为0
  Sum=(~Sum)+1;
  //写校验和
  FlashWriteByte((Sum>>24)&0xFF);
  FlashWriteByte((Sum>>16)&0xFF);
  FlashWriteByte((Sum>>8)&0xFF);
  FlashWriteByte((Sum)&0xFF);
  //剩余字节写0xFF
  for(j=5;j<FLASH_PAGE_SIZE;j++)
  {
   FlashWriteByte(0xFF);
  }
  FlashWritePage(); //写页
 }
}
Exemplo n.º 12
0
void LoggingStateMachine(){

  static uint16_t nextBlockAddress = 0;
  static uint8_t pageCount = 0;
  uint16_u outInt16;

  switch(loggingState){
  case CHECK_4K:
    if(VerifyWriteReady() == false){
      break;
    }
    if (FlashGetByte((nextBlockAddress + pageCount),0) != 0xFF){
      loggingState = ERASE;
      break;
    }
    pageCount++;
    if(pageCount == 16){
      pageCount = 0;
      loggingState = WRITE_READY;
    }
    break;
  case ERASE:
    if(VerifyWriteReady() == false){
      break;
    }
    FlashEraseBlock4k(nextBlockAddress);
    loggingState = WRITE_READY;
    break;
  case WRITE_READY:
    if(VerifyWriteReady() == false){
      break;
    }
    loggingReady = true;
    if (startNewLog == true){
      endCurrentLog = false;
      startNewLog = false;
      startOfRecordDataToFlash = true;
      loggingState = START_NEW_LOG;
      break;
    }
    if (endCurrentLog == true){
      logEnabled = false;
      endCurrentLog = false;
      startNewLog = false;
      loggingState = END_CURRENT_LOG;
      loggingReady = false;
      break;
    }
    break;
  case COMPLETE_PAGE:
    if(VerifyWriteReady() == false){
      break;
    }
    FlashWriteByte(currentPageAddress,0,WRITE_COMPLETE);
    currentPageAddress += 1;
    if (currentPageAddress > 0x3FFF){
      currentPageAddress = 0;
    }
    if ((currentPageAddress & 0x000F) == 0x000F){
      loggingState = CHECK_4K;
      pageCount = 0;
      nextBlockAddress = (currentPageAddress & 0xFFF0) + 0x0010;
      if (nextBlockAddress > 0x3FF0){
        nextBlockAddress = 0;
      }
      break;
    }
    loggingState = WRITE_READY;
    break;
  case START_NEW_LOG:
    if(VerifyWriteReady() == false){
      break;
    }
    outInt16.val = currentRecordNumber;
    writeBuffer[0] = WRITE_STARTED_REC_START;
    writeBuffer[1] = outInt16.buffer[0];
    writeBuffer[2] = outInt16.buffer[1];
    writeBuffer[3] = 0xFF;
    writeBuffer[4] = 0xFF;
    writeBuffer[5] = 0xFF;
    FlashWritePartialPage(currentPageAddress,0,6,writeBuffer);
    writeBufferIndex = 6;
    loggingState = WRITE_READY;
    logEnabled = true;
    loggingReady = false;
    break;
  case END_CURRENT_LOG:
    if(VerifyWriteReady() == false){
      break;
    }
    WriteBufferRemainder();
    break;
  case COMPLETE_LAST_PAGE:  
    if(VerifyWriteReady() == false){
      break;
    }
    FlashWriteByte(currentPageAddress,0,WRITE_COMPLETE);
    loggingState = UPDATE_FIRST_PAGE;
    break;
  case UPDATE_FIRST_PAGE:
    if(VerifyWriteReady() == false){
      break;
    }
    outInt16.val = currentPageAddress;
    writeBuffer[0] = 0x00;
    writeBuffer[1] = outInt16.buffer[0];
    writeBuffer[2] = outInt16.buffer[1];
    FlashWritePartialPage(currentRecordAddress,3,3,writeBuffer);
    loggingState = BOUND_CHECK;
    break;
  case BOUND_CHECK:
    if(VerifyWriteReady() == false){
      break;
    }
    writePageStarted = false;
    loggingReady = false;
    currentPageAddress += 1;
    currentRecordAddress = currentPageAddress;
    if (currentPageAddress > 0x3FFF){
      currentPageAddress = 0;
    }
    if ((currentPageAddress & 0x000F) == 0x000F){
      loggingState = CHECK_4K;
      pageCount = 0;
      nextBlockAddress = (currentPageAddress & 0xFFF0) + 0x0010;
      if (nextBlockAddress > 0x3FF0){
        nextBlockAddress = 0;
      }
      break;
    }
    loggingState = WRITE_READY;
    break;

  }
}