📄 iic.c
字号:
// MAC Address Write to IIC EEPROM /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int MacAddrWriteIIC(U8 * data){ IICWrite // Write IIC ( IIC_EEPROM_addr , // IIC device's slave address IIC_mac_addr_start , // MAC address offset data , // data buffer IIC_mac_addr_size // data buffer size );// return(1);}#ifdef IIC_BYTE_DEBUG// Print BF flag ////////////////////////////////////////////////////////////////* The BF bit is set when : *//* the buffer is empty in transmit mode, or *//* the buffer is full in receive mode */#define PrintIICBF() Print("\nBF=%d",((IICCON & IICCON_BF) ? 1 : 0))/* 0 = The most recent SDA is Low. (ACK is received) *//* 1 = The most recent SDA is High. (ACK not received) */#define PrintIICLRB() Print("\nACK %sRx",((IICCON & IICCON_LRB)==0) ? "":"not ") #define PrintIICMSG(msg) Print("\n%s",msg)#define PrintIICBYTE(msg,ch) Print("\n%s0x%02x",msg,ch)#else#define PrintIICBF()#define PrintIICLRB()#define PrintIICMSG(msg)#define PrintIICBYTE(msg,ch)#endif // IIC_BYTE_DEBUG////////////////////////////////////////////////////////////////////////////////// Wait Tx & Rx Complete ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#define WaitIICBF() while((IICCON & IICCON_BF) == 0) {;}////////////////////////////////////////////////////////////////////////////////// write byte to serial EEPROM in pooling mode /////////////////////////////////////////////////////////////////////////////////////////////////////////////////int IICWriteByte(U32 addr, U8 ch){// static int mcnt = 20000; U8 dev; // device address// disable interrupts <= byte write in pooling mode //////////////////////////// Disable_Int(nIIC_INT); // Disable IIC interrupt while((IICCON & IICCON_BUSY) != 0){;}// Setup IICON register for transmit start ///////////////////////////////////// PrintIICMSG("\nSTART BF"); // debug message START ACK BF IICCON = IICCON_BF | // tx buffer empty IICCON_COND_START; // Now, Start to transmit////////////////////////////////////////////////////////////////////////////////// Send Slave Address and Write command //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// dev = IIC_EEPROM_addr; // write page address to device addr 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; // write bit clear PrintIICBF(); // Print BF before IICBUF write PrintIICBYTE("<-", dev); // Print writed device address IICBUF = dev; // write device address PrintIICBF(); // Print BF after IICBUF write WaitIICBF(); // wait tx complete PrintIICLRB(); // Print ACK status if((IICCON & IICCON_LRB)){Print("\nByte Write ACK not received. Dev 0x%02x.",dev);}////////////////////////////////////////////////////////////////////////////////// write word address ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// PrintIICBF(); // Print BF before IICBUF write PrintIICBYTE("<-", addr); // print writed word address IICBUF = addr; // write address PrintIICBF(); // Print BF after IICBUF write WaitIICBF(); // wait tx complete PrintIICLRB(); // Print ACK Status if((IICCON & IICCON_LRB)){Print("\nByte Write ACK not received.Addr 0x%02x",addr);}////////////////////////////////////////////////////////////////////////////////// write byte ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// PrintIICBYTE("<-", ch); // print writed word IICBUF = ch; // write byte PrintIICBF(); // Print BF after IICBUF write WaitIICBF(); // wait tx complete PrintIICLRB(); // Print ACK status if((IICCON & IICCON_LRB)){Print("\nByte Write ACK not received. Data 0x%02x",ch);} PrintIICMSG("STOP"); // print STOP condition IICCON = IICCON_COND_STOP; // generate STOP condition { int wait; wait = (fMCLK / 1000 / 4 ) * 10; for(; wait > 0; --wait); } return(1);}////////////////////////////////////////////////////////////////////////////////// read byte from serial EEPROM in pooling mode ////////////////////////////////////////////////////////////////////////////////////////////////////////////////int IICReadByte(U32 addr, U8 * ch){ U8 dev; // device address if(ch == 0) { return(0); } // disable interrupts <= read byte in pooling mode ///////////////////////////// Disable_Int(nIIC_INT); // Disable IIC interrupt while((IICCON & IICCON_BUSY) != 0) {;}////////////////////////////////////////////////////////////////////////////////// generate start condition //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// PrintIICMSG("START BF"); // IICCON = IICCON_BF | // Tx buffer empty (in transmit mode) IICCON_COND_START; // Now, Start to transmit// Send Slave Address and Write command //////////////////////////////////////// dev = IIC_EEPROM_addr; 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; }// send device address, page number, write bit ///////////////////////////////// dev |= S_WRITE; // PrintIICBF(); // print BF before write PrintIICBYTE("<-", dev); // print writed device address IICBUF = dev; // Write to EEPROM device address PrintIICBF(); // print BF after write WaitIICBF(); // wait tx complete PrintIICLRB(); // print ACK status if((IICCON & IICCON_LRB)){Print("\nRead Byte ACK not received. Dev 0x%02x.",dev);}////////////////////////////////////////////////////////////////////////////////// send word address /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// PrintIICBYTE("<-", addr); // print writed word address IICBUF = addr; // write address PrintIICBF(); // print BF after write WaitIICBF(); // wait tx complete PrintIICLRB(); // print ACK status if((IICCON & IICCON_LRB)){Print("\nRead Byte ACK not received.Addr 0x%02x.",addr);}////////////////////////////////////////////////////////////////////////////////// generate RESTART condition ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// PrintIICMSG("RESTART");// IICCON = IICCON_COND_RESTART; // Now, Restart to transmit// send device addres, page bits, write/read bit /////////////////////////////// dev = (dev & 0xFE) | S_READ; // set read bit////////////////////////////////////////////////////////////////////////////////// generate start condition //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// PrintIICMSG("START BF"); IICCON = IICCON_BF | // Tx buffer empty (in tx mode) IICCON_COND_START; // Now, Start to transmit PrintIICBF(); // print BF before write PrintIICBYTE("<-", dev); // print device address & read bit WaitIICBF(); // wait tx done IICBUF = dev; // Write to EEPROM device address PrintIICBF(); // print BF after write WaitIICBF(); // wait tx done PrintIICLRB(); // print ACK status if((IICCON & IICCON_LRB)){Print("\nRead Byte ACK not received. Dev 0x%02x.",dev);}////////////////////////////////////////////////////////////////////////////////// read byte /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// *ch = IICBUF; // read byte for clear BF PrintIICBYTE("->", *ch); // print read byte WaitIICBF(); PrintIICBF(); // print BF after write PrintIICLRB(); // print ACK status *ch = IICBUF; PrintIICBYTE("->", *ch); WaitIICBF(); ////////////////////////////////////////////////////////////////////////////////// generate stop condition ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// PrintIICMSG("IIC STOP"); IICCON = IICCON_COND_STOP; return(1);}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int IICByteTest(void){ int lcnt; // pass count int lnum; // pass num int wskiped; char * name; // serial EEPROM name U32 size; // serial EEPROM size U32 pos; // address int rvl; // return code U8 ch; // // rvl = 1; // start return code // size = IICEEPROMSize(); // calculate EEPROM size if(size > IIC_buffer_size) { size = IIC_buffer_size; } name = IICEEPROMName(); Print("\n\nSerial EEPROM %s (%dbytes)byte write & read test.", name , // EEPROM name size // EEPROM size in bytes );// test buffer start filling /////////////////////////////////////////////////// for(pos = 0; pos < size; ++pos) { IIC_buffer[pos] = PatternGen(pos); } // write to EEPROM ///////////////////////////////////////////////////////////// Print("\nSkip write EEPROM [Y/N]"); wskiped = get_upper(); if(wskiped != 'Y') { U8 it; Print("\nRandom pattern [Y/N]"); it = get_upper(); if(it != 'Y') {// not random fill pattern ///////////////////////////////////////////////////// for(pos = 0; pos < size; ++pos) { IIC_buffer[pos] = pos; } } } lcnt = 10; Print("\nInput pass count (%d) ", lcnt); lcnt = get_number(10, 0); if(lcnt == 0) { lcnt = 10; } for(lnum = 0; lnum < lcnt; ++lnum) { if(kbd_hit()) { ch = get_byte(); if(ch == 'Q' || ch == 'q') { break; } } if(wskiped != 'Y') { Print("\n%d Write serial EEPROM...", lnum); for(pos = 0; pos < size; ++pos) { ch = IIC_buffer[pos]; // read character IICWriteByte(pos,ch); // write to EEPROM } }// read from EEPROM //////////////////////////////////////////////////////////// Print("\n%d Read serial EEPROM...", lnum); for(pos = 0; pos < size; ++pos) { IICReadByte(pos,& ch); if(ch != IIC_buffer[pos]) { Print("\nError, address=[0x%x], write=[0x%02x], read=[0x%02x]", pos , IIC_buffer[pos], ch );// rvl = 0; if(kbd_hit()) { get_byte(); break; } } } if(rvl == 0) { break; } } if(rvl == 1) { Print("\nOk.\n"); } else { Print("\nFail.\n"); }// return(rvl);}/* Byte Slave transmitter and receive status flags */#define IIC_DEV_ADDR ((U32)0x01) // device address#define IIC_BYTE_ADDR_MSB ((U32)0x02) // byte msb addr#define IIC_BYTE_ADDR_LSB ((U32)0x04) // byte lsb addr#define IIC_PAGE_TX_DONE ((U32)0x08) // Page data transmit done#define IIC_BYTE_RX_DONE ((U32)0x10) // byte data receive done#define IIC_REPEAT_START ((U32)0x20) // flag for repeat start#define IIC_MULTI_RECV ((U32)0x40) // recv multiple data#define IIC_NO_MORE_RECV ((U32)0x80) // no more recv from slave/* Data structure for multiple byte slave transmitter format */typedef struct { volatile U32 flag; volatile U32 count; // Page buffer byte counter volatile U32 size; // Page buffer byte counter volatile U32 noack; // no ACK flag volatile U8 dev; // Slave address volatile U8 msb; // Byte MSB address volatile U8 lsb; // Byte LSB address volatile U8 buffer[16]; // IIC Page data buffer} IIC_DATA_TX_FORMAT;IIC_DATA_TX_FORMAT IIC_TX;/* Data structure for multiple byte slave receiver format */typedef struct { volatile U32 flag; volatile U32 count; volatile U32 size; volatile U8 dev; volatile U8 msb; volatile U8 lsb; volatile U32 noack; // no ACK flag volatile U8 * buffer;} IIC_DATA_RX_FORMAT;IIC_DATA_RX_FORMAT IIC_RX;#ifdef IIC_DEBUG// #define IIC_DEBUG_BUF_SIZE 128 // debug buffer size U16 IIC_DEBUG_BUF[IIC_DEBUG_BUF_SIZE]; // debig buffer U32 IIC_DEBUG_CNT = 0; // debug cnt #define IIC_DEBUG_W_CON (U16)(0x0100) // write controll register#define IIC_DEBUG_R_CON (U16)(0x0200) // read control register#define IIC_DEBUG_W_BUF (U16)(0x0400) // write buffer register #define IIC_DEBUG_R_BUF (U16)(0x0800) // read buffer register #define IIC_DEBUG_INT (U16)(0x4000) // int start#define IIC_DEBUG_UNKNOWN (U16)(0x8000) // unknown interrupt // put debug message to buffer /////////////////////////////////////////////////void IIC_DEBUG_PUT(U16 typ, U8 val){ if(IIC_DEBUG_CNT >= IIC_DEBUG_BUF_SIZE) { // debug buffer full return; } IIC_DEBUG_BUF[IIC_DEBUG_CNT++] = typ | val;}// print debug buffer //////////////////////////////////////////////////////////void IIC_DEBUG_DUMP(void){ U32 pos; // position in debug buffer for(pos = 0; pos < IIC_DEBUG_CNT; ++pos) { U16 val; // debug message val = IIC_DEBUG_BUF[pos]; // read debug message if((val & IIC_DEBUG_INT) != 0) { Print("\nINT"); } else if( (val & IIC_DEBUG_W_CON) != 0 || // write control register (val & IIC_DEBUG_R_CON) != 0 // read control register ) { if((val & IIC_DEBUG_W_CON) != 0) {// write control register header /////////////////////////////////////////////// Print("\nW IICCON "); } else {// read control register header //////////////////////////////////////////////// Print("\nR IICCON "); }// condition code ////////////////////////////////////////////////////////////// switch(val & IICCON_COND) { case IICCON_COND_NULL : break; case IICCON_COND_START : Print("START "); break; // start condition case IICCON_COND_STOP : Print("STOP "); break; // stop condition case IICCON_COND_RESTART : Print("RESTART "); break; // restart condition }// if((val & IICCON_BF ) != 0) Print("BF "); // if((val & IICCON_IEN ) != 0) Print("IEN "); // if((val & IICCON_LRB ) != 0) Print("LRB "); // if((val & IICCON_ACK ) != 0) Print("ACK "); // if((val & IICCON_BUSY ) != 0) Print("BUSY "); // if((val & IICCON_RESET) != 0) Print("RESET "); // } else if((val & IIC_DEBUG_W_BUF) != 0) {// write buffer register /////////////////////////////////////////////////////// Print("\nW IICBUF %02x", val & 0xFF); // } else if((val & IIC_DEBUG_R_BUF) != 0) {// read buffer register //////////////////////////////////////////////////////// Print("\nR IICBUF %02x", val & 0xFF); // } else { Print("\nUNKNOWN"); } } IIC_DEBUG_CNT = 0;}// write controll register /////////////////////////////////////////////////////#define IIC_W_CON(val) {IIC_DEBUG_PUT(IIC_DEBUG_W_CON, val); IICCON = val;} // read control register //////////////////////////////////////////////////////#define IIC_R_CON(val) {val = IICCON; IIC_DEBUG_PUT(IIC_DEBUG_R_CON, val);}// write buffer register ///////////////////////////////////////////////////////#define IIC_W_BUF(val) {IIC_DEBUG_PUT(IIC_DEBUG_W_BUF, val); IICBUF = val;} // read buffer register ////////////////////////////////////////////////////////#define IIC_R_BUF(val) {val = IICBUF; IIC_DEBUG_PUT(IIC_DEBUG_R_BUF, val);} // int start ///////////////////////////////////////////////////////////////////#define IIC_S_INT() IIC_DEBUG_PUT(IIC_DEBUG_INT,0);// unknown interrupt ///////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -