Preliminary main mbed library for nexpaq development

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?

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