]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blobdiff - rpp-test-sw/commands/cmd_sdram.c
Merge branches 'master' and 'rm48/master'
[pes-rpp/rpp-test-sw.git] / rpp-test-sw / commands / cmd_sdram.c
diff --git a/rpp-test-sw/commands/cmd_sdram.c b/rpp-test-sw/commands/cmd_sdram.c
new file mode 100644 (file)
index 0000000..908639b
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2012-2013 Czech Technical University in Prague
+ *
+ * Created on: 28.2.2013
+ *
+ * Authors:
+ *     - Michal Horn
+ *     - Carlos Jenkins <carlos@jenkins.co.cr>
+ *
+ * This document contains proprietary information belonging to Czech
+ * Technical University in Prague. Passing on and copying of this
+ * document, and communication of its contents is not permitted
+ * without prior written authorization.
+ *
+ * File : cmd_sdram.c
+ *
+ * Abstract:
+ *      This file contains commands for testing external SDRAM of RPP board.
+ *
+ */
+
+#include "cmd_sdram.h"
+
+#ifndef DOCGEN
+
+#include "rpp/rpp.h"
+#include <stdlib.h>
+
+#define BASE_FREQ_MILLIS    1000
+#define FREQ_VARIABILITY    100
+#define TEST_TASK_PRIORITY  0
+#define TEST_TASK_STACK     512
+#define INPUT_IDLE          50
+
+
+// Task control
+extern xSemaphoreHandle rpp_sdr_cmdproc_semaphore;
+static boolean_t stop_tasks = FALSE;    /**< Flag for stopping all related tasks. */
+static uint8_t tasks_running = 0;       /**< Task counter - incremented each time task is spawn, decremented when task is deleted */
+
+/**
+ * @brief Set flag for tasks to finish.
+ *
+ * All tasks are reading the flag during their work and when
+ * they detect this flag is up, they stop the routine, decrement
+ * task counter and delete themselves.
+ */
+static void wait_tasks_to_finish()
+{
+       stop_tasks = TRUE;
+       while (tasks_running > 0)
+               taskYIELD();
+       stop_tasks = FALSE;
+}
+
+/**
+ * @brief Wait for user input "q" to quit the loop.
+ */
+void wait_for_quit()
+{
+       while (rpp_sci_getc() < 0)
+               vTaskDelay(INPUT_IDLE / portTICK_RATE_MS);
+}
+
+
+/**
+ * FreeRTOS Task that send some noise to the log from time to time.
+ */
+void sdr_test_task(void *par)
+{
+       // Calculate wait time in OS ticks
+       static const portTickType freq_ticks = BASE_FREQ_MILLIS / portTICK_RATE_MS;
+       portTickType last_wake_time = xTaskGetTickCount();
+
+       // Initialize rand
+       srand(2097925); // They are random, I swear xD
+
+       uint32_t i = 0;
+       uint32_t variation = 0;
+       int8_t plus_minus = 1;
+       while (!stop_tasks) {
+
+               // Put something in the log
+               rpp_sdr_printf((const char *)
+                                          "This is the noise generator at iteration %d "
+                                          "putting some noise value %d.", i, rand()
+                                          );
+               i++;
+
+               if (!stop_tasks) {
+                       variation = freq_ticks +
+                                               (plus_minus * ((rand() % FREQ_VARIABILITY) + 1));
+                       plus_minus = plus_minus * -1;
+                       vTaskDelayUntil(&last_wake_time, variation);
+               }
+       }
+
+       // Delete myself
+       tasks_running--;
+       vTaskDelete(NULL);
+}
+
+/**
+ * SDR Test entry point.
+ */
+void test_sdr()
+{
+       /// Configure module
+       // - See note below.
+
+
+       /// Spawn tasks
+       xTaskHandle test_task_handle;
+
+       // Spawn noise task first, and later enable logging. Depending on the time
+       // required the first logs might not be registered, but that's ok, is better
+       // to check if logging could be enabled after data is being sent that enable
+       // command processor (which output messages to the SCI), and that inmediatly
+       // after the noise task could not be created, forcing to close the just
+       // opened command processor.
+       portBASE_TYPE task_created = xTaskCreate(sdr_test_task,
+                                                                                        (const signed char *)"sdr_test_task",
+                                                                                        TEST_TASK_STACK, NULL, TEST_TASK_PRIORITY,
+                                                                                        &test_task_handle
+                                                                                        );
+
+       if (task_created != pdPASS) {
+
+               rpp_sci_printf((const char *)
+                                          "ERROR: Problem spawning the test task. "
+                                          "Error code: %d\r\n", (uint32_t)task_created
+                                          );
+
+               wait_for_quit();
+               return;
+       }
+       tasks_running++;
+
+       if (rpp_sdr_setup(TRUE) != SUCCESS) {
+               rpp_sci_printf((const char *)
+                                          "ERROR: Problem enabling the logging module. "
+                                          );
+               wait_for_quit();
+               wait_tasks_to_finish();
+               return;
+       }
+
+       // Wait for the SDR included command processor to finish
+       xSemaphoreTake(rpp_sdr_cmdproc_semaphore, portMAX_DELAY);
+       wait_tasks_to_finish();
+
+       /// Reset module configuration
+       if (rpp_sdr_setup(FALSE) != SUCCESS) {
+               rpp_sci_printf((const char *)
+                                          "ERROR: Could not stop logging module.\r\n"
+                                          );
+               wait_for_quit();
+       }
+
+       rpp_sci_printf((const char *)"\r\n");
+
+       return;
+}
+
+
+/**
+ * @brief Start SDR test routine
+ *
+ * @param[in]  cmd_io  Pointer to IO stack
+ * @param[in]  des             Pointer to command descriptor
+ * @param[in]  param   Parameters of command
+ * @return always 0
+ */
+int cmd_do_test_log(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+       test_sdr();
+       return 0;
+}
+
+/**
+ * @brief      Tests the capacity and fitness of connected SDRAM
+ *
+ * @param[in]  cmd_io  Pointer to IO stack
+ * @param[in]  des             Pointer to command descriptor
+ * @param[in]  param   Parameters of command
+ * @return     0 when OK or error code
+ */
+int cmd_do_test_ram(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+       volatile uint32_t *addrPtr = (uint32_t *)0x80000000U;
+       volatile uint32_t *endAddr = (uint32_t *)0x83FFFFFFU;
+       uint32_t pattern = 0x55555555U;
+       uint32_t cnt = 0;
+       uint32_t errCnt = 0;
+       uint32_t readVal = 0;
+
+       while (addrPtr <= endAddr) {
+               *addrPtr = pattern;
+               pattern += 0x55555555U;
+               addrPtr++;
+       }
+
+       addrPtr = (uint32_t *)0x80000000U;
+       pattern = 0x55555555U;
+       while (addrPtr <= endAddr) {
+               readVal = *addrPtr;
+               if (pattern == readVal) cnt++;
+               else if (errCnt++ <= 10)
+                       rpp_sci_printf("Error at %h\r\n",addrPtr);
+               else break;
+               pattern += 0x55555555U;
+               addrPtr++;
+       }
+
+       cnt = cnt * sizeof(uint32_t) / 1024 / 1024;
+       if (cnt == 0)
+               rpp_sci_printf("SDRAM not connected.");
+       else
+               rpp_sci_printf("SDRAM installed: %d MB", cnt);
+
+       return 0;
+}
+
+#endif  /* DOCGEN */
+
+/** Command descriptor for test SDRAM */
+cmd_des_t const cmd_des_test_sdram = {
+       0, 0,
+       "sdramtest","Test if the SDRAM module is connected and if so, measures its capacity",
+       "### Command syntax ###\n"
+       "\n"
+       "    sdramtest\n"
+       "\n"
+       "### Description ###\n"
+       "\n"
+       "This command tests SDRAM address space by writing and reading a\n"
+       "pattern to/from it. It detects the SDRAM capacity.\n"
+       "\n"
+       "### Example ###\n"
+       "\n"
+       "    --> sdramtest\n"
+       "    SDRAM installed: 64 MB\n",
+       CMD_HANDLER(cmd_do_test_ram), (void *)&cmd_list_sdram
+};
+
+/** Command descriptor for test log to SDRAM */
+cmd_des_t const cmd_des_test_log = {
+       0, 0,
+       "sdramlogtest","Open a command subprocessor for managing SDRAM logging",
+       "### Command syntax ###\n"
+       "\n"
+       "    sdramlogtest\n"
+       "\n"
+       "### Description ###\n"
+       "\n"
+       "The command opens a subcommand processor, which contains testing\n"
+       "commands for logging into SDRAM.\n",
+       CMD_HANDLER(cmd_do_test_log), (void *)&cmd_list_sdram
+};
+
+/** List of commands for sdram, defined as external */
+cmd_des_t const *cmd_list_sdram[] = {
+       &cmd_des_test_sdram,
+       &cmd_des_test_log,
+       NULL
+};