??? 07/10/07 14:28 Read: times |
#141686 - updated post Responding to: ???'s previous message |
My second problem, when think I have workng code.
I add a simple functions, the original behavior changes, as if some var's or registers are being written over. Any idea's why? // Status code for the SMBus // (SMB0STA register) switch (SMB0STA) { // Master Transmitter/Receiver: case SMB_START_08: SMB0DAT = EPROM_DEVICE_ID; SMB0DAT &= 0xFE; // Load R/W bit SMB0DAT |= SMB_RW; STA = 0; // Manually clear STA bit i = 0; break; // Master Transmitter/Receiver: // Repeated START condition case SMB_RP_START_10: SMB0DAT = EPROM_DEVICE_ID; . SMB0DAT |= SMB_RW; STA = 0; i = 0; break; // Master Transmitter: Slave address // + WRITE transmitted. // ACK received. case SMB_MTADDACK_18: // Hi addr has been send, // Flag it, to send low byte addrLowSendFlag = 1; SMB0DAT = CHAR_ADDR_HIGH; if (SMB_RANDOMREAD) { //Send a START after //the next ACK cycle SEND_START = 1; SMB_RW = READ; } break; ///-RANSMIT ROUTINES /// ///------------------/// // Master Transmitter: Slave // address + WRITE transmitted. NACK received. case SMB_MTADDNACK_20: if(SMB_ACKPOLL) { // Restart transfer STA = 1; } else { // Indicate failed transfer FAIL = 1; } break; // Master Transmitter: Data byte // transmitted. ACK received. case SMB_MTDB_ACK_28: // Has the Addr Hi byte been // sent, if Yes, send the //low byte, Flag it if (addrLowSendFlag) { SMB0DAT = CHAR_ADDR_LOW; //Reset the flag to skip addrLowSendFlag = 0; } else { if (SEND_START) { STA = 1; SEND_START = 0; break; } // Is this transfer a WRITE? if (SMB_RW==WRITE) { // Is there data to send? if (i < SMB_DATA_LEN) { SMB0DAT = SMB_SINGLEBYTE_OUT; i++; } else { // Set STO to terminte transfer STO = 1; // Clear software busy flag SMB_BUSY = 0; } } else {} // If this transfer is a READ, then // take no action, as a repeated // start will be generated for the // read operation } break; // Master Transmitter: Data //byte transmitted.NACK received. case SMB_MTDB_NACK_30: if(SMB_ACKPOLL) { STA = 1;// Restart transfer } else { FAIL = 1;// Indicate failed transfer } break; // Master Transmitter: Arbitration lost. case SMB_MTARBLOST_38: FAIL = 1; // Indicate failed transfer // and handle at end of ISR break; // For a READ: check if this is a one //-byte transfer. if so, set the // NACK after the data byte is received to end the transfer. if not, // set the ACK and receive the other data bytes. // // For a WRITE: N/A case SMB_MRADDACK_40: STA =0; if (i == SMB_DATA_LEN) { AA = 0; // Only one byte in this transfer, // send NACK after byte is received } else { AA = 1; // More than one byte in this transfer, // send ACK after byte is received } break; // Master Receiver: Slave address //+ READ transmitted. NACK received. case SMB_MRADDNACK_48: if(SMB_ACKPOLL) { STA = 1; // Restart transfer } else { FAIL = 1; // Indicate failed transfer } // and handle at end of ISR break; // For a READ: receive each byte // from the EEPROM. if this is the last // byte, send a NACK and set the STOP bit. // For a WRITE: N/AGA case SMB_MRDBACK_50: if ( i < SMB_DATA_LEN ) // Is there any data remaining? { // Read_Array // ==1 reading Epprom Read Array switch (ucREAD_Epprom) { case 0x01: // array //hiLowFlag == 0: save low byte; if (lo_hiByteFlag == 0) { *ipSMB_DATA_IN = (int) SMB0DAT; AA = 1; lo_hiByteFlag = 1; } else { //Load Hi Byte; shift to the Lt; mask out low bytes; //Store it in temp itemp = 0x0000; itemp = (int) (SMB0DAT); AA = 1; itemp = ((itemp <<8) & 0xFF00); //assign to hi byte of ifoo foo = *ipSMB_DATA_IN | itemp; *ipSMB_DATA_IN = ifoo; //inc to next location ipSMB_DATA_IN ++; //task completed; reset flag; lo_hiByteFlag = 0; } break; case 0x00: *pSMB_DATA_IN = SMB0DAT; // Store received byte break; }// i < SMB_DATA_LEN i++; // Increment number of bytes received AA = 1; // Send ACK (may be cleared later // in the code) } if (i == SMB_DATA_LEN) // This is the last byte { SMB_BUSY = 0; // Free SMBus interface AA = 0; // Send NACK last byte STO = 1; // Send STOP to terminate transfer break; } break; // Master Receiver: Data byte received. NACK transmitted. // Read operation has completed. Read data register and send STOP. case SMB_MRDBNACK_58: switch (ucREAD_Epprom) { case 0x01: // array //hiLowFlag == 0: save low byte; if (lo_hiByteFlag == 0) { *ipSMB_DATA_IN = (int) SMB0DAT; AA = 1; lo_hiByteFlag = 1; } else { //Load Hi Byte; shift to the Lt; mask out low bytes; //Store it in temp itemp = 0x0000; itemp = (int) (SMB0DAT); AA = 1; itemp = ((itemp <<8) & 0xFF00); //assign to hi byte of ifoo foo = *ipSMB_DATA_IN | itemp; *ipSMB_DATA_IN = ifoo; //inc to next location ipSMB_DATA_IN ++; //task completed; reset flag; lo_hiByteFlag = 0; } break; case 0x00: *pSMB_DATA_IN = SMB0DAT; // Store received byte break; } i++; // Increment number of bytes received AA = 1; // Send ACK (may be cleared later // in the code) if (i == SMB_DATA_LEN) // This is the last byte { SMB_BUSY = 0; // Free SMBus interface AA = 0; // Send NACK to indicate last byte // of this transfer STO = 1; // Send STOP to terminate transfer break; } STO = 1; SMB_BUSY = 0; AA = 1; // Set AA for next transfer break; // All other status codes invalid. Reset communication. default: FAIL = 1; break; } if (FAIL) // If the transfer failed, { SMB0CN &= ~0x40; // Reset communication SMB0CN |= 0x40; STA = 0; STO = 0; AA = 0; SMB_BUSY = 0; // Free SMBus FAIL = 0; } SI = 0; // Clear interrupt flag } thanks |
Topic | Author | Date |
silican labs SMBus and I2c problem f040 | 01/01/70 00:00 | |
Something missing? | 01/01/70 00:00 | |
updated post | 01/01/70 00:00 | |
Read it as single-byte variable array![]() | 01/01/70 00:00 | |
totally ambigous | 01/01/70 00:00 | |
now that you added f040 I suggest | 01/01/70 00:00 |