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

Committer:
dkato
Date:
Thu Mar 23 08:25:54 2017 +0000
Revision:
0:b22a1df967cb
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew 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 }