#include "test_env.h" /****************************************************************************** This will test an I2C EEPROM connected to mbed by writing a predefined byte at address 0 and then reading it back and comparing it with the known byte value a number of times. This test was written specifically for reproducing the bug reported here: https://mbed.org/forum/bugs-suggestions/topic/4128/ Test configuration: * set 'ntests' to the number of iterations * set 'i2c_speed_hz' to the desired speed of the I2C interface * set 'i2c_delay_us' to the delay that will be inserted between 'write' and 'read' I2C operations (https://mbed.org/users/mbed_official/code/mbed/issues/1 for more details). '0' disables the delay. * define I2C_EEPROM_VERBOSE to get verbose output The test ran with a 24LC256 external EEPROM memory, but any I2C EEPROM memory that uses two byte addresses should work. ******************************************************************************/ // Test configuration block static const int ntests = 10000; static const int i2c_freq_hz = 400000; static const int i2c_delay_us = 0; //#define I2C_EEPROM_VERBOSE // End of test configuration block #if defined(TARGET_KL25Z) I2C i2c(PTE0, PTE1); #else I2C i2c(p28, p27); #endif #ifdef I2C_EEPROM_VERBOSE #define dprintf printf #else int dprintf(const char* args, ...) { return 0; } #endif class TestHelper { public: // Defaults to 'passed' TestHelper() { passed(); } void passed() { m_result = true; } void failed() { m_result = false; } ~TestHelper() { notify_completion(m_result); } private: bool m_result; }; int main() { const int addr = 0xA0; const char mark = 0x66; char data[3]; int fw = 0, fr = 0, fc = 0; int i2c_stat; TestHelper helper; i2c.frequency(i2c_freq_hz); // Data write data[0] = data[1] = 0; data[2] = mark; if((i2c_stat = i2c.write(addr, data, 3)) != 0) { dprintf("Unable to write data to EEPROM (i2c_stat = 0x%02X), aborting\r\n", i2c_stat); helper.failed(); return 1; } // ACK polling (assumes write will be successful eventually) while(i2c.write(addr, data, 0) != 0); // Data read (actual test) for(int i = 0; i < ntests; i ++) { data[0] = data[1] = 0; if((i2c_stat = i2c.write(addr, data, 2, true)) != 0) { dprintf("Test %d failed at write, i2c_stat is 0x%02X\r\n", i, i2c_stat); fw ++; continue; } if(i2c_delay_us != 0) wait_us(i2c_delay_us); if((i2c_stat = i2c.read(addr, data, 1)) != 0) { dprintf("Test %d failed at read, i2c_stat is 0x%02X\r\n", i, i2c_stat); fr ++; continue; } if(data[0] != mark) { dprintf("Test %d failed at data match\r\n", i); fc ++; } } dprintf("Test finished.\r\n"); if(fw + fr + fc == 0) dprintf("No failures in %d tests.\r\n", ntests); else { dprintf("Statistics:\r\n"); dprintf(" Total tests: %d\r\n", ntests); dprintf(" Failed at write: %d\r\n", fw); dprintf(" Failed at read: %d\r\n", fr); dprintf(" Data mismatch: %d\r\n", fc); dprintf(" Total failures: %d\r\n", fw + fr + fc); helper.failed(); } }