BA / SerialCom

Fork of OmniWheels by Gustav Atmel

Committer:
gustavatmel
Date:
Tue May 01 15:55:34 2018 +0000
Revision:
2:798925c9e4a8
Parent:
1:9c5af431a1f1
bluetooth

Who changed what in which revision?

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