|
| 1 | +/* mbed Microcontroller Library |
| 2 | + * Copyright (c) 2018 ARM Limited |
| 3 | + * |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | + * you may not use this file except in compliance with the License. |
| 6 | + * You may obtain a copy of the License at |
| 7 | + * |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | + * |
| 10 | + * Unless required by applicable law or agreed to in writing, software |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | + * See the License for the specific language governing permissions and |
| 14 | + * limitations under the License. |
| 15 | + */ |
| 16 | +#include "utest/utest.h" |
| 17 | +#include "unity/unity.h" |
| 18 | +#include "greentea-client/test_env.h" |
| 19 | +#include "mbed.h" |
| 20 | +#include "math.h" |
| 21 | +#include "crc_api.h" |
| 22 | + |
| 23 | +#if !DEVICE_CRC |
| 24 | +#error [NOT_SUPPORTED] CRC not supported for this target |
| 25 | +#endif |
| 26 | + |
| 27 | +using namespace utest::v1; |
| 28 | + |
| 29 | +#define POLY_8BIT_MAXIM 0x31 |
| 30 | +#define POLY_16BIT_MAXIM 0x8005 |
| 31 | +#define POLY_32BIT_POSIX 0x4C11DB7 |
| 32 | + |
| 33 | +#define UNSUPPORTED (-1) |
| 34 | +#define POL_CNT (2) |
| 35 | + |
| 36 | +const uint8_t input_data[] = "123456789"; |
| 37 | + |
| 38 | +typedef struct |
| 39 | +{ |
| 40 | + const crc_mbed_config config_data; |
| 41 | + uint32_t expected_result; |
| 42 | + |
| 43 | +} TEST_CASE; |
| 44 | + |
| 45 | +/* We will allocate test case array on stack since memory limits on some boards |
| 46 | + * like NUCLEO_F070RB. */ |
| 47 | +static TEST_CASE *test_cases; |
| 48 | +static uint32_t test_cases_size; |
| 49 | + |
| 50 | +/* Test that hal_crc_is_supported() function returns true if given polynomial |
| 51 | + * is supported, false otherwise (at least one polynomial from the predefined list must be supported). */ |
| 52 | +void crc_is_supported_test() |
| 53 | +{ |
| 54 | + /* Check if at least one crc polynomial/config is supported. */ |
| 55 | + uint32_t num_of_supported_polynomials = 0; |
| 56 | + |
| 57 | + for (unsigned int i = 0; i < (test_cases_size / sizeof(TEST_CASE)); i++) { |
| 58 | + if (hal_crc_is_supported(&test_cases[i].config_data) == true) { |
| 59 | + |
| 60 | + num_of_supported_polynomials++; |
| 61 | + } |
| 62 | + } |
| 63 | + |
| 64 | + TEST_ASSERT(num_of_supported_polynomials > 0); |
| 65 | +} |
| 66 | + |
| 67 | +/* Test that CRC module can be successfully configured, fed with data and the result can |
| 68 | + * be successfully obtained. */ |
| 69 | +void crc_calc_single_test() |
| 70 | +{ |
| 71 | + for (unsigned int i = 0; i < (test_cases_size / sizeof(TEST_CASE)); i++) { |
| 72 | + if (hal_crc_is_supported(&test_cases[i].config_data) == true) { |
| 73 | + |
| 74 | + hal_crc_compute_partial_start(&test_cases[i].config_data); |
| 75 | + hal_crc_compute_partial((uint8_t*) input_data, strlen((const char*) input_data)); |
| 76 | + const uint32_t crc = hal_crc_get_result(); |
| 77 | + |
| 78 | + TEST_ASSERT_EQUAL(test_cases[i].expected_result, crc); |
| 79 | + } |
| 80 | + } |
| 81 | +} |
| 82 | + |
| 83 | +/* Test that hal_crc_compute_partial() function can be call multiple times in |
| 84 | + * succession in order to provide additional data to CRC module. */ |
| 85 | +void crc_calc_multi_test() |
| 86 | +{ |
| 87 | + for (unsigned int i = 0; i < (test_cases_size / sizeof(TEST_CASE)); i++) { |
| 88 | + if (hal_crc_is_supported(&test_cases[i].config_data) == true) { |
| 89 | + |
| 90 | + const uint32_t first_part_bytes = 3; |
| 91 | + const uint32_t second_part_bytes = 1; |
| 92 | + const uint32_t third_part_bytes = strlen((const char*) input_data) - first_part_bytes |
| 93 | + - second_part_bytes; |
| 94 | + |
| 95 | + hal_crc_compute_partial_start(&test_cases[i].config_data); |
| 96 | + hal_crc_compute_partial((uint8_t*) input_data, first_part_bytes); |
| 97 | + hal_crc_compute_partial((uint8_t*) (input_data + first_part_bytes), second_part_bytes); |
| 98 | + hal_crc_compute_partial((uint8_t*) (input_data + first_part_bytes + second_part_bytes), |
| 99 | + third_part_bytes); |
| 100 | + const uint32_t crc = hal_crc_get_result(); |
| 101 | + |
| 102 | + TEST_ASSERT_EQUAL(test_cases[i].expected_result, crc); |
| 103 | + } |
| 104 | + } |
| 105 | +} |
| 106 | + |
| 107 | +/* Test that calling hal_crc_compute_partial_start() without finalising the |
| 108 | + * CRC calculation overrides the current configuration. */ |
| 109 | +void crc_reconfigure_test() |
| 110 | +{ |
| 111 | + int pol_idx[POL_CNT] = |
| 112 | + { UNSUPPORTED, UNSUPPORTED }; |
| 113 | + int pol_cnt = 0; |
| 114 | + const uint8_t dummy_input_data[] = "abcdefghijklmnopqrstuvwxyz"; |
| 115 | + |
| 116 | + /* At least one configuration must be supported. If two are supported, then |
| 117 | + * re-initialize CRC module using different config. */ |
| 118 | + for (unsigned int i = 0; i < (test_cases_size / sizeof(TEST_CASE)); i++) { |
| 119 | + |
| 120 | + /* Find two supported polynomials if possible. */ |
| 121 | + if (hal_crc_is_supported(&test_cases[i].config_data) == true) { |
| 122 | + if (pol_cnt == 0) { |
| 123 | + pol_idx[pol_cnt] = i; |
| 124 | + pol_cnt++; |
| 125 | + } else if (test_cases[pol_idx[0]].config_data.polynomial != test_cases[i].config_data.polynomial) { |
| 126 | + pol_idx[pol_cnt] = i; |
| 127 | + pol_cnt++; |
| 128 | + } |
| 129 | + |
| 130 | + if (pol_cnt == POL_CNT) { |
| 131 | + break; |
| 132 | + } |
| 133 | + } |
| 134 | + } |
| 135 | + |
| 136 | + pol_cnt = 0; |
| 137 | + |
| 138 | + /* Init CRC module and provide some data, but do not read the result. */ |
| 139 | + hal_crc_compute_partial_start(&test_cases[pol_idx[pol_cnt]].config_data); |
| 140 | + hal_crc_compute_partial((uint8_t*) dummy_input_data, strlen((const char*) dummy_input_data)); |
| 141 | + |
| 142 | + /* Change index only if more than one supported polynomial has been found. */ |
| 143 | + if (pol_idx[POL_CNT - 1] != UNSUPPORTED) { |
| 144 | + pol_cnt++; |
| 145 | + } |
| 146 | + |
| 147 | + /* Now re-init CRC module and provide new data and check the result. */ |
| 148 | + hal_crc_compute_partial_start(&test_cases[pol_idx[pol_cnt]].config_data); |
| 149 | + hal_crc_compute_partial((uint8_t*) input_data, strlen((const char*) input_data)); |
| 150 | + const uint32_t crc = hal_crc_get_result(); |
| 151 | + |
| 152 | + TEST_ASSERT_EQUAL(test_cases[pol_idx[pol_cnt]].expected_result, crc); |
| 153 | +} |
| 154 | + |
| 155 | +/* Test that hal_crc_compute_partial() does nothing if pointer to buffer is undefined or |
| 156 | + * data length is equal to 0. */ |
| 157 | +void crc_compute_partial_invalid_param_test() |
| 158 | +{ |
| 159 | + uint32_t crc = 0; |
| 160 | + |
| 161 | + /* At least one polynomial must be supported. */ |
| 162 | + for (unsigned int i = 0; i < (test_cases_size / sizeof(TEST_CASE)); i++) { |
| 163 | + if (hal_crc_is_supported(&test_cases[i].config_data) == true) { |
| 164 | + |
| 165 | + hal_crc_compute_partial_start(&test_cases[i].config_data); |
| 166 | + |
| 167 | + /* Call hal_crc_compute_partial() with invalid parameters. */ |
| 168 | + hal_crc_compute_partial((uint8_t*) NULL, strlen((const char*) input_data)); |
| 169 | + hal_crc_compute_partial((uint8_t*) input_data, 0); |
| 170 | + |
| 171 | + /* Now use valid parameters. */ |
| 172 | + hal_crc_compute_partial((uint8_t*) input_data, |
| 173 | + strlen((const char*) input_data)); |
| 174 | + |
| 175 | + crc = hal_crc_get_result(); |
| 176 | + |
| 177 | + TEST_ASSERT_EQUAL(test_cases[i].expected_result, crc); |
| 178 | + |
| 179 | + break; |
| 180 | + } |
| 181 | + } |
| 182 | +} |
| 183 | + |
| 184 | +/* Test that hal_crc_is_supported() returns false if pointer to the config structure is undefined. */ |
| 185 | +void crc_is_supported_invalid_param_test() |
| 186 | +{ |
| 187 | + TEST_ASSERT_EQUAL(false, hal_crc_is_supported(NULL)); |
| 188 | +} |
| 189 | + |
| 190 | +Case cases[] = { |
| 191 | + Case("test: supported polynomials.", crc_is_supported_test), |
| 192 | + Case("test: CRC calculation - single input.", crc_calc_single_test), |
| 193 | + Case("test: CRC calculation - multi input.", crc_calc_multi_test), |
| 194 | + Case("test: re-configure without getting the result.", crc_reconfigure_test), |
| 195 | + Case("test: hal_crc_compute_partial() - invalid parameters.", crc_compute_partial_invalid_param_test), |
| 196 | + Case("test: hal_crc_is_supported() - invalid parameter.", crc_is_supported_invalid_param_test), |
| 197 | +}; |
| 198 | + |
| 199 | +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) |
| 200 | +{ |
| 201 | + GREENTEA_SETUP(30, "default_auto"); |
| 202 | + return greentea_test_setup_handler(number_of_cases); |
| 203 | +} |
| 204 | + |
| 205 | +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); |
| 206 | + |
| 207 | +int main() |
| 208 | +{ |
| 209 | + TEST_CASE local_test_cases[] = { |
| 210 | + /* Predefined polynomials. */ |
| 211 | +/* 00 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, false, false}, 0xEA }, |
| 212 | +/* 01 */{ {POLY_7BIT_SD , 7, 0x0000007F, 0x00000000, false, false}, 0xA0 }, |
| 213 | +/* 02 */{ {POLY_7BIT_SD , 7, 0x0000002B, 0x00000000, false, false}, 0x74 }, |
| 214 | +/* 03 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x0000007F, false, false}, 0x95 }, |
| 215 | +/* 04 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x0000002B, false, false}, 0xC1 }, |
| 216 | +/* 05 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, true , false}, 0xA4 }, |
| 217 | +/* 06 */{ {POLY_7BIT_SD , 7, 0x00000000, 0x00000000, false, true }, 0x57 }, |
| 218 | + |
| 219 | +/* 07 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x00000000, false, false}, 0xF4 }, |
| 220 | +/* 08 */{ {POLY_8BIT_CCITT , 8, 0x000000FF, 0x00000000, false, false}, 0xFB }, |
| 221 | +/* 09 */{ {POLY_8BIT_CCITT , 8, 0x000000AB, 0x00000000, false, false}, 0x87 }, |
| 222 | +/* 10 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x000000FF, false, false}, 0x0B }, |
| 223 | +/* 11 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x000000AB, false, false}, 0x5F }, |
| 224 | +/* 12 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x00000000, true , false}, 0x04 }, |
| 225 | +/* 13 */{ {POLY_8BIT_CCITT , 8, 0x00000000, 0x00000000, false, true }, 0x2F }, |
| 226 | + |
| 227 | +/* 14 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x00000000, false, false}, 0x31C3 }, |
| 228 | +/* 15 */{ {POLY_16BIT_CCITT , 16, 0x0000FFFF, 0x00000000, false, false}, 0x29B1 }, |
| 229 | +/* 16 */{ {POLY_16BIT_CCITT , 16, 0x0000ABAB, 0x00000000, false, false}, 0x7D70 }, |
| 230 | +/* 17 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x0000FFFF, false, false}, 0xCE3C }, |
| 231 | +/* 18 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x0000ABAB, false, false}, 0x9A68 }, |
| 232 | +/* 19 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x00000000, true , false}, 0x9184 }, |
| 233 | +/* 20 */{ {POLY_16BIT_CCITT , 16, 0x00000000, 0x00000000, false, true }, 0xC38C }, |
| 234 | + |
| 235 | +/* 21 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x00000000, false, false}, 0xFEE8 }, |
| 236 | +/* 22 */{ {POLY_16BIT_IBM , 16, 0x0000FFFF, 0x00000000, false, false}, 0xAEE7 }, |
| 237 | +/* 23 */{ {POLY_16BIT_IBM , 16, 0x0000ABAB, 0x00000000, false, false}, 0x0887 }, |
| 238 | +/* 24 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x0000FFFF, false, false}, 0x0117 }, |
| 239 | +/* 25 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x0000ABAB, false, false}, 0x5543 }, |
| 240 | +/* 26 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x00000000, true , false}, 0xBCDD }, |
| 241 | +/* 27 */{ {POLY_16BIT_IBM , 16, 0x00000000, 0x00000000, false, true }, 0x177F }, |
| 242 | + |
| 243 | +/* 28 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0x00000000, false, false}, 0x89A1897F }, |
| 244 | +/* 29 */{ {POLY_32BIT_ANSI , 32, 0xFFFFFFFF, 0x00000000, false, false}, 0x0376E6E7 }, |
| 245 | +/* 30 */{ {POLY_32BIT_ANSI , 32, 0xABABABAB, 0x00000000, false, false}, 0x871A2FAA }, |
| 246 | +/* 31 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0xFFFFFFFF, false, false}, 0x765E7680 }, |
| 247 | +/* 32 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0xABABABAB, false, false}, 0x220A22D4 }, |
| 248 | +/* 33 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0x00000000, true , false}, 0x11B4BFB4 }, |
| 249 | +/* 34 */{ {POLY_32BIT_ANSI , 32, 0x00000000, 0x00000000, false, true }, 0xFE918591 }, |
| 250 | + |
| 251 | + /* Not-predefined polynomials. */ |
| 252 | +/* 35 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x00000000, false, false}, 0xA2 }, |
| 253 | +/* 36 */{ {POLY_8BIT_MAXIM , 8, 0x000000FF, 0x00000000, false, false}, 0xF7 }, |
| 254 | +/* 37 */{ {POLY_8BIT_MAXIM , 8, 0x000000AB, 0x00000000, false, false}, 0x71 }, |
| 255 | +/* 38 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x000000FF, false, false}, 0x5D }, |
| 256 | +/* 39 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x000000AB, false, false}, 0x09 }, |
| 257 | +/* 40 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x00000000, true , false}, 0x85 }, |
| 258 | +/* 41 */{ {POLY_8BIT_MAXIM , 8, 0x00000000, 0x00000000, false, true }, 0x45 }, |
| 259 | + |
| 260 | +/* 42 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x00000000, false, false}, 0xFEE8 }, |
| 261 | +/* 43 */{ {POLY_16BIT_MAXIM , 16, 0x0000FFFF, 0x00000000, false, false}, 0xAEE7 }, |
| 262 | +/* 44 */{ {POLY_16BIT_MAXIM , 16, 0x0000ABAB, 0x00000000, false, false}, 0x0887 }, |
| 263 | +/* 45 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x0000FFFF, false, false}, 0x0117 }, |
| 264 | +/* 46 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x0000ABAB, false, false}, 0x5543 }, |
| 265 | +/* 47 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x00000000, true , false}, 0xBCDD }, |
| 266 | +/* 48 */{ {POLY_16BIT_MAXIM , 16, 0x00000000, 0x00000000, false, true }, 0x177F }, |
| 267 | + |
| 268 | +/* 49 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0x00000000, false, false}, 0x89A1897F }, |
| 269 | +/* 50 */{ {POLY_32BIT_POSIX , 32, 0xFFFFFFFF, 0x00000000, false, false}, 0x0376E6E7 }, |
| 270 | +/* 51 */{ {POLY_32BIT_POSIX , 32, 0xABABABAB, 0x00000000, false, false}, 0x871A2FAA }, |
| 271 | +/* 52 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0xFFFFFFFF, false, false}, 0x765E7680 }, |
| 272 | +/* 53 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0xABABABAB, false, false}, 0x220A22D4 }, |
| 273 | +/* 54 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0x00000000, true , false}, 0x11B4BFB4 }, |
| 274 | +/* 55 */{ {POLY_32BIT_POSIX , 32, 0x00000000, 0x00000000, false, true }, 0xFE918591 }, |
| 275 | + }; |
| 276 | + |
| 277 | + test_cases = local_test_cases; |
| 278 | + test_cases_size = sizeof(local_test_cases); |
| 279 | + |
| 280 | + Harness::run(specification); |
| 281 | +} |
0 commit comments