/** * \brief Application entry point for TRNG example. * * Enable the TRNG, display the generated random value. * * \return Unused (ANSI-C compatibility). */ int main(void) { /* Initialize the SAM system */ sysclk_init(); board_init(); /* Configure console UART */ configure_console(); /* Output example information */ printf("-- TRNG Example --\n\r"); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); /* Configure PMC */ pmc_enable_periph_clk(ID_TRNG); /* Enable TRNG */ trng_enable(TRNG); /* Enable TRNG interrupt */ NVIC_DisableIRQ(TRNG_IRQn); NVIC_ClearPendingIRQ(TRNG_IRQn); NVIC_SetPriority(TRNG_IRQn, 0); NVIC_EnableIRQ(TRNG_IRQn); trng_enable_interrupt(TRNG); /* User input loop */ while (1) { } }
/** * \brief $page_name$ Application entry point. * * \return Unused (ANSI-C compatibility). * \callgraph */ int main(void) { /* Output example information */ console_example_info("TRNG Example"); trng_enable(); trng_enable_it(&trng_callback, NULL); while (1) ; }
/** Initialize the TRNG peripheral * * @param obj The TRNG object */ void trng_init(trng_t *obj) { (void)obj; /* TRNG module clock enable */ rcu_periph_clock_enable(RCU_TRNG); /* TRNG registers reset */ trng_deinit(); trng_enable(); }
int main(void) { /* Initialize TRNG */ trng_enable(); /* Output example information */ console_example_info("QSPI Example"); pio_configure(pins_qspi, ARRAY_SIZE(pins_qspi)); qspi_initialize(QSPIFLASH_ADDR); uint32_t baudrate = qspi_set_baudrate(QSPIFLASH_ADDR, QSPIFLASH_BAUDRATE); printf("set baudrate to %u\r\n", (unsigned)baudrate); struct _qspiflash flash; bool rc = qspiflash_configure(&flash, QSPIFLASH_ADDR); printf("configure returns %s\r\n", rc ? "true" : "false"); uint32_t start = 0x280000; uint8_t buf[768]; printf("erasing block at 0x%08x\r\n", (int)start); rc = qspiflash_erase_block(&flash, start, 64 * 1024); printf("erase returns %s\r\n", rc ? "true" : "false"); printf("reading %d bytes at 0x%08x\r\n", sizeof(buf), (int)start); memset(buf, 0, sizeof(buf)); rc = qspiflash_read(&flash, start, buf, sizeof(buf)); printf("read returns %s\r\n", rc ? "true" : "false"); _display_buf(buf, sizeof(buf)); printf("preparing write buffer\r\n"); uint8_t r = trng_get_random_data() & 0xff; uint32_t i = 0; while (i * 32 < sizeof(buf)) { memset(buf + i * 32, r + i, 32); i++; } _display_buf(buf, sizeof(buf)); printf("writing %d bytes at 0x%08x\r\n", sizeof(buf), (int)start); rc = qspiflash_write(&flash, start, buf, sizeof(buf)); printf("write returns %s\r\n", rc ? "true" : "false"); printf("reading %d bytes at 0x%08x\r\n", sizeof(buf), (int)start); memset(buf, 0, sizeof(buf)); rc = qspiflash_read(&flash, start, buf, sizeof(buf)); printf("read returns %s\r\n", rc ? "true" : "false"); _display_buf(buf, sizeof(buf)); while (1) { } }
/** * \brief Test TRNG setting. * * This test sets the TRNG to generate interrupt when new random value is completed. * * \param test Current test case. */ static void run_trng_test(const struct test_case *test) { /* Configure PMC */ pmc_enable_periph_clk(ID_TRNG); /* Enable TRNG */ trng_enable(TRNG); /* Enable TRNG interrupt */ NVIC_DisableIRQ(TRNG_IRQn); NVIC_ClearPendingIRQ(TRNG_IRQn); NVIC_SetPriority(TRNG_IRQn, 0); NVIC_EnableIRQ(TRNG_IRQn); trng_enable_interrupt(TRNG); while(trng_int_flag == 0); test_assert_true(test, trng_int_flag == 1, "No random value is generated"); }
/** * \internal * \brief Test for TRNG polling mode read. * * This test reads three random data in polling mode and check the result. * * \param test Current test case */ static void run_trng_polling_read_test(const struct test_case *test) { uint32_t i; uint32_t timeout; uint32_t random_result[3]; /* Structure for TRNG configuration */ struct trng_config config; /* Initialize and enable the TRNG */ trng_get_config_defaults(&config); trng_init(&trng_instance, TRNG, &config); trng_enable(&trng_instance); /* Read random data */ for (i = 0; i < 3; i++) { /* A new 32-bits random data will be generated for every * 84 CLK_TRNG_APB clock cycles. */ timeout = 84; if (trng_read(&trng_instance, &random_result[i]) != STATUS_OK) { timeout--; if (timeout == 0) { /* Skip test if fail to read random data */ test_assert_true(test, false, "Fail to read random data in polling mode."); } } } /* Assume there is no probability to read same three * consecutive random number */ if ((random_result[0] == random_result[1]) && (random_result[0] == random_result[2])) { test_assert_true(test, false, "Get same random data in polling mode."); } }
/** \brief Get data from the TRNG. \param[in] handle trng handle to operate. \param[out] data Pointer to buffer with data get from TRNG \param[in] num Number of data items to obtain \return error code */ int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num) { TRNG_NULL_PARAM_CHK(handle); TRNG_NULL_PARAM_CHK(data); TRNG_NULL_PARAM_CHK(num); ck_trng_priv_t *trng_priv = handle; trng_priv->status.busy = 1U; trng_priv->status.data_valid = 0U; uint8_t left_len = (uint32_t)data & 0x3; uint32_t result = 0; /* if the data addr is not aligned by word */ if (left_len) { trng_enable(); while (!trng_data_is_ready()); result = trng_get_data(); /* wait the data is ready */ while (trng_data_is_ready()); if (num > (4 - left_len)) { memcpy(data, &result, 4 - left_len); } else { memcpy(data, &result, num); trng_priv->status.busy = 0U; trng_priv->status.data_valid = 1U; if (trng_priv->cb) { trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE); } return 0; } num -= (4 - left_len); data += (4 - left_len); } uint32_t word_len = num >> 2; left_len = num & 0x3; /* obtain the data by word */ while (word_len--) { trng_enable(); while (!trng_data_is_ready()); result = trng_get_data(); while (trng_data_is_ready()); *(uint32_t *)data = result; data = (void *)((uint32_t)data + 4); } /* if the num is not aligned by word */ if (left_len) { trng_enable(); while (!trng_data_is_ready()); result = trng_get_data(); while (trng_data_is_ready()); memcpy(data, &result, left_len); } trng_priv->status.busy = 0U; trng_priv->status.data_valid = 1U; if (trng_priv->cb) { trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE); } return 0; }