From 77c96631cce0feb4aeb89c280df5eae776984b14 Mon Sep 17 00:00:00 2001 From: Przemek Wirkus Date: Thu, 24 Apr 2014 12:00:40 +0100 Subject: [PATCH] Updated MBED_A19 24LC256 EEPROM test. Added new test MBED_A25 24LC256 I2C EEPROM pattern write/read to test suite --- libraries/tests/mbed/i2c_eeprom/main.cpp | 190 ++++++++++-------- libraries/tests/mbed/i2c_eeprom_line/main.cpp | 114 +++++++++++ workspace_tools/tests.py | 11 +- 3 files changed, 228 insertions(+), 87 deletions(-) create mode 100644 libraries/tests/mbed/i2c_eeprom_line/main.cpp diff --git a/libraries/tests/mbed/i2c_eeprom/main.cpp b/libraries/tests/mbed/i2c_eeprom/main.cpp index 6a41622d62..4d1b6e6ff6 100644 --- a/libraries/tests/mbed/i2c_eeprom/main.cpp +++ b/libraries/tests/mbed/i2c_eeprom/main.cpp @@ -1,108 +1,126 @@ #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: - +* 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. +* '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. +* +* 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 +namespace { +const int ntests = 10000; +const int i2c_freq_hz = 400000; +const int i2c_delay_us = 0; +const int EEPROM_24LC256_SIZE = (256 * 1024 / 8); // 256 kbit memory +} // End of test configuration block #if defined(TARGET_KL25Z) -I2C i2c(PTE0, PTE1); +I2C i2c(PTC9, PTC8); + +#elif defined(TARGET_KL46Z) +I2C i2c(PTC9, PTC8); + +#elif defined(TARGET_LPC812) +I2C i2c(P0_10, P0_11); + +#elif defined(TARGET_LPC1549) +I2C i2c(P0_23, P0_22); + #elif defined(TARGET_NUCLEO_F103RB) I2C i2c(I2C_SDA, I2C_SCL); + #elif defined(TARGET_K64F) I2C i2c(PTE25, PTE24); + #else I2C i2c(p28, p27); #endif -#ifdef I2C_EEPROM_VERBOSE -#define dprintf printf -#else -int dprintf(const char* args, ...) { - return 0; -} -#endif - -int main() { - const int addr = 0xA0; - const char mark = 0x66; - char data[3]; - int fw = 0, fr = 0, fc = 0; - int i2c_stat; - - 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); - notify_completion(false); - 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); - notify_completion(false); - } - - notify_completion(true); +int main() +{ + const int EEPROM_MEM_ADDR = 0xA0; + const char MARK = 0x66; + int fw = 0; + int fr = 0; + int fc = 0; + int i2c_stat = 0; + bool result = true; + + i2c.frequency(i2c_freq_hz); + + // Data write + { + char data[] = { 0, 0, MARK }; + if ((i2c_stat = i2c.write(EEPROM_MEM_ADDR, data, sizeof(data))) != 0) { + printf("Unable to write data to EEPROM (i2c_stat = 0x%02X), aborting\r\n", i2c_stat); + notify_completion(false); + return 1; + } + + // ACK polling (assumes write will be successful eventually) + while (i2c.write(EEPROM_MEM_ADDR, data, 0) != 0) + ; + } + + // Data read (actual test) + for (int i = 0; i < ntests; i++) { + // Write data to EEPROM memory + { + char data[] = { 0, 0 }; + if ((i2c_stat = i2c.write(EEPROM_MEM_ADDR, data, 2, true)) != 0) { + printf("Test %d failed at write, i2c_stat is 0x%02X\r\n", i, i2c_stat); + fw++; + continue; + } + } + + // us delay if specified + if (i2c_delay_us != 0) + wait_us(i2c_delay_us); + + // Read data + { + char data[1] = { 0 }; + if ((i2c_stat = i2c.read(EEPROM_MEM_ADDR, data, 1)) != 0) { + printf("Test %d failed at read, i2c_stat is 0x%02X\r\n", i, i2c_stat); + fr++; + continue; + } + + if (data[0] != MARK) { + printf("Test %d failed at data match\r\n", i); + fc++; + } + } + } + + result = (fw + fr + fc == 0); + printf("EEPROM: Test result ... [%s]\r\n", result ? "OK" : "FAIL"); + + if (!result) { + printf("Test Statistics:\r\n"); + printf("\tTotal tests: %d\r\n", ntests); + printf("\tFailed at write: %d\r\n", fw); + printf("\tFailed at read: %d\r\n", fr); + printf("\tData mismatch: %d\r\n", fc); + printf("\tTotal failures: %d\r\n", fw + fr + fc); + } + + notify_completion(result); } diff --git a/libraries/tests/mbed/i2c_eeprom_line/main.cpp b/libraries/tests/mbed/i2c_eeprom_line/main.cpp new file mode 100644 index 0000000000..dd67c63895 --- /dev/null +++ b/libraries/tests/mbed/i2c_eeprom_line/main.cpp @@ -0,0 +1,114 @@ +#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 +namespace { +const int ntests = 1000; +const int i2c_freq_hz = 400000; +const int i2c_delay_us = 0; +// const int EEPROM_24LC256_SIZE = (256 * 1024 / 8); // 256 kbit memory +} +// End of test configuration block + +#if defined(TARGET_KL25Z) +I2C i2c(PTC9, PTC8); + +#elif defined(TARGET_KL46Z) +I2C i2c(PTC9, PTC8); + +#elif defined(TARGET_LPC812) +I2C i2c(P0_10, P0_11); + +#elif defined(TARGET_LPC1549) +I2C i2c(P0_23, P0_22); + +#elif defined(TARGET_NUCLEO_F103RB) +I2C i2c(I2C_SDA, I2C_SCL); + +#elif defined(TARGET_K64F) +I2C i2c(PTE25, PTE24); + +#else +I2C i2c(p28, p27); +#endif + +#define PATTERN_MASK 0x66, ~0x66, 0x00, 0xFF, 0xA5, 0x5A, 0xF0, 0x0F + +int main() +{ + const int EEPROM_MEM_ADDR = 0xA0; + int i2c_stat = 0; + bool result = true; + + i2c.frequency(i2c_freq_hz); + + printf("I2C: Lines pattern write test ... "); + + int write_errors = 0; + for (int i = 0; i < ntests; i++) { + char data[] = { 0 /*MSB*/, 0 /*LSB*/, PATTERN_MASK }; + const int addr = i * 8; // 8 bytes of data in data array + data[0] = ((0xFF00 & addr) >> 8) & 0x00FF; + data[1] = (addr & 0x00FF); + + if ((i2c_stat = i2c.write(EEPROM_MEM_ADDR, data, sizeof(data))) != 0) + write_errors++; + + while (i2c.write(EEPROM_MEM_ADDR, NULL, 0)) ; // wait to complete + + // us delay if specified + if (i2c_delay_us != 0) + wait_us(i2c_delay_us); + } + + printf("[%s]\r\n", write_errors ? "FAIL" : "OK"); + printf("I2C: Write errors: %d ... [%s]\r\n", write_errors, write_errors ? "FAIL" : "OK"); + + printf("I2C: Lines pattern read test ... "); + int read_errors = 0; + int pattern_errors = 0; + for (int i = 0; i < ntests; i++) { + char data[8] = { 0 }; // General puspose buffer + const int addr = i * 8; // 8 bytes of data in data array + data[0] = ((0xFF00 & addr) >> 8) & 0x00FF; + data[1] = (addr & 0x00FF); + + // Set address for read + if ((i2c_stat = i2c.write(EEPROM_MEM_ADDR, data, 2, true)) != 0) { + } + + if ((i2c_stat = i2c.read(EEPROM_MEM_ADDR, data, 8)) != 0) + read_errors++; + + static char pattern[] = { PATTERN_MASK }; + if (memcmp(pattern, data, sizeof(data))) + pattern_errors++; + } + + printf("[%s]\r\n", read_errors ? "FAIL" : "OK"); + printf("I2C: Read errors: %d ... [%s]\r\n", read_errors, read_errors ? "FAIL" : "OK"); + printf("EEPROM: Pattern match errors: %d ... [%s]\r\n", pattern_errors, pattern_errors ? "FAIL" : "OK"); + + result = write_errors == 0 && read_errors == 0; + notify_completion(result); +} diff --git a/workspace_tools/tests.py b/workspace_tools/tests.py index fab2cc0530..cc221202d0 100644 --- a/workspace_tools/tests.py +++ b/workspace_tools/tests.py @@ -92,7 +92,7 @@ TESTS = [ "id": "MBED_A3", "description": "C++ STL", "source_dir": join(TEST_DIR, "mbed", "stl"), "dependencies": [MBED_LIBRARIES, TEST_MBED_LIB], - "automated": True, + "automated": False, }, { "id": "MBED_A4", "description": "I2C TMP102", @@ -158,6 +158,7 @@ TESTS = [ "source_dir": join(TEST_DIR, "mbed", "sd"), "dependencies": [MBED_LIBRARIES, TEST_MBED_LIB, SD_FS, FAT_FS], "automated": True, + "duration": 15, "peripherals": ["SD"] }, { @@ -236,6 +237,13 @@ TESTS = [ "mcu": ["LPC1768"], "peripherals": ["extra_serial"] }, + { + "id": "MBED_A25", "description": "I2C EEPROM line read/write test", + "source_dir": join(TEST_DIR, "mbed", "i2c_eeprom_line"), + "dependencies": [MBED_LIBRARIES, TEST_MBED_LIB], + "peripherals": ["24LC256"], + "automated": True, + }, # Size benchmarks { @@ -353,6 +361,7 @@ TESTS = [ "id": "MBED_15", "description": "RPC", "source_dir": join(TEST_DIR, "mbed", "rpc"), "dependencies": [MBED_LIBRARIES, join(LIB_DIR, "rpc"), TEST_MBED_LIB], + "mcu": ["LPC1768"], "automated": True, }, {