]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp-test-sw/commands/cmd_sdram.c
Apply uncrustify
[pes-rpp/rpp-test-sw.git] / rpp-test-sw / commands / cmd_sdram.c
1 /*
2  * Copyright (C) 2012-2013 Czech Technical University in Prague
3  *
4  * Created on: 28.2.2013
5  *
6  * Authors:
7  *     - Michal Horn
8  *     - Carlos Jenkins <carlos@jenkins.co.cr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  * File : cmd_sdram.c
24  *
25  * Abstract:
26  *      This file contains commands for testing external SDRAM of RPP board.
27  *
28  */
29
30 #include "cmd_sdram.h"
31
32 #ifndef DOCGEN
33
34 #include "rpp/rpp.h"
35 #include <stdlib.h>
36
37 #define BASE_FREQ_MILLIS    1000
38 #define FREQ_VARIABILITY    100
39 #define TEST_TASK_PRIORITY  0
40 #define TEST_TASK_STACK     512
41 #define INPUT_IDLE          50
42
43
44 // Task control
45 extern xSemaphoreHandle rpp_sdr_cmdproc_semaphore;
46 static boolean_t stop_tasks = FALSE;    /**< Flag for stopping all related tasks. */
47 static uint8_t tasks_running = 0;       /**< Task counter - incremented each time task is spawn, decremented when task is deleted */
48
49 /**
50  * @brief Set flag for tasks to finish.
51  *
52  * All tasks are reading the flag during their work and when
53  * they detect this flag is up, they stop the routine, decrement
54  * task counter and delete themselves.
55  */
56 static void wait_tasks_to_finish()
57 {
58         stop_tasks = TRUE;
59         while (tasks_running > 0)
60                 taskYIELD();
61         stop_tasks = FALSE;
62 }
63
64 /**
65  * @brief Wait for user input "q" to quit the loop.
66  */
67 void wait_for_quit()
68 {
69         while (rpp_sci_getc() < 0)
70                 vTaskDelay(INPUT_IDLE / portTICK_RATE_MS);
71 }
72
73
74 /**
75  * FreeRTOS Task that send some noise to the log from time to time.
76  */
77 void sdr_test_task(void *par)
78 {
79         // Calculate wait time in OS ticks
80         static const portTickType freq_ticks = BASE_FREQ_MILLIS / portTICK_RATE_MS;
81         portTickType last_wake_time = xTaskGetTickCount();
82
83         // Initialize rand
84         srand(2097925); // They are random, I swear xD
85
86         uint32_t i = 0;
87         uint32_t variation = 0;
88         int8_t plus_minus = 1;
89         while (!stop_tasks) {
90
91                 // Put something in the log
92                 rpp_sdr_printf((const char*)
93                                            "This is the noise generator at iteration %d "
94                                            "putting some noise value %d.", i, rand()
95                                            );
96                 i++;
97
98                 if (!stop_tasks) {
99                         variation = freq_ticks +
100                                                 (plus_minus * ((rand() % FREQ_VARIABILITY) + 1));
101                         plus_minus = plus_minus * -1;
102                         vTaskDelayUntil(&last_wake_time, variation);
103                 }
104         }
105
106         // Delete myself
107         tasks_running--;
108         vTaskDelete(NULL);
109 }
110
111 /**
112  * SDR Test entry point.
113  */
114 void test_sdr()
115 {
116         /// Configure module
117         // - See note below.
118
119
120         /// Spawn tasks
121         xTaskHandle test_task_handle;
122
123         // Spawn noise task first, and later enable logging. Depending on the time
124         // required the first logs might not be registered, but that's ok, is better
125         // to check if logging could be enabled after data is being sent that enable
126         // command processor (which output messages to the SCI), and that inmediatly
127         // after the noise task could not be created, forcing to close the just
128         // opened command processor.
129         portBASE_TYPE task_created = xTaskCreate(sdr_test_task,
130                                                                                          (const signed char*)"sdr_test_task",
131                                                                                          TEST_TASK_STACK, NULL, TEST_TASK_PRIORITY,
132                                                                                          &test_task_handle
133                                                                                          );
134
135         if (task_created != pdPASS) {
136
137                 rpp_sci_printf((const char*)
138                                            "ERROR: Problem spawning the test task. "
139                                            "Error code: %d\r\n", (uint32_t)task_created
140                                            );
141
142                 wait_for_quit();
143                 return;
144         }
145         tasks_running++;
146
147         if (rpp_sdr_setup(TRUE) != SUCCESS) {
148                 rpp_sci_printf((const char*)
149                                            "ERROR: Problem enabling the logging module. "
150                                            );
151                 wait_for_quit();
152                 wait_tasks_to_finish();
153                 return;
154         }
155
156         // Wait for the SDR included command processor to finish
157         xSemaphoreTake(rpp_sdr_cmdproc_semaphore, portMAX_DELAY);
158         wait_tasks_to_finish();
159
160         /// Reset module configuration
161         if (rpp_sdr_setup(FALSE) != SUCCESS) {
162                 rpp_sci_printf((const char*)
163                                            "ERROR: Could not stop logging module.\r\n"
164                                            );
165                 wait_for_quit();
166         }
167
168         rpp_sci_printf((const char*)"\r\n");
169
170         return;
171 }
172
173
174 /**
175  * @brief Start SDR test routine
176  *
177  * @param[in]   cmd_io  Pointer to IO stack
178  * @param[in]   des             Pointer to command descriptor
179  * @param[in]   param   Parameters of command
180  * @return always 0
181  */
182 int cmd_do_test_log(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
183 {
184         test_sdr();
185         return 0;
186 }
187
188 /**
189  * @brief       Tests the capacity and fitness of connected SDRAM
190  *
191  * @param[in]   cmd_io  Pointer to IO stack
192  * @param[in]   des             Pointer to command descriptor
193  * @param[in]   param   Parameters of command
194  * @return      0 when OK or error code
195  */
196 int cmd_do_test_ram(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
197 {
198         volatile uint32_t *addrPtr = (uint32_t*)0x80000000U;
199         volatile uint32_t *endAddr = (uint32_t*)0x83FFFFFFU;
200         uint32_t pattern = 0x55555555U;
201         uint32_t cnt = 0;
202         uint32_t errCnt = 0;
203         uint32_t readVal = 0;
204
205         while (addrPtr <= endAddr) {
206                 *addrPtr = pattern;
207                 pattern += 0x55555555U;
208                 addrPtr++;
209         }
210
211         addrPtr = (uint32_t*)0x80000000U;
212         pattern = 0x55555555U;
213         while (addrPtr <= endAddr) {
214                 readVal = *addrPtr;
215                 if (pattern == readVal) cnt++;
216                 else if (errCnt++ <= 10)
217                         rpp_sci_printf("Error at %h\r\n",addrPtr);
218                 else break;
219                 pattern += 0x55555555U;
220                 addrPtr++;
221         }
222
223         cnt = cnt * sizeof(uint32_t) / 1024 / 1024;
224         if (cnt == 0)
225                 rpp_sci_printf("SDRAM not connected.");
226         else
227                 rpp_sci_printf("SDRAM installed: %d MB", cnt);
228
229         return 0;
230 }
231
232 #endif  /* DOCGEN */
233
234 /** Command descriptor for test SDRAM */
235 cmd_des_t const cmd_des_test_sdram = {
236         0, 0,
237         "sdramtest","Test if the SDRAM module is connected and if so, measures its capacity",
238         "### Command syntax ###\n"
239         "\n"
240         "    sdramtest\n"
241         "\n"
242         "### Description ###\n"
243         "\n"
244         "This command tests SDRAM address space by writing and reading a\n"
245         "pattern to/from it. It detects the SDRAM capacity.\n"
246         "\n"
247         "### Example ###\n"
248         "\n"
249         "    --> sdramtest\n"
250         "    SDRAM installed: 64 MB\n",
251         CMD_HANDLER(cmd_do_test_ram), (void*)&cmd_list_sdram
252 };
253
254 /** Command descriptor for test log to SDRAM */
255 cmd_des_t const cmd_des_test_log = {
256         0, 0,
257         "sdramlogtest","Open a command subprocessor for managing SDRAM logging",
258         "### Command syntax ###\n"
259         "\n"
260         "    sdramlogtest\n"
261         "\n"
262         "### Description ###\n"
263         "\n"
264         "The command opens a subcommand processor, which contains testing\n"
265         "commands for logging into SDRAM.\n",
266         CMD_HANDLER(cmd_do_test_log), (void*)&cmd_list_sdram
267 };
268
269 /** List of commands for sdram, defined as external */
270 cmd_des_t const *cmd_list_sdram[] = {
271         &cmd_des_test_sdram,
272         &cmd_des_test_log,
273         NULL
274 };