⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mbusman.cpp

📁 coldfire5206芯片的boot程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:

/**
 *  CAT24C021: write several bytes( less than or equal to 16 bytes).
 *
 *  @param  baseAddr   the first address
 *  @param  byteNum    the number of bytes to be written
 *  @param  data       point to what to write
 *
 *  @return  1   if the operation succeed.
 *           0   if the operation failure because packetQue is full.
 */
CHAR  CAT24C021WritePage(UINT16 baseAddr, UINT16 byteNum, UCHAR *data)
{
   MBusPackType  thePack;
   UCHAR         sect_addr;

   CHAR i;

   // one page has less than 16 bytes
   if ( 1 > byteNum || CAT24C021_PAGE_SIZE < byteNum)
      return 0;

   thePack.txLen1 = 2 + byteNum;
   thePack.txLen2 = 0;
   thePack.rxLen  = 0;

   thePack.repeatTimes = CAT24C021_WRITE_REPEAT;

   // The bit8 and bit9 of baseaddr must put in slave address
   // a sector has 256 bytes, so the following operation will
   // save the bit8 and bit9 in sect_addr
   sect_addr = baseAddr >> 8;
   sect_addr = sect_addr << 1;

   thePack.txData[0] = CAT24C021_SLAVE_ADDR | sect_addr | OP_WRITE;
   thePack.txData[1] = (baseAddr & 0xff);

   for (i = 0; i < byteNum; i ++)
      thePack.txData[2+i] = *data ++;
/*
   if (OPMODE_INTERRUPT == sMBusInfo.mode)
   {
      if (1 == MBusPackQuePut(&gCAT24C021WritePackQue, &thePack))
      {
         EnterInterrupt( );
         return 1;
      }
      return 0;
   }
   else
*/
   return MBusTransferByQuery(&thePack);
}


/**
 *  CAT24C021: write several bytes( no limitation to the number).
 *
 *  @param  baseAddr   the first address
 *  @param  byteNum    the number of bytes to be written
 *  @param  data       point to what to write
 *
 *  @return  1   if the operation succeed.
 *           0   if the operation failure because packetQue is full
 *               or byteNum is improper.
 */
CHAR  CAT24C021WriteSeqByte(UINT16 baseAddr, UINT16 byteNum, UCHAR *data)
{
   UCHAR  i;

   if (1 > byteNum || 2048 < (baseAddr + byteNum) )
      return 0;

   // write the first bytes of one page.
   i = CAT24C021_PAGE_SIZE - ( baseAddr % CAT24C021_PAGE_SIZE );
   if (i > byteNum)
      i = byteNum;

   if (0 == CAT24C021WritePage(baseAddr, i, data) )
      return 0;

   baseAddr += i;
   data     += i;
   byteNum  -= i;

   // transfer data page by page
   while (CAT24C021_PAGE_SIZE <= byteNum)
   {
      if (0 == CAT24C021WritePage(baseAddr, CAT24C021_PAGE_SIZE, data) )
         return 0;

      baseAddr += CAT24C021_PAGE_SIZE;
      data     += CAT24C021_PAGE_SIZE;
      byteNum  -= CAT24C021_PAGE_SIZE;
   }

   // transfer the remained data.
   if (0 < byteNum)
      return CAT24C021WritePage(baseAddr, byteNum, data);
   else
      return 1;   
}


/**
 *  CAT24C021: read several bytes.
 *
 *  @param  baseAddr   the first byte address
 *  @param  byteNum    the number of bytes to be read
 *  @param  dataAddr   where to store result
 *
 *  @return  1   if the operation succeed.
 *           0   if the operation failure because packetQue is full
 *               or byteNum is improper.
 *  @note  A NU_Sleep will be called if MBUS operated in interupt mode. 
 */
CHAR  CAT24C021ReadSeqByte(UINT16 baseAddr, UINT16 byteNum, UCHAR *dataAddr)
{
   MBusPackType  thePack;
   UCHAR         sect_addr;
	int				k;

   if (1 > byteNum || 2048 < (baseAddr + byteNum) )
      return 0;

   thePack.txLen1 = 2;
   thePack.txLen2 = 1;
   thePack.rxLen  = byteNum;
   thePack.rxData = dataAddr;

   thePack.repeatTimes = CAT24C021_READ_REPEAT;

   // The bit8 and bit9 of baseaddr must put in slave address
   // a sector has 256 bytes, so the following operation will
   // save the bit8 and bit9 in sect_addr
   sect_addr = baseAddr >> 8;
   sect_addr = sect_addr << 1;

   thePack.txData[0] = CAT24C021_SLAVE_ADDR | sect_addr | OP_WRITE;
   thePack.txData[1] = (baseAddr & 0xff);
   thePack.txData[2] = CAT24C021_SLAVE_ADDR | sect_addr | OP_READ;

 /*
	if (OPMODE_INTERRUPT == sMBusInfo.mode)
   {
      if (1 == MBusPackQuePut(&gCAT24C021ReadPackQue, &thePack))
      {
         EnterInterrupt( );

         // Important changing: LLH.2001.07.04
         // A Sleep added here to wait for the data trasnferring been done,
         // so, after returning from this function, you can use data be read
         // immedidately.
         //NU_Sleep( 50);
			k = 0;
			while( k < 50000 )
				k++;

         return 1;
      }
      return 0;
   }
   else
*/
   return MBusTransferByQuery(&thePack);
}


/**
 *  Reset watchdog. the command sequence of CAT24C021(reading current byte)
 *  is used here.
 *
 *  @note   CAT24C021 has a watchdog, which will reset CPU every 1.6 seconds
 *          if no MBUS operation occurred in this period.
 */
// CHAR  CAT24C021ReadCurrentByte(UCHAR *dataAddr)
VOID  ResetWatchdog( VOID )
{
   static UCHAR data;

   MBusPackType  thePack;

   thePack.txLen1 = 1;
   thePack.txLen2 = 0;
   thePack.rxLen  = 1;
   thePack.rxData = &data;

   thePack.repeatTimes = 0;

   thePack.txData[0] = CAT24C021_SLAVE_ADDR | OP_READ;
/*
   if (OPMODE_INTERRUPT == sMBusInfo.mode)
   {
      if (1 == MBusPackQuePut(&gCAT24C021ReadPackQue, &thePack))
         EnterInterrupt( );
   }
   else
*/
	MBusTransferByQuery(&thePack);
}


/**
 *  MBUS: Transfer a packet by query.
 *
 *  @param   thePack   the packet to be transfered
 *
 *  @return  1   if the operation succeed.
 *           0   if the operation failure because packetQue is full.
 */
static CHAR  MBusTransferByQuery(MBusPackType *thePack)
{

   // if MBUS working not in query mode, return
   if (OPMODE_QUERY != sMBusInfo.mode)
      return 0;

   // Don't goto the following code if there another task using it.
   // use the statement to protect the following code being used exclusively.
   if (1 != sMBusInfo.currPackFinished)
      return 0;

   // packet has not been transfered
   sMBusInfo.currPackFinished = 0;

   // Remember the pack being transfered.
   sMBusInfo.currPack = *thePack;

   // construct command sequence
   ConstructSequence(thePack);

   // if MBUS is not free until function return, transfer stop
	
   if (0 == WaitForMBusFree())
	{
		sMBusInfo.currPackFinished = 1;

      return 0;
   }

   StartTransfer();

   do
   {
      // if MIF has not been set until function return, transfer stop
      if (0 == WaitForMIF())
		{
		  sMBusInfo.currPackFinished = 1;

        return 0;
		}

      // currPackFinished will be set to 1 if the packet transfered in MBusLisr
      Mbus_Lisr(0);
   }while (0 == sMBusInfo.currPackFinished);


   return 1;
}


/**
 *  Wait for some times until MBUS is not busy.
 *
 *  @return    1  if MBUS is free when returned.
 *             0  MBUS is still busy until return
 */
static UCHAR  WaitForMBusFree(VOID)
{
   UCHAR  status;
   UINT16 i;

   // wait for 500 loops
   for (i = 0; i < 500; i ++)
   {
      status = *(UCHAR*)MBSR;
      if (0 == (status&0x20))
         return 1;
   }
   return 0;
}


/**
 *  Wait for some times until MBUS Interrupt is set, which indicate that a data
 *  transfer is completed.
 *
 *  @return    1  if MBUS is free when returned.
 *             0  MBUS is still busy until return
 */
static UCHAR  WaitForMIF(VOID)
{
   UCHAR  status;
   UINT16 i;

   // wait for 500 loops
   for (i = 0; i < 500; i ++)
   {
      status = *(UCHAR*)MBSR;
      if (2 == (status&2))
         return 1;
   }
   return 0;
}


/**
 *  CAT24C021: Calculate checksum and write it to memory.
 *
 *  @param  baseAddr   the first address
 *  @param  byteNum    the number of bytes to be written
 *  @param  data       point to what to write
 *
 *  @return  1   if the operation succeed.
 *           0   if the operation failure because packetQue is full.
 *
 *  @note  the sCheckSum must been calculated when sMemoryMap loaded
 *
static VOID  UpdateCheckSum(UINT16 baseAddr, UINT16 byteNum, UCHAR *data)
{
   INT16  i;
   INT16  index;

   index = baseAddr;
   for (i = 0; i < byteNum; i ++)
   {
      sCheckSum -= sMemoryMap[index];
      sCheckSum += *data;

      sMemoryMap[index++] = *data ++;
   }

   CAT24C021WriteSeqByte(MAP_CHECK_SUM, 1, &sCheckSum);
}


/**
 *  CAT24C021: Load the EEPROM to make a copy in DRAM and check the checkSum.
 *  this function must be called before any writing operation to CAT24C021
 *  with checkSum, or the check sum will be wrong.
 *
 *  @param  memoryMap   where to save the copy
 *
 *  @return   1   load memoryMap and stored checkSum succeeded and checkSum is right
 *            0   load memoryMap or stored checkSum failed
 *            2   load memoryMap and stored checkSum succeeded but checkSum is wrong
 *
static CHAR  CAT24C021LoadMemoryMap(UCHAR *memoryMap)
{
   UCHAR storedCheckSum;
   INT16 i;
   INT   eeprom_size = EEPROM_SIZE;

   // if MBUS working not in query mode, return
   if (OPMODE_QUERY != sMBusInfo.mode)
      return 0;

   // Read memory map, 512 bytes at one time reading
   for (i = 0; i < eeprom_size / 512; i ++)
   {
      if ( 0 == CAT24C021ReadSeqByte( i * 512, 512, memoryMap + i * 512) )
         return 0;
   }

   if ( 0 != (eeprom_size%512) )
      if ( 0 == CAT24C021ReadSeqByte( i * 512, eeprom_size%512, memoryMap + i * 512) )
         return 0;

   // Read stored checkSum
   if ( 0 == CAT24C021ReadSeqByte( MAP_CHECK_SUM, 1, &storedCheckSum) )
      return 0;

   // Calculate checksum
   sCheckSum = 0;
   for (i = MAP_SYS_KEYVOL_LEAD_LANG_ARR; i < MAP_CHECK_SUM; i++)
     sCheckSum += sMemoryMap[i];

   if (sCheckSum != storedCheckSum)
      return 2;
   else
      return 1;
}


/**
 *  The copy of CAT24C021WritePage with checksum calculating and writing
 *
 *  @see CAT24C021WritePage
 *
CHAR   CAT24C021WritePageWithCheck(UINT16 baseAddr, UINT16 byteNum, UCHAR *data)
{
   if (CAT24C021WritePage(baseAddr, byteNum, data))
   {
      UpdateCheckSum(baseAddr, byteNum, data);
      return 1;
   }
   else
      return 0;
}


/**
 *  The copy of CAT24C021WriteSeqByte with checksum calculating and writing
 *
 *  @see CAT24C021WriteSeqByte
 *
CHAR   CAT24C021WriteSeqByteWithCheck(UINT16 baseAddr, UINT16 byteNum, UCHAR *data)
{
   if (CAT24C021WriteSeqByte(baseAddr, byteNum, data))
   {
      UpdateCheckSum(baseAddr, byteNum, data);
      return 1;
   }
   else
      return 0;
}


/**
 *  Whether MBUS is work in query mode.
 *
 *  @return  1  if work in query mode
 *           0  if not in query mode
 */
INT IsMBusInQueryMode( VOID )
{
   if (OPMODE_QUERY == sMBusInfo.mode)
      return 1;
   else
      return 0;
}



/*
CHAR*  GetMBusRegisters( VOID )
{
   static  CHAR sStatusString[100];

   sprintf( sStatusString,
            "MADR:%02x, MFDR:%02x, MBCR:%02x, MBSR:%02x, MBDR:%02x, MBUS_ICR:%02x",
            *(UCHAR*)MADR,  *(UCHAR*)MFDR, *(UCHAR*)MBCR,
            *(UCHAR*)MBSR,  *(UCHAR*)MBDR, *(UCHAR*)MBUS_ICR );

   return sStatusString;
}*/

VOID  ReInitializeMBus( VOID )
{
   if (OPMODE_QUERY == sMBusInfo.mode)
      MBusInit( );
   else
   {
      MBusInit( );
   }
}


#define EEPROM_RETRY_NUM	10
BOOL WriteEeprom(UINT32 addr, UINT32 count, UCHAR* data)
{
	UCHAR temp_data[EEPROM_SIZE];
	int i;

	for (i = 0; i < EEPROM_RETRY_NUM; i++ )	
	{
		CAT24C021WriteSeqByte(addr, count, data);
		for (int j = 0; j < 1000; j++ )
			;
		CAT24C021ReadSeqByte(addr, count, temp_data);
		if ( 0 == memcmp(temp_data, data, count))
			break;
	}
	if (i == EEPROM_RETRY_NUM)
	{	
		return FALSE;
	}
	else
	{
		return TRUE;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -