Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers basicAPI.cpp Source File

basicAPI.cpp

00001 /*
00002  * Copyright (c) 2006-2016, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #if !DEVICE_STORAGE
00019     #error [NOT_SUPPORTED] Storage not supported for this target
00020 #endif
00021 
00022 #ifndef AVOID_GREENTEA
00023 #include "greentea-client/test_env.h"
00024 #endif
00025 #include "utest/utest.h"
00026 #include "unity/unity.h"
00027 
00028 #include "storage_abstraction/Driver_Storage.h"
00029 
00030 #include <string.h>
00031 #include <inttypes.h>
00032 
00033 using namespace utest::v1;
00034 
00035 extern ARM_DRIVER_STORAGE ARM_Driver_Storage_MTD_K64F;
00036 ARM_DRIVER_STORAGE *drv = &ARM_Driver_Storage_MTD_K64F;
00037 
00038 /* temporary buffer to hold data for testing. */
00039 static const unsigned BUFFER_SIZE = 16384;
00040 static uint8_t buffer[BUFFER_SIZE];
00041 
00042 /* forward declaration */
00043 void initializationCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation);
00044 
00045 /*
00046  * Most tests need some basic initialization of the driver before proceeding
00047  * with their operations.
00048  */
00049 static control_t preambleForBasicInitialization(void)
00050 {
00051     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00052 
00053     int32_t rc = drv->Initialize(initializationCompleteCallback);
00054     TEST_ASSERT(rc >= ARM_DRIVER_OK);
00055     if (rc == ARM_DRIVER_OK) {
00056         TEST_ASSERT_EQUAL(1,  capabilities.asynchronous_ops);
00057         return CaseTimeout(200) + CaseRepeatAll;
00058     } else {
00059         TEST_ASSERT(rc == 1);
00060         return CaseRepeatAll;
00061     }
00062 }
00063 
00064 template<typename T>
00065 static void verifyBytePattern(uint64_t addr, size_t sizeofData, T bytePattern)
00066 {
00067     /* we're limited by BUFFER_SIZE in how much we can verify in a single iteration;
00068      * the variable 'amountBeingVerified' captures the size being verified in each
00069      * iteration. */
00070     size_t amountBeingVerified = sizeofData;
00071     if (amountBeingVerified > BUFFER_SIZE) {
00072         amountBeingVerified = BUFFER_SIZE;
00073     }
00074     TEST_ASSERT((amountBeingVerified % sizeof(T)) == 0);
00075 
00076     while (sizeofData) {
00077         int32_t rc = drv->ReadData(addr, buffer, amountBeingVerified);
00078         TEST_ASSERT_EQUAL(amountBeingVerified, rc);
00079         for (size_t index = 0; index < amountBeingVerified / sizeof(T); index++) {
00080             // if (bytePattern != ((const T *)buffer)[index]) {
00081             //     printf("%u: expected %x, found %x\n", index, bytePattern, ((const T *)buffer)[index]);
00082             // }
00083             TEST_ASSERT_EQUAL(bytePattern, ((const T *)buffer)[index]);
00084         }
00085 
00086         sizeofData -= amountBeingVerified;
00087         addr       += amountBeingVerified;
00088     }
00089 }
00090 
00091 void test_getVersion()
00092 {
00093     ARM_DRIVER_VERSION version = drv->GetVersion();
00094 
00095     TEST_ASSERT_EQUAL(version.api, ARM_STORAGE_API_VERSION);
00096     TEST_ASSERT_EQUAL(version.drv, ARM_DRIVER_VERSION_MAJOR_MINOR(1,00));
00097 }
00098 
00099 void test_getCapabilities()
00100 {
00101     TEST_ASSERT(sizeof(ARM_STORAGE_CAPABILITIES) == sizeof(uint32_t));
00102 
00103     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00104     TEST_ASSERT_EQUAL(0, capabilities.reserved);
00105 }
00106 
00107 void test_getInfo()
00108 {
00109     ARM_STORAGE_INFO info = {};
00110     int32_t rc = drv->GetInfo(&info);
00111     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00112 
00113     TEST_ASSERT_EQUAL(0, info.security.reserved1);
00114     TEST_ASSERT_EQUAL(0, info.security.reserved2);
00115     TEST_ASSERT((info.program_cycles == ARM_STORAGE_PROGRAM_CYCLES_INFINITE) || (info.program_cycles > 0));
00116     TEST_ASSERT(info.total_storage > 0);
00117 }
00118 
00119 void initializationCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation)
00120 {
00121     printf("init complete callback\n");
00122     TEST_ASSERT_EQUAL(1, status);
00123     TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_INITIALIZE);
00124 
00125     Harness::validate_callback();
00126 }
00127 
00128 control_t test_initialize(const size_t call_count)
00129 {
00130     static const unsigned REPEAT_INSTANCES = 3;
00131     printf("in test_initialize with call_count %u\n", call_count);
00132 
00133     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00134 
00135     int32_t rc = drv->Initialize(initializationCompleteCallback);
00136     TEST_ASSERT(rc >= ARM_DRIVER_OK);
00137     if (rc == ARM_DRIVER_OK) {
00138         TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00139         return (call_count < REPEAT_INSTANCES) ? (CaseTimeout(200) + CaseRepeatAll) : (control_t) CaseNext;
00140     }
00141 
00142     TEST_ASSERT(rc == 1);
00143     return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext;
00144 }
00145 
00146 void uninitializationCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation)
00147 {
00148     printf("uninit complete callback\n");
00149     TEST_ASSERT_EQUAL(status, ARM_DRIVER_OK);
00150     TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_UNINITIALIZE);
00151 
00152     Harness::validate_callback();
00153 }
00154 
00155 control_t test_uninitialize(const size_t call_count)
00156 {
00157     static const unsigned REPEAT_INSTANCES = 3;
00158     printf("in test_uninitialize with call_count %u\n", call_count);
00159 
00160     /* update the completion callback. */
00161     if (call_count == 1) {
00162         /* Achieve basic initialization for the driver before anything else. */
00163         return preambleForBasicInitialization();
00164     }
00165 
00166     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00167 
00168     int32_t rc = drv->Uninitialize();
00169     if (call_count > 2) {
00170         /* the driver should return some error for repeated un-initialization. */
00171         TEST_ASSERT(rc < ARM_DRIVER_OK);
00172         return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext;
00173     }
00174     TEST_ASSERT(rc >= ARM_DRIVER_OK);
00175     if (rc == ARM_DRIVER_OK) {
00176         /* asynchronous operation */
00177         TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00178         return CaseTimeout(200) + CaseRepeatAll;
00179     }
00180 
00181     /* synchronous operation */
00182     TEST_ASSERT(rc == 1);
00183     return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext;
00184 }
00185 
00186 void powerControlCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation)
00187 {
00188     printf("power control complete callback\n");
00189     TEST_ASSERT_EQUAL(status, ARM_DRIVER_OK);
00190     TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_POWER_CONTROL);
00191 
00192     Harness::validate_callback();
00193 }
00194 
00195 control_t test_powerControl(const size_t call_count)
00196 {
00197     static const unsigned REPEAT_INSTANCES = 2;
00198     printf("in test_powerControl with call_count %u\n", call_count);
00199 
00200     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00201 
00202     if (call_count == 1) {
00203         /* Achieve basic initialization for the driver before anything else. */
00204         return preambleForBasicInitialization();
00205     }
00206 
00207     /* Update the completion callback to 'powerControlCompleteCallback'. */
00208     if (call_count == 2) {
00209         int32_t rc = drv->Initialize(powerControlCompleteCallback);
00210         TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been
00211                                * initialized by the previous iteration. */
00212     }
00213 
00214     int32_t rc = drv->PowerControl(ARM_POWER_FULL);
00215     if (rc == ARM_DRIVER_OK) {
00216         TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00217         return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200);
00218     } else {
00219         TEST_ASSERT(rc == 1);
00220         return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext;
00221     }
00222 }
00223 
00224 void readDataCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation)
00225 {
00226     printf("ReadData complete callback\n");
00227     TEST_ASSERT_EQUAL(status, ARM_DRIVER_OK);
00228     TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_READ_DATA);
00229 
00230     Harness::validate_callback();
00231 }
00232 
00233 control_t test_readData(const size_t call_count)
00234 {
00235     static const unsigned REPEAT_INSTANCES = 5;
00236     printf("in test_readData with call_count %u\n", call_count);
00237 
00238     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00239 
00240     if (call_count == 1) {
00241         /* Achieve basic initialization for the driver before anything else. */
00242         return preambleForBasicInitialization();
00243     }
00244 
00245     /* Update the completion callback to 'readDataCompleteCallback'. */
00246     int32_t rc;
00247     if (call_count == 2) {
00248         rc = drv->Initialize(readDataCompleteCallback);
00249         TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been
00250                                * initialized by the previous iteration. */
00251     }
00252 
00253     /* Get the first block. */
00254     ARM_STORAGE_BLOCK firstBlock;
00255     drv->GetNextBlock(NULL, &firstBlock); /* get first block */
00256     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
00257     TEST_ASSERT(firstBlock.size > 0);
00258 
00259     ARM_STORAGE_INFO info;
00260     rc = drv->GetInfo(&info);
00261     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00262 
00263     TEST_ASSERT(info.program_unit <= BUFFER_SIZE);
00264     TEST_ASSERT(firstBlock.size >= (REPEAT_INSTANCES - 1) * info.program_unit);
00265 
00266     /* choose an increasing address for each iteration. */
00267     uint64_t addr = firstBlock.addr + (call_count - 1) * info.program_unit;
00268     size_t sizeofData = info.program_unit;
00269 
00270     rc = drv->ReadData(addr, buffer, sizeofData);
00271     if (rc == ARM_DRIVER_OK) {
00272         TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00273         return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200);
00274     } else {
00275         TEST_ASSERT(rc > 0);
00276         return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext;
00277     }
00278 }
00279 
00280 void programDataCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation)
00281 {
00282     TEST_ASSERT(status >= 0);
00283     static unsigned programIteration = 0;
00284 
00285     static const uint32_t BYTE_PATTERN = 0xAA551122;
00286     ARM_STORAGE_BLOCK firstBlock;
00287     drv->GetNextBlock(NULL, &firstBlock); /* get first block */
00288     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
00289 
00290     ARM_STORAGE_INFO info;
00291     int32_t rc = drv->GetInfo(&info);
00292     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00293 
00294     const uint64_t addr = firstBlock.addr + programIteration * firstBlock.attributes.erase_unit;
00295     size_t sizeofData = info.program_unit;
00296     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00297 
00298     TEST_ASSERT((operation == ARM_STORAGE_OPERATION_ERASE) || (operation == ARM_STORAGE_OPERATION_PROGRAM_DATA));
00299     if (operation == ARM_STORAGE_OPERATION_ERASE) {
00300         // printf("programming %u bytes at address %lu with pattern 0x%" PRIx32 "\n", sizeofData, (uint32_t)addr, BYTE_PATTERN);
00301 
00302         size_t sizeofData = info.program_unit;
00303         TEST_ASSERT(BUFFER_SIZE >= sizeofData);
00304         TEST_ASSERT((sizeofData % sizeof(uint32_t)) == 0);
00305         for (size_t index = 0; index < sizeofData / sizeof(uint32_t); index++) {
00306             ((uint32_t *)buffer)[index] = BYTE_PATTERN;
00307         }
00308 
00309         status = drv->ProgramData(addr, buffer, sizeofData);
00310         if (status < ARM_DRIVER_OK) {
00311             return; /* failure. this will trigger a timeout and cause test failure. */
00312         }
00313         if (status == ARM_DRIVER_OK) {
00314             TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00315             return; /* We've successfully pended a programData operation; we'll have another
00316                      * invocation of this callback when programming completes. */
00317         }
00318     }
00319 
00320     /* We come here either because of completion for program-data or as a very
00321      * unlikely fall through from synchronous completion of program-data (above). */
00322 
00323 #ifndef __CC_ARM
00324     printf("verifying programmed sector at addr %lu\n", (uint32_t)addr);
00325 #endif
00326     verifyBytePattern(addr, sizeofData, BYTE_PATTERN);
00327     ++programIteration;
00328 
00329     Harness::validate_callback();
00330 }
00331 
00332 control_t test_programDataUsingProgramUnit(const size_t call_count)
00333 {
00334     static const unsigned REPEAT_INSTANCES = 5;
00335     printf("in test_programDataUsingProgramUnit with call_count %u\n", call_count);
00336 
00337     if (call_count == 1) {
00338         /* Achieve basic initialization for the driver before anything else. */
00339         return preambleForBasicInitialization();
00340     }
00341 
00342     /* Get the first block. */
00343     ARM_STORAGE_BLOCK firstBlock;
00344     drv->GetNextBlock(NULL, &firstBlock); /* get first block */
00345     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
00346     TEST_ASSERT(firstBlock.size > 0);
00347 
00348     ARM_STORAGE_INFO info;
00349     int32_t rc = drv->GetInfo(&info);
00350     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00351 
00352     TEST_ASSERT(info.program_unit <= firstBlock.attributes.erase_unit);
00353     TEST_ASSERT(firstBlock.size >= (REPEAT_INSTANCES - 1) * firstBlock.attributes.erase_unit);
00354 
00355     /* initialize the buffer to hold the pattern. */
00356     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00357 
00358     /* Update the completion callback to 'programDataCompleteCallback'. */
00359     if (call_count == 2) {
00360         int32_t rc = drv->Initialize(programDataCompleteCallback);
00361         TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been
00362                                * initialized by the previous iteration. */
00363     }
00364 
00365     /* choose an increasing address for each iteration. */
00366     uint64_t addr = firstBlock.addr + (call_count - 2) * firstBlock.attributes.erase_unit;
00367 
00368     /* erase the sector at 'addr' */
00369     printf("erasing sector at addr %lu\n", (uint32_t)addr);
00370     rc = drv->Erase(addr, firstBlock.attributes.erase_unit);
00371     TEST_ASSERT(rc >= 0);
00372     if (rc == ARM_DRIVER_OK) {
00373         TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00374         return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200);
00375     } else {
00376         TEST_ASSERT_EQUAL(firstBlock.attributes.erase_unit, rc);
00377         verifyBytePattern(addr, firstBlock.attributes.erase_unit, info.erased_value ? (uint8_t)0xFF : (uint8_t)0);
00378 
00379         static const uint32_t BYTE_PATTERN = 0xAA551122;
00380         size_t sizeofData = info.program_unit;
00381         TEST_ASSERT(BUFFER_SIZE >= sizeofData);
00382         TEST_ASSERT((sizeofData % sizeof(uint32_t)) == 0);
00383         for (size_t index = 0; index < sizeofData / sizeof(uint32_t); index++) {
00384             ((uint32_t *)buffer)[index] = BYTE_PATTERN;
00385         }
00386 
00387         /* program the sector at addr */
00388         // printf("programming %u bytes at address %lu with pattern 0x%" PRIx32 "\n", sizeofData, (uint32_t)addr, BYTE_PATTERN);
00389         rc = drv->ProgramData((uint32_t)addr, buffer, sizeofData);
00390         if (rc == ARM_DRIVER_OK) {
00391             TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00392             return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200);
00393         } else {
00394             TEST_ASSERT(rc > 0);
00395 
00396             printf("verifying programmed sector at addr %lu\n", (uint32_t)addr);
00397             verifyBytePattern(addr, sizeofData, BYTE_PATTERN);
00398 
00399             return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext;
00400         }
00401     }
00402 }
00403 
00404 void programDataOptimalCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation)
00405 {
00406     TEST_ASSERT(status >= 0);
00407     static unsigned programIteration = 0;
00408 
00409     static const uint8_t BYTE_PATTERN = 0xAA;
00410     ARM_STORAGE_BLOCK firstBlock;
00411     drv->GetNextBlock(NULL, &firstBlock); /* get first block */
00412     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
00413     const uint64_t addr = firstBlock.addr + programIteration * firstBlock.attributes.erase_unit;
00414 
00415     ARM_STORAGE_INFO info;
00416     int32_t rc = drv->GetInfo(&info);
00417     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00418 
00419     size_t sizeofData = info.optimal_program_unit;
00420     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00421 
00422     TEST_ASSERT((operation == ARM_STORAGE_OPERATION_ERASE) || (operation == ARM_STORAGE_OPERATION_PROGRAM_DATA));
00423     if (operation == ARM_STORAGE_OPERATION_ERASE) {
00424 #ifndef __CC_ARM
00425         printf("programming %u bytes at address %lu with pattern 0x%x\n", sizeofData, (uint32_t)addr, BYTE_PATTERN);
00426 #endif
00427         size_t sizeofData = info.optimal_program_unit;
00428         TEST_ASSERT(BUFFER_SIZE >= sizeofData);
00429         memset(buffer, BYTE_PATTERN, sizeofData);
00430 
00431         status = drv->ProgramData(addr, buffer, sizeofData);
00432         if (status < ARM_DRIVER_OK) {
00433             return; /* failure. this will trigger a timeout and cause test failure. */
00434         }
00435         if (status == ARM_DRIVER_OK) {
00436             TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00437             return; /* We've successfully pended a programData operation; we'll have another
00438                      * invocation of this callback when programming completes. */
00439         }
00440     }
00441 
00442     /* We come here either because of completion for program-data or as a very
00443      * unlikely fall through from synchronous completion of program-data (above). */
00444 
00445 #ifndef __CC_ARM
00446     printf("verifying programmed sector at addr %lu\n", (uint32_t)addr);
00447 #endif
00448     verifyBytePattern(addr, sizeofData, BYTE_PATTERN);
00449     ++programIteration;
00450 
00451     Harness::validate_callback();
00452 }
00453 
00454 control_t test_programDataUsingOptimalProgramUnit(const size_t call_count)
00455 {
00456     static const unsigned REPEAT_INSTANCES = 5;
00457     printf("in test_programDataUsingOptimalProgramUnit with call_count %u\n", call_count);
00458 
00459     if (call_count == 1) {
00460         /* Achieve basic initialization for the driver before anything else. */
00461         return preambleForBasicInitialization();
00462     }
00463 
00464     /* Get the first block. */
00465     ARM_STORAGE_BLOCK firstBlock;
00466     drv->GetNextBlock(NULL, &firstBlock); /* get first block */
00467     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
00468     TEST_ASSERT(firstBlock.size > 0);
00469 
00470     ARM_STORAGE_INFO info;
00471     int32_t rc = drv->GetInfo(&info);
00472     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00473 
00474     TEST_ASSERT(info.optimal_program_unit <= firstBlock.attributes.erase_unit);
00475     TEST_ASSERT(firstBlock.size >= (REPEAT_INSTANCES - 1) * firstBlock.attributes.erase_unit);
00476 
00477     /* initialize the buffer to hold the pattern. */
00478     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00479 
00480     /* Update the completion callback to 'programDataCompleteCallback'. */
00481     if (call_count == 2) {
00482         int32_t rc = drv->Initialize(programDataOptimalCompleteCallback);
00483         TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been
00484                                * initialized by the previous iteration. */
00485     }
00486 
00487     /* choose an increasing address for each iteration. */
00488     uint64_t addr = firstBlock.addr + (call_count - 2) * firstBlock.attributes.erase_unit;
00489 
00490     /* erase the sector at 'addr' */
00491     printf("erasing sector at addr %lu\n", (uint32_t)addr);
00492     rc = drv->Erase(addr, firstBlock.attributes.erase_unit);
00493     TEST_ASSERT(rc >= 0);
00494     if (rc == ARM_DRIVER_OK) {
00495         TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00496         return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200);
00497     } else {
00498         TEST_ASSERT_EQUAL(firstBlock.attributes.erase_unit, rc);
00499         verifyBytePattern(addr, firstBlock.attributes.erase_unit, info.erased_value ? (uint8_t)0xFF : (uint8_t)0);
00500 
00501         static const uint8_t BYTE_PATTERN = 0xAA;
00502         size_t sizeofData = info.optimal_program_unit;
00503         TEST_ASSERT(BUFFER_SIZE >= sizeofData);
00504         memset(buffer, BYTE_PATTERN, sizeofData);
00505 
00506         /* program the sector at addr */
00507         printf("programming %u bytes at address %lu with pattern 0x%x\n", sizeofData, (uint32_t)addr, BYTE_PATTERN);
00508         rc = drv->ProgramData((uint32_t)addr, buffer, sizeofData);
00509         if (rc == ARM_DRIVER_OK) {
00510             TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00511             return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200);
00512         } else {
00513             TEST_ASSERT_EQUAL(sizeofData, rc);
00514 
00515             printf("verifying programmed sector at addr %lu\n", (uint32_t)addr);
00516             verifyBytePattern(addr, sizeofData, BYTE_PATTERN);
00517 
00518             return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext;
00519         }
00520     }
00521 }
00522 
00523 void test_eraseWithInvalidParameters(void)
00524 {
00525     int32_t rc;
00526 
00527     rc = drv->Erase(0, 0);
00528     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00529 
00530     /* operate before the start of the first block. */
00531     ARM_STORAGE_BLOCK block;
00532     rc = drv->GetNextBlock(NULL, &block); /* get the first block */
00533     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00534     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&block));
00535     TEST_ASSERT(block.size > 0);
00536     rc = drv->Erase(block.addr - 1, BUFFER_SIZE);
00537     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00538 
00539     /* operate at an address past the end of the last block */
00540     uint64_t endAddr = block.addr + block.size;
00541     for (; ARM_STORAGE_VALID_BLOCK(&block); drv->GetNextBlock(&block, &block)) {
00542         endAddr = block.addr + block.size;
00543     }
00544     rc = drv->Erase(endAddr + 1, BUFFER_SIZE);
00545     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00546 
00547     ARM_STORAGE_INFO info;
00548     rc = drv->GetInfo(&info);
00549     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00550 
00551     drv->GetNextBlock(NULL, &block); /* get the first block */
00552     TEST_ASSERT(block.size >= block.attributes.erase_unit);
00553     TEST_ASSERT((block.size % block.attributes.erase_unit) == 0);
00554 
00555     rc = drv->Erase(block.addr + 1, block.attributes.erase_unit);
00556     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00557     rc = drv->Erase(block.addr, block.attributes.erase_unit - 1);
00558     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00559     rc = drv->Erase(block.addr, block.attributes.erase_unit + 1);
00560     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00561     rc = drv->Erase(block.addr, block.attributes.erase_unit / 2);
00562     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00563 }
00564 
00565 template<size_t ERASE_UNITS_PER_ITERATION>
00566 void eraseCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation)
00567 {
00568     static unsigned eraseIteration = 0;
00569 #ifndef __CC_ARM
00570     printf("erase<%u> complete callback: iteration %u\n", ERASE_UNITS_PER_ITERATION, eraseIteration);
00571 #endif
00572     TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_ERASE);
00573 
00574     /* test that the actual sector has been erased */
00575     ARM_STORAGE_BLOCK firstBlock;
00576     drv->GetNextBlock(NULL, &firstBlock); /* get first block */
00577     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
00578     TEST_ASSERT_EQUAL(ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit, status);
00579 
00580     const uint64_t addr = firstBlock.addr + eraseIteration * ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit;
00581     ++eraseIteration;
00582 
00583     ARM_STORAGE_INFO info;
00584     int32_t rc = drv->GetInfo(&info);
00585     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00586 
00587     //printf("testing erased sector at addr %lu", (uint32_t)addr);
00588     verifyBytePattern(addr, ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit, info.erased_value ? (uint8_t)0xFF : (uint8_t)0);
00589 
00590     Harness::validate_callback();
00591 }
00592 
00593 template <size_t ERASE_UNITS_PER_ITERATION>
00594 control_t test_erase(const size_t call_count)
00595 {
00596     static const unsigned REPEAT_INSTANCES = 5;
00597     printf("in test_erase<%u> with call_count %u\n", ERASE_UNITS_PER_ITERATION, call_count);
00598 
00599     if (call_count == 1) {
00600         /* Achieve basic initialization for the driver before anything else. */
00601         return preambleForBasicInitialization();
00602     }
00603 
00604     /* Get the first block. */
00605     ARM_STORAGE_BLOCK firstBlock;
00606     drv->GetNextBlock(NULL, &firstBlock); /* get first block */
00607     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
00608     TEST_ASSERT(firstBlock.size > 0);
00609     if (firstBlock.size < ((call_count - 1) * ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit)) {
00610         printf("firstBlock isn't large enough to support instance %u of test_erase<%u>\n", call_count, ERASE_UNITS_PER_ITERATION);
00611         return CaseNext;
00612     }
00613 
00614     /* Update the completion callback to 'eraseCompleteCallback'. */
00615     if (call_count == 2) {
00616         int32_t rc = drv->Initialize(eraseCompleteCallback<ERASE_UNITS_PER_ITERATION>);
00617         TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been
00618                                * initialized by the previous iteration. */
00619     }
00620 
00621     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00622 
00623     /* choose an increasing address for each iteration. */
00624     uint64_t addr = firstBlock.addr + (call_count - 2) * ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit;
00625 
00626     printf("erasing %lu bytes at addr %lu\n", (ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit), (uint32_t)addr);
00627     int32_t rc = drv->Erase(addr, ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit);
00628     if (rc == ARM_DRIVER_OK) {
00629         TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00630         return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200);
00631     } else {
00632         TEST_ASSERT_EQUAL(ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit, rc);
00633 
00634         ARM_STORAGE_INFO info;
00635         rc = drv->GetInfo(&info);
00636         TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00637 
00638         /* test that the actual sector has been erased */
00639         printf("testing erased sector at addr %lu\n", (uint32_t)addr);
00640         verifyBytePattern(addr, ERASE_UNITS_PER_ITERATION * firstBlock.attributes.erase_unit, (uint8_t)0xFF);
00641 
00642         return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext;
00643     }
00644 }
00645 
00646 void eraseChipCompleteCallback(int32_t status, ARM_STORAGE_OPERATION operation)
00647 {
00648 #ifndef __CC_ARM
00649     printf("eraseChip complete callback\n");
00650 #endif
00651     TEST_ASSERT_EQUAL(status, ARM_DRIVER_OK);
00652     TEST_ASSERT_EQUAL(operation, ARM_STORAGE_OPERATION_ERASE_ALL);
00653 
00654     ARM_STORAGE_BLOCK firstBlock;
00655     drv->GetNextBlock(NULL, &firstBlock); /* get first block */
00656     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
00657     uint64_t addr = firstBlock.addr;
00658 
00659     /* test that the flash has been erased */
00660 #ifndef __CC_ARM
00661     printf("testing erased chip\n");
00662 #endif
00663     unsigned index = 0;
00664     static const unsigned MAX_VERIFY_ITERATIONS = 5;
00665     while ((index < MAX_VERIFY_ITERATIONS) && (addr < (firstBlock.addr + firstBlock.size))) {
00666         // printf("testing erased chip at addr %lu\n", (uint32_t)addr);
00667         verifyBytePattern(addr, firstBlock.attributes.erase_unit, (uint8_t)0xFF);
00668 
00669         index++;
00670         addr += firstBlock.attributes.erase_unit;
00671     }
00672 
00673     Harness::validate_callback();
00674 }
00675 
00676 control_t test_eraseAll(const size_t call_count)
00677 {
00678     static const unsigned REPEAT_INSTANCES = 5;
00679     printf("in test_eraseAll with call_count %u\n", call_count);
00680 
00681     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00682     if (!capabilities.erase_all) {
00683         printf("chip erase not supported on this flash\n");
00684         return CaseNext;
00685     }
00686 
00687     if (call_count == 1) {
00688         /* Achieve basic initialization for the driver before anything else. */
00689         return preambleForBasicInitialization();
00690     }
00691 
00692     /* Update the completion callback to 'eraseChipCompleteCallback'. */
00693     if (call_count == 2) {
00694         int32_t rc = drv->Initialize(eraseChipCompleteCallback);
00695         TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been
00696                                * initialized by the previous iteration. */
00697     }
00698 
00699     /* Get the first block. */
00700     ARM_STORAGE_BLOCK firstBlock;
00701     drv->GetNextBlock(NULL, &firstBlock); /* get first block */
00702     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
00703     TEST_ASSERT(firstBlock.size > 0);
00704     uint64_t addr = firstBlock.addr;
00705     printf("erasing chip\n");
00706 
00707     int32_t rc = drv->EraseAll();
00708     if (rc == ARM_DRIVER_OK) {
00709         TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00710         return (call_count < REPEAT_INSTANCES) ? CaseTimeout(200) + CaseRepeatAll: CaseTimeout(200);
00711     } else {
00712         TEST_ASSERT(rc == 1);
00713 
00714         /* test that the flash has been erased */
00715         unsigned index = 0;
00716         static const unsigned MAX_VERIFY_ITERATIONS = 5;
00717         while ((index < MAX_VERIFY_ITERATIONS) && (addr < (firstBlock.addr + firstBlock.size))) {
00718             //printf("testing erased chip at addr %lu", (uint32_t)addr);
00719             ARM_STORAGE_INFO info;
00720             rc = drv->GetInfo(&info);
00721             TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00722 
00723             verifyBytePattern(addr, firstBlock.attributes.erase_unit, info.erased_value ? (uint8_t)0xFF : (uint8_t)0);
00724 
00725             index++;
00726             addr += firstBlock.attributes.erase_unit;
00727         }
00728 
00729         return (call_count < REPEAT_INSTANCES) ? CaseRepeatAll : CaseNext;
00730     }
00731 }
00732 
00733 void test_programDataWithInvalidParameters(void)
00734 {
00735     int32_t rc;
00736 
00737     rc = drv->ProgramData(0, NULL, 0);
00738     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00739     rc = drv->ProgramData(0, buffer, 0);
00740     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00741     rc = drv->ProgramData(0, NULL, BUFFER_SIZE);
00742     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00743 
00744     /* operate before the start of the first block. */
00745     ARM_STORAGE_BLOCK block;
00746     rc = drv->GetNextBlock(NULL, &block); /* get the first block */
00747     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00748     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&block));
00749     TEST_ASSERT(block.size > 0);
00750     rc = drv->ProgramData(block.addr - 1, buffer, BUFFER_SIZE);
00751     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00752 
00753     /* operate at an address past the end of the last block */
00754     uint64_t endAddr = block.addr + block.size;
00755     for (; ARM_STORAGE_VALID_BLOCK(&block); drv->GetNextBlock(&block, &block)) {
00756         endAddr = block.addr + block.size;
00757     }
00758     rc = drv->ProgramData(endAddr + 1, buffer, BUFFER_SIZE);
00759     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00760 
00761     ARM_STORAGE_INFO info;
00762     rc = drv->GetInfo(&info);
00763     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00764     if (info.program_unit <= 1) {
00765         return; /* if program_unit is 1 (or 0), we can't proceed with any alignment tests */
00766     }
00767 
00768     drv->GetNextBlock(NULL, &block); /* get the first block */
00769 
00770     TEST_ASSERT(block.size >= info.program_unit);
00771 
00772     rc = drv->ProgramData(block.addr + 1, buffer, info.program_unit);
00773     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00774     rc = drv->ProgramData(block.addr, buffer, info.program_unit - 1);
00775     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00776     rc = drv->ProgramData(block.addr, buffer, info.program_unit + 1);
00777     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00778     rc = drv->ProgramData(block.addr, buffer, info.program_unit / 2);
00779     TEST_ASSERT_EQUAL(ARM_DRIVER_ERROR_PARAMETER, rc);
00780 }
00781 
00782 template <size_t N_UNITS>
00783 void programDataWithMultipleProgramUnitsCallback(int32_t status, ARM_STORAGE_OPERATION operation)
00784 {
00785     TEST_ASSERT(status >= ARM_DRIVER_OK);
00786 
00787     ARM_STORAGE_BLOCK firstBlock;
00788     drv->GetNextBlock(NULL, &firstBlock); /* get first block */
00789     TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
00790     TEST_ASSERT(firstBlock.size > 0);
00791 
00792     ARM_STORAGE_INFO info;
00793     int32_t rc = drv->GetInfo(&info);
00794     TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00795 
00796     ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00797 
00798     size_t rangeNeededForTest = (N_UNITS * info.program_unit);
00799     /* round-up range to the nearest erase_unit */
00800     rangeNeededForTest = ((rangeNeededForTest + firstBlock.attributes.erase_unit - 1) / firstBlock.attributes.erase_unit) * firstBlock.attributes.erase_unit;
00801 
00802     static const uint32_t BYTE_PATTERN = 0xABCDEF00;
00803 
00804     if (operation == ARM_STORAGE_OPERATION_ERASE) {
00805         TEST_ASSERT_EQUAL(rangeNeededForTest, status);
00806         TEST_ASSERT((N_UNITS * info.program_unit) <= BUFFER_SIZE);
00807 
00808         /* setup byte pattern in buffer */
00809         if (info.program_unit >= sizeof(BYTE_PATTERN)) {
00810             for (size_t index = 0; index < ((N_UNITS * info.program_unit) / sizeof(BYTE_PATTERN)); index++) {
00811                 ((uint32_t *)buffer)[index] = BYTE_PATTERN;
00812             }
00813         } else {
00814            for (size_t index = 0; index < ((N_UNITS * info.program_unit)); index++) {
00815                buffer[index] = ((const uint8_t *)&BYTE_PATTERN)[0];
00816            }
00817         }
00818 
00819 #ifndef __CC_ARM
00820         printf("Callback: programming %lu bytes at address %lu with pattern 0x%lx\n", (N_UNITS * info.program_unit), (uint32_t)firstBlock.addr, BYTE_PATTERN);
00821 #endif
00822         rc = drv->ProgramData(firstBlock.addr, buffer, (N_UNITS * info.program_unit));
00823         TEST_ASSERT(rc >= ARM_DRIVER_OK);
00824         if (rc == ARM_DRIVER_OK) {
00825             TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00826             return; /* We've successfully pended a programData operation; we'll have another
00827                      * invocation of this callback when programming completes. */
00828         }
00829 
00830         status = rc;
00831     }
00832 
00833     TEST_ASSERT_EQUAL((N_UNITS * info.program_unit), status);
00834 
00835 #ifndef __CC_ARM
00836     printf("Callback: verifying programmed sector at addr %lu\n", (uint32_t)firstBlock.addr);
00837 #endif
00838     if (info.program_unit >= sizeof(BYTE_PATTERN)) {
00839         verifyBytePattern(firstBlock.addr, (N_UNITS * info.program_unit), BYTE_PATTERN);
00840     } else {
00841         verifyBytePattern(firstBlock.addr, (N_UNITS * info.program_unit), ((const uint8_t *)&BYTE_PATTERN)[0]);
00842     }
00843 
00844     Harness::validate_callback();
00845 }
00846 
00847 template<size_t N_UNITS>
00848 control_t test_programDataWithMultipleProgramUnits(const size_t call_count)
00849 {
00850     int32_t rc;
00851     printf("in test_programDataWithMultipleProgramUnits<%u> with call_count %u\n", N_UNITS, call_count);
00852 
00853     if (call_count == 1) {
00854         /* Achieve basic initialization for the driver before anything else. */
00855         return preambleForBasicInitialization();
00856     }
00857 
00858     /* Update the completion callback to 'programDataWithMultipleProgramUnitsCallback'. */
00859     if (call_count == 2) {
00860         rc = drv->Initialize(programDataWithMultipleProgramUnitsCallback<N_UNITS>);
00861         TEST_ASSERT(rc == 1); /* Expect synchronous completion of initialization; the system must have been
00862                                * initialized by the previous iteration. */
00863 
00864         ARM_STORAGE_BLOCK firstBlock;
00865         drv->GetNextBlock(NULL, &firstBlock); /* get first block */
00866         TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
00867         TEST_ASSERT(firstBlock.size > 0);
00868 
00869         ARM_STORAGE_INFO info;
00870         int32_t rc = drv->GetInfo(&info);
00871         TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
00872 
00873         ARM_STORAGE_CAPABILITIES capabilities = drv->GetCapabilities();
00874 
00875         size_t rangeNeededForTest = (N_UNITS * info.program_unit);
00876         /* round-up range to the nearest erase_unit */
00877         rangeNeededForTest = ((rangeNeededForTest + firstBlock.attributes.erase_unit - 1) / firstBlock.attributes.erase_unit) * firstBlock.attributes.erase_unit;
00878         if (firstBlock.size < rangeNeededForTest) {
00879             printf("first block not large enough; rangeNeededForTest: %u\n", rangeNeededForTest);
00880             return CaseNext; /* first block isn't large enough for the intended operation */
00881         }
00882 
00883         if (rangeNeededForTest > BUFFER_SIZE) {
00884             printf("buffer (%u) not large enough; rangeNeededForTest: %u\n", BUFFER_SIZE, rangeNeededForTest);
00885             return CaseNext;
00886         }
00887 
00888         // printf("erasing %u bytes at addr %lu\n", rangeNeededForTest, (uint32_t)firstBlock.addr);
00889         rc = drv->Erase(firstBlock.addr, rangeNeededForTest);
00890         TEST_ASSERT(rc >= 0);
00891         if (rc == ARM_DRIVER_OK) {
00892             TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00893             return CaseTimeout(500);
00894         } else {
00895             TEST_ASSERT_EQUAL(rangeNeededForTest, rc);
00896 
00897             /* setup byte pattern in buffer */
00898             static const uint32_t BYTE_PATTERN = 0xABCDEF00;
00899             if (info.program_unit >= sizeof(BYTE_PATTERN)) {
00900                 for (size_t index = 0; index < ((N_UNITS * info.program_unit) / sizeof(BYTE_PATTERN)); index++) {
00901                     ((uint32_t *)buffer)[index] = BYTE_PATTERN;
00902                 }
00903             } else {
00904                for (size_t index = 0; index < ((N_UNITS * info.program_unit)); index++) {
00905                    buffer[index] = ((const uint8_t *)&BYTE_PATTERN)[0];
00906                }
00907             }
00908 
00909             printf("programming %lu bytes at address %lu with pattern 0x%lx\n", (N_UNITS * info.program_unit), (uint32_t)firstBlock.addr, BYTE_PATTERN);
00910             rc = drv->ProgramData(firstBlock.addr, buffer, (N_UNITS * info.program_unit));
00911             TEST_ASSERT(rc >= 0);
00912             if (rc == ARM_DRIVER_OK) {
00913                 TEST_ASSERT_EQUAL(1, capabilities.asynchronous_ops);
00914                 return CaseTimeout(500);
00915             } else {
00916                 TEST_ASSERT_EQUAL((N_UNITS * info.program_unit), rc);
00917 
00918                 printf("verifying programmed sector at addr %lu\n", (uint32_t)firstBlock.addr);
00919                 if (info.program_unit >= sizeof(BYTE_PATTERN)) {
00920                     verifyBytePattern(firstBlock.addr, (N_UNITS * info.program_unit), BYTE_PATTERN);
00921                 } else {
00922                     verifyBytePattern(firstBlock.addr, (N_UNITS * info.program_unit), ((const uint8_t *)&BYTE_PATTERN)[0]);
00923                 }
00924 
00925                 return CaseNext;
00926             }
00927         }
00928     }
00929 
00930     return CaseNext;
00931 }
00932 
00933 #ifndef AVOID_GREENTEA
00934 // Custom setup handler required for proper Greentea support
00935 utest::v1::status_t greentea_setup(const size_t number_of_cases)
00936 {
00937     GREENTEA_SETUP(60, "default_auto");
00938     // Call the default reporting function
00939     return greentea_test_setup_handler(number_of_cases);
00940 }
00941 #else
00942 status_t default_setup(const size_t)
00943 {
00944     return STATUS_CONTINUE;
00945 }
00946 #endif
00947 
00948 // Specify all your test cases here
00949 Case cases[] = {
00950     Case("get version",                              test_getVersion),
00951     Case("get capabilities",                         test_getCapabilities),
00952     Case("get info",                                 test_getInfo),
00953     Case("initialize",                               test_initialize),
00954     Case("uninitialize",                             test_uninitialize),
00955     Case("power control",                            test_powerControl),
00956     Case("erase all",                                test_eraseAll),
00957     Case("read data",                                test_readData),
00958     Case("erase with invalid parameters",            test_eraseWithInvalidParameters),
00959     Case("erase single unit",                        test_erase<1>),
00960     Case("erase two units",                          test_erase<2>),
00961     Case("erase four units",                         test_erase<4>),
00962     Case("erase eight units",                        test_erase<8>),
00963     Case("program data with invalid parameters",     test_programDataWithInvalidParameters),
00964     Case("program data using program_unit",          test_programDataUsingProgramUnit),
00965     Case("program data using optimal_program_unit",  test_programDataUsingOptimalProgramUnit),
00966     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<1>),
00967     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<2>),
00968     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<7>),
00969     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<8>),
00970     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<9>),
00971     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<31>),
00972     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<32>),
00973     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<33>),
00974     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<127>),
00975     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<128>),
00976     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<129>),
00977     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<1023>),
00978     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<1024>),
00979     Case("program data with multiple program units", test_programDataWithMultipleProgramUnits<1025>),
00980 };
00981 
00982 // Declare your test specification with a custom setup handler
00983 #ifndef AVOID_GREENTEA
00984 Specification specification(greentea_setup, cases);
00985 #else
00986 Specification specification(default_setup, cases);
00987 #endif
00988 
00989 int main(int argc, char** argv)
00990 {
00991     // Run the test specification
00992     Harness::run(specification);
00993 }