??? 03/11/11 12:05 Modified: 03/11/11 13:57 Read: times |
#181545 - Smb Reading a two byte address |
Hi I would like to perform a random read with a EEprom. A 16 bit address is written then a repeat start is issued this updates the pointer in the eeprom and allow the new memory loaction to be read.
The problem is the memory pointer is not being up dated, the data be read is last position written to. The problem is the memory pointer is not being updated in the eprom, the data read back is the last position written to the processor is the c8051f042. For a random read my status register contains: 08 Start condition transmitted( control) 18 slave address ack recieve( low byte) 28 data byte (High address byte) 28 issue a repeat start 10 repeat start transmit 40 slave address transmitted wait for recive data 58 data byte recieved I look at the data being sent, it'as all there. Which leads me to believe its a timing issue. What did I miss thanks ...insert code here[ ///----------------------------------------------------------------------------- // Interrupt Service Routines //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // SMBus Interrupt Service Routine (ISR) //----------------------------------------------------------------------------- // // SMBus ISR state machine // - Master only implementation - no slave states defined // - All incoming data is written starting at the global pointer <pSMB_DATA_IN> // - All outgoing data is read from the global pointer <pSMB_DATA_OUT> // void SMBUS_ISR (void) interrupt 7 { int xdata itemp = 0xFFFF; int xdata ifoo; static bit lo_hiByteFlag = 0; bit FAIL = 0; // Used by the ISR to flag failed // transfers static char xdata ByteCnt; // Used by the ISR to count the // number of data bytes sent or // received static bit SEND_START = 0; // Send a start static bit addrLowSendFlag = 0; // Has the low byte Been sent? // = 1 sent hi Addr byte; =0 Low addr sent smb[smbcnt] = SMB0STA; smbcnt++; // Status code for the SMBus (SMB0STA register) switch (SMB0STA) { // Master Transmitter/Receiver: START condition transmitted. // Load SMB0DAT with slave device (EEPROM) address. case SMB_START_08: SMB0DAT = EPROM_DEVICE_ID; // Load address of the slave. SMB0DAT &= 0xFE; // Clear the LSB of the address for the // R/W bit SMB0DAT |= SMB_RW; // Load R/W bit STA = 0; // Manually clear STA bit ByteCnt = 0; // reset data byte counter break; // Master Transmitter/Receiver: Repeated START condition transmitted. // For a READ: This state only occurs during an EEPROM read operation // for the EEPROM's "random read", where a write operation with the // data address must be done before the read operation. // // For a WRITE: N/A case SMB_RP_START_10: lo_hiByteFlag = 0; SMB0DAT = EPROM_DEVICE_ID; SMB0DAT &= 0xFE; // Load address of the slave. SMB0DAT |= SMB_RW; // Load R/W bit STA = 0; STO = 0; // Manually clear START bit. ByteCnt = 0; // reset data byte counter break; // Master Transmitter: Slave address + WRITE transmitted. ACK received. // For a READ or WRITE: the word (data) address in the EEPROM must now // be sent after the slave address // slave case SMB_MTADDACK_18: SMB0DAT = CHAR_ADDR_HIGH; addrLowSendFlag = 1; break; ///------------------------TRANSMIT ROUTINES -------------------------------------/// ///-------------------------------------------------------------------------------/// // Master Transmitter: Slave address + WRITE transmitted. NACK received. // If the EEPROM should be polled, restart the transfer. // Otherwise, reset the SMBus case SMB_MTADDNACK_20: if(SMB_ACKPOLL) { STA = 1; // Restart transfer } else { FAIL = 1; // Indicate failed transfer } // and handle at end of ISR break; // Master Transmitter: Data byte transmitted. ACK received. // For a READ: the word address has been trasmitted, and a repeated // start should be generated. // 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; addrLowSendFlag = 0; } else { if (SMB_RANDOMREAD) { STA = 1; STO = 0; SMB_RW = READ; AA = 1; break; } else // Is this transfer a WRITE? { if (SMB_RW == WRITE) { // Is there data to send? if (ByteCnt < SMB_DATA_LEN) { SMB0DAT = SMB_SINGLEBYTE_OUT; ByteCnt++; } else { STA = 0; AA = 0; STO = 1; // Set STO to terminte transfer SMB_BUSY = 0; // Clear software busy flag } } 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. // If the EEPROM should be polled, restart the transfer. // Otherwise, reset the SMBus case SMB_MTDB_NACK_30: if(SMB_ACKPOLL) { STA = 1; // Restart transfer } else { FAIL = 1; // Indicate failed transfer } // and handle at end of ISR break; // Master Transmitter: Arbitration lost. case SMB_MTARBLOST_38: FAIL = 1; // Indicate failed transfer // and handle at end of ISR break; ///------------------------ RECEIVE ROUTINE --------------------------------------/// ///-------------------------------------------------------------------------------/// // Master Receiver: Slave address + READ transmitted. ACK received. // 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: if (ByteCnt == SMB_DATA_LEN) { AA = 0; // 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. // If the EEPROM should be polled, restart the transfer. // Otherwise, reset the SMBus case SMB_MRADDNACK_48: if(SMB_ACKPOLL) { STA = 1; // Restart transfer } else { FAIL = 1; // Indicate failed transfer } // and handle at end of ISR break; // Master Receiver: Data byte received. ACK transmitted. // 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 (ByteCnt < SMB_DATA_LEN) { *pSMB_DATA_IN = SMB0DAT; // Store received byte ByteCnt++; // Increment number of bytes received if (ByteCnt == SMB_DATA_LEN) { SMB_BUSY = 0; // Free SMBus interface AA = 0; // Send NACK to indicate last byte of this transfer STO = 1; // Send STOP to terminate transfer } else { AA = 1; // Send ACK (may be cleared later in the code) STO = 0; } } break; // Master Receiver: Data byte received. NACK transmitted. // Read operation has completed. Read data register and send STOP. case SMB_MRDBNACK_58: // Read_Array // ==1 reading Epprom Read Array *pSMB_DATA_IN = SMB0DAT; // Store received byte 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 } ] |
Topic | Author | Date |
Smb Reading a two byte address | 01/01/70 00:00 | |
using HW IIC .... | 01/01/70 00:00 | |
now that you added ... | 01/01/70 00:00 |