]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - sw/app/rocon/appl_tests.c
Optimize PXMCC firmware to use only 32-bit types and change mode selection back.
[fpga/lx-cpu1/lx-rocon.git] / sw / app / rocon / appl_tests.c
1 #include <system_def.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <stddef.h>
7 #include <malloc.h>
8 #include <utils.h>
9 #include <cmd_proc.h>
10 #include <hal_gpio.h>
11 #include <hal_machperiph.h>
12 #include <LPC17xx.h>
13 #include <lpcTIM.h>
14 #include <spi_drv.h>
15 #include <pxmc.h>
16 #include <inttypes.h>
17
18 #include <ul_log.h>
19 #include <ul_logreg.h>
20
21 #include "appl_defs.h"
22 #include "appl_fpga.h"
23 #include "pxmcc_types.h"
24
25 int cmd_do_test_memusage(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
26 {
27   void *maxaddr;
28   char str[40];
29
30   maxaddr = sbrk(0);
31
32   snprintf(str, sizeof(str), "memusage maxaddr 0x%08lx\n", (unsigned long)maxaddr);
33   cmd_io_write(cmd_io, str, strlen(str));
34
35   return 0;
36 }
37
38 int cmd_do_test_adc(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
39 {
40   printf("ADC: %ld %ld %ld %ld %ld\n", (LPC_ADC->DR[0] & 0xFFF0) >> 4,
41          (LPC_ADC->DR[1] & 0xFFF0) >> 4,
42          (LPC_ADC->DR[2] & 0xFFF0) >> 4,
43          (LPC_ADC->DR[3] & 0xFFF0) >> 4,
44          (LPC_ADC->DR[7] & 0xFFF0) >> 4);
45   return 0;
46 }
47
48 #ifdef APPL_WITH_DISTORE_EEPROM_USER
49 int cmd_do_test_distore(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
50 {
51   appl_distore_user_set_check4change();
52   return 0;
53 }
54
55 int cmd_do_test_diload(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
56 {
57   appl_distore_user_restore();
58   return 0;
59 }
60 #endif /*APPL_WITH_DISTORE_EEPROM_USER*/
61
62 int cmd_do_test_loglevel_cb(ul_log_domain_t *domain, void *context)
63 {
64   char s[30];
65   cmd_io_t *cmd_io = (cmd_io_t *)context;
66
67   s[sizeof(s) - 1] = 0;
68   snprintf(s, sizeof(s) - 1, "%s (%d)\n\r", domain->name, domain->level);
69   cmd_io_puts(cmd_io, s);
70   return 0;
71 }
72
73 int cmd_do_test_loglevel(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
74 {
75   int res = 0;
76   char *line;
77   line = param[1];
78
79   if (!line || (si_skspace(&line), !*line))
80   {
81     ul_logreg_for_each_domain(cmd_do_test_loglevel_cb, cmd_io);
82   }
83   else
84   {
85     res = ul_log_domain_arg2levels(line);
86   }
87
88   return res >= 0 ? 0 : CMDERR_BADPAR;
89 }
90
91 int cmd_do_spimst_blocking(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
92 {
93   int res;
94   int opchar;
95   char *p = param[3];
96   int spi_chan = (int)(intptr_t)des->info[0];
97   uint8_t *tx_buff = NULL;
98   uint8_t *rx_buff = NULL;
99   long addr = 0;
100   int len = 0;
101   spi_drv_t *spi_drv;
102
103   if ((opchar = cmd_opchar_check(cmd_io, des, param)) < 0)
104     return opchar;
105
106   if (opchar != ':')
107     return -CMDERR_OPCHAR;
108
109   if (spi_chan == -1)
110     spi_chan = *param[1] - '0';
111
112   spi_drv = spi_find_drv(NULL, spi_chan);
113
114   if (spi_drv == NULL)
115     return -CMDERR_BADSUF;
116
117   p = param[3];
118
119   si_skspace(&p);
120
121   if (isdigit((int)*p))
122   {
123     if (si_long(&p, &addr, 16) < 0)
124       return -CMDERR_BADPAR;
125   }
126
127   if (si_fndsep(&p, "({") < 0)
128     return -CMDERR_BADSEP;
129
130   if ((res = si_add_to_arr(&p, (void **)&tx_buff, &len, 16, 1, "})")) < 0)
131     return -CMDERR_BADPAR;
132
133   rx_buff = malloc(len);
134
135   res = -1;
136
137   if (rx_buff != NULL)
138     res = spi_transfer(spi_drv, addr, len, tx_buff, rx_buff);
139
140   if (res < 0)
141   {
142     printf("SPI! %02lX ERROR\n", addr);
143   }
144   else
145   {
146     int i;
147     printf("SPI! %02lX ", addr);
148     printf("TX(");
149
150     for (i = 0; i < len; i++)
151       printf("%s%02X", i ? "," : "", tx_buff[i]);
152
153     printf(") RX(");
154
155     for (i = 0; i < len; i++)
156       printf("%s%02X", i ? "," : "", rx_buff[i]);
157
158     printf(")");
159     printf("\n");
160     return 0;
161   }
162
163   if (rx_buff)
164     free(rx_buff);
165
166   if (tx_buff)
167     free(tx_buff);
168
169   return 0;
170 }
171
172 #ifdef SDRAM_BASE
173 int sdram_access_test(void)
174 {
175   unsigned int *ptr;
176   unsigned int pattern;
177   size_t ramsz = SDRAM_SIZE;
178   size_t cnt;
179   lt_mstime_t tic;
180   size_t blksz, i;
181
182   lt_mstime_update();
183   tic = actual_msec;
184
185   pattern = 0x12abcdef;
186
187   for (cnt = ramsz / sizeof(*ptr), ptr = (typeof(ptr))SDRAM_BASE; cnt--;)
188   {
189     *(ptr++) = pattern;
190     pattern = pattern + 0x87654321;
191   }
192
193   lt_mstime_update();
194   printf("SDRAM write %d ms\n", (int)(lt_msdiff_t)(actual_msec - tic));
195
196   lt_mstime_update();
197   tic = actual_msec;
198
199   pattern = 0x12abcdef;
200
201   for (cnt = ramsz / sizeof(*ptr), ptr = (typeof(ptr))SDRAM_BASE; cnt--;)
202   {
203     if (*ptr != pattern)
204     {
205       printf("SDRAM error modify at %p (%08x)\n", ptr, *ptr ^ pattern);
206       return -1;
207     }
208
209     *(ptr++) = ~pattern;
210     pattern = pattern + 0x87654321;
211   }
212
213   lt_mstime_update();
214   printf("SDRAM modify %d ms\n", (int)(lt_msdiff_t)(actual_msec - tic));
215
216   lt_mstime_update();
217   tic = actual_msec;
218
219   pattern = 0x12abcdef;
220
221   for (cnt = ramsz / sizeof(*ptr), ptr = (typeof(ptr))SDRAM_BASE; cnt--;)
222   {
223     if (*(ptr++) != ~pattern)
224     {
225       printf("SDRAM error read at %p (%08x)\n", ptr, *ptr ^ pattern);
226       return -1;
227     }
228
229     pattern = pattern + 0x87654321;
230   }
231
232   lt_mstime_update();
233   printf("SDRAM read %d ms\n", (int)(lt_msdiff_t)(actual_msec - tic));
234
235   lt_mstime_update();
236   tic = actual_msec;
237
238   pattern = 0;
239
240   for (cnt = ramsz / sizeof(*ptr), ptr = (typeof(ptr))SDRAM_BASE; cnt--;)
241   {
242     pattern += *(ptr++);
243   }
244
245   lt_mstime_update();
246   printf("SDRAM sum %d ms res 0x%08x\n", (int)(lt_msdiff_t)(actual_msec - tic), pattern);
247
248   for (blksz = 1; blksz < 256 ; blksz *= 2)
249   {
250     lt_mstime_update();
251     tic = actual_msec;
252
253     pattern = 0;
254
255     for (cnt = ramsz / sizeof(*ptr); cnt; cnt -= blksz)
256     {
257       ptr = (typeof(ptr))SDRAM_BASE;
258
259       //ptr = (typeof(ptr))cmd_do_test_memusage;
260       //ptr = (typeof(ptr))&ptr;
261       for (i = blksz; i--;)
262         pattern += *(ptr++);
263     }
264
265     lt_mstime_update();
266     printf("SDRAM sum %d blksz %d ms res 0x%08x\n", (int)(lt_msdiff_t)(actual_msec - tic), (int)blksz, pattern);
267   }
268
269   return 0;
270 }
271
272 int cmd_do_testsdram(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
273 {
274   sdram_access_test();
275   return 0;
276 }
277 #endif /*SDRAM_BASE*/
278
279 int cmd_do_testlxpwrrx(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
280 {
281   char *ps = param[1];
282   long mode = 0;
283   uint32_t *ptr;
284
285   if (ps != NULL) {
286     si_skspace(&ps);
287     if (*ps) {
288       if (si_ulong(&ps, &mode, 0) < 0)
289         return -CMDERR_BADPAR;
290     }
291   }
292   pxmc_rocon_rx_data_hist_buff = NULL;
293   pxmc_rocon_rx_data_hist_mode = mode;
294
295  #ifndef PXMC_ROCON_TIMED_BY_RX_DONE
296   pxmc_rocon_rx_done_isr_setup(pxmc_rocon_rx_done_isr);
297  #endif /*PXMC_ROCON_TIMED_BY_RX_DONE*/
298   pxmc_rocon_rx_data_hist_buff_end = (void *)(FPGA_CONFIGURATION_FILE_ADDRESS +
299                                          0x80000);
300   ptr = (void *)FPGA_CONFIGURATION_FILE_ADDRESS;
301   if (mode != 0) {
302     *(ptr++) = '10XL';
303     *(ptr++) = mode;
304   }
305   pxmc_rocon_rx_data_hist_buff = (void *)ptr;
306   return 0;
307 }
308
309 int cmd_do_testlxpwrstat(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
310 {
311   printf("lxpwrrx period %ld latency %ld max %ld\n",
312          (long)pxmc_rocon_rx_cycle_time, (long)pxmc_rocon_rx_irq_latency,
313          (long)pxmc_rocon_rx_irq_latency_max);
314   return 0;
315 }
316
317 #include <math.h>
318
319 int cmd_do_testfncapprox(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
320 {
321   char *ps = param[1];
322   unsigned long fnc;
323   unsigned long val;
324   unsigned long res;
325   long diff;
326   long diff_max = 0;
327   unsigned int  xb;
328   uint32_t x;
329   uint32_t xl;
330   double   xf;
331   int64_t  yl;
332   long count = 1;
333   long step = 1 << (30-7-18+1  +4);
334
335   si_skspace(&ps);
336   if (si_ulong(&ps, &fnc, 0) < 0)
337       return -CMDERR_BADPAR;
338
339   si_skspace(&ps);
340   if (!strcmp(ps, "all")) {
341     val = 0;
342     count = 0x80000000UL / step;
343     if (fnc == 1) {
344       val = 1;
345     }
346   } else {
347     if (si_ulong(&ps, &val, 0) < 0)
348         return -CMDERR_BADPAR;
349   }
350
351   for (; count--;  val += step) {
352
353     if (fnc == 1) {
354       x = val;
355       xb = __builtin_clz(x);
356       xl = x << xb;
357     } else {
358       xl = val;
359     }
360
361     fpga_fncapprox_base[fnc] = xl;
362
363     /* dummy read to provide time to function aproximator to proceed computation */
364     res = fpga_fncapprox_base[fnc];
365     res = fpga_fncapprox_base[fnc];
366
367     switch (fnc) {
368       case 0:
369         yl = xl;
370       case 1:
371         yl = (1LL << 62) / xl;
372         break;
373       case 2:
374         xf = (double)xl * M_PI / 2.0 / (1UL << 30);
375         yl = round(sin(xf) * (1UL << 16));
376         break;
377       case 3:
378         xf = (double)xl * M_PI / 2.0 / (1UL << 30);
379         yl = round(cos(xf) * (1UL << 16));
380         break;
381       default:
382       yl = 0;
383     }
384
385     diff = yl - res;
386
387     if ((diff > 0) && (diff > diff_max))
388       diff_max = diff;
389     else if ((diff < 0) && (-diff > diff_max))
390       diff_max = -diff;
391
392   }
393
394   val -= step;
395
396   printf("fnc=%ld val=0x%08lx res=0x%08lx ref=0x%08lx diff=%ld max %ld\n",
397          fnc, val, res, (unsigned long)yl, diff, diff_max);
398
399   return 0;
400 }
401
402 int cmd_do_testtumblefw(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
403 {
404   char *ps = param[1];
405   long pwm_d;
406   long pwm_q;
407   uint32_t ptofs;
408   uint32_t irc;
409   uint32_t ptirc;
410   uint32_t ptreci;
411   uint32_t pwmtx_info;
412   uint64_t ull;
413   pxmc_state_t *mcs = pxmc_main_list.pxml_arr[0];
414   volatile pxmcc_data_t *mcc_data = (pxmcc_data_t *)fpga_tumbl_dmem;
415   volatile pxmcc_axis_data_t *mcc_axis = mcc_data->axis + 0;
416
417   mcc_axis->ccflg = 0;
418
419   si_skspace(&ps);
420   if (si_long(&ps, &pwm_d, 0) < 0)
421       return -CMDERR_BADPAR;
422
423   si_skspace(&ps);
424   if (si_ulong(&ps, &pwm_q, 0) < 0)
425         return -CMDERR_BADPAR;
426
427   irc = fpga_irc[0]->count;
428   ptofs = (int16_t)(mcs->pxms_ptofs - irc) + irc;
429
430   ptirc = mcs->pxms_ptirc;
431   ull = (1ULL << 32) * mcs->pxms_ptper;
432   ptreci = (ull + ptirc / 2) / ptirc;
433
434   pwmtx_info = (9 << 0) | (10 << 8) | (11 << 16);
435
436   mcc_axis->mode = 0;
437
438   mcc_axis->inp_info = mcs->pxms_inp_info;
439   mcc_axis->out_info = mcs->pxms_out_info;
440   mcc_axis->pwmtx_info = pwmtx_info;
441
442   mcc_axis->ptirc = ptirc;
443   mcc_axis->ptreci = ptreci;
444   mcc_axis->ptofs = ptofs;
445
446   mcc_axis->ccflg = 0;
447   mcc_axis->pwm_dq = (pwm_d << 16) | (pwm_q & 0xffff);
448
449   pxmc_clear_flags(mcs,PXMS_ENO_m|PXMS_ENG_m|PXMS_ENR_m|PXMS_BSY_m);
450
451   mcc_axis->ccflg = 1;
452
453   if (0) {
454     mcc_data->axis[1].inp_info = 1;
455     mcc_data->axis[1].out_info = 3;
456     mcc_data->axis[1].pwmtx_info = (12 << 0) | (13 << 8) | (14 << 16);
457     mcc_data->axis[1].mode = 0;
458     mcc_data->axis[1].ccflg = 1;
459     mcc_data->axis[2].inp_info = 2;
460     mcc_data->axis[2].out_info = 6;
461     mcc_data->axis[2].pwmtx_info = (15 << 0) | (16 << 8) | (18 << 16);
462     mcc_data->axis[2].mode = 0;
463     mcc_data->axis[2].ccflg = 1;
464     mcc_data->axis[3].inp_info = 3;
465     mcc_data->axis[3].out_info = 9;
466     mcc_data->axis[3].pwmtx_info = (19 << 0) | (20 << 8) | (21 << 16);
467     mcc_data->axis[3].mode = 0;
468     mcc_data->axis[3].ccflg = 1;
469   }
470
471   printf("spd %ld act_idle %"PRIu32" min_idle %"PRIu32" avail %lu pwm_cycle %"PRIu32"\n",
472          mcs->pxms_as, mcc_data->common.act_idle, mcc_data->common.min_idle,
473          (mcc_data->common.pwm_cycle + 6) / 6, mcc_data->common.pwm_cycle);
474   mcc_data->common.min_idle = 0x7fff;
475
476   return 0;
477 }
478
479 #define CK_IRC_WORDS 16
480 #define CK_TX_WORDS  16
481 #define CK_RX_WORDS  16
482
483 #define CK_IRC_START ((uint32_t*)fpga_irc[0])
484 #define CK_TX_START  (fpga_lx_master_transmitter_base+9)
485 #define CK_RX_START  (fpga_lx_master_receiver_base+44)
486
487 typedef struct ck_state_t {
488   uint32_t ck_irc_base[CK_IRC_WORDS];
489   uint32_t ck_irc_read[CK_IRC_WORDS];
490   uint32_t ck_tx_base[CK_TX_WORDS];
491   uint32_t ck_tx_read[CK_TX_WORDS];
492   uint32_t ck_rx_base[CK_RX_WORDS];
493   uint32_t ck_rx_read[CK_RX_WORDS];
494
495   uint32_t ck_irc_err;
496   uint32_t ck_tx_err;
497   uint32_t ck_rx_err;
498 } ck_state_t;
499
500 int cmd_do_testtumblebus(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
501 {
502   int i;
503   int cycles = 10000;
504   static ck_state_t *ckst = NULL;
505   if (ckst == NULL)
506     ckst = malloc(sizeof(*ckst));
507   if (ckst == NULL)
508     return 1;
509
510   ckst->ck_irc_err = 0;
511   ckst->ck_tx_err = 0;
512   ckst->ck_rx_err = 0;
513
514   for (i = 0; i < CK_IRC_WORDS; i++)
515     ckst->ck_irc_base[i] = CK_IRC_START[i];
516
517   for (i = 0; i < CK_TX_WORDS; i++)
518     ckst->ck_tx_base[i] = CK_TX_START[i];
519
520   for (i = 0; i < CK_RX_WORDS; i++)
521     ckst->ck_rx_base[i] = CK_RX_START[i];
522
523   while (cycles--) {
524     if (!ckst->ck_irc_err) {
525       for (i = 0; i < CK_IRC_WORDS; i++)
526         ckst->ck_irc_read[i] = CK_IRC_START[i];
527       for (i = 0; i < CK_IRC_WORDS; i++)
528         if (ckst->ck_irc_read[i] != ckst->ck_irc_base[i]) {
529           ckst->ck_irc_err++;
530           printf("irc+%x %08"PRIx32" != %08"PRIx32"\n",
531                  i, ckst->ck_irc_read[i], ckst->ck_irc_base[i]);
532         }
533     }
534
535     if (!ckst->ck_tx_err) {
536       for (i = 0; i < CK_TX_WORDS; i++)
537         ckst->ck_tx_read[i] = CK_TX_START[i];
538       for (i = 0; i < CK_TX_WORDS; i++)
539         if (ckst->ck_tx_read[i] != ckst->ck_tx_base[i]) {
540           ckst->ck_tx_err++;
541           printf("tx+%x %08"PRIx32" != %08"PRIx32"\n",
542                  i, ckst->ck_tx_read[i], ckst->ck_tx_base[i]);
543         }
544     }
545
546     if (!ckst->ck_rx_err) {
547       for (i = 0; i < CK_RX_WORDS; i++)
548         ckst->ck_rx_read[i] = CK_RX_START[i];
549       for (i = 0; i < CK_RX_WORDS; i++)
550         if (ckst->ck_rx_read[i] != ckst->ck_rx_base[i]) {
551           ckst->ck_rx_err++;
552           printf("rx+%x %08"PRIx32" != %08"PRIx32"\n",
553                  i, ckst->ck_rx_read[i], ckst->ck_rx_base[i]);
554         }
555     }
556   }
557
558   return 0;
559 }
560
561 cmd_des_t const cmd_des_test_memusage = {0, 0,
562                 "memusage", "report memory usage", cmd_do_test_memusage,
563 {
564   0,
565   0
566 }
567                                         };
568
569 cmd_des_t const cmd_des_test_adc = {0, 0,
570                                     "testadc", "adc test", cmd_do_test_adc,
571 {
572   0,
573   0
574 }
575                                    };
576
577 #ifdef APPL_WITH_DISTORE_EEPROM_USER
578 cmd_des_t const cmd_des_test_distore = {0, 0,
579                                         "testdistore", "test DINFO store", cmd_do_test_distore,
580 {
581   0,
582   0
583 }
584                                        };
585
586 cmd_des_t const cmd_des_test_diload = {0, 0,
587                                        "testdiload", "test DINFO load", cmd_do_test_diload,
588 {
589   0,
590   0
591 }
592                                       };
593 #endif /*APPL_WITH_DISTORE_EEPROM_USER*/
594
595 cmd_des_t const cmd_des_test_loglevel = {0, 0,
596                 "loglevel", "select logging level",
597                 cmd_do_test_loglevel, {}
598                                         };
599
600 cmd_des_t const cmd_des_spimst = {0, CDESM_OPCHR | CDESM_WR,
601                                   "SPIMST", "SPI master communication request",
602                                   cmd_do_spimst_blocking, {(void *)0}
603                                  };
604
605 cmd_des_t const cmd_des_spimstx = {0, CDESM_OPCHR | CDESM_WR,
606                                    "SPIMST#", "SPI# master communication request",
607                                    cmd_do_spimst_blocking, {(void *) - 1}
608                                   };
609
610 #ifdef SDRAM_BASE
611 cmd_des_t const cmd_des_testsdram = {0, 0,
612                                      "testsdram", "test SDRAM",
613                                      cmd_do_testsdram, {(void *)0}
614                                     };
615 #endif /*SDRAM_BASE*/
616
617
618 cmd_des_t const cmd_des_testlxpwrrx = {0, 0,
619                                      "testlxpwrrx", "capture data stream from lxpwr",
620                                      cmd_do_testlxpwrrx, {(void *)0}
621                                     };
622
623 cmd_des_t const cmd_des_testlxpwrstat = {0, 0,
624                                      "testlxpwrstat", "lxpwr interrupt statistic",
625                                      cmd_do_testlxpwrstat, {(void *)0}
626                                     };
627
628 cmd_des_t const cmd_des_testfncapprox = {0, 0,
629                                      "testfncapprox", "test of function approximator",
630                                      cmd_do_testfncapprox, {(void *)0}
631                                     };
632
633 cmd_des_t const cmd_des_testtumblefw = {0, 0,
634                                      "testtumblefw", "test Tumble coprocesor firmware",
635                                      cmd_do_testtumblefw, {(void *)0}
636                                     };
637
638 cmd_des_t const cmd_des_testtumblebus = {0, 0,
639                                      "testtumblebus", "test Tumble coprocesor bus",
640                                      cmd_do_testtumblebus, {(void *)0}
641                                     };
642
643
644 cmd_des_t const *const cmd_appl_tests[] =
645 {
646   &cmd_des_test_memusage,
647   &cmd_des_test_adc,
648 #ifdef APPL_WITH_DISTORE_EEPROM_USER
649   &cmd_des_test_distore,
650   &cmd_des_test_diload,
651 #endif /*APPL_WITH_DISTORE_EEPROM_USER*/
652   &cmd_des_test_loglevel,
653   &cmd_des_spimst,
654   &cmd_des_spimstx,
655 #ifdef SDRAM_BASE
656   &cmd_des_testsdram,
657 #endif /*SDRAM_BASE*/
658   &cmd_des_testlxpwrrx,
659   &cmd_des_testlxpwrstat,
660   &cmd_des_testfncapprox,
661   &cmd_des_testtumblefw,
662   &cmd_des_testtumblebus,
663   NULL
664 };