Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /* mbed Microcontroller Library
kadonotakashi 0:8fdf9a60065b 2 * Copyright (c) 2017 ARM Limited
kadonotakashi 0:8fdf9a60065b 3 *
kadonotakashi 0:8fdf9a60065b 4 * Licensed under the Apache License, Version 2.0 (the "License");
kadonotakashi 0:8fdf9a60065b 5 * you may not use this file except in compliance with the License.
kadonotakashi 0:8fdf9a60065b 6 * You may obtain a copy of the License at
kadonotakashi 0:8fdf9a60065b 7 *
kadonotakashi 0:8fdf9a60065b 8 * http://www.apache.org/licenses/LICENSE-2.0
kadonotakashi 0:8fdf9a60065b 9 *
kadonotakashi 0:8fdf9a60065b 10 * Unless required by applicable law or agreed to in writing, software
kadonotakashi 0:8fdf9a60065b 11 * distributed under the License is distributed on an "AS IS" BASIS,
kadonotakashi 0:8fdf9a60065b 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kadonotakashi 0:8fdf9a60065b 13 * See the License for the specific language governing permissions and
kadonotakashi 0:8fdf9a60065b 14 * limitations under the License.
kadonotakashi 0:8fdf9a60065b 15 */
kadonotakashi 0:8fdf9a60065b 16
kadonotakashi 0:8fdf9a60065b 17 #if !DEVICE_FLASH
kadonotakashi 0:8fdf9a60065b 18 #error [NOT_SUPPORTED] Flash API not supported for this target
kadonotakashi 0:8fdf9a60065b 19 #endif
kadonotakashi 0:8fdf9a60065b 20
kadonotakashi 0:8fdf9a60065b 21 #include "utest/utest.h"
kadonotakashi 0:8fdf9a60065b 22 #include "unity/unity.h"
kadonotakashi 0:8fdf9a60065b 23 #include "greentea-client/test_env.h"
kadonotakashi 0:8fdf9a60065b 24
kadonotakashi 0:8fdf9a60065b 25 #include "mbed.h"
kadonotakashi 0:8fdf9a60065b 26 #include "flash_api.h"
kadonotakashi 0:8fdf9a60065b 27
kadonotakashi 0:8fdf9a60065b 28 using namespace utest::v1;
kadonotakashi 0:8fdf9a60065b 29
kadonotakashi 0:8fdf9a60065b 30 #define TEST_CYCLES 10000000
kadonotakashi 0:8fdf9a60065b 31
kadonotakashi 0:8fdf9a60065b 32 #define ALLOWED_DRIFT_PPM (1000000/5000) //0.5%
kadonotakashi 0:8fdf9a60065b 33
kadonotakashi 0:8fdf9a60065b 34 /*
kadonotakashi 0:8fdf9a60065b 35 return values to be checked are documented at:
kadonotakashi 0:8fdf9a60065b 36 http://arm-software.github.io/CMSIS_5/Pack/html/algorithmFunc.html#Verify
kadonotakashi 0:8fdf9a60065b 37 */
kadonotakashi 0:8fdf9a60065b 38
kadonotakashi 0:8fdf9a60065b 39 #ifndef ALIGN_DOWN
kadonotakashi 0:8fdf9a60065b 40 #define ALIGN_DOWN(x, a) ((x)& ~((a) - 1))
kadonotakashi 0:8fdf9a60065b 41 #endif
kadonotakashi 0:8fdf9a60065b 42
kadonotakashi 0:8fdf9a60065b 43 static int timer_diff_start;
kadonotakashi 0:8fdf9a60065b 44
kadonotakashi 0:8fdf9a60065b 45 static void erase_range(flash_t *flash, uint32_t addr, uint32_t size)
kadonotakashi 0:8fdf9a60065b 46 {
kadonotakashi 0:8fdf9a60065b 47 while (size > 0) {
kadonotakashi 0:8fdf9a60065b 48 uint32_t sector_size = flash_get_sector_size(flash, addr);
kadonotakashi 0:8fdf9a60065b 49 TEST_ASSERT_NOT_EQUAL(0, sector_size);
kadonotakashi 0:8fdf9a60065b 50 int32_t ret = flash_erase_sector(flash, addr);
kadonotakashi 0:8fdf9a60065b 51 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 52 addr += sector_size;
kadonotakashi 0:8fdf9a60065b 53 size = size > sector_size ? size - sector_size : 0;
kadonotakashi 0:8fdf9a60065b 54 }
kadonotakashi 0:8fdf9a60065b 55 }
kadonotakashi 0:8fdf9a60065b 56 #ifdef __CC_ARM
kadonotakashi 0:8fdf9a60065b 57 MBED_NOINLINE
kadonotakashi 0:8fdf9a60065b 58 __asm static void delay_loop(uint32_t count)
kadonotakashi 0:8fdf9a60065b 59 {
kadonotakashi 0:8fdf9a60065b 60 // AStyle should not format inline assembly
kadonotakashi 0:8fdf9a60065b 61 // *INDENT-OFF*
kadonotakashi 0:8fdf9a60065b 62 1
kadonotakashi 0:8fdf9a60065b 63 SUBS a1, a1, #1
kadonotakashi 0:8fdf9a60065b 64 BCS %BT1
kadonotakashi 0:8fdf9a60065b 65 BX lr
kadonotakashi 0:8fdf9a60065b 66 // *INDENT-ON*
kadonotakashi 0:8fdf9a60065b 67 }
kadonotakashi 0:8fdf9a60065b 68 #elif defined (__ICCARM__)
kadonotakashi 0:8fdf9a60065b 69 MBED_NOINLINE
kadonotakashi 0:8fdf9a60065b 70 static void delay_loop(uint32_t count)
kadonotakashi 0:8fdf9a60065b 71 {
kadonotakashi 0:8fdf9a60065b 72 __asm volatile(
kadonotakashi 0:8fdf9a60065b 73 "loop: \n"
kadonotakashi 0:8fdf9a60065b 74 " SUBS %0, %0, #1 \n"
kadonotakashi 0:8fdf9a60065b 75 " BCS.n loop\n"
kadonotakashi 0:8fdf9a60065b 76 : "+r"(count)
kadonotakashi 0:8fdf9a60065b 77 :
kadonotakashi 0:8fdf9a60065b 78 : "cc"
kadonotakashi 0:8fdf9a60065b 79 );
kadonotakashi 0:8fdf9a60065b 80 }
kadonotakashi 0:8fdf9a60065b 81 #elif defined ( __GNUC__ ) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
kadonotakashi 0:8fdf9a60065b 82 MBED_NOINLINE
kadonotakashi 0:8fdf9a60065b 83 static void delay_loop(uint32_t count)
kadonotakashi 0:8fdf9a60065b 84 {
kadonotakashi 0:8fdf9a60065b 85 __asm__ volatile(
kadonotakashi 0:8fdf9a60065b 86 "%=:\n\t"
kadonotakashi 0:8fdf9a60065b 87 #if defined(__thumb__) && !defined(__thumb2__) && !defined(__ARMCC_VERSION)
kadonotakashi 0:8fdf9a60065b 88 "SUB %0, #1\n\t"
kadonotakashi 0:8fdf9a60065b 89 #else
kadonotakashi 0:8fdf9a60065b 90 "SUBS %0, %0, #1\n\t"
kadonotakashi 0:8fdf9a60065b 91 #endif
kadonotakashi 0:8fdf9a60065b 92 "BCS %=b\n\t"
kadonotakashi 0:8fdf9a60065b 93 : "+l"(count)
kadonotakashi 0:8fdf9a60065b 94 :
kadonotakashi 0:8fdf9a60065b 95 : "cc"
kadonotakashi 0:8fdf9a60065b 96 );
kadonotakashi 0:8fdf9a60065b 97 }
kadonotakashi 0:8fdf9a60065b 98 #endif
kadonotakashi 0:8fdf9a60065b 99
kadonotakashi 0:8fdf9a60065b 100 MBED_NOINLINE
kadonotakashi 0:8fdf9a60065b 101 static int time_cpu_cycles(uint32_t cycles)
kadonotakashi 0:8fdf9a60065b 102 {
kadonotakashi 0:8fdf9a60065b 103 Timer timer;
kadonotakashi 0:8fdf9a60065b 104
kadonotakashi 0:8fdf9a60065b 105 core_util_critical_section_enter();
kadonotakashi 0:8fdf9a60065b 106
kadonotakashi 0:8fdf9a60065b 107 timer.start();
kadonotakashi 0:8fdf9a60065b 108
kadonotakashi 0:8fdf9a60065b 109 delay_loop(cycles);
kadonotakashi 0:8fdf9a60065b 110
kadonotakashi 0:8fdf9a60065b 111 timer.stop();
kadonotakashi 0:8fdf9a60065b 112
kadonotakashi 0:8fdf9a60065b 113 core_util_critical_section_exit();
kadonotakashi 0:8fdf9a60065b 114
kadonotakashi 0:8fdf9a60065b 115 return timer.read_us();
kadonotakashi 0:8fdf9a60065b 116 }
kadonotakashi 0:8fdf9a60065b 117
kadonotakashi 0:8fdf9a60065b 118 void flash_init_test()
kadonotakashi 0:8fdf9a60065b 119 {
kadonotakashi 0:8fdf9a60065b 120 timer_diff_start = time_cpu_cycles(TEST_CYCLES);
kadonotakashi 0:8fdf9a60065b 121
kadonotakashi 0:8fdf9a60065b 122 flash_t test_flash;
kadonotakashi 0:8fdf9a60065b 123 int32_t ret = flash_init(&test_flash);
kadonotakashi 0:8fdf9a60065b 124 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 125 ret = flash_free(&test_flash);
kadonotakashi 0:8fdf9a60065b 126 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 127 }
kadonotakashi 0:8fdf9a60065b 128
kadonotakashi 0:8fdf9a60065b 129 void flash_mapping_alignment_test()
kadonotakashi 0:8fdf9a60065b 130 {
kadonotakashi 0:8fdf9a60065b 131 flash_t test_flash;
kadonotakashi 0:8fdf9a60065b 132 int32_t ret = flash_init(&test_flash);
kadonotakashi 0:8fdf9a60065b 133 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 134
kadonotakashi 0:8fdf9a60065b 135 const uint32_t page_size = flash_get_page_size(&test_flash);
kadonotakashi 0:8fdf9a60065b 136 const uint32_t flash_start = flash_get_start_address(&test_flash);
kadonotakashi 0:8fdf9a60065b 137 const uint32_t flash_size = flash_get_size(&test_flash);
kadonotakashi 0:8fdf9a60065b 138 TEST_ASSERT_TRUE(page_size != 0UL);
kadonotakashi 0:8fdf9a60065b 139
kadonotakashi 0:8fdf9a60065b 140 uint32_t sector_size = flash_get_sector_size(&test_flash, flash_start);
kadonotakashi 0:8fdf9a60065b 141 for (uint32_t offset = 0; offset < flash_size; offset += sector_size) {
kadonotakashi 0:8fdf9a60065b 142 const uint32_t sector_start = flash_start + offset;
kadonotakashi 0:8fdf9a60065b 143 sector_size = flash_get_sector_size(&test_flash, sector_start);
kadonotakashi 0:8fdf9a60065b 144 const uint32_t sector_end = sector_start + sector_size - 1;
kadonotakashi 0:8fdf9a60065b 145 const uint32_t end_sector_size = flash_get_sector_size(&test_flash, sector_end);
kadonotakashi 0:8fdf9a60065b 146
kadonotakashi 0:8fdf9a60065b 147 // Sector size must be a valid value
kadonotakashi 0:8fdf9a60065b 148 TEST_ASSERT_NOT_EQUAL(MBED_FLASH_INVALID_SIZE, sector_size);
kadonotakashi 0:8fdf9a60065b 149 // Sector size must be greater than zero
kadonotakashi 0:8fdf9a60065b 150 TEST_ASSERT_NOT_EQUAL(0, sector_size);
kadonotakashi 0:8fdf9a60065b 151 // All flash sectors must be a multiple of page size
kadonotakashi 0:8fdf9a60065b 152 TEST_ASSERT_EQUAL(0, sector_size % page_size);
kadonotakashi 0:8fdf9a60065b 153 // Sector address must be a multiple of sector size
kadonotakashi 0:8fdf9a60065b 154 TEST_ASSERT_EQUAL(0, sector_start % sector_size);
kadonotakashi 0:8fdf9a60065b 155 // All address in a sector must return the same sector size
kadonotakashi 0:8fdf9a60065b 156 TEST_ASSERT_EQUAL(sector_size, end_sector_size);
kadonotakashi 0:8fdf9a60065b 157 }
kadonotakashi 0:8fdf9a60065b 158
kadonotakashi 0:8fdf9a60065b 159 // Make sure unmapped flash is reported correctly
kadonotakashi 0:8fdf9a60065b 160 TEST_ASSERT_EQUAL(MBED_FLASH_INVALID_SIZE, flash_get_sector_size(&test_flash, flash_start - 1));
kadonotakashi 0:8fdf9a60065b 161 TEST_ASSERT_EQUAL(MBED_FLASH_INVALID_SIZE, flash_get_sector_size(&test_flash, flash_start + flash_size));
kadonotakashi 0:8fdf9a60065b 162
kadonotakashi 0:8fdf9a60065b 163 ret = flash_free(&test_flash);
kadonotakashi 0:8fdf9a60065b 164 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 165 }
kadonotakashi 0:8fdf9a60065b 166
kadonotakashi 0:8fdf9a60065b 167 void flash_erase_sector_test()
kadonotakashi 0:8fdf9a60065b 168 {
kadonotakashi 0:8fdf9a60065b 169 flash_t test_flash;
kadonotakashi 0:8fdf9a60065b 170 int32_t ret = flash_init(&test_flash);
kadonotakashi 0:8fdf9a60065b 171 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 172
kadonotakashi 0:8fdf9a60065b 173 uint32_t addr_after_last = flash_get_start_address(&test_flash) + flash_get_size(&test_flash);
kadonotakashi 0:8fdf9a60065b 174 uint32_t last_sector_size = flash_get_sector_size(&test_flash, addr_after_last - 1);
kadonotakashi 0:8fdf9a60065b 175 uint32_t last_sector = addr_after_last - last_sector_size;
kadonotakashi 0:8fdf9a60065b 176 TEST_ASSERT_EQUAL_INT32(0, last_sector % last_sector_size);
kadonotakashi 0:8fdf9a60065b 177 ret = flash_erase_sector(&test_flash, last_sector);
kadonotakashi 0:8fdf9a60065b 178 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 179
kadonotakashi 0:8fdf9a60065b 180 ret = flash_free(&test_flash);
kadonotakashi 0:8fdf9a60065b 181 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 182 }
kadonotakashi 0:8fdf9a60065b 183
kadonotakashi 0:8fdf9a60065b 184 // Erase sector, write one page, erase sector and write new data
kadonotakashi 0:8fdf9a60065b 185 void flash_program_page_test()
kadonotakashi 0:8fdf9a60065b 186 {
kadonotakashi 0:8fdf9a60065b 187 flash_t test_flash;
kadonotakashi 0:8fdf9a60065b 188 int32_t ret = flash_init(&test_flash);
kadonotakashi 0:8fdf9a60065b 189 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 190
kadonotakashi 0:8fdf9a60065b 191 uint32_t test_size = flash_get_page_size(&test_flash);
kadonotakashi 0:8fdf9a60065b 192 uint8_t *data = new uint8_t[test_size];
kadonotakashi 0:8fdf9a60065b 193 uint8_t *data_flashed = new uint8_t[test_size];
kadonotakashi 0:8fdf9a60065b 194 for (uint32_t i = 0; i < test_size; i++) {
kadonotakashi 0:8fdf9a60065b 195 data[i] = 0xCE;
kadonotakashi 0:8fdf9a60065b 196 }
kadonotakashi 0:8fdf9a60065b 197
kadonotakashi 0:8fdf9a60065b 198 // the one before the last page in the system
kadonotakashi 0:8fdf9a60065b 199 uint32_t address = flash_get_start_address(&test_flash) + flash_get_size(&test_flash) - (2 * test_size);
kadonotakashi 0:8fdf9a60065b 200
kadonotakashi 0:8fdf9a60065b 201 // sector size might not be same as page size
kadonotakashi 0:8fdf9a60065b 202 uint32_t erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address));
kadonotakashi 0:8fdf9a60065b 203 ret = flash_erase_sector(&test_flash, erase_sector_boundary);
kadonotakashi 0:8fdf9a60065b 204 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 205
kadonotakashi 0:8fdf9a60065b 206 ret = flash_program_page(&test_flash, address, data, test_size);
kadonotakashi 0:8fdf9a60065b 207 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 208
kadonotakashi 0:8fdf9a60065b 209 ret = flash_read(&test_flash, address, data_flashed, test_size);
kadonotakashi 0:8fdf9a60065b 210 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 211 TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, test_size);
kadonotakashi 0:8fdf9a60065b 212
kadonotakashi 0:8fdf9a60065b 213 // sector size might not be same as page size
kadonotakashi 0:8fdf9a60065b 214 erase_sector_boundary = ALIGN_DOWN(address, flash_get_sector_size(&test_flash, address));
kadonotakashi 0:8fdf9a60065b 215 ret = flash_erase_sector(&test_flash, erase_sector_boundary);
kadonotakashi 0:8fdf9a60065b 216 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 217
kadonotakashi 0:8fdf9a60065b 218 // write another data to be certain we are re-flashing
kadonotakashi 0:8fdf9a60065b 219 for (uint32_t i = 0; i < test_size; i++) {
kadonotakashi 0:8fdf9a60065b 220 data[i] = 0xAC;
kadonotakashi 0:8fdf9a60065b 221 }
kadonotakashi 0:8fdf9a60065b 222 ret = flash_program_page(&test_flash, address, data, test_size);
kadonotakashi 0:8fdf9a60065b 223 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 224
kadonotakashi 0:8fdf9a60065b 225 ret = flash_read(&test_flash, address, data_flashed, test_size);
kadonotakashi 0:8fdf9a60065b 226 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 227 TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, test_size);
kadonotakashi 0:8fdf9a60065b 228
kadonotakashi 0:8fdf9a60065b 229 ret = flash_free(&test_flash);
kadonotakashi 0:8fdf9a60065b 230 TEST_ASSERT_EQUAL_INT32(0, ret);
kadonotakashi 0:8fdf9a60065b 231 delete[] data;
kadonotakashi 0:8fdf9a60065b 232 delete[] data_flashed;
kadonotakashi 0:8fdf9a60065b 233 }
kadonotakashi 0:8fdf9a60065b 234
kadonotakashi 0:8fdf9a60065b 235 // check the execution speed at the start and end of the test to make sure
kadonotakashi 0:8fdf9a60065b 236 // cache settings weren't changed
kadonotakashi 0:8fdf9a60065b 237 void flash_clock_and_cache_test()
kadonotakashi 0:8fdf9a60065b 238 {
kadonotakashi 0:8fdf9a60065b 239 const int timer_diff_end = time_cpu_cycles(TEST_CYCLES);
kadonotakashi 0:8fdf9a60065b 240 const int acceptable_range = timer_diff_start / (ALLOWED_DRIFT_PPM);
kadonotakashi 0:8fdf9a60065b 241 TEST_ASSERT_UINT32_WITHIN(acceptable_range, timer_diff_start, timer_diff_end);
kadonotakashi 0:8fdf9a60065b 242 }
kadonotakashi 0:8fdf9a60065b 243
kadonotakashi 0:8fdf9a60065b 244 Case cases[] = {
kadonotakashi 0:8fdf9a60065b 245 Case("Flash - init", flash_init_test),
kadonotakashi 0:8fdf9a60065b 246 Case("Flash - mapping alignment", flash_mapping_alignment_test),
kadonotakashi 0:8fdf9a60065b 247 Case("Flash - erase sector", flash_erase_sector_test),
kadonotakashi 0:8fdf9a60065b 248 Case("Flash - program page", flash_program_page_test),
kadonotakashi 0:8fdf9a60065b 249 Case("Flash - clock and cache test", flash_clock_and_cache_test),
kadonotakashi 0:8fdf9a60065b 250 };
kadonotakashi 0:8fdf9a60065b 251
kadonotakashi 0:8fdf9a60065b 252 utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
kadonotakashi 0:8fdf9a60065b 253 {
kadonotakashi 0:8fdf9a60065b 254 GREENTEA_SETUP(20, "default_auto");
kadonotakashi 0:8fdf9a60065b 255 return greentea_test_setup_handler(number_of_cases);
kadonotakashi 0:8fdf9a60065b 256 }
kadonotakashi 0:8fdf9a60065b 257
kadonotakashi 0:8fdf9a60065b 258 Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
kadonotakashi 0:8fdf9a60065b 259
kadonotakashi 0:8fdf9a60065b 260 int main()
kadonotakashi 0:8fdf9a60065b 261 {
kadonotakashi 0:8fdf9a60065b 262 Harness::run(specification);
kadonotakashi 0:8fdf9a60065b 263 }