Preliminary main mbed library for nexpaq development
TESTS/storage_abstraction/basicAPI/basicAPI.cpp@0:6c56fb4bc5f0, 2016-11-04 (annotated)
- Committer:
- nexpaq
- Date:
- Fri Nov 04 20:27:58 2016 +0000
- Revision:
- 0:6c56fb4bc5f0
Moving to library for sharing updates
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nexpaq | 0:6c56fb4bc5f0 | 1 | /* |
nexpaq | 0:6c56fb4bc5f0 | 2 | * Copyright (c) 2006-2016, ARM Limited, All Rights Reserved |
nexpaq | 0:6c56fb4bc5f0 | 3 | * SPDX-License-Identifier: Apache-2.0 |
nexpaq | 0:6c56fb4bc5f0 | 4 | * |
nexpaq | 0:6c56fb4bc5f0 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may |
nexpaq | 0:6c56fb4bc5f0 | 6 | * not use this file except in compliance with the License. |
nexpaq | 0:6c56fb4bc5f0 | 7 | * You may obtain a copy of the License at |
nexpaq | 0:6c56fb4bc5f0 | 8 | * |
nexpaq | 0:6c56fb4bc5f0 | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
nexpaq | 0:6c56fb4bc5f0 | 10 | * |
nexpaq | 0:6c56fb4bc5f0 | 11 | * Unless required by applicable law or agreed to in writing, software |
nexpaq | 0:6c56fb4bc5f0 | 12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
nexpaq | 0:6c56fb4bc5f0 | 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
nexpaq | 0:6c56fb4bc5f0 | 14 | * See the License for the specific language governing permissions and |
nexpaq | 0:6c56fb4bc5f0 | 15 | * limitations under the License. |
nexpaq | 0:6c56fb4bc5f0 | 16 | */ |
nexpaq | 0:6c56fb4bc5f0 | 17 | |
nexpaq | 0:6c56fb4bc5f0 | 18 | #if !DEVICE_STORAGE |
nexpaq | 0:6c56fb4bc5f0 | 19 | #error [NOT_SUPPORTED] Storage not supported for this target |
nexpaq | 0:6c56fb4bc5f0 | 20 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 21 | |
nexpaq | 0:6c56fb4bc5f0 | 22 | #ifndef AVOID_GREENTEA |
nexpaq | 0:6c56fb4bc5f0 | 23 | #include "greentea-client/test_env.h" |
nexpaq | 0:6c56fb4bc5f0 | 24 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 25 | #include "utest/utest.h" |
nexpaq | 0:6c56fb4bc5f0 | 26 | #include "unity/unity.h" |
nexpaq | 0:6c56fb4bc5f0 | 27 | |
nexpaq | 0:6c56fb4bc5f0 | 28 | #include "storage_abstraction/Driver_Storage.h" |
nexpaq | 0:6c56fb4bc5f0 | 29 | |
nexpaq | 0:6c56fb4bc5f0 | 30 | #include <string.h> |
nexpaq | 0:6c56fb4bc5f0 | 31 | #include <inttypes.h> |
nexpaq | 0:6c56fb4bc5f0 | 32 | |
nexpaq | 0:6c56fb4bc5f0 | 33 | using namespace utest::v1; |
nexpaq | 0:6c56fb4bc5f0 | 34 | |
nexpaq | 0:6c56fb4bc5f0 | 35 | extern ARM_DRIVER_STORAGE ARM_Driver_Storage_(0); |
nexpaq | 0:6c56fb4bc5f0 | 36 | ARM_DRIVER_STORAGE *drv = &ARM_Driver_Storage_(0); |
nexpaq | 0:6c56fb4bc5f0 | 37 | |
nexpaq | 0:6c56fb4bc5f0 | 38 | /* temporary buffer to hold data for testing. */ |
nexpaq | 0:6c56fb4bc5f0 | 39 | static const unsigned BUFFER_SIZE = 16384; |
nexpaq | 0:6c56fb4bc5f0 | 40 | static uint8_t buffer[BUFFER_SIZE]; |
nexpaq | 0:6c56fb4bc5f0 | 41 | |
nexpaq | 0:6c56fb4bc5f0 | 42 | /* forward declaration */ |
nexpaq | 0:6c56fb4bc5f0 | 43 | void initializationCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation); |
nexpaq | 0:6c56fb4bc5f0 | 44 | |
nexpaq | 0:6c56fb4bc5f0 | 45 | /* |
nexpaq | 0:6c56fb4bc5f0 | 46 | * Most tests need some basic initialization of the driver before proceeding |
nexpaq | 0:6c56fb4bc5f0 | 47 | * with their operations. |
nexpaq | 0:6c56fb4bc5f0 | 48 | */ |
nexpaq | 0:6c56fb4bc5f0 | 49 | static control_t preambleForBasicInitialization(void) |
nexpaq | 0:6c56fb4bc5f0 | 50 | { |
nexpaq | 0:6c56fb4bc5f0 | 51 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 52 | |
nexpaq | 0:6c56fb4bc5f0 | 53 | int32_t rc = drv->Initialize(initializationCompleteCallback); |
nexpaq | 0:6c56fb4bc5f0 | 54 | TEST_ASSERT(rc >= ARM_DRIVER_OK); |
nexpaq | 0:6c56fb4bc5f0 | 55 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 56 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 57 | return CaseTimeout(200) + CaseRepeatAll; |
nexpaq | 0:6c56fb4bc5f0 | 58 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 59 | TEST_ASSERT(rc == 1); |
nexpaq | 0:6c56fb4bc5f0 | 60 | return CaseRepeatAll; |
nexpaq | 0:6c56fb4bc5f0 | 61 | } |
nexpaq | 0:6c56fb4bc5f0 | 62 | } |
nexpaq | 0:6c56fb4bc5f0 | 63 | |
nexpaq | 0:6c56fb4bc5f0 | 64 | template<typename T> |
nexpaq | 0:6c56fb4bc5f0 | 65 | static void verifyBytePattern(uint64_t addr, size_t sizeofData, T bytePattern) |
nexpaq | 0:6c56fb4bc5f0 | 66 | { |
nexpaq | 0:6c56fb4bc5f0 | 67 | /* we're limited by BUFFER_SIZE in how much we can verify in a single iteration; |
nexpaq | 0:6c56fb4bc5f0 | 68 | * the variable 'amountBeingVerified' captures the size being verified in each |
nexpaq | 0:6c56fb4bc5f0 | 69 | * iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 70 | size_t amountBeingVerified = sizeofData; |
nexpaq | 0:6c56fb4bc5f0 | 71 | if (amountBeingVerified > BUFFER_SIZE) { |
nexpaq | 0:6c56fb4bc5f0 | 72 | amountBeingVerified = BUFFER_SIZE; |
nexpaq | 0:6c56fb4bc5f0 | 73 | } |
nexpaq | 0:6c56fb4bc5f0 | 74 | TEST_ASSERT((amountBeingVerified % sizeof(T)) == 0); |
nexpaq | 0:6c56fb4bc5f0 | 75 | |
nexpaq | 0:6c56fb4bc5f0 | 76 | while (sizeofData) { |
nexpaq | 0:6c56fb4bc5f0 | 77 | int32_t rc = drv->ReadData(addr, buffer, amountBeingVerified); |
nexpaq | 0:6c56fb4bc5f0 | 78 | TEST_ASSERT_EQUAL(amountBeingVerified, rc); |
nexpaq | 0:6c56fb4bc5f0 | 79 | for (size_t index = 0; index < amountBeingVerified / sizeof(T); index++) { |
nexpaq | 0:6c56fb4bc5f0 | 80 | // if (bytePattern != ((const T *)buffer)[index]) { |
nexpaq | 0:6c56fb4bc5f0 | 81 | // printf("%u: expected %x, found %x\n", index, bytePattern, ((const T *)buffer)[index]); |
nexpaq | 0:6c56fb4bc5f0 | 82 | // } |
nexpaq | 0:6c56fb4bc5f0 | 83 | TEST_ASSERT_EQUAL(bytePattern, ((const T *)buffer)[index]); |
nexpaq | 0:6c56fb4bc5f0 | 84 | } |
nexpaq | 0:6c56fb4bc5f0 | 85 | |
nexpaq | 0:6c56fb4bc5f0 | 86 | sizeofData -= amountBeingVerified; |
nexpaq | 0:6c56fb4bc5f0 | 87 | addr += amountBeingVerified; |
nexpaq | 0:6c56fb4bc5f0 | 88 | } |
nexpaq | 0:6c56fb4bc5f0 | 89 | } |
nexpaq | 0:6c56fb4bc5f0 | 90 | |
nexpaq | 0:6c56fb4bc5f0 | 91 | void test_getVersion() |
nexpaq | 0:6c56fb4bc5f0 | 92 | { |
nexpaq | 0:6c56fb4bc5f0 | 93 | ARM_DRIVER_VERSION version = drv->GetVersion(); |
nexpaq | 0:6c56fb4bc5f0 | 94 | |
nexpaq | 0:6c56fb4bc5f0 | 95 | TEST_ASSERT_EQUAL(version.api, ARM_STORAGE_API_VERSION); |
nexpaq | 0:6c56fb4bc5f0 | 96 | TEST_ASSERT_EQUAL(version.drv, ARM_DRIVER_VERSION_MAJOR_MINOR(1,00)); |
nexpaq | 0:6c56fb4bc5f0 | 97 | } |
nexpaq | 0:6c56fb4bc5f0 | 98 | |
nexpaq | 0:6c56fb4bc5f0 | 99 | void test_getCapabilities() |
nexpaq | 0:6c56fb4bc5f0 | 100 | { |
nexpaq | 0:6c56fb4bc5f0 | 101 | TEST_ASSERT(sizeof(ARM_STORAGE_CAPABILITIES) == sizeof(uint32_t)); |
nexpaq | 0:6c56fb4bc5f0 | 102 | |
nexpaq | 0:6c56fb4bc5f0 | 103 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 104 | TEST_ASSERT_EQUAL(0, capabilities.reserved); |
nexpaq | 0:6c56fb4bc5f0 | 105 | } |
nexpaq | 0:6c56fb4bc5f0 | 106 | |
nexpaq | 0:6c56fb4bc5f0 | 107 | void test_getInfo() |
nexpaq | 0:6c56fb4bc5f0 | 108 | { |
nexpaq | 0:6c56fb4bc5f0 | 109 | ARM_STORAGE_INFO info = {}; |
nexpaq | 0:6c56fb4bc5f0 | 110 | int32_t rc = drv->GetInfo(&info); |
nexpaq | 0:6c56fb4bc5f0 | 111 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 112 | |
nexpaq | 0:6c56fb4bc5f0 | 113 | TEST_ASSERT_EQUAL(0, info.security.reserved1); |
nexpaq | 0:6c56fb4bc5f0 | 114 | TEST_ASSERT_EQUAL(0, info.security.reserved2); |
nexpaq | 0:6c56fb4bc5f0 | 115 | TEST_ASSERT(info.total_storage > 0); |
nexpaq | 0:6c56fb4bc5f0 | 116 | } |
nexpaq | 0:6c56fb4bc5f0 | 117 | |
nexpaq | 0:6c56fb4bc5f0 | 118 | void initializationCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation) |
nexpaq | 0:6c56fb4bc5f0 | 119 | { |
nexpaq | 0:6c56fb4bc5f0 | 120 | printf("init complete callback\n"); |
nexpaq | 0:6c56fb4bc5f0 | 121 | TEST_ASSERT_EQUAL(1, status); |
nexpaq | 0:6c56fb4bc5f0 | 122 | TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_INITIALIZE); |
nexpaq | 0:6c56fb4bc5f0 | 123 | |
nexpaq | 0:6c56fb4bc5f0 | 124 | Harness::validate_callback(); |
nexpaq | 0:6c56fb4bc5f0 | 125 | } |
nexpaq | 0:6c56fb4bc5f0 | 126 | |
nexpaq | 0:6c56fb4bc5f0 | 127 | control_t test_initialize(const size_t call_count) |
nexpaq | 0:6c56fb4bc5f0 | 128 | { |
nexpaq | 0:6c56fb4bc5f0 | 129 | static const unsigned REPEAT_INSTANCES = 3; |
nexpaq | 0:6c56fb4bc5f0 | 130 | printf("in test_initialize with call_count %u\n", call_count); |
nexpaq | 0:6c56fb4bc5f0 | 131 | |
nexpaq | 0:6c56fb4bc5f0 | 132 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 133 | |
nexpaq | 0:6c56fb4bc5f0 | 134 | int32_t rc = drv->Initialize(initializationCompleteCallback); |
nexpaq | 0:6c56fb4bc5f0 | 135 | TEST_ASSERT(rc >= ARM_DRIVER_OK); |
nexpaq | 0:6c56fb4bc5f0 | 136 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 137 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 138 | return (call_count < REPEAT_INSTANCES) ? (CaseTimeout(200) + CaseRepeatAll) : (control_t) CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 139 | } |
nexpaq | 0:6c56fb4bc5f0 | 140 | |
nexpaq | 0:6c56fb4bc5f0 | 141 | TEST_ASSERT(rc == 1); |
nexpaq | 0:6c56fb4bc5f0 | 142 | return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 143 | } |
nexpaq | 0:6c56fb4bc5f0 | 144 | |
nexpaq | 0:6c56fb4bc5f0 | 145 | void uninitializationCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation) |
nexpaq | 0:6c56fb4bc5f0 | 146 | { |
nexpaq | 0:6c56fb4bc5f0 | 147 | printf("uninit complete callback\n"); |
nexpaq | 0:6c56fb4bc5f0 | 148 | TEST_ASSERT_EQUAL(status, ARM_DRIVER_OK); |
nexpaq | 0:6c56fb4bc5f0 | 149 | TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_UNINITIALIZE); |
nexpaq | 0:6c56fb4bc5f0 | 150 | |
nexpaq | 0:6c56fb4bc5f0 | 151 | Harness::validate_callback(); |
nexpaq | 0:6c56fb4bc5f0 | 152 | } |
nexpaq | 0:6c56fb4bc5f0 | 153 | |
nexpaq | 0:6c56fb4bc5f0 | 154 | control_t test_uninitialize(const size_t call_count) |
nexpaq | 0:6c56fb4bc5f0 | 155 | { |
nexpaq | 0:6c56fb4bc5f0 | 156 | static const unsigned REPEAT_INSTANCES = 3; |
nexpaq | 0:6c56fb4bc5f0 | 157 | printf("in test_uninitialize with call_count %u\n", call_count); |
nexpaq | 0:6c56fb4bc5f0 | 158 | |
nexpaq | 0:6c56fb4bc5f0 | 159 | /* update the completion callback. */ |
nexpaq | 0:6c56fb4bc5f0 | 160 | if (call_count == 1) { |
nexpaq | 0:6c56fb4bc5f0 | 161 | /* Achieve basic initialization for the driver before anything else. */ |
nexpaq | 0:6c56fb4bc5f0 | 162 | return preambleForBasicInitialization(); |
nexpaq | 0:6c56fb4bc5f0 | 163 | } |
nexpaq | 0:6c56fb4bc5f0 | 164 | |
nexpaq | 0:6c56fb4bc5f0 | 165 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 166 | |
nexpaq | 0:6c56fb4bc5f0 | 167 | int32_t rc = drv->Uninitialize(); |
nexpaq | 0:6c56fb4bc5f0 | 168 | if (call_count > 2) { |
nexpaq | 0:6c56fb4bc5f0 | 169 | /* the driver should return some error for repeated un-initialization. */ |
nexpaq | 0:6c56fb4bc5f0 | 170 | TEST_ASSERT(rc < ARM_DRIVER_OK); |
nexpaq | 0:6c56fb4bc5f0 | 171 | return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 172 | } |
nexpaq | 0:6c56fb4bc5f0 | 173 | TEST_ASSERT(rc >= ARM_DRIVER_OK); |
nexpaq | 0:6c56fb4bc5f0 | 174 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 175 | /* asynchronous operation */ |
nexpaq | 0:6c56fb4bc5f0 | 176 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 177 | return CaseTimeout(200) + CaseRepeatAll; |
nexpaq | 0:6c56fb4bc5f0 | 178 | } |
nexpaq | 0:6c56fb4bc5f0 | 179 | |
nexpaq | 0:6c56fb4bc5f0 | 180 | /* synchronous operation */ |
nexpaq | 0:6c56fb4bc5f0 | 181 | TEST_ASSERT(rc == 1); |
nexpaq | 0:6c56fb4bc5f0 | 182 | return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 183 | } |
nexpaq | 0:6c56fb4bc5f0 | 184 | |
nexpaq | 0:6c56fb4bc5f0 | 185 | void powerControlCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation) |
nexpaq | 0:6c56fb4bc5f0 | 186 | { |
nexpaq | 0:6c56fb4bc5f0 | 187 | printf("power control complete callback\n"); |
nexpaq | 0:6c56fb4bc5f0 | 188 | TEST_ASSERT_EQUAL(status, ARM_DRIVER_OK); |
nexpaq | 0:6c56fb4bc5f0 | 189 | TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_POWER_CONTROL); |
nexpaq | 0:6c56fb4bc5f0 | 190 | |
nexpaq | 0:6c56fb4bc5f0 | 191 | Harness::validate_callback(); |
nexpaq | 0:6c56fb4bc5f0 | 192 | } |
nexpaq | 0:6c56fb4bc5f0 | 193 | |
nexpaq | 0:6c56fb4bc5f0 | 194 | control_t test_powerControl(const size_t call_count) |
nexpaq | 0:6c56fb4bc5f0 | 195 | { |
nexpaq | 0:6c56fb4bc5f0 | 196 | static const unsigned REPEAT_INSTANCES = 2; |
nexpaq | 0:6c56fb4bc5f0 | 197 | printf("in test_powerControl with call_count %u\n", call_count); |
nexpaq | 0:6c56fb4bc5f0 | 198 | |
nexpaq | 0:6c56fb4bc5f0 | 199 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 200 | |
nexpaq | 0:6c56fb4bc5f0 | 201 | if (call_count == 1) { |
nexpaq | 0:6c56fb4bc5f0 | 202 | /* Achieve basic initialization for the driver before anything else. */ |
nexpaq | 0:6c56fb4bc5f0 | 203 | return preambleForBasicInitialization(); |
nexpaq | 0:6c56fb4bc5f0 | 204 | } |
nexpaq | 0:6c56fb4bc5f0 | 205 | |
nexpaq | 0:6c56fb4bc5f0 | 206 | /* Update the completion callback to 'powerControlCompleteCallback'. */ |
nexpaq | 0:6c56fb4bc5f0 | 207 | if (call_count == 2) { |
nexpaq | 0:6c56fb4bc5f0 | 208 | int32_t rc = drv->Initialize(powerControlCompleteCallback); |
nexpaq | 0:6c56fb4bc5f0 | 209 | TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been |
nexpaq | 0:6c56fb4bc5f0 | 210 | * initialized by the previous iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 211 | } |
nexpaq | 0:6c56fb4bc5f0 | 212 | |
nexpaq | 0:6c56fb4bc5f0 | 213 | int32_t rc = drv->PowerControl(ARM_POWER_FULL); |
nexpaq | 0:6c56fb4bc5f0 | 214 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 215 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 216 | return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200); |
nexpaq | 0:6c56fb4bc5f0 | 217 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 218 | TEST_ASSERT(rc == 1); |
nexpaq | 0:6c56fb4bc5f0 | 219 | return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 220 | } |
nexpaq | 0:6c56fb4bc5f0 | 221 | } |
nexpaq | 0:6c56fb4bc5f0 | 222 | |
nexpaq | 0:6c56fb4bc5f0 | 223 | void readDataCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation) |
nexpaq | 0:6c56fb4bc5f0 | 224 | { |
nexpaq | 0:6c56fb4bc5f0 | 225 | printf("ReadData complete callback\n"); |
nexpaq | 0:6c56fb4bc5f0 | 226 | TEST_ASSERT_EQUAL(status, ARM_DRIVER_OK); |
nexpaq | 0:6c56fb4bc5f0 | 227 | TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_READ_DATA); |
nexpaq | 0:6c56fb4bc5f0 | 228 | |
nexpaq | 0:6c56fb4bc5f0 | 229 | Harness::validate_callback(); |
nexpaq | 0:6c56fb4bc5f0 | 230 | } |
nexpaq | 0:6c56fb4bc5f0 | 231 | |
nexpaq | 0:6c56fb4bc5f0 | 232 | control_t test_readData(const size_t call_count) |
nexpaq | 0:6c56fb4bc5f0 | 233 | { |
nexpaq | 0:6c56fb4bc5f0 | 234 | static const unsigned REPEAT_INSTANCES = 5; |
nexpaq | 0:6c56fb4bc5f0 | 235 | printf("in test_readData with call_count %u\n", call_count); |
nexpaq | 0:6c56fb4bc5f0 | 236 | |
nexpaq | 0:6c56fb4bc5f0 | 237 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 238 | |
nexpaq | 0:6c56fb4bc5f0 | 239 | if (call_count == 1) { |
nexpaq | 0:6c56fb4bc5f0 | 240 | /* Achieve basic initialization for the driver before anything else. */ |
nexpaq | 0:6c56fb4bc5f0 | 241 | return preambleForBasicInitialization(); |
nexpaq | 0:6c56fb4bc5f0 | 242 | } |
nexpaq | 0:6c56fb4bc5f0 | 243 | |
nexpaq | 0:6c56fb4bc5f0 | 244 | /* Update the completion callback to 'readDataCompleteCallback'. */ |
nexpaq | 0:6c56fb4bc5f0 | 245 | int32_t rc; |
nexpaq | 0:6c56fb4bc5f0 | 246 | if (call_count == 2) { |
nexpaq | 0:6c56fb4bc5f0 | 247 | rc = drv->Initialize(readDataCompleteCallback); |
nexpaq | 0:6c56fb4bc5f0 | 248 | TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been |
nexpaq | 0:6c56fb4bc5f0 | 249 | * initialized by the previous iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 250 | } |
nexpaq | 0:6c56fb4bc5f0 | 251 | |
nexpaq | 0:6c56fb4bc5f0 | 252 | /* Get the first block. */ |
nexpaq | 0:6c56fb4bc5f0 | 253 | ARM_STORAGE_BLOCK firstBlock; |
nexpaq | 0:6c56fb4bc5f0 | 254 | drv->GetNextBlock(NULL, &firstBlock); /* get first block */ |
nexpaq | 0:6c56fb4bc5f0 | 255 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); |
nexpaq | 0:6c56fb4bc5f0 | 256 | TEST_ASSERT(firstBlock.size > 0); |
nexpaq | 0:6c56fb4bc5f0 | 257 | |
nexpaq | 0:6c56fb4bc5f0 | 258 | ARM_STORAGE_INFO info; |
nexpaq | 0:6c56fb4bc5f0 | 259 | rc = drv->GetInfo(&info); |
nexpaq | 0:6c56fb4bc5f0 | 260 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 261 | |
nexpaq | 0:6c56fb4bc5f0 | 262 | TEST_ASSERT(info.program_unit <= BUFFER_SIZE); |
nexpaq | 0:6c56fb4bc5f0 | 263 | TEST_ASSERT(firstBlock.size >= (REPEAT_INSTANCES - 1) * info.program_unit); |
nexpaq | 0:6c56fb4bc5f0 | 264 | |
nexpaq | 0:6c56fb4bc5f0 | 265 | /* choose an increasing address for each iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 266 | uint64_t addr = firstBlock.addr + (call_count - 1) * info.program_unit; |
nexpaq | 0:6c56fb4bc5f0 | 267 | size_t sizeofData = info.program_unit; |
nexpaq | 0:6c56fb4bc5f0 | 268 | |
nexpaq | 0:6c56fb4bc5f0 | 269 | rc = drv->ReadData(addr, buffer, sizeofData); |
nexpaq | 0:6c56fb4bc5f0 | 270 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 271 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 272 | return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200); |
nexpaq | 0:6c56fb4bc5f0 | 273 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 274 | TEST_ASSERT(rc > 0); |
nexpaq | 0:6c56fb4bc5f0 | 275 | return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 276 | } |
nexpaq | 0:6c56fb4bc5f0 | 277 | } |
nexpaq | 0:6c56fb4bc5f0 | 278 | |
nexpaq | 0:6c56fb4bc5f0 | 279 | void programDataCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation) |
nexpaq | 0:6c56fb4bc5f0 | 280 | { |
nexpaq | 0:6c56fb4bc5f0 | 281 | TEST_ASSERT(status >= 0); |
nexpaq | 0:6c56fb4bc5f0 | 282 | static unsigned programIteration = 0; |
nexpaq | 0:6c56fb4bc5f0 | 283 | |
nexpaq | 0:6c56fb4bc5f0 | 284 | static const uint32_t BYTE_PATTERN = 0xAA551122; |
nexpaq | 0:6c56fb4bc5f0 | 285 | ARM_STORAGE_BLOCK firstBlock; |
nexpaq | 0:6c56fb4bc5f0 | 286 | drv->GetNextBlock(NULL, &firstBlock); /* get first block */ |
nexpaq | 0:6c56fb4bc5f0 | 287 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); |
nexpaq | 0:6c56fb4bc5f0 | 288 | |
nexpaq | 0:6c56fb4bc5f0 | 289 | ARM_STORAGE_INFO info; |
nexpaq | 0:6c56fb4bc5f0 | 290 | int32_t rc = drv->GetInfo(&info); |
nexpaq | 0:6c56fb4bc5f0 | 291 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 292 | |
nexpaq | 0:6c56fb4bc5f0 | 293 | const uint64_t addr = firstBlock.addr + programIteration * firstBlock.attributes.erase_unit; |
nexpaq | 0:6c56fb4bc5f0 | 294 | size_t sizeofData = info.program_unit; |
nexpaq | 0:6c56fb4bc5f0 | 295 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 296 | |
nexpaq | 0:6c56fb4bc5f0 | 297 | TEST_ASSERT((operation == ARM_STORAGE_OPERATION_ERASE) || (operation == ARM_STORAGE_OPERATION_PROGRAM_DATA)); |
nexpaq | 0:6c56fb4bc5f0 | 298 | if (operation == ARM_STORAGE_OPERATION_ERASE) { |
nexpaq | 0:6c56fb4bc5f0 | 299 | // printf("programming %u bytes at address %lu with pattern 0x%" PRIx32 "\n", sizeofData, (uint32_t)addr, BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 300 | |
nexpaq | 0:6c56fb4bc5f0 | 301 | size_t sizeofData = info.program_unit; |
nexpaq | 0:6c56fb4bc5f0 | 302 | TEST_ASSERT(BUFFER_SIZE >= sizeofData); |
nexpaq | 0:6c56fb4bc5f0 | 303 | TEST_ASSERT((sizeofData % sizeof(uint32_t)) == 0); |
nexpaq | 0:6c56fb4bc5f0 | 304 | for (size_t index = 0; index < sizeofData / sizeof(uint32_t); index++) { |
nexpaq | 0:6c56fb4bc5f0 | 305 | ((uint32_t *)buffer)[index] = BYTE_PATTERN; |
nexpaq | 0:6c56fb4bc5f0 | 306 | } |
nexpaq | 0:6c56fb4bc5f0 | 307 | |
nexpaq | 0:6c56fb4bc5f0 | 308 | status = drv->ProgramData(addr, buffer, sizeofData); |
nexpaq | 0:6c56fb4bc5f0 | 309 | if (status < ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 310 | return; /* failure. this will trigger a timeout and cause test failure. */ |
nexpaq | 0:6c56fb4bc5f0 | 311 | } |
nexpaq | 0:6c56fb4bc5f0 | 312 | if (status == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 313 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 314 | return; /* We've successfully pended a programData operation; we'll have another |
nexpaq | 0:6c56fb4bc5f0 | 315 | * invocation of this callback when programming completes. */ |
nexpaq | 0:6c56fb4bc5f0 | 316 | } |
nexpaq | 0:6c56fb4bc5f0 | 317 | } |
nexpaq | 0:6c56fb4bc5f0 | 318 | |
nexpaq | 0:6c56fb4bc5f0 | 319 | /* We come here either because of completion for program-data or as a very |
nexpaq | 0:6c56fb4bc5f0 | 320 | * unlikely fall through from synchronous completion of program-data (above). */ |
nexpaq | 0:6c56fb4bc5f0 | 321 | |
nexpaq | 0:6c56fb4bc5f0 | 322 | #ifndef __CC_ARM |
nexpaq | 0:6c56fb4bc5f0 | 323 | printf("verifying programmed sector at addr %lu\n", (uint32_t)addr); |
nexpaq | 0:6c56fb4bc5f0 | 324 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 325 | verifyBytePattern(addr, sizeofData, BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 326 | ++programIteration; |
nexpaq | 0:6c56fb4bc5f0 | 327 | |
nexpaq | 0:6c56fb4bc5f0 | 328 | Harness::validate_callback(); |
nexpaq | 0:6c56fb4bc5f0 | 329 | } |
nexpaq | 0:6c56fb4bc5f0 | 330 | |
nexpaq | 0:6c56fb4bc5f0 | 331 | control_t test_programDataUsingProgramUnit(const size_t call_count) |
nexpaq | 0:6c56fb4bc5f0 | 332 | { |
nexpaq | 0:6c56fb4bc5f0 | 333 | static const unsigned REPEAT_INSTANCES = 5; |
nexpaq | 0:6c56fb4bc5f0 | 334 | printf("in test_programDataUsingProgramUnit with call_count %u\n", call_count); |
nexpaq | 0:6c56fb4bc5f0 | 335 | |
nexpaq | 0:6c56fb4bc5f0 | 336 | if (call_count == 1) { |
nexpaq | 0:6c56fb4bc5f0 | 337 | /* Achieve basic initialization for the driver before anything else. */ |
nexpaq | 0:6c56fb4bc5f0 | 338 | return preambleForBasicInitialization(); |
nexpaq | 0:6c56fb4bc5f0 | 339 | } |
nexpaq | 0:6c56fb4bc5f0 | 340 | |
nexpaq | 0:6c56fb4bc5f0 | 341 | /* Get the first block. */ |
nexpaq | 0:6c56fb4bc5f0 | 342 | ARM_STORAGE_BLOCK firstBlock; |
nexpaq | 0:6c56fb4bc5f0 | 343 | drv->GetNextBlock(NULL, &firstBlock); /* get first block */ |
nexpaq | 0:6c56fb4bc5f0 | 344 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); |
nexpaq | 0:6c56fb4bc5f0 | 345 | TEST_ASSERT(firstBlock.size > 0); |
nexpaq | 0:6c56fb4bc5f0 | 346 | |
nexpaq | 0:6c56fb4bc5f0 | 347 | ARM_STORAGE_INFO info; |
nexpaq | 0:6c56fb4bc5f0 | 348 | int32_t rc = drv->GetInfo(&info); |
nexpaq | 0:6c56fb4bc5f0 | 349 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 350 | |
nexpaq | 0:6c56fb4bc5f0 | 351 | TEST_ASSERT(info.program_unit <= firstBlock.attributes.erase_unit); |
nexpaq | 0:6c56fb4bc5f0 | 352 | TEST_ASSERT(firstBlock.size >= (REPEAT_INSTANCES - 1) * firstBlock.attributes.erase_unit); |
nexpaq | 0:6c56fb4bc5f0 | 353 | |
nexpaq | 0:6c56fb4bc5f0 | 354 | /* initialize the buffer to hold the pattern. */ |
nexpaq | 0:6c56fb4bc5f0 | 355 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 356 | |
nexpaq | 0:6c56fb4bc5f0 | 357 | /* Update the completion callback to 'programDataCompleteCallback'. */ |
nexpaq | 0:6c56fb4bc5f0 | 358 | if (call_count == 2) { |
nexpaq | 0:6c56fb4bc5f0 | 359 | int32_t rc = drv->Initialize(programDataCompleteCallback); |
nexpaq | 0:6c56fb4bc5f0 | 360 | TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been |
nexpaq | 0:6c56fb4bc5f0 | 361 | * initialized by the previous iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 362 | } |
nexpaq | 0:6c56fb4bc5f0 | 363 | |
nexpaq | 0:6c56fb4bc5f0 | 364 | /* choose an increasing address for each iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 365 | uint64_t addr = firstBlock.addr + (call_count - 2) * firstBlock.attributes.erase_unit; |
nexpaq | 0:6c56fb4bc5f0 | 366 | |
nexpaq | 0:6c56fb4bc5f0 | 367 | /* erase the sector at 'addr' */ |
nexpaq | 0:6c56fb4bc5f0 | 368 | printf("erasing sector at addr %lu\n", (uint32_t)addr); |
nexpaq | 0:6c56fb4bc5f0 | 369 | rc = drv->Erase(addr, firstBlock.attributes.erase_unit); |
nexpaq | 0:6c56fb4bc5f0 | 370 | TEST_ASSERT(rc >= 0); |
nexpaq | 0:6c56fb4bc5f0 | 371 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 372 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 373 | return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200); |
nexpaq | 0:6c56fb4bc5f0 | 374 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 375 | TEST_ASSERT_EQUAL(firstBlock.attributes.erase_unit, rc); |
nexpaq | 0:6c56fb4bc5f0 | 376 | verifyBytePattern(addr, firstBlock.attributes.erase_unit, (uint8_t)0xFF); |
nexpaq | 0:6c56fb4bc5f0 | 377 | |
nexpaq | 0:6c56fb4bc5f0 | 378 | static const uint32_t BYTE_PATTERN = 0xAA551122; |
nexpaq | 0:6c56fb4bc5f0 | 379 | size_t sizeofData = info.program_unit; |
nexpaq | 0:6c56fb4bc5f0 | 380 | TEST_ASSERT(BUFFER_SIZE >= sizeofData); |
nexpaq | 0:6c56fb4bc5f0 | 381 | TEST_ASSERT((sizeofData % sizeof(uint32_t)) == 0); |
nexpaq | 0:6c56fb4bc5f0 | 382 | for (size_t index = 0; index < sizeofData / sizeof(uint32_t); index++) { |
nexpaq | 0:6c56fb4bc5f0 | 383 | ((uint32_t *)buffer)[index] = BYTE_PATTERN; |
nexpaq | 0:6c56fb4bc5f0 | 384 | } |
nexpaq | 0:6c56fb4bc5f0 | 385 | |
nexpaq | 0:6c56fb4bc5f0 | 386 | /* program the sector at addr */ |
nexpaq | 0:6c56fb4bc5f0 | 387 | // printf("programming %u bytes at address %lu with pattern 0x%" PRIx32 "\n", sizeofData, (uint32_t)addr, BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 388 | rc = drv->ProgramData((uint32_t)addr, buffer, sizeofData); |
nexpaq | 0:6c56fb4bc5f0 | 389 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 390 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 391 | return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200); |
nexpaq | 0:6c56fb4bc5f0 | 392 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 393 | TEST_ASSERT(rc > 0); |
nexpaq | 0:6c56fb4bc5f0 | 394 | |
nexpaq | 0:6c56fb4bc5f0 | 395 | printf("verifying programmed sector at addr %lu\n", (uint32_t)addr); |
nexpaq | 0:6c56fb4bc5f0 | 396 | verifyBytePattern(addr, sizeofData, BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 397 | |
nexpaq | 0:6c56fb4bc5f0 | 398 | return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 399 | } |
nexpaq | 0:6c56fb4bc5f0 | 400 | } |
nexpaq | 0:6c56fb4bc5f0 | 401 | } |
nexpaq | 0:6c56fb4bc5f0 | 402 | |
nexpaq | 0:6c56fb4bc5f0 | 403 | void programDataOptimalCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation) |
nexpaq | 0:6c56fb4bc5f0 | 404 | { |
nexpaq | 0:6c56fb4bc5f0 | 405 | TEST_ASSERT(status >= 0); |
nexpaq | 0:6c56fb4bc5f0 | 406 | static unsigned programIteration = 0; |
nexpaq | 0:6c56fb4bc5f0 | 407 | |
nexpaq | 0:6c56fb4bc5f0 | 408 | static const uint8_t BYTE_PATTERN = 0xAA; |
nexpaq | 0:6c56fb4bc5f0 | 409 | ARM_STORAGE_BLOCK firstBlock; |
nexpaq | 0:6c56fb4bc5f0 | 410 | drv->GetNextBlock(NULL, &firstBlock); /* get first block */ |
nexpaq | 0:6c56fb4bc5f0 | 411 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); |
nexpaq | 0:6c56fb4bc5f0 | 412 | const uint64_t addr = firstBlock.addr + programIteration * firstBlock.attributes.erase_unit; |
nexpaq | 0:6c56fb4bc5f0 | 413 | |
nexpaq | 0:6c56fb4bc5f0 | 414 | ARM_STORAGE_INFO info; |
nexpaq | 0:6c56fb4bc5f0 | 415 | int32_t rc = drv->GetInfo(&info); |
nexpaq | 0:6c56fb4bc5f0 | 416 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 417 | |
nexpaq | 0:6c56fb4bc5f0 | 418 | size_t sizeofData = info.optimal_program_unit; |
nexpaq | 0:6c56fb4bc5f0 | 419 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 420 | |
nexpaq | 0:6c56fb4bc5f0 | 421 | TEST_ASSERT((operation == ARM_STORAGE_OPERATION_ERASE) || (operation == ARM_STORAGE_OPERATION_PROGRAM_DATA)); |
nexpaq | 0:6c56fb4bc5f0 | 422 | if (operation == ARM_STORAGE_OPERATION_ERASE) { |
nexpaq | 0:6c56fb4bc5f0 | 423 | #ifndef __CC_ARM |
nexpaq | 0:6c56fb4bc5f0 | 424 | printf("programming %u bytes at address %lu with pattern 0x%x\n", sizeofData, (uint32_t)addr, BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 425 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 426 | size_t sizeofData = info.optimal_program_unit; |
nexpaq | 0:6c56fb4bc5f0 | 427 | TEST_ASSERT(BUFFER_SIZE >= sizeofData); |
nexpaq | 0:6c56fb4bc5f0 | 428 | memset(buffer, BYTE_PATTERN, sizeofData); |
nexpaq | 0:6c56fb4bc5f0 | 429 | |
nexpaq | 0:6c56fb4bc5f0 | 430 | status = drv->ProgramData(addr, buffer, sizeofData); |
nexpaq | 0:6c56fb4bc5f0 | 431 | if (status < ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 432 | return; /* failure. this will trigger a timeout and cause test failure. */ |
nexpaq | 0:6c56fb4bc5f0 | 433 | } |
nexpaq | 0:6c56fb4bc5f0 | 434 | if (status == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 435 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 436 | return; /* We've successfully pended a programData operation; we'll have another |
nexpaq | 0:6c56fb4bc5f0 | 437 | * invocation of this callback when programming completes. */ |
nexpaq | 0:6c56fb4bc5f0 | 438 | } |
nexpaq | 0:6c56fb4bc5f0 | 439 | } |
nexpaq | 0:6c56fb4bc5f0 | 440 | |
nexpaq | 0:6c56fb4bc5f0 | 441 | /* We come here either because of completion for program-data or as a very |
nexpaq | 0:6c56fb4bc5f0 | 442 | * unlikely fall through from synchronous completion of program-data (above). */ |
nexpaq | 0:6c56fb4bc5f0 | 443 | |
nexpaq | 0:6c56fb4bc5f0 | 444 | #ifndef __CC_ARM |
nexpaq | 0:6c56fb4bc5f0 | 445 | printf("verifying programmed sector at addr %lu\n", (uint32_t)addr); |
nexpaq | 0:6c56fb4bc5f0 | 446 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 447 | verifyBytePattern(addr, sizeofData, BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 448 | ++programIteration; |
nexpaq | 0:6c56fb4bc5f0 | 449 | |
nexpaq | 0:6c56fb4bc5f0 | 450 | Harness::validate_callback(); |
nexpaq | 0:6c56fb4bc5f0 | 451 | } |
nexpaq | 0:6c56fb4bc5f0 | 452 | |
nexpaq | 0:6c56fb4bc5f0 | 453 | control_t test_programDataUsingOptimalProgramUnit(const size_t call_count) |
nexpaq | 0:6c56fb4bc5f0 | 454 | { |
nexpaq | 0:6c56fb4bc5f0 | 455 | static const unsigned REPEAT_INSTANCES = 5; |
nexpaq | 0:6c56fb4bc5f0 | 456 | printf("in test_programDataUsingOptimalProgramUnit with call_count %u\n", call_count); |
nexpaq | 0:6c56fb4bc5f0 | 457 | |
nexpaq | 0:6c56fb4bc5f0 | 458 | if (call_count == 1) { |
nexpaq | 0:6c56fb4bc5f0 | 459 | /* Achieve basic initialization for the driver before anything else. */ |
nexpaq | 0:6c56fb4bc5f0 | 460 | return preambleForBasicInitialization(); |
nexpaq | 0:6c56fb4bc5f0 | 461 | } |
nexpaq | 0:6c56fb4bc5f0 | 462 | |
nexpaq | 0:6c56fb4bc5f0 | 463 | /* Get the first block. */ |
nexpaq | 0:6c56fb4bc5f0 | 464 | ARM_STORAGE_BLOCK firstBlock; |
nexpaq | 0:6c56fb4bc5f0 | 465 | drv->GetNextBlock(NULL, &firstBlock); /* get first block */ |
nexpaq | 0:6c56fb4bc5f0 | 466 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); |
nexpaq | 0:6c56fb4bc5f0 | 467 | TEST_ASSERT(firstBlock.size > 0); |
nexpaq | 0:6c56fb4bc5f0 | 468 | |
nexpaq | 0:6c56fb4bc5f0 | 469 | ARM_STORAGE_INFO info; |
nexpaq | 0:6c56fb4bc5f0 | 470 | int32_t rc = drv->GetInfo(&info); |
nexpaq | 0:6c56fb4bc5f0 | 471 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 472 | |
nexpaq | 0:6c56fb4bc5f0 | 473 | TEST_ASSERT(info.optimal_program_unit <= firstBlock.attributes.erase_unit); |
nexpaq | 0:6c56fb4bc5f0 | 474 | TEST_ASSERT(firstBlock.size >= (REPEAT_INSTANCES - 1) * firstBlock.attributes.erase_unit); |
nexpaq | 0:6c56fb4bc5f0 | 475 | |
nexpaq | 0:6c56fb4bc5f0 | 476 | /* initialize the buffer to hold the pattern. */ |
nexpaq | 0:6c56fb4bc5f0 | 477 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 478 | |
nexpaq | 0:6c56fb4bc5f0 | 479 | /* Update the completion callback to 'programDataCompleteCallback'. */ |
nexpaq | 0:6c56fb4bc5f0 | 480 | if (call_count == 2) { |
nexpaq | 0:6c56fb4bc5f0 | 481 | int32_t rc = drv->Initialize(programDataOptimalCompleteCallback); |
nexpaq | 0:6c56fb4bc5f0 | 482 | TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been |
nexpaq | 0:6c56fb4bc5f0 | 483 | * initialized by the previous iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 484 | } |
nexpaq | 0:6c56fb4bc5f0 | 485 | |
nexpaq | 0:6c56fb4bc5f0 | 486 | /* choose an increasing address for each iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 487 | uint64_t addr = firstBlock.addr + (call_count - 2) * firstBlock.attributes.erase_unit; |
nexpaq | 0:6c56fb4bc5f0 | 488 | |
nexpaq | 0:6c56fb4bc5f0 | 489 | /* erase the sector at 'addr' */ |
nexpaq | 0:6c56fb4bc5f0 | 490 | printf("erasing sector at addr %lu\n", (uint32_t)addr); |
nexpaq | 0:6c56fb4bc5f0 | 491 | rc = drv->Erase(addr, firstBlock.attributes.erase_unit); |
nexpaq | 0:6c56fb4bc5f0 | 492 | TEST_ASSERT(rc >= 0); |
nexpaq | 0:6c56fb4bc5f0 | 493 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 494 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 495 | return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200); |
nexpaq | 0:6c56fb4bc5f0 | 496 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 497 | TEST_ASSERT_EQUAL(firstBlock.attributes.erase_unit, rc); |
nexpaq | 0:6c56fb4bc5f0 | 498 | verifyBytePattern(addr, firstBlock.attributes.erase_unit, (uint8_t)0xFF); |
nexpaq | 0:6c56fb4bc5f0 | 499 | |
nexpaq | 0:6c56fb4bc5f0 | 500 | static const uint8_t BYTE_PATTERN = 0xAA; |
nexpaq | 0:6c56fb4bc5f0 | 501 | size_t sizeofData = info.optimal_program_unit; |
nexpaq | 0:6c56fb4bc5f0 | 502 | TEST_ASSERT(BUFFER_SIZE >= sizeofData); |
nexpaq | 0:6c56fb4bc5f0 | 503 | memset(buffer, BYTE_PATTERN, sizeofData); |
nexpaq | 0:6c56fb4bc5f0 | 504 | |
nexpaq | 0:6c56fb4bc5f0 | 505 | /* program the sector at addr */ |
nexpaq | 0:6c56fb4bc5f0 | 506 | printf("programming %u bytes at address %lu with pattern 0x%x\n", sizeofData, (uint32_t)addr, BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 507 | rc = drv->ProgramData((uint32_t)addr, buffer, sizeofData); |
nexpaq | 0:6c56fb4bc5f0 | 508 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 509 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 510 | return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200); |
nexpaq | 0:6c56fb4bc5f0 | 511 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 512 | TEST_ASSERT_EQUAL(sizeofData, rc); |
nexpaq | 0:6c56fb4bc5f0 | 513 | |
nexpaq | 0:6c56fb4bc5f0 | 514 | printf("verifying programmed sector at addr %lu\n", (uint32_t)addr); |
nexpaq | 0:6c56fb4bc5f0 | 515 | verifyBytePattern(addr, sizeofData, BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 516 | |
nexpaq | 0:6c56fb4bc5f0 | 517 | return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 518 | } |
nexpaq | 0:6c56fb4bc5f0 | 519 | } |
nexpaq | 0:6c56fb4bc5f0 | 520 | } |
nexpaq | 0:6c56fb4bc5f0 | 521 | |
nexpaq | 0:6c56fb4bc5f0 | 522 | void test_eraseWithInvalidParameters(void) |
nexpaq | 0:6c56fb4bc5f0 | 523 | { |
nexpaq | 0:6c56fb4bc5f0 | 524 | int32_t rc; |
nexpaq | 0:6c56fb4bc5f0 | 525 | |
nexpaq | 0:6c56fb4bc5f0 | 526 | rc = drv->Erase(0, 0); |
nexpaq | 0:6c56fb4bc5f0 | 527 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 528 | |
nexpaq | 0:6c56fb4bc5f0 | 529 | /* operate before the start of the first block. */ |
nexpaq | 0:6c56fb4bc5f0 | 530 | ARM_STORAGE_BLOCK block; |
nexpaq | 0:6c56fb4bc5f0 | 531 | rc = drv->GetNextBlock(NULL, &block); /* get the first block */ |
nexpaq | 0:6c56fb4bc5f0 | 532 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 533 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&block)); |
nexpaq | 0:6c56fb4bc5f0 | 534 | TEST_ASSERT(block.size > 0); |
nexpaq | 0:6c56fb4bc5f0 | 535 | rc = drv->Erase(block.addr - 1, BUFFER_SIZE); |
nexpaq | 0:6c56fb4bc5f0 | 536 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 537 | |
nexpaq | 0:6c56fb4bc5f0 | 538 | /* operate at an address past the end of the last block */ |
nexpaq | 0:6c56fb4bc5f0 | 539 | uint64_t endAddr = block.addr + block.size; |
nexpaq | 0:6c56fb4bc5f0 | 540 | for (; ARM_STORAGE_VALID_BLOCK(&block); drv->GetNextBlock(&block, &block)) { |
nexpaq | 0:6c56fb4bc5f0 | 541 | endAddr = block.addr + block.size; |
nexpaq | 0:6c56fb4bc5f0 | 542 | } |
nexpaq | 0:6c56fb4bc5f0 | 543 | rc = drv->Erase(endAddr + 1, BUFFER_SIZE); |
nexpaq | 0:6c56fb4bc5f0 | 544 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 545 | |
nexpaq | 0:6c56fb4bc5f0 | 546 | ARM_STORAGE_INFO info; |
nexpaq | 0:6c56fb4bc5f0 | 547 | rc = drv->GetInfo(&info); |
nexpaq | 0:6c56fb4bc5f0 | 548 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 549 | |
nexpaq | 0:6c56fb4bc5f0 | 550 | drv->GetNextBlock(NULL, &block); /* get the first block */ |
nexpaq | 0:6c56fb4bc5f0 | 551 | TEST_ASSERT(block.size >= block.attributes.erase_unit); |
nexpaq | 0:6c56fb4bc5f0 | 552 | TEST_ASSERT((block.size % block.attributes.erase_unit) == 0); |
nexpaq | 0:6c56fb4bc5f0 | 553 | |
nexpaq | 0:6c56fb4bc5f0 | 554 | rc = drv->Erase(block.addr + 1, block.attributes.erase_unit); |
nexpaq | 0:6c56fb4bc5f0 | 555 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 556 | rc = drv->Erase(block.addr, block.attributes.erase_unit - 1); |
nexpaq | 0:6c56fb4bc5f0 | 557 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 558 | rc = drv->Erase(block.addr, block.attributes.erase_unit + 1); |
nexpaq | 0:6c56fb4bc5f0 | 559 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 560 | rc = drv->Erase(block.addr, block.attributes.erase_unit / 2); |
nexpaq | 0:6c56fb4bc5f0 | 561 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 562 | } |
nexpaq | 0:6c56fb4bc5f0 | 563 | |
nexpaq | 0:6c56fb4bc5f0 | 564 | template<size_t ERASE_UNITS_PER_ITERATION> |
nexpaq | 0:6c56fb4bc5f0 | 565 | void eraseCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation) |
nexpaq | 0:6c56fb4bc5f0 | 566 | { |
nexpaq | 0:6c56fb4bc5f0 | 567 | static unsigned eraseIteration = 0; |
nexpaq | 0:6c56fb4bc5f0 | 568 | #ifndef __CC_ARM |
nexpaq | 0:6c56fb4bc5f0 | 569 | printf("erase<%u> complete callback: iteration %u\n", ERASE_UNITS_PER_ITERATION, eraseIteration); |
nexpaq | 0:6c56fb4bc5f0 | 570 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 571 | TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_ERASE); |
nexpaq | 0:6c56fb4bc5f0 | 572 | |
nexpaq | 0:6c56fb4bc5f0 | 573 | /* test that the actual sector has been erased */ |
nexpaq | 0:6c56fb4bc5f0 | 574 | ARM_STORAGE_BLOCK firstBlock; |
nexpaq | 0:6c56fb4bc5f0 | 575 | drv->GetNextBlock(NULL, &firstBlock); /* get first block */ |
nexpaq | 0:6c56fb4bc5f0 | 576 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); |
nexpaq | 0:6c56fb4bc5f0 | 577 | TEST_ASSERT_EQUAL(ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit, status); |
nexpaq | 0:6c56fb4bc5f0 | 578 | |
nexpaq | 0:6c56fb4bc5f0 | 579 | const uint64_t addr = firstBlock.addr + eraseIteration * ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit; |
nexpaq | 0:6c56fb4bc5f0 | 580 | ++eraseIteration; |
nexpaq | 0:6c56fb4bc5f0 | 581 | |
nexpaq | 0:6c56fb4bc5f0 | 582 | #ifndef __CC_ARM |
nexpaq | 0:6c56fb4bc5f0 | 583 | printf("testing erased sector at addr %lu\n", (uint32_t)addr); |
nexpaq | 0:6c56fb4bc5f0 | 584 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 585 | verifyBytePattern(addr, ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit, (uint8_t)0xFF); |
nexpaq | 0:6c56fb4bc5f0 | 586 | |
nexpaq | 0:6c56fb4bc5f0 | 587 | Harness::validate_callback(); |
nexpaq | 0:6c56fb4bc5f0 | 588 | } |
nexpaq | 0:6c56fb4bc5f0 | 589 | |
nexpaq | 0:6c56fb4bc5f0 | 590 | template <size_t ERASE_UNITS_PER_ITERATION> |
nexpaq | 0:6c56fb4bc5f0 | 591 | control_t test_erase(const size_t call_count) |
nexpaq | 0:6c56fb4bc5f0 | 592 | { |
nexpaq | 0:6c56fb4bc5f0 | 593 | static const unsigned REPEAT_INSTANCES = 5; |
nexpaq | 0:6c56fb4bc5f0 | 594 | printf("in test_erase<%u> with call_count %u\n", ERASE_UNITS_PER_ITERATION, call_count); |
nexpaq | 0:6c56fb4bc5f0 | 595 | |
nexpaq | 0:6c56fb4bc5f0 | 596 | if (call_count == 1) { |
nexpaq | 0:6c56fb4bc5f0 | 597 | /* Achieve basic initialization for the driver before anything else. */ |
nexpaq | 0:6c56fb4bc5f0 | 598 | return preambleForBasicInitialization(); |
nexpaq | 0:6c56fb4bc5f0 | 599 | } |
nexpaq | 0:6c56fb4bc5f0 | 600 | |
nexpaq | 0:6c56fb4bc5f0 | 601 | /* Get the first block. */ |
nexpaq | 0:6c56fb4bc5f0 | 602 | ARM_STORAGE_BLOCK firstBlock; |
nexpaq | 0:6c56fb4bc5f0 | 603 | drv->GetNextBlock(NULL, &firstBlock); /* get first block */ |
nexpaq | 0:6c56fb4bc5f0 | 604 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); |
nexpaq | 0:6c56fb4bc5f0 | 605 | TEST_ASSERT(firstBlock.size > 0); |
nexpaq | 0:6c56fb4bc5f0 | 606 | if (firstBlock.size < ((call_count - 1) * ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit)) { |
nexpaq | 0:6c56fb4bc5f0 | 607 | printf("firstBlock isn't large enough to support instance %u of test_erase<%u>\n", call_count, ERASE_UNITS_PER_ITERATION); |
nexpaq | 0:6c56fb4bc5f0 | 608 | return CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 609 | } |
nexpaq | 0:6c56fb4bc5f0 | 610 | |
nexpaq | 0:6c56fb4bc5f0 | 611 | /* Update the completion callback to 'eraseCompleteCallback'. */ |
nexpaq | 0:6c56fb4bc5f0 | 612 | if (call_count == 2) { |
nexpaq | 0:6c56fb4bc5f0 | 613 | int32_t rc = drv->Initialize(eraseCompleteCallback<ERASE_UNITS_PER_ITERATION>); |
nexpaq | 0:6c56fb4bc5f0 | 614 | TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been |
nexpaq | 0:6c56fb4bc5f0 | 615 | * initialized by the previous iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 616 | } |
nexpaq | 0:6c56fb4bc5f0 | 617 | |
nexpaq | 0:6c56fb4bc5f0 | 618 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 619 | |
nexpaq | 0:6c56fb4bc5f0 | 620 | /* choose an increasing address for each iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 621 | uint64_t addr = firstBlock.addr + (call_count - 2) * ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit; |
nexpaq | 0:6c56fb4bc5f0 | 622 | |
nexpaq | 0:6c56fb4bc5f0 | 623 | printf("erasing %lu bytes at addr %lu\n", (ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit), (uint32_t)addr); |
nexpaq | 0:6c56fb4bc5f0 | 624 | int32_t rc = drv->Erase(addr, ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit); |
nexpaq | 0:6c56fb4bc5f0 | 625 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 626 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 627 | return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200); |
nexpaq | 0:6c56fb4bc5f0 | 628 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 629 | TEST_ASSERT_EQUAL(ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit, rc); |
nexpaq | 0:6c56fb4bc5f0 | 630 | |
nexpaq | 0:6c56fb4bc5f0 | 631 | /* test that the actual sector has been erased */ |
nexpaq | 0:6c56fb4bc5f0 | 632 | printf("testing erased sector at addr %lu\n", (uint32_t)addr); |
nexpaq | 0:6c56fb4bc5f0 | 633 | verifyBytePattern(addr, ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit, (uint8_t)0xFF); |
nexpaq | 0:6c56fb4bc5f0 | 634 | |
nexpaq | 0:6c56fb4bc5f0 | 635 | return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 636 | } |
nexpaq | 0:6c56fb4bc5f0 | 637 | } |
nexpaq | 0:6c56fb4bc5f0 | 638 | |
nexpaq | 0:6c56fb4bc5f0 | 639 | void eraseChipCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation) |
nexpaq | 0:6c56fb4bc5f0 | 640 | { |
nexpaq | 0:6c56fb4bc5f0 | 641 | #ifndef __CC_ARM |
nexpaq | 0:6c56fb4bc5f0 | 642 | printf("eraseChip complete callback\n"); |
nexpaq | 0:6c56fb4bc5f0 | 643 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 644 | TEST_ASSERT_EQUAL(status, ARM_DRIVER_OK); |
nexpaq | 0:6c56fb4bc5f0 | 645 | TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_ERASE_ALL); |
nexpaq | 0:6c56fb4bc5f0 | 646 | |
nexpaq | 0:6c56fb4bc5f0 | 647 | ARM_STORAGE_BLOCK firstBlock; |
nexpaq | 0:6c56fb4bc5f0 | 648 | drv->GetNextBlock(NULL, &firstBlock); /* get first block */ |
nexpaq | 0:6c56fb4bc5f0 | 649 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); |
nexpaq | 0:6c56fb4bc5f0 | 650 | uint64_t addr = firstBlock.addr; |
nexpaq | 0:6c56fb4bc5f0 | 651 | |
nexpaq | 0:6c56fb4bc5f0 | 652 | /* test that the flash has been erased */ |
nexpaq | 0:6c56fb4bc5f0 | 653 | #ifndef __CC_ARM |
nexpaq | 0:6c56fb4bc5f0 | 654 | printf("testing erased chip\n"); |
nexpaq | 0:6c56fb4bc5f0 | 655 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 656 | unsigned index = 0; |
nexpaq | 0:6c56fb4bc5f0 | 657 | static const unsigned MAX_VERIFY_ITERATIONS = 5; |
nexpaq | 0:6c56fb4bc5f0 | 658 | while ((index < MAX_VERIFY_ITERATIONS) && (addr < (firstBlock.addr + firstBlock.size))) { |
nexpaq | 0:6c56fb4bc5f0 | 659 | // printf("testing erased chip at addr %lu\n", (uint32_t)addr); |
nexpaq | 0:6c56fb4bc5f0 | 660 | verifyBytePattern(addr, firstBlock.attributes.erase_unit, (uint8_t)0xFF); |
nexpaq | 0:6c56fb4bc5f0 | 661 | |
nexpaq | 0:6c56fb4bc5f0 | 662 | index++; |
nexpaq | 0:6c56fb4bc5f0 | 663 | addr += firstBlock.attributes.erase_unit; |
nexpaq | 0:6c56fb4bc5f0 | 664 | } |
nexpaq | 0:6c56fb4bc5f0 | 665 | |
nexpaq | 0:6c56fb4bc5f0 | 666 | Harness::validate_callback(); |
nexpaq | 0:6c56fb4bc5f0 | 667 | } |
nexpaq | 0:6c56fb4bc5f0 | 668 | |
nexpaq | 0:6c56fb4bc5f0 | 669 | control_t test_eraseAll(const size_t call_count) |
nexpaq | 0:6c56fb4bc5f0 | 670 | { |
nexpaq | 0:6c56fb4bc5f0 | 671 | static const unsigned REPEAT_INSTANCES = 5; |
nexpaq | 0:6c56fb4bc5f0 | 672 | printf("in test_eraseAll with call_count %u\n", call_count); |
nexpaq | 0:6c56fb4bc5f0 | 673 | |
nexpaq | 0:6c56fb4bc5f0 | 674 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 675 | if (!capabilities.erase_all) { |
nexpaq | 0:6c56fb4bc5f0 | 676 | printf("chip erase not supported on this flash\n"); |
nexpaq | 0:6c56fb4bc5f0 | 677 | return CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 678 | } |
nexpaq | 0:6c56fb4bc5f0 | 679 | |
nexpaq | 0:6c56fb4bc5f0 | 680 | if (call_count == 1) { |
nexpaq | 0:6c56fb4bc5f0 | 681 | /* Achieve basic initialization for the driver before anything else. */ |
nexpaq | 0:6c56fb4bc5f0 | 682 | return preambleForBasicInitialization(); |
nexpaq | 0:6c56fb4bc5f0 | 683 | } |
nexpaq | 0:6c56fb4bc5f0 | 684 | |
nexpaq | 0:6c56fb4bc5f0 | 685 | /* Update the completion callback to 'eraseChipCompleteCallback'. */ |
nexpaq | 0:6c56fb4bc5f0 | 686 | if (call_count == 2) { |
nexpaq | 0:6c56fb4bc5f0 | 687 | int32_t rc = drv->Initialize(eraseChipCompleteCallback); |
nexpaq | 0:6c56fb4bc5f0 | 688 | TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been |
nexpaq | 0:6c56fb4bc5f0 | 689 | * initialized by the previous iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 690 | } |
nexpaq | 0:6c56fb4bc5f0 | 691 | |
nexpaq | 0:6c56fb4bc5f0 | 692 | /* Get the first block. */ |
nexpaq | 0:6c56fb4bc5f0 | 693 | ARM_STORAGE_BLOCK firstBlock; |
nexpaq | 0:6c56fb4bc5f0 | 694 | drv->GetNextBlock(NULL, &firstBlock); /* get first block */ |
nexpaq | 0:6c56fb4bc5f0 | 695 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); |
nexpaq | 0:6c56fb4bc5f0 | 696 | TEST_ASSERT(firstBlock.size > 0); |
nexpaq | 0:6c56fb4bc5f0 | 697 | uint64_t addr = firstBlock.addr; |
nexpaq | 0:6c56fb4bc5f0 | 698 | printf("erasing chip\n"); |
nexpaq | 0:6c56fb4bc5f0 | 699 | |
nexpaq | 0:6c56fb4bc5f0 | 700 | int32_t rc = drv->EraseAll(); |
nexpaq | 0:6c56fb4bc5f0 | 701 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 702 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 703 | return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200); |
nexpaq | 0:6c56fb4bc5f0 | 704 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 705 | TEST_ASSERT(rc == 1); |
nexpaq | 0:6c56fb4bc5f0 | 706 | |
nexpaq | 0:6c56fb4bc5f0 | 707 | /* test that the flash has been erased */ |
nexpaq | 0:6c56fb4bc5f0 | 708 | unsigned index = 0; |
nexpaq | 0:6c56fb4bc5f0 | 709 | static const unsigned MAX_VERIFY_ITERATIONS = 5; |
nexpaq | 0:6c56fb4bc5f0 | 710 | while ((index < MAX_VERIFY_ITERATIONS) && (addr < (firstBlock.addr + firstBlock.size))) { |
nexpaq | 0:6c56fb4bc5f0 | 711 | printf("testing erased chip at addr %lu\n", (uint32_t)addr); |
nexpaq | 0:6c56fb4bc5f0 | 712 | verifyBytePattern(addr, firstBlock.attributes.erase_unit, (uint8_t)0xFF); |
nexpaq | 0:6c56fb4bc5f0 | 713 | |
nexpaq | 0:6c56fb4bc5f0 | 714 | index++; |
nexpaq | 0:6c56fb4bc5f0 | 715 | addr += firstBlock.attributes.erase_unit; |
nexpaq | 0:6c56fb4bc5f0 | 716 | } |
nexpaq | 0:6c56fb4bc5f0 | 717 | |
nexpaq | 0:6c56fb4bc5f0 | 718 | return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 719 | } |
nexpaq | 0:6c56fb4bc5f0 | 720 | } |
nexpaq | 0:6c56fb4bc5f0 | 721 | |
nexpaq | 0:6c56fb4bc5f0 | 722 | void test_programDataWithInvalidParameters(void) |
nexpaq | 0:6c56fb4bc5f0 | 723 | { |
nexpaq | 0:6c56fb4bc5f0 | 724 | int32_t rc; |
nexpaq | 0:6c56fb4bc5f0 | 725 | |
nexpaq | 0:6c56fb4bc5f0 | 726 | rc = drv->ProgramData(0, NULL, 0); |
nexpaq | 0:6c56fb4bc5f0 | 727 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 728 | rc = drv->ProgramData(0, buffer, 0); |
nexpaq | 0:6c56fb4bc5f0 | 729 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 730 | rc = drv->ProgramData(0, NULL, BUFFER_SIZE); |
nexpaq | 0:6c56fb4bc5f0 | 731 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 732 | |
nexpaq | 0:6c56fb4bc5f0 | 733 | /* operate before the start of the first block. */ |
nexpaq | 0:6c56fb4bc5f0 | 734 | ARM_STORAGE_BLOCK block; |
nexpaq | 0:6c56fb4bc5f0 | 735 | rc = drv->GetNextBlock(NULL, &block); /* get the first block */ |
nexpaq | 0:6c56fb4bc5f0 | 736 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 737 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&block)); |
nexpaq | 0:6c56fb4bc5f0 | 738 | TEST_ASSERT(block.size > 0); |
nexpaq | 0:6c56fb4bc5f0 | 739 | rc = drv->ProgramData(block.addr - 1, buffer, BUFFER_SIZE); |
nexpaq | 0:6c56fb4bc5f0 | 740 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 741 | |
nexpaq | 0:6c56fb4bc5f0 | 742 | /* operate at an address past the end of the last block */ |
nexpaq | 0:6c56fb4bc5f0 | 743 | uint64_t endAddr = block.addr + block.size; |
nexpaq | 0:6c56fb4bc5f0 | 744 | for (; ARM_STORAGE_VALID_BLOCK(&block); drv->GetNextBlock(&block, &block)) { |
nexpaq | 0:6c56fb4bc5f0 | 745 | endAddr = block.addr + block.size; |
nexpaq | 0:6c56fb4bc5f0 | 746 | } |
nexpaq | 0:6c56fb4bc5f0 | 747 | rc = drv->ProgramData(endAddr + 1, buffer, BUFFER_SIZE); |
nexpaq | 0:6c56fb4bc5f0 | 748 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 749 | |
nexpaq | 0:6c56fb4bc5f0 | 750 | ARM_STORAGE_INFO info; |
nexpaq | 0:6c56fb4bc5f0 | 751 | rc = drv->GetInfo(&info); |
nexpaq | 0:6c56fb4bc5f0 | 752 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 753 | if (info.program_unit <= 1) { |
nexpaq | 0:6c56fb4bc5f0 | 754 | return; /* if program_unit is 1 (or 0), we can't proceed with any alignment tests */ |
nexpaq | 0:6c56fb4bc5f0 | 755 | } |
nexpaq | 0:6c56fb4bc5f0 | 756 | |
nexpaq | 0:6c56fb4bc5f0 | 757 | drv->GetNextBlock(NULL, &block); /* get the first block */ |
nexpaq | 0:6c56fb4bc5f0 | 758 | |
nexpaq | 0:6c56fb4bc5f0 | 759 | TEST_ASSERT(block.size >= info.program_unit); |
nexpaq | 0:6c56fb4bc5f0 | 760 | |
nexpaq | 0:6c56fb4bc5f0 | 761 | rc = drv->ProgramData(block.addr + 1, buffer, info.program_unit); |
nexpaq | 0:6c56fb4bc5f0 | 762 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 763 | rc = drv->ProgramData(block.addr, buffer, info.program_unit - 1); |
nexpaq | 0:6c56fb4bc5f0 | 764 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 765 | rc = drv->ProgramData(block.addr, buffer, info.program_unit + 1); |
nexpaq | 0:6c56fb4bc5f0 | 766 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 767 | rc = drv->ProgramData(block.addr, buffer, info.program_unit / 2); |
nexpaq | 0:6c56fb4bc5f0 | 768 | TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc); |
nexpaq | 0:6c56fb4bc5f0 | 769 | } |
nexpaq | 0:6c56fb4bc5f0 | 770 | |
nexpaq | 0:6c56fb4bc5f0 | 771 | template <size_t N_UNITS> |
nexpaq | 0:6c56fb4bc5f0 | 772 | void programDataWithMultipleProgramUnitsCallback(int32_t status, ARM_STORAGE_OPERATION operation) |
nexpaq | 0:6c56fb4bc5f0 | 773 | { |
nexpaq | 0:6c56fb4bc5f0 | 774 | TEST_ASSERT(status >= ARM_DRIVER_OK); |
nexpaq | 0:6c56fb4bc5f0 | 775 | |
nexpaq | 0:6c56fb4bc5f0 | 776 | ARM_STORAGE_BLOCK firstBlock; |
nexpaq | 0:6c56fb4bc5f0 | 777 | drv->GetNextBlock(NULL, &firstBlock); /* get first block */ |
nexpaq | 0:6c56fb4bc5f0 | 778 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); |
nexpaq | 0:6c56fb4bc5f0 | 779 | TEST_ASSERT(firstBlock.size > 0); |
nexpaq | 0:6c56fb4bc5f0 | 780 | |
nexpaq | 0:6c56fb4bc5f0 | 781 | ARM_STORAGE_INFO info; |
nexpaq | 0:6c56fb4bc5f0 | 782 | int32_t rc = drv->GetInfo(&info); |
nexpaq | 0:6c56fb4bc5f0 | 783 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 784 | |
nexpaq | 0:6c56fb4bc5f0 | 785 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 786 | |
nexpaq | 0:6c56fb4bc5f0 | 787 | size_t rangeNeededForTest = (N_UNITS * info.program_unit); |
nexpaq | 0:6c56fb4bc5f0 | 788 | /* round-up range to the nearest erase_unit */ |
nexpaq | 0:6c56fb4bc5f0 | 789 | rangeNeededForTest = ((rangeNeededForTest + firstBlock.attributes.erase_unit - 1) / firstBlock.attributes.erase_unit) * firstBlock.attributes.erase_unit; |
nexpaq | 0:6c56fb4bc5f0 | 790 | |
nexpaq | 0:6c56fb4bc5f0 | 791 | static const uint32_t BYTE_PATTERN = 0xABCDEF00; |
nexpaq | 0:6c56fb4bc5f0 | 792 | |
nexpaq | 0:6c56fb4bc5f0 | 793 | if (operation == ARM_STORAGE_OPERATION_ERASE) { |
nexpaq | 0:6c56fb4bc5f0 | 794 | TEST_ASSERT_EQUAL(rangeNeededForTest, status); |
nexpaq | 0:6c56fb4bc5f0 | 795 | TEST_ASSERT((N_UNITS * info.program_unit) <= BUFFER_SIZE); |
nexpaq | 0:6c56fb4bc5f0 | 796 | |
nexpaq | 0:6c56fb4bc5f0 | 797 | /* setup byte pattern in buffer */ |
nexpaq | 0:6c56fb4bc5f0 | 798 | if (info.program_unit >= sizeof(BYTE_PATTERN)) { |
nexpaq | 0:6c56fb4bc5f0 | 799 | for (size_t index = 0; index < ((N_UNITS * info.program_unit) / sizeof(BYTE_PATTERN)); index++) { |
nexpaq | 0:6c56fb4bc5f0 | 800 | ((uint32_t *)buffer)[index] = BYTE_PATTERN; |
nexpaq | 0:6c56fb4bc5f0 | 801 | } |
nexpaq | 0:6c56fb4bc5f0 | 802 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 803 | for (size_t index = 0; index < ((N_UNITS * info.program_unit)); index++) { |
nexpaq | 0:6c56fb4bc5f0 | 804 | buffer[index] = ((const uint8_t *)&BYTE_PATTERN)[0]; |
nexpaq | 0:6c56fb4bc5f0 | 805 | } |
nexpaq | 0:6c56fb4bc5f0 | 806 | } |
nexpaq | 0:6c56fb4bc5f0 | 807 | |
nexpaq | 0:6c56fb4bc5f0 | 808 | #ifndef __CC_ARM |
nexpaq | 0:6c56fb4bc5f0 | 809 | printf("Callback: programming %lu bytes at address %lu with pattern 0x%lx\n", (N_UNITS * info.program_unit), (uint32_t)firstBlock.addr, BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 810 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 811 | rc = drv->ProgramData(firstBlock.addr, buffer, (N_UNITS * info.program_unit)); |
nexpaq | 0:6c56fb4bc5f0 | 812 | TEST_ASSERT(rc >= ARM_DRIVER_OK); |
nexpaq | 0:6c56fb4bc5f0 | 813 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 814 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 815 | return; /* We've successfully pended a programData operation; we'll have another |
nexpaq | 0:6c56fb4bc5f0 | 816 | * invocation of this callback when programming completes. */ |
nexpaq | 0:6c56fb4bc5f0 | 817 | } |
nexpaq | 0:6c56fb4bc5f0 | 818 | |
nexpaq | 0:6c56fb4bc5f0 | 819 | status = rc; |
nexpaq | 0:6c56fb4bc5f0 | 820 | } |
nexpaq | 0:6c56fb4bc5f0 | 821 | |
nexpaq | 0:6c56fb4bc5f0 | 822 | TEST_ASSERT_EQUAL((N_UNITS * info.program_unit), status); |
nexpaq | 0:6c56fb4bc5f0 | 823 | |
nexpaq | 0:6c56fb4bc5f0 | 824 | #ifndef __CC_ARM |
nexpaq | 0:6c56fb4bc5f0 | 825 | printf("Callback: verifying programmed sector at addr %lu\n", (uint32_t)firstBlock.addr); |
nexpaq | 0:6c56fb4bc5f0 | 826 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 827 | if (info.program_unit >= sizeof(BYTE_PATTERN)) { |
nexpaq | 0:6c56fb4bc5f0 | 828 | verifyBytePattern(firstBlock.addr, (N_UNITS * info.program_unit), BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 829 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 830 | verifyBytePattern(firstBlock.addr, (N_UNITS * info.program_unit), ((const uint8_t *)&BYTE_PATTERN)[0]); |
nexpaq | 0:6c56fb4bc5f0 | 831 | } |
nexpaq | 0:6c56fb4bc5f0 | 832 | |
nexpaq | 0:6c56fb4bc5f0 | 833 | Harness::validate_callback(); |
nexpaq | 0:6c56fb4bc5f0 | 834 | } |
nexpaq | 0:6c56fb4bc5f0 | 835 | |
nexpaq | 0:6c56fb4bc5f0 | 836 | template<size_t N_UNITS> |
nexpaq | 0:6c56fb4bc5f0 | 837 | control_t test_programDataWithMultipleProgramUnits(const size_t call_count) |
nexpaq | 0:6c56fb4bc5f0 | 838 | { |
nexpaq | 0:6c56fb4bc5f0 | 839 | int32_t rc; |
nexpaq | 0:6c56fb4bc5f0 | 840 | printf("in test_programDataWithMultipleProgramUnits<%u> with call_count %u\n", N_UNITS, call_count); |
nexpaq | 0:6c56fb4bc5f0 | 841 | |
nexpaq | 0:6c56fb4bc5f0 | 842 | if (call_count == 1) { |
nexpaq | 0:6c56fb4bc5f0 | 843 | /* Achieve basic initialization for the driver before anything else. */ |
nexpaq | 0:6c56fb4bc5f0 | 844 | return preambleForBasicInitialization(); |
nexpaq | 0:6c56fb4bc5f0 | 845 | } |
nexpaq | 0:6c56fb4bc5f0 | 846 | |
nexpaq | 0:6c56fb4bc5f0 | 847 | /* Update the completion callback to 'programDataWithMultipleProgramUnitsCallback'. */ |
nexpaq | 0:6c56fb4bc5f0 | 848 | if (call_count == 2) { |
nexpaq | 0:6c56fb4bc5f0 | 849 | rc = drv->Initialize(programDataWithMultipleProgramUnitsCallback<N_UNITS>); |
nexpaq | 0:6c56fb4bc5f0 | 850 | TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been |
nexpaq | 0:6c56fb4bc5f0 | 851 | * initialized by the previous iteration. */ |
nexpaq | 0:6c56fb4bc5f0 | 852 | |
nexpaq | 0:6c56fb4bc5f0 | 853 | ARM_STORAGE_BLOCK firstBlock; |
nexpaq | 0:6c56fb4bc5f0 | 854 | drv->GetNextBlock(NULL, &firstBlock); /* get first block */ |
nexpaq | 0:6c56fb4bc5f0 | 855 | TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock)); |
nexpaq | 0:6c56fb4bc5f0 | 856 | TEST_ASSERT(firstBlock.size > 0); |
nexpaq | 0:6c56fb4bc5f0 | 857 | |
nexpaq | 0:6c56fb4bc5f0 | 858 | ARM_STORAGE_INFO info; |
nexpaq | 0:6c56fb4bc5f0 | 859 | int32_t rc = drv->GetInfo(&info); |
nexpaq | 0:6c56fb4bc5f0 | 860 | TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc); |
nexpaq | 0:6c56fb4bc5f0 | 861 | |
nexpaq | 0:6c56fb4bc5f0 | 862 | ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities(); |
nexpaq | 0:6c56fb4bc5f0 | 863 | |
nexpaq | 0:6c56fb4bc5f0 | 864 | size_t rangeNeededForTest = (N_UNITS * info.program_unit); |
nexpaq | 0:6c56fb4bc5f0 | 865 | /* round-up range to the nearest erase_unit */ |
nexpaq | 0:6c56fb4bc5f0 | 866 | rangeNeededForTest = ((rangeNeededForTest + firstBlock.attributes.erase_unit - 1) / firstBlock.attributes.erase_unit) * firstBlock.attributes.erase_unit; |
nexpaq | 0:6c56fb4bc5f0 | 867 | if (firstBlock.size < rangeNeededForTest) { |
nexpaq | 0:6c56fb4bc5f0 | 868 | printf("first block not large enough; rangeNeededForTest: %u\n", rangeNeededForTest); |
nexpaq | 0:6c56fb4bc5f0 | 869 | return CaseNext; /* first block isn't large enough for the intended operation */ |
nexpaq | 0:6c56fb4bc5f0 | 870 | } |
nexpaq | 0:6c56fb4bc5f0 | 871 | |
nexpaq | 0:6c56fb4bc5f0 | 872 | if (rangeNeededForTest > BUFFER_SIZE) { |
nexpaq | 0:6c56fb4bc5f0 | 873 | printf("buffer (%u) not large enough; rangeNeededForTest: %u\n", BUFFER_SIZE, rangeNeededForTest); |
nexpaq | 0:6c56fb4bc5f0 | 874 | return CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 875 | } |
nexpaq | 0:6c56fb4bc5f0 | 876 | |
nexpaq | 0:6c56fb4bc5f0 | 877 | // printf("erasing %u bytes at addr %lu\n", rangeNeededForTest, (uint32_t)firstBlock.addr); |
nexpaq | 0:6c56fb4bc5f0 | 878 | rc = drv->Erase(firstBlock.addr, rangeNeededForTest); |
nexpaq | 0:6c56fb4bc5f0 | 879 | TEST_ASSERT(rc >= 0); |
nexpaq | 0:6c56fb4bc5f0 | 880 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 881 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 882 | return CaseTimeout(500); |
nexpaq | 0:6c56fb4bc5f0 | 883 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 884 | TEST_ASSERT_EQUAL(rangeNeededForTest, rc); |
nexpaq | 0:6c56fb4bc5f0 | 885 | |
nexpaq | 0:6c56fb4bc5f0 | 886 | /* setup byte pattern in buffer */ |
nexpaq | 0:6c56fb4bc5f0 | 887 | static const uint32_t BYTE_PATTERN = 0xABCDEF00; |
nexpaq | 0:6c56fb4bc5f0 | 888 | if (info.program_unit >= sizeof(BYTE_PATTERN)) { |
nexpaq | 0:6c56fb4bc5f0 | 889 | for (size_t index = 0; index < ((N_UNITS * info.program_unit) / sizeof(BYTE_PATTERN)); index++) { |
nexpaq | 0:6c56fb4bc5f0 | 890 | ((uint32_t *)buffer)[index] = BYTE_PATTERN; |
nexpaq | 0:6c56fb4bc5f0 | 891 | } |
nexpaq | 0:6c56fb4bc5f0 | 892 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 893 | for (size_t index = 0; index < ((N_UNITS * info.program_unit)); index++) { |
nexpaq | 0:6c56fb4bc5f0 | 894 | buffer[index] = ((const uint8_t *)&BYTE_PATTERN)[0]; |
nexpaq | 0:6c56fb4bc5f0 | 895 | } |
nexpaq | 0:6c56fb4bc5f0 | 896 | } |
nexpaq | 0:6c56fb4bc5f0 | 897 | |
nexpaq | 0:6c56fb4bc5f0 | 898 | printf("programming %lu bytes at address %lu with pattern 0x%lx\n", (N_UNITS * info.program_unit), (uint32_t)firstBlock.addr, BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 899 | rc = drv->ProgramData(firstBlock.addr, buffer, (N_UNITS * info.program_unit)); |
nexpaq | 0:6c56fb4bc5f0 | 900 | TEST_ASSERT(rc >= 0); |
nexpaq | 0:6c56fb4bc5f0 | 901 | if (rc == ARM_DRIVER_OK) { |
nexpaq | 0:6c56fb4bc5f0 | 902 | TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops); |
nexpaq | 0:6c56fb4bc5f0 | 903 | return CaseTimeout(500); |
nexpaq | 0:6c56fb4bc5f0 | 904 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 905 | TEST_ASSERT_EQUAL((N_UNITS * info.program_unit), rc); |
nexpaq | 0:6c56fb4bc5f0 | 906 | |
nexpaq | 0:6c56fb4bc5f0 | 907 | printf("verifying programmed sector at addr %lu\n", (uint32_t)firstBlock.addr); |
nexpaq | 0:6c56fb4bc5f0 | 908 | if (info.program_unit >= sizeof(BYTE_PATTERN)) { |
nexpaq | 0:6c56fb4bc5f0 | 909 | verifyBytePattern(firstBlock.addr, (N_UNITS * info.program_unit), BYTE_PATTERN); |
nexpaq | 0:6c56fb4bc5f0 | 910 | } else { |
nexpaq | 0:6c56fb4bc5f0 | 911 | verifyBytePattern(firstBlock.addr, (N_UNITS * info.program_unit), ((const uint8_t *)&BYTE_PATTERN)[0]); |
nexpaq | 0:6c56fb4bc5f0 | 912 | } |
nexpaq | 0:6c56fb4bc5f0 | 913 | |
nexpaq | 0:6c56fb4bc5f0 | 914 | return CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 915 | } |
nexpaq | 0:6c56fb4bc5f0 | 916 | } |
nexpaq | 0:6c56fb4bc5f0 | 917 | } |
nexpaq | 0:6c56fb4bc5f0 | 918 | |
nexpaq | 0:6c56fb4bc5f0 | 919 | return CaseNext; |
nexpaq | 0:6c56fb4bc5f0 | 920 | } |
nexpaq | 0:6c56fb4bc5f0 | 921 | |
nexpaq | 0:6c56fb4bc5f0 | 922 | #ifndef AVOID_GREENTEA |
nexpaq | 0:6c56fb4bc5f0 | 923 | // Custom setup handler required for proper Greentea support |
nexpaq | 0:6c56fb4bc5f0 | 924 | utest::v1::status_t greentea_setup(const size_t number_of_cases) |
nexpaq | 0:6c56fb4bc5f0 | 925 | { |
nexpaq | 0:6c56fb4bc5f0 | 926 | GREENTEA_SETUP(60, "default_auto"); |
nexpaq | 0:6c56fb4bc5f0 | 927 | // Call the default reporting function |
nexpaq | 0:6c56fb4bc5f0 | 928 | return greentea_test_setup_handler(number_of_cases); |
nexpaq | 0:6c56fb4bc5f0 | 929 | } |
nexpaq | 0:6c56fb4bc5f0 | 930 | #else |
nexpaq | 0:6c56fb4bc5f0 | 931 | status_t default_setup(const size_t) |
nexpaq | 0:6c56fb4bc5f0 | 932 | { |
nexpaq | 0:6c56fb4bc5f0 | 933 | return STATUS_CONTINUE; |
nexpaq | 0:6c56fb4bc5f0 | 934 | } |
nexpaq | 0:6c56fb4bc5f0 | 935 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 936 | |
nexpaq | 0:6c56fb4bc5f0 | 937 | // Specify all your test cases here |
nexpaq | 0:6c56fb4bc5f0 | 938 | Case cases[] = { |
nexpaq | 0:6c56fb4bc5f0 | 939 | Case("get version", test_getVersion), |
nexpaq | 0:6c56fb4bc5f0 | 940 | Case("get capabilities", test_getCapabilities), |
nexpaq | 0:6c56fb4bc5f0 | 941 | Case("get info", test_getInfo), |
nexpaq | 0:6c56fb4bc5f0 | 942 | Case("initialize", test_initialize), |
nexpaq | 0:6c56fb4bc5f0 | 943 | Case("uninitialize", test_uninitialize), |
nexpaq | 0:6c56fb4bc5f0 | 944 | Case("power control", test_powerControl), |
nexpaq | 0:6c56fb4bc5f0 | 945 | Case("erase all", test_eraseAll), |
nexpaq | 0:6c56fb4bc5f0 | 946 | Case("read data", test_readData), |
nexpaq | 0:6c56fb4bc5f0 | 947 | Case("erase with invalid parameters", test_eraseWithInvalidParameters), |
nexpaq | 0:6c56fb4bc5f0 | 948 | Case("erase single unit", test_erase<1>), |
nexpaq | 0:6c56fb4bc5f0 | 949 | Case("erase two units", test_erase<2>), |
nexpaq | 0:6c56fb4bc5f0 | 950 | Case("erase four units", test_erase<4>), |
nexpaq | 0:6c56fb4bc5f0 | 951 | Case("erase eight units", test_erase<8>), |
nexpaq | 0:6c56fb4bc5f0 | 952 | Case("program data with invalid parameters", test_programDataWithInvalidParameters), |
nexpaq | 0:6c56fb4bc5f0 | 953 | Case("program data using program_unit", test_programDataUsingProgramUnit), |
nexpaq | 0:6c56fb4bc5f0 | 954 | Case("program data using optimal_program_unit", test_programDataUsingOptimalProgramUnit), |
nexpaq | 0:6c56fb4bc5f0 | 955 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<1>), |
nexpaq | 0:6c56fb4bc5f0 | 956 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<2>), |
nexpaq | 0:6c56fb4bc5f0 | 957 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<7>), |
nexpaq | 0:6c56fb4bc5f0 | 958 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<8>), |
nexpaq | 0:6c56fb4bc5f0 | 959 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<9>), |
nexpaq | 0:6c56fb4bc5f0 | 960 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<31>), |
nexpaq | 0:6c56fb4bc5f0 | 961 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<32>), |
nexpaq | 0:6c56fb4bc5f0 | 962 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<33>), |
nexpaq | 0:6c56fb4bc5f0 | 963 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<127>), |
nexpaq | 0:6c56fb4bc5f0 | 964 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<128>), |
nexpaq | 0:6c56fb4bc5f0 | 965 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<129>), |
nexpaq | 0:6c56fb4bc5f0 | 966 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<1023>), |
nexpaq | 0:6c56fb4bc5f0 | 967 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<1024>), |
nexpaq | 0:6c56fb4bc5f0 | 968 | Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<1025>), |
nexpaq | 0:6c56fb4bc5f0 | 969 | }; |
nexpaq | 0:6c56fb4bc5f0 | 970 | |
nexpaq | 0:6c56fb4bc5f0 | 971 | // Declare your test specification with a custom setup handler |
nexpaq | 0:6c56fb4bc5f0 | 972 | #ifndef AVOID_GREENTEA |
nexpaq | 0:6c56fb4bc5f0 | 973 | Specification specification(greentea_setup, cases); |
nexpaq | 0:6c56fb4bc5f0 | 974 | #else |
nexpaq | 0:6c56fb4bc5f0 | 975 | Specification specification(default_setup, cases); |
nexpaq | 0:6c56fb4bc5f0 | 976 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 977 | |
nexpaq | 0:6c56fb4bc5f0 | 978 | int main(int argc, char** argv) |
nexpaq | 0:6c56fb4bc5f0 | 979 | { |
nexpaq | 0:6c56fb4bc5f0 | 980 | // Run the test specification |
nexpaq | 0:6c56fb4bc5f0 | 981 | Harness::run(specification); |
nexpaq | 0:6c56fb4bc5f0 | 982 | } |