--- /dev/null
+/*
+ * 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
+};