High-speed access version sd-driver.
Dependents: SDBlockDevice_GR_PEACH SDBlockDevice_GR_PEACH HagridOS5
This library has modified SDBlockDevice.h based on revision "14: c7dba87" of sd-driver.
https://github.com/ARMmbed/sd-driver
features/TESTS/filesystem/spif/main.cpp@0:b22a1df967cb, 2017-03-23 (annotated)
- Committer:
- dkato
- Date:
- Thu Mar 23 08:25:54 2017 +0000
- Revision:
- 0:b22a1df967cb
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dkato | 0:b22a1df967cb | 1 | #include "mbed.h" |
dkato | 0:b22a1df967cb | 2 | #include "greentea-client/test_env.h" |
dkato | 0:b22a1df967cb | 3 | #include "unity.h" |
dkato | 0:b22a1df967cb | 4 | #include "utest.h" |
dkato | 0:b22a1df967cb | 5 | |
dkato | 0:b22a1df967cb | 6 | #include "SPIFBlockDevice.h" |
dkato | 0:b22a1df967cb | 7 | #include <stdlib.h> |
dkato | 0:b22a1df967cb | 8 | |
dkato | 0:b22a1df967cb | 9 | using namespace utest::v1; |
dkato | 0:b22a1df967cb | 10 | |
dkato | 0:b22a1df967cb | 11 | #ifndef SPIF_INSTALLED |
dkato | 0:b22a1df967cb | 12 | // todo: sdh |
dkato | 0:b22a1df967cb | 13 | //#define SPIF_INSTALLED defined(TARGET_K82F) |
dkato | 0:b22a1df967cb | 14 | #define SPIF_INSTALLED defined(TARGET_K64F) |
dkato | 0:b22a1df967cb | 15 | #endif |
dkato | 0:b22a1df967cb | 16 | |
dkato | 0:b22a1df967cb | 17 | #if !SPIF_INSTALLED |
dkato | 0:b22a1df967cb | 18 | #error [NOT_SUPPORTED] SPIF Required |
dkato | 0:b22a1df967cb | 19 | #endif |
dkato | 0:b22a1df967cb | 20 | |
dkato | 0:b22a1df967cb | 21 | /* |
dkato | 0:b22a1df967cb | 22 | #if defined(TARGET_K82F) |
dkato | 0:b22a1df967cb | 23 | #define TEST_PINS PTE2, PTE4, PTE1, PTE5 |
dkato | 0:b22a1df967cb | 24 | #define TEST_FREQ 40000000 |
dkato | 0:b22a1df967cb | 25 | #else |
dkato | 0:b22a1df967cb | 26 | #define TEST_PINS D11, D12, D13, D10 |
dkato | 0:b22a1df967cb | 27 | #define TEST_FREQ 1000000 |
dkato | 0:b22a1df967cb | 28 | #endif |
dkato | 0:b22a1df967cb | 29 | */ |
dkato | 0:b22a1df967cb | 30 | #if defined(TARGET_K64F) |
dkato | 0:b22a1df967cb | 31 | #define TEST_PINS PTD2, PTD3, PTD1, PTD0 |
dkato | 0:b22a1df967cb | 32 | //#define TEST_FREQ 40000000 |
dkato | 0:b22a1df967cb | 33 | //#define TEST_FREQ 1000000 |
dkato | 0:b22a1df967cb | 34 | #define TEST_FREQ 50000 |
dkato | 0:b22a1df967cb | 35 | #else |
dkato | 0:b22a1df967cb | 36 | #error "no TEST_PINS defined" |
dkato | 0:b22a1df967cb | 37 | #endif |
dkato | 0:b22a1df967cb | 38 | |
dkato | 0:b22a1df967cb | 39 | |
dkato | 0:b22a1df967cb | 40 | #define TEST_BLOCK_COUNT 10 |
dkato | 0:b22a1df967cb | 41 | #define TEST_ERROR_MASK 16 |
dkato | 0:b22a1df967cb | 42 | |
dkato | 0:b22a1df967cb | 43 | /* |
dkato | 0:b22a1df967cb | 44 | const struct { |
dkato | 0:b22a1df967cb | 45 | const char *name; |
dkato | 0:b22a1df967cb | 46 | bd_size_t (BlockDevice::*method)() const; |
dkato | 0:b22a1df967cb | 47 | } ATTRS[] = { |
dkato | 0:b22a1df967cb | 48 | {"read size", &BlockDevice::get_read_size}, |
dkato | 0:b22a1df967cb | 49 | {"program size", &BlockDevice::get_program_size}, |
dkato | 0:b22a1df967cb | 50 | {"erase size", &BlockDevice::get_erase_size}, |
dkato | 0:b22a1df967cb | 51 | {"total size", &BlockDevice::size}, |
dkato | 0:b22a1df967cb | 52 | }; |
dkato | 0:b22a1df967cb | 53 | */ |
dkato | 0:b22a1df967cb | 54 | const struct { |
dkato | 0:b22a1df967cb | 55 | const char *name; |
dkato | 0:b22a1df967cb | 56 | bd_size_t (BlockDevice::*method)() const; |
dkato | 0:b22a1df967cb | 57 | } ATTRS[] = { |
dkato | 0:b22a1df967cb | 58 | {"read size", &BlockDevice::get_read_size}, |
dkato | 0:b22a1df967cb | 59 | {"program size", &BlockDevice::get_program_size}, |
dkato | 0:b22a1df967cb | 60 | {"erase size", &BlockDevice::get_erase_size}, |
dkato | 0:b22a1df967cb | 61 | // {"total size", &BlockDevice::size}, |
dkato | 0:b22a1df967cb | 62 | }; |
dkato | 0:b22a1df967cb | 63 | |
dkato | 0:b22a1df967cb | 64 | // todo: fix me |
dkato | 0:b22a1df967cb | 65 | void test_read_write() { |
dkato | 0:b22a1df967cb | 66 | SPIFBlockDevice bd(TEST_PINS, TEST_FREQ); |
dkato | 0:b22a1df967cb | 67 | |
dkato | 0:b22a1df967cb | 68 | int err = bd.init(); |
dkato | 0:b22a1df967cb | 69 | TEST_ASSERT_EQUAL(0, err); |
dkato | 0:b22a1df967cb | 70 | |
dkato | 0:b22a1df967cb | 71 | for (unsigned a = 0; a < sizeof(ATTRS)/sizeof(ATTRS[0]); a++) { |
dkato | 0:b22a1df967cb | 72 | static const char *prefixes[] = {"", "k", "M", "G"}; |
dkato | 0:b22a1df967cb | 73 | for (int i = 3; i >= 0; i--) { |
dkato | 0:b22a1df967cb | 74 | bd_size_t size = (bd.*ATTRS[a].method)(); |
dkato | 0:b22a1df967cb | 75 | if (size >= (1ULL << 10*i)) { |
dkato | 0:b22a1df967cb | 76 | printf("%s: %llu%sbytes (%llubytes)\n", |
dkato | 0:b22a1df967cb | 77 | ATTRS[a].name, size >> 10*i, prefixes[i], size); |
dkato | 0:b22a1df967cb | 78 | break; |
dkato | 0:b22a1df967cb | 79 | } |
dkato | 0:b22a1df967cb | 80 | } |
dkato | 0:b22a1df967cb | 81 | } |
dkato | 0:b22a1df967cb | 82 | |
dkato | 0:b22a1df967cb | 83 | |
dkato | 0:b22a1df967cb | 84 | bd_size_t block_size = bd.get_erase_size(); |
dkato | 0:b22a1df967cb | 85 | uint8_t *write_block = new uint8_t[block_size]; |
dkato | 0:b22a1df967cb | 86 | uint8_t *read_block = new uint8_t[block_size]; |
dkato | 0:b22a1df967cb | 87 | uint8_t *error_mask = new uint8_t[TEST_ERROR_MASK]; |
dkato | 0:b22a1df967cb | 88 | |
dkato | 0:b22a1df967cb | 89 | #if ! defined(__ARMCC_VERSION) && defined(__GNUC__) |
dkato | 0:b22a1df967cb | 90 | unsigned addrwidth = ceil(log(bd.size()-1) / log(16))+1; |
dkato | 0:b22a1df967cb | 91 | #else |
dkato | 0:b22a1df967cb | 92 | unsigned addrwidth = 0; |
dkato | 0:b22a1df967cb | 93 | #endif |
dkato | 0:b22a1df967cb | 94 | |
dkato | 0:b22a1df967cb | 95 | for (int b = 0; b < TEST_BLOCK_COUNT; b++) { |
dkato | 0:b22a1df967cb | 96 | // Find a random block |
dkato | 0:b22a1df967cb | 97 | bd_addr_t block = (rand()*block_size) % bd.size(); |
dkato | 0:b22a1df967cb | 98 | |
dkato | 0:b22a1df967cb | 99 | // Use next random number as temporary seed to keep |
dkato | 0:b22a1df967cb | 100 | // the address progressing in the pseudorandom sequence |
dkato | 0:b22a1df967cb | 101 | unsigned seed = rand(); |
dkato | 0:b22a1df967cb | 102 | |
dkato | 0:b22a1df967cb | 103 | // Fill with random sequence |
dkato | 0:b22a1df967cb | 104 | srand(seed); |
dkato | 0:b22a1df967cb | 105 | for (bd_size_t i = 0; i < block_size; i++) { |
dkato | 0:b22a1df967cb | 106 | write_block[i] = 0xff & rand(); |
dkato | 0:b22a1df967cb | 107 | } |
dkato | 0:b22a1df967cb | 108 | |
dkato | 0:b22a1df967cb | 109 | // Write, sync, and read the block |
dkato | 0:b22a1df967cb | 110 | printf("test %0*llx:%llu...\n", addrwidth, block, block_size); |
dkato | 0:b22a1df967cb | 111 | |
dkato | 0:b22a1df967cb | 112 | err = bd.program(write_block, block, block_size); |
dkato | 0:b22a1df967cb | 113 | TEST_ASSERT_EQUAL(0, err); |
dkato | 0:b22a1df967cb | 114 | |
dkato | 0:b22a1df967cb | 115 | printf("write %0*llx:%llu ", addrwidth, block, block_size); |
dkato | 0:b22a1df967cb | 116 | for (int i = 0; i < 16; i++) { |
dkato | 0:b22a1df967cb | 117 | printf("%02x", write_block[i]); |
dkato | 0:b22a1df967cb | 118 | } |
dkato | 0:b22a1df967cb | 119 | printf("...\n"); |
dkato | 0:b22a1df967cb | 120 | |
dkato | 0:b22a1df967cb | 121 | err = bd.read(read_block, block, block_size); |
dkato | 0:b22a1df967cb | 122 | TEST_ASSERT_EQUAL(0, err); |
dkato | 0:b22a1df967cb | 123 | |
dkato | 0:b22a1df967cb | 124 | printf("read %0*llx:%llu ", addrwidth, block, block_size); |
dkato | 0:b22a1df967cb | 125 | for (int i = 0; i < 16; i++) { |
dkato | 0:b22a1df967cb | 126 | printf("%02x", read_block[i]); |
dkato | 0:b22a1df967cb | 127 | } |
dkato | 0:b22a1df967cb | 128 | printf("...\n"); |
dkato | 0:b22a1df967cb | 129 | |
dkato | 0:b22a1df967cb | 130 | |
dkato | 0:b22a1df967cb | 131 | //for (int i = 0; i < block_size; i++) { |
dkato | 0:b22a1df967cb | 132 | // printf("%02x:%02x:%s\n", write_block[i], read_block[i], write_block[i] == read_block[i] ? "1" : "0"); |
dkato | 0:b22a1df967cb | 133 | //} |
dkato | 0:b22a1df967cb | 134 | |
dkato | 0:b22a1df967cb | 135 | // Find error mask for debugging |
dkato | 0:b22a1df967cb | 136 | memset(error_mask, 0, TEST_ERROR_MASK); |
dkato | 0:b22a1df967cb | 137 | bd_size_t error_scale = block_size / (TEST_ERROR_MASK*8); |
dkato | 0:b22a1df967cb | 138 | |
dkato | 0:b22a1df967cb | 139 | srand(seed); |
dkato | 0:b22a1df967cb | 140 | for (bd_size_t i = 0; i < TEST_ERROR_MASK*8; i++) { |
dkato | 0:b22a1df967cb | 141 | for (bd_size_t j = 0; j < error_scale; j++) { |
dkato | 0:b22a1df967cb | 142 | if ((0xff & rand()) != read_block[i*error_scale + j]) { |
dkato | 0:b22a1df967cb | 143 | error_mask[i/8] |= 1 << (i%8); |
dkato | 0:b22a1df967cb | 144 | } |
dkato | 0:b22a1df967cb | 145 | } |
dkato | 0:b22a1df967cb | 146 | } |
dkato | 0:b22a1df967cb | 147 | |
dkato | 0:b22a1df967cb | 148 | printf("error %0*llx:%llu ", addrwidth, block, block_size); |
dkato | 0:b22a1df967cb | 149 | for (int i = 0; i < 16; i++) { |
dkato | 0:b22a1df967cb | 150 | printf("%02x", error_mask[i]); |
dkato | 0:b22a1df967cb | 151 | } |
dkato | 0:b22a1df967cb | 152 | printf("\n"); |
dkato | 0:b22a1df967cb | 153 | |
dkato | 0:b22a1df967cb | 154 | // Check that the data was unmodified |
dkato | 0:b22a1df967cb | 155 | srand(seed); |
dkato | 0:b22a1df967cb | 156 | for (bd_size_t i = 0; i < block_size; i++) { |
dkato | 0:b22a1df967cb | 157 | TEST_ASSERT_EQUAL(0xff & rand(), read_block[i]); |
dkato | 0:b22a1df967cb | 158 | } |
dkato | 0:b22a1df967cb | 159 | } |
dkato | 0:b22a1df967cb | 160 | |
dkato | 0:b22a1df967cb | 161 | err = bd.deinit(); |
dkato | 0:b22a1df967cb | 162 | TEST_ASSERT_EQUAL(0, err); |
dkato | 0:b22a1df967cb | 163 | } |
dkato | 0:b22a1df967cb | 164 | |
dkato | 0:b22a1df967cb | 165 | |
dkato | 0:b22a1df967cb | 166 | // Test setup |
dkato | 0:b22a1df967cb | 167 | utest::v1::status_t test_setup(const size_t number_of_cases) { |
dkato | 0:b22a1df967cb | 168 | GREENTEA_SETUP(30, "default_auto"); |
dkato | 0:b22a1df967cb | 169 | return verbose_test_setup_handler(number_of_cases); |
dkato | 0:b22a1df967cb | 170 | } |
dkato | 0:b22a1df967cb | 171 | |
dkato | 0:b22a1df967cb | 172 | Case cases[] = { |
dkato | 0:b22a1df967cb | 173 | Case("Testing read write random blocks", test_read_write), |
dkato | 0:b22a1df967cb | 174 | }; |
dkato | 0:b22a1df967cb | 175 | |
dkato | 0:b22a1df967cb | 176 | Specification specification(test_setup, cases); |
dkato | 0:b22a1df967cb | 177 | |
dkato | 0:b22a1df967cb | 178 | int main() { |
dkato | 0:b22a1df967cb | 179 | return !Harness::run(specification); |
dkato | 0:b22a1df967cb | 180 | } |