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

📄 iic.c

📁 本source code 為s3c4510的bootloader
💻 C
📖 第 1 页 / 共 4 页
字号:
#define IIC_UNKNOWN()   IIC_DEBUG_PUT(IIC_DEBUG_UNKNOWN,0);#else#define IIC_DEBUG_DUMP()#define IIC_W_CON(val) 		IICCON = val #define IIC_R_CON(val)          val = IICCON#define IIC_W_BUF(val) 		IICBUF = val #define IIC_R_BUF(val)          val = IICBUF#define IIC_S_INT()    #define IIC_UNKNOWN()#endif 							// IIC_DEBUG////////////////////////////////////////////////////////////////////////////////// LIBRARY FUNCTIONS FOR IIC READ & WRITE //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////static void IICWriteIsr(void);// write page, return count of writed bytes  static int IICWritePage(U32 type, U8 dev, U32 addr, U8 * data, U32 len){ int pos;  while((IICCON & IICCON_BUSY) != 0){;} 	// wait IIC busy//  switch(type)  {   case IIC_EEPROM_AT24C01 : 		// AT24C01   case IIC_EEPROM_AT24C02 :		// AT24C02    pos = 8 - (addr & 0x7);		//    break;   case IIC_EEPROM_AT24C04 : 		// AT24C04   case IIC_EEPROM_AT24C08 :		// AT24C08   case IIC_EEPROM_AT24C16 :		// AT24C16    pos = 16 - (addr & 0xF);    break;      default  		   :    return(0);  } if(pos < len)  {   len = pos;  } // Disable_Int(nGLOBAL_INT);		//  IIC_TX.flag  = 0x0;			// clear flag  IIC_TX.count = 0x0;			// current tx byte IIC_TX.msb   = 0;			// 8 bits of address IIC_TX.lsb   = addr & 0xff;		// 8 bits of address IIC_TX.size  = len;		        // Page buffer byte counter IIC_TX.noack = 0;			// no ACK flag  for(pos = 0; pos < len; ++pos)  {   IIC_TX.buffer[pos] = *data++;	//   }      switch(type)  {   case IIC_EEPROM_AT24C04 : dev = (dev & 0xFC) | ((addr >> 7) & 0x2); break;   case IIC_EEPROM_AT24C08 : dev = (dev & 0xF8) | ((addr >> 7) & 0x6); break;   case IIC_EEPROM_AT24C16 : dev = (dev & 0xF0) | ((addr >> 7) & 0xE); break;   default                 : dev = (dev & 0xFE);   break;  } dev |= S_WRITE;			// slave device address & page address IIC_TX.dev = dev;			// Write to EEPROM 	 Enable_Int(nGLOBAL_INT);		// // Setup IICON register for transmit start ///////////////////////////////////// IIC_W_CON(IICCON_BF|IICCON_COND_START|IICCON_IEN);// Send Slave Address and Write command //////////////////////////////////////// while((IIC_TX.flag & IIC_PAGE_TX_DONE) == 0 && IIC_TX.noack == 0) {;}  if(IIC_TX.noack != 0)  {   Print("\nPage write error. %d\nReset IIC", IIC_TX.noack);   IICCON = IICCON_RESET;   return(0);  } {  int wait;  wait = (fMCLK / 1000 / 4 ) * 10;  for(; wait > 0; --wait);   }// return(len);}//// dev  = device address// addr = address // data = data buffer// len  = data length // int IICWrite(U8 dev, U32 addr, U8 * data, U32 len){ U32 size; int cnt;//  switch(IIC_EEPROM_type)  {   case IIC_EEPROM_AT24C01 : size =  128; break;   case IIC_EEPROM_AT24C02 : size =  256; break;   case IIC_EEPROM_AT24C04 : size =  512; break;   case IIC_EEPROM_AT24C08 : size = 1024; break;   case IIC_EEPROM_AT24C16 : size = 2048; break;  } if(data == 0 || len == 0 || addr + len > size)  {   return(0);  }  SysSetInterrupt(nIIC_INT,IICWriteIsr); // Setup IIC Tx interrupt Enable_Int(nIIC_INT);			// Enable IIC interrupt 	 while(len > 0)  {   cnt = IICWritePage(IIC_EEPROM_type, dev, addr, data, len);   if(cnt == 0)    {     Print("\nIICWrite error");     Disable_Int(nIIC_INT);			     return(0);    }   len  -= cnt;   			// remain write bytes   addr += cnt;				// move address    data += cnt;   			// move data pointer  } Disable_Int(nIIC_INT);			 return(1);}////////////////////////////////////////////////////////////////////////////////// IIC INTERRUPT SERVICE ROUTINES //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void IICWriteIsr(void){ U32 iiccon; U8 ch; IIC_S_INT(); if((IIC_TX.flag & IIC_DEV_ADDR) == 0)   {   IIC_R_CON(iiccon);			// read control reg   IIC_W_BUF(IIC_TX.dev);		// write dev address to buffer reg   IIC_TX.flag |= IIC_DEV_ADDR;		// set write dev address done flag  } else if((IIC_TX.flag & IIC_BYTE_ADDR_LSB) == 0)   {// send write address //////////////////////////////////////////////////////////   IIC_R_CON(iiccon);			// read control register   if(iiccon & IICCON_LRB)     {					// not rx device address ack      IIC_TX.noack |= IIC_DEV_ADDR;    }    IIC_W_BUF(IIC_TX.lsb);		// write address   IIC_TX.flag |= IIC_BYTE_ADDR_LSB; 	// set write address done flag  } else  if(IIC_TX.count < IIC_TX.size)   {   IIC_R_CON(iiccon);			// read control register    if(iiccon & IICCON_LRB)     {					// no ack     if(IIC_TX.count == 0)      {       IIC_TX.noack |= IIC_BYTE_ADDR_LSB;      }      else      {       IIC_TX.noack |= IIC_PAGE_TX_DONE;      }     } // send next character /////////////////////////////////////////////////////////   ch = IIC_TX.buffer[IIC_TX.count++];	//    IIC_W_BUF(ch);			// write byte to buffer reg  } else  if((IIC_TX.flag & IIC_PAGE_TX_DONE) == 0)  {    IIC_R_CON(iiccon);   if(IICCON & IICCON_LRB)     {     IIC_TX.noack |= IIC_PAGE_TX_DONE;    } // generate stop condition //////////////////////////////////////////////////////* STOP IIC Controller */   IIC_W_CON(IICCON_COND_STOP);		// write control reg   IIC_R_BUF(ch);   /* byte data or page data transmit done */   IIC_TX.flag |= IIC_PAGE_TX_DONE;  } else  {   IIC_R_CON(iiccon);   IIC_UNKNOWN();  }}////////////////////////////////////////////////////////////////////////////////// Read From Serial EEPROM /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////static void IICReadIsr(void);void IICRead(U8 dev,U32 addr, U8 * data, U32 len){ Disable_Int(nGLOBAL_INT);		// disable global Int SysSetInterrupt(nIIC_INT,IICReadIsr) ; // Setup IIC Rx interrupt Enable_Int(nIIC_INT);			// Enable IIC interrupt  // Wait while the iic bus is busy ////////////////////////////////////////////// while((IICCON & IICCON_BUSY) != 0) {;}//  switch(IIC_EEPROM_type)  {   case IIC_EEPROM_AT24C04 : dev = (dev & 0xFC) | ((addr >> 7) & 0x2); break;   case IIC_EEPROM_AT24C08 : dev = (dev & 0xF8) | ((addr >> 7) & 0x6); break;   case IIC_EEPROM_AT24C16 : dev = (dev & 0xF0) | ((addr >> 7) & 0xE); break;   default  		   : dev = (dev & 0xFE); break;  } dev |= S_WRITE;			// //  IIC_RX.buffer = data;			// data buffer pointer  IIC_RX.flag  = 0x0;			// interrupt flag  IIC_RX.count = 0x0;			// read byte count IIC_RX.size  = len;			// read size IIC_RX.dev   = dev;			// device address  IIC_RX.msb   = (U8)((addr>>8) & 0xff); IIC_RX.lsb   = (U8) (addr & 0xff);	// low byte of address IIC_RX.noack = 0;// Start, interrupt enable Enable_Int(nGLOBAL_INT);		// Enable global interrupt  IIC_W_CON(IICCON_BF | IICCON_COND_START | IICCON_IEN);//  while((IIC_RX.flag & IIC_BYTE_RX_DONE) == 0 && IIC_RX.noack == 0)  {// wait rx done or no ack condition   } if(IIC_RX.noack != 0)  {   Print("\nIIC read error. No ack %d\nReset IIC", IIC_RX.noack);   IICCON = IICCON_RESET;  } Disable_Int(nIIC_INT);			// Enable IIC interrupt   IIC_DEBUG_DUMP();}////////////////////////////////////////////////////////////////////////////////// IIC read ISR ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void IICReadIsr(void){ U32 iiccon;				//  U8 ch;					//  IIC_S_INT(); if((IIC_RX.flag & IIC_DEV_ADDR) == 0)   {   IIC_W_BUF(IIC_RX.dev);		// write dev addr    IIC_RX.flag |= IIC_DEV_ADDR;		// set write device address done flag    } else if((IIC_RX.flag & IIC_BYTE_ADDR_LSB) == 0)   {////////////////////////////////////////////////////////////////////////////////// send low byte of word address ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   IIC_R_CON(iiccon); 			// read control reg   if(iiccon & IICCON_LRB)     {     IIC_RX.noack |= IIC_DEV_ADDR;    }   IIC_W_BUF(IIC_RX.lsb);		// write low byte of address word   IIC_RX.flag |= IIC_BYTE_ADDR_LSB; 	// send lsb byte addr  } else  if((IIC_RX.flag & IIC_REPEAT_START) == 0)   {////////////////////////////////////////////////////////////////////////////////// Generate Repeat Start ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   IIC_R_CON(iiccon);   if(iiccon & IICCON_LRB)     {     IIC_RX.noack |= IIC_BYTE_ADDR_LSB;    }   IIC_W_CON(IICCON_COND_RESTART|IICCON_IEN);// Generate Start //////////////////////////////////////////////////////////////// BF, Start Condition, ACK enable, interrupt enable   IIC_W_CON(IICCON_BF|IICCON_COND_START|IICCON_ACK|IICCON_IEN);// Select device ///////////////////////////////////////////////////////////////// device address// read bit    IIC_W_BUF((IIC_RX.dev | S_READ));   IIC_RX.flag |= IIC_REPEAT_START;  } else  if((IIC_RX.flag & IIC_MULTI_RECV) == 0)   {/* Receive multiple data */   IIC_R_CON(iiccon);   if(IICCON & IICCON_BF)    {     IIC_RX.flag |= IIC_MULTI_RECV;    }       IIC_W_CON(IICCON_ACK|IICCON_IEN);   IIC_R_BUF(ch);  } else  if(IIC_RX.count < IIC_RX.size)   {////////////////////////////////////////////////////////////////////////////////// read received byte //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   IIC_R_CON(iiccon);   if(iiccon & IICCON_LRB)     {     IIC_RX.noack |= IIC_MULTI_RECV;    }   IIC_R_BUF(ch);   *(IIC_RX.buffer)++ = ch;		// write rx byte to buffer     IIC_RX.count++;			// received bytes  } else  if((IIC_RX.flag & IIC_NO_MORE_RECV) == 0)   { /* Now,no more received data is required from slave */   IIC_W_CON(IICCON_NOACK | IICCON_IEN);   IIC_RX.flag |= IIC_NO_MORE_RECV;  } else  if((IIC_RX.flag & IIC_BYTE_RX_DONE) == 0)  { /* Receive last data and STOP */   IIC_R_BUF(ch);   IIC_W_CON(IICCON_COND_STOP);   IIC_R_BUF(ch);/* byte data receive done */   IIC_RX.flag |= IIC_BYTE_RX_DONE;  } else  {   IIC_UNKNOWN();  }}////////////////////////////////////////////////////////////////////////////////// read from console address & byte value and write byte to serial EEPROM //////////////////////////////////////////////////////////////////////////////////////void IICWriteByteTest(void){ U32 size;				// EEPROM size U32 addr;				// EEPROM address U8 ch;					// writed character//  size = IICEEPROMSize(); Print("\nEnter Byte Write address of IIC EEPROM (up to [0x%x]) ",    size					// up limit off address   );//  addr = get_number(16,0);			// read address from console  if(addr >= size)			// check input address  {   Print("\nByte address [0x%x] not valid\n", addr);   return;  } while(kbd_hit())  {					// clear input   ch = get_byte();			// from console  } //  Print("\nEnter writed byte 0x"); ch = get_number(16,0); 			// read byte from console IICWriteByte(addr, ch);}////////////////////////////////////////////////////////////////////////////////// read address from console and read byte from EEPROM /////////////////////////////////////////////////////////////////////////////////////////////////////////void IICReadByteTest(void){ U32 size;				// serial EEPROM size U32 addr;				// addres int cnt; U8 ch;					// read character //  size = IICEEPROMSize(); Print("\nEnter Byte Read address of IIC EEPROM (up to [0x%x]) ",    size					// up limit off address   );//  addr = get_number(16,0);		// read address from console  if(addr >= size)			// check input address  {   Print("\nByte address [0x%x] not valid\n", addr);   return;  } Print("\nEnter count of bytes (up to %d) ", size - addr); cnt = get_number(10, 3); if(cnt > size - addr) {cnt = size - addr;}  if(cnt < 1) {cnt = 1;} Print("\n");  while(cnt-- > 0)  {   if(IICReadByte(addr, & ch) != 0)    {     Print("0x%02x ", ch);     }   addr++;   }}////////////////////////////////////////////////////////////////////////////////// IIC Test using IIC 64Kbit Serial EEPROM /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void IICTest(void) { IICSetup();				// Initialize IIC control block Enable_Int(nGLOBAL_INT); 		// enable global interrupt mask while(1)  {   U8 it;// print EEPROM name, device address   Print("\n\nIIC %s Test. Device Address %d",     IICEEPROMName(), IICEEPROMAddr());//   Print("\n[W] IIC Page Write Test.");   Print("\n[R] IIC Sequential Read Test.");   Print("\n[L] IIC Read/Write Test.");   Print("\n[C] IIC Configuration View.");   Print("\n[S] IIC EEPROM type & address Select.");   Print("\n[B] IIC Byte Write.");   Print("\n[D] IIC Byte Read.");   Print("\n[T] IIC Byte Write & Read Test.");   Print("\n[Q] Quit IIC Test");   Print("\nSelect Test Item : ");   it = get_upper();   switch(it)    {     case 'W' : IICWriteTest(); break;	   // EEPROM write      case 'R' : IICReadTest(); break;	   // EEPROM read      case 'L' : IICWriteReadTest(0); break; // EEPROM write & read test      case 'C' : IICConfig(); break;	   // IIC configuration      case 'S' : IICEEPROMSelect(); break;  // Select IIC EEPROM 	     case 'B' : IICWriteByteTest(); break;     case 'D' : IICReadByteTest(); break;     case 'T' : IICByteTest(); break;	   // IIC Byte Write & Read Test     case 'Q' : return;     default  : break;    }//    Print("\nPress Any Key to Continue IIC Test") ;    it = get_upper();   if(it == 'Q')    {     return;    }   } }

⌨️ 快捷键说明

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