Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Dec 16 16:27:57 2016 +0000
Revision:
3:1198227e6421
Parent:
0:5c4d7b2438d3
Changed ADC scale for MAX32625 platforms to 1.2V full scale to match MAX32630 platforms

Who changed what in which revision?

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