/*! \brief This is an example demonstrating flash read / write data accesses * using the FLASHCALW driver. * * \param caption Caption to print before running the example. * \param nvram_data Pointer to the NVRAM data structure to use in the example. */ static void flash_rw_example(const char *caption, nvram_data_t *nvram_data) { static const uint8_t write_data[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; printf("%s", caption); printf("Initial values of NVRAM variables:\r\n"); print_nvram_variables(nvram_data); printf("\r\nClearing NVRAM variables..."); /* Clear NVRAM */ flashcalw_memset((void *)nvram_data, 0x0, 8, sizeof(*nvram_data), true); printf("\r\nNVRAM variables cleared:\r\n"); print_nvram_variables(nvram_data); printf("\r\nWriting new values to NVRAM variables..."); flashcalw_memcpy((void *)&nvram_data->var8, &write_data, sizeof(nvram_data->var8), true); flashcalw_memcpy((void *)&nvram_data->var16, &write_data, sizeof(nvram_data->var16), true); flashcalw_memcpy((void *)&nvram_data->var8_3, &write_data, sizeof(nvram_data->var8_3), true); flashcalw_memcpy((void *)&nvram_data->var32, &write_data, sizeof(nvram_data->var32), true); printf("\r\nNVRAM variables written:\r\n"); print_nvram_variables(nvram_data); }
status_code_t nvm_write(mem_type_t mem, uint32_t address, void *buffer, uint32_t len) { switch (mem) { case INT_FLASH: #if SAM4S /*! This erases 8 pages of flash before writing */ if (flash_erase_page(address, IFLASH_ERASE_PAGES_8)) { return ERR_INVALID_ARG; } if (flash_write(address, (const void *)buffer, len, false)) { return ERR_INVALID_ARG; } #elif SAM4L flashcalw_memcpy((volatile void *)address, (const void *)buffer, len, true); #else if (flash_write(address, (const void *)buffer, len, true)) { return ERR_INVALID_ARG; } #endif break; #if SAM4S case INT_USERPAGE: if (flash_write_user_signature((const void *)buffer, len)) { return ERR_INVALID_ARG; } break; #endif #if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX) case AT45DBX: { uint32_t sector = address / AT45DBX_SECTOR_SIZE; if (!at45dbx_write_sector_open(sector)) { return ERR_BAD_ADDRESS; } at45dbx_write_sector_from_ram((const void *)buffer); at45dbx_write_close(); } break; #endif default: return ERR_INVALID_ARG; } return STATUS_OK; }
/** * \brief Application entry point for CRCCU example. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint32_t ul_counter; uint32_t ul_crc; /* Initialize the system */ sysclk_init(); board_init(); /* Configure the console uart */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Enable CRCCU peripheral clock */ sysclk_enable_peripheral_clock(CRCCU); /* Fill data buffer in SRAM (The data may be random data) */ for (ul_counter = 0; ul_counter < BUFFER_LENGTH; ul_counter++) { g_uc_data_buf[ul_counter] = ul_counter; } /* Fill data buffer in Flash, the data is same as in SRAM */ flashcalw_memcpy((void *)FLASH_BUFFER_ADDRESS, g_uc_data_buf, sizeof(g_uc_data_buf), true); /* Test CRC with CCITT-16 polynomial */ puts("\n\r====Test CRC with CCITT 16 (0x1021) ====\r"); /* Compute CRC in SRAM */ puts("Test CRC in SRAM buffer\r"); ul_crc = compute_crc(g_uc_data_buf, BUFFER_LENGTH, CRCCU_MR_PTYPE_CCITT16); /* Compute CRC in Flash and compare it with the result in SRAM */ puts("Test CRC in Flash buffer\r"); compute_crc_and_compare((uint8_t *) FLASH_BUFFER_ADDRESS, BUFFER_LENGTH, CRCCU_MR_PTYPE_CCITT16, ul_crc); /* Test CRC with CASTAGNOLI polynomial */ puts("\n\r====Test CRC with CASTAGNOLI (0x1EDC6F41) ====\r"); /* Compute CRC in SRAM */ puts("Test CRC in SRAM buffer\r"); ul_crc = compute_crc(g_uc_data_buf, BUFFER_LENGTH, CRCCU_MR_PTYPE_CASTAGNOLI); /* Compute CRC in Flash and compare it with the result in SRAM */ puts("Test CRC in Flash buffer\r"); compute_crc_and_compare((uint8_t *) FLASH_BUFFER_ADDRESS, BUFFER_LENGTH, CRCCU_MR_PTYPE_CASTAGNOLI, ul_crc); /* Test CRC with CCITT 802.3 polynomial */ puts("\n\r====Test CRC with CCITT 802.3 (0x04C11DB7) ====\r"); /* Compute CRC in SRAM */ puts("Test CRC in SRAM buffer\r"); ul_crc = compute_crc(g_uc_data_buf, BUFFER_LENGTH, CRCCU_MR_PTYPE_CCITT8023); /* Compute CRC in Flash and compare it with the result in SRAM */ puts("Test CRC in Flash buffer\r"); compute_crc_and_compare((uint8_t *) FLASH_BUFFER_ADDRESS, BUFFER_LENGTH, CRCCU_MR_PTYPE_CCITT8023, ul_crc); while (1) { } }
/** * \brief Test watchdog for all cases. * * \note Because MCU will be reset serval times druing the test, * to simplify the design, only one test case but with many test stages. * * \param test Current test case. */ static void run_wdt_test_all(const struct test_case *test) { struct wdt_dev_inst wdt_inst; struct wdt_config wdt_cfg; uint32_t wdt_window_ms = 0; uint32_t wdt_timeout_ms = 0; uint32_t wdt_ut_stage; /* Get test stage */ wdt_ut_stage = (uint32_t)(*(uint32_t *)WDT_UT_TAG_ADDR); if (is_wdt_reset()) { /* Check if the reset is as expected */ switch (wdt_ut_stage) { case WDT_UT_STAGE_START: test_assert_true(test, 0, "Unexpected watchdog reset at start stage!"); break; case WDT_UT_STAGE_RST_MCU: /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_BM_NORMAL; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); break; case WDT_UT_STAGE_BM_NORMAL: test_assert_true(test, 0, "Unexpected watchdog reset at basic mode!"); break; case WDT_UT_STAGE_BM_TIMEOUT_RST: /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_WM_NORMAL; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); break; case WDT_UT_STAGE_WM_NORMAL: test_assert_true(test, 0, "Unexpected watchdog reset at window mode!"); break; case WDT_UT_STAGE_WM_TIMEBAN_RST: /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_WM_TIMEOUT_RST; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); break; case WDT_UT_STAGE_WM_TIMEOUT_RST: /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_END; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); break; case WDT_UT_STAGE_END: test_assert_true(test, 0, "Unexpected watchdog reset at end stage!"); break; default: test_assert_true(test, 0, "Unexpected watchdog reset!"); break; } } else { /* First WDT unit test start at here, set stage flag */ wdt_ut_stage = WDT_UT_STAGE_START; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); } /* * ---- Test reset MCU by the WDT ---- */ if (wdt_ut_stage == WDT_UT_STAGE_START) { bool ret; /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_RST_MCU; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); /* Reset MCU by the watchdog. */ ret = wdt_reset_mcu(); test_assert_false(test, ret, "Can't reset MCU by the WDT: failed!"); /* The code should not go to here */ test_assert_true(test, 0, "Reset MCU by the WDT: failed!"); } /* * ---- Test the WDT in basic mode ---- */ if ((wdt_ut_stage & WDT_UT_STAGE_MASK) == WDT_UT_STAGE_BM) { /* * Intialize the watchdog in basic mode: * - Use default configuration. * - But change timeout period to 0.57s * (Ttimeout = 2pow(PSEL+1) / Fclk_cnt = 65535 / 115000). */ wdt_get_config_defaults(&wdt_cfg); wdt_cfg.timeout_period = WDT_PERIOD_65536_CLK; wdt_timeout_ms = 570; wdt_init(&wdt_inst, WDT, &wdt_cfg); wdt_enable(&wdt_inst); wdt_clear(&wdt_inst); mdelay(wdt_timeout_ms / 2); wdt_clear(&wdt_inst); /* The code should reach here */ test_assert_true(test, 1, "Clear the WDT in basic mode: passed."); /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_BM_TIMEOUT_RST; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); /* Wait for the WDT reset */ mdelay(wdt_timeout_ms * 2); /* The code should not go to here, disable watchdog for default */ wdt_disable(&wdt_inst); test_assert_true(test, 0, "No WDT reset happened in basic mode!"); } /* * ---- Test the WDT in window mode ---- */ if ((wdt_ut_stage & WDT_UT_STAGE_MASK) == WDT_UT_STAGE_WM) { /* Enable WDT clock source if need */ if (BPM->BPM_PMCON & BPM_PMCON_CK32S) { /* Enable 32K RC oscillator */ if (!osc_is_ready(OSC_ID_RC32K)) { osc_enable(OSC_ID_RC32K); osc_wait_ready(OSC_ID_RC32K); } } else { /* Enable external OSC32 oscillator */ if (!osc_is_ready(OSC_ID_OSC32)) { osc_enable(OSC_ID_OSC32); osc_wait_ready(OSC_ID_OSC32); } } /* * Intialize the watchdog in window mode: * - Use 32K oscillator as WDT clock source. * - Set timeout/timeban period to 0.5s * (Ttimeout = 2pow(PSEL+1) / Fclk_cnt = 16384 / 32768). */ wdt_get_config_defaults(&wdt_cfg); wdt_cfg.wdt_mode = WDT_MODE_WINDOW; wdt_cfg.clk_src = WDT_CLK_SRC_32K; wdt_cfg.window_period = WDT_PERIOD_16384_CLK; wdt_cfg.timeout_period = WDT_PERIOD_16384_CLK; wdt_window_ms = 500; wdt_timeout_ms = 500; wdt_init(&wdt_inst, WDT, &wdt_cfg); wdt_enable(&wdt_inst); mdelay(wdt_window_ms + wdt_timeout_ms / 10); wdt_clear(&wdt_inst); /* The code should reach here */ test_assert_true(test, 1, "Clear the WDT in window mode: passed."); if (wdt_ut_stage == WDT_UT_STAGE_WM_NORMAL) { /* Move to next stage */ wdt_ut_stage = WDT_UT_STAGE_WM_TIMEBAN_RST; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); /* Clear the WDT in time ban window */ wdt_clear(&wdt_inst); /* The WDT reset should happen */ mdelay(50); } else if (wdt_ut_stage == WDT_UT_STAGE_WM_TIMEOUT_RST) { /* Wait for the WDT reset when timeout */ mdelay(wdt_window_ms); mdelay(wdt_timeout_ms * 2); } /* The code should not go to here, disable watchdog for default */ wdt_disable(&wdt_inst); test_assert_true(test, 0, "No WDT reset happened in window mode!"); } /* * ---- Check if all test are OK ---- */ if (wdt_ut_stage == WDT_UT_STAGE_END) { test_assert_true(test, 1, "All test stages done for WDT."); /* Clear flash content */ wdt_ut_stage = 0xFFFFFFFFu; flashcalw_memcpy((void *)WDT_UT_TAG_ADDR, &wdt_ut_stage, 4, true); } else { test_assert_true(test, 0, "WDT test stopped with unexpected stages."); } }