Coverage Report

Created: 2025-06-15 00:57

/src/cmp_tool/lib/rdcu_compress/rdcu_ctrl.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file   rdcu_ctrl.c
3
 * @author Armin Luntzer (armin.luntzer@univie.ac.at)
4
 * @date   2018
5
 *
6
 * @copyright GPLv2
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms and conditions of the GNU General Public License,
9
 * version 2, as published by the Free Software Foundation.
10
 *
11
 * This program is distributed in the hope it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14
 * more details.
15
 *
16
 * @brief RMAP RDCU control library
17
 * @see FPGA Requirement Specification PLATO-IWF-PL-RS-005 Issue 0.7
18
 *
19
 * USAGE:
20
 *  All sync() calls respect the direction of the sync, i.e. read-only
21
 *  registers in the RDCU are synced to the local mirror
22
 *  and vice-versa for write-only register
23
 *  The only exception are SRAM (data) related syncs, they specify
24
 *  the direction by a directional suffix, which is either _icu_rdcu
25
 *  for ICU->RDCU, i.e. transfer local to remote, or _rdcu_icu for a
26
 *  read-back
27
 *
28
 *  Access to the local mirror is provided by _get or _set calls, so
29
 *  to configure a register in the RDCU, one would call the sequence:
30
 *
31
 *  set_register_xyz(someargument);
32
 *  sync_register_xyz();
33
 *
34
 *  while(rdcu_sync_status())
35
 *    wait_busy_or_do_something_else_your_choice();
36
 *
37
 *  [sync_comple]
38
 *
39
 *  and to read a register:
40
 *
41
 *  sync_register_uvw()
42
 *
43
 *  while(rdcu_sync_status())
44
 *    wait_busy_or_do_something_else_your_choice();
45
 *
46
 *  [sync_comple]
47
 *
48
 *  value = get_register_uvw();
49
 *
50
 *
51
 * @warning this has not been thoroughly tested and is in need of inspection
52
 *      with regards to the specification, in order to locate any
53
 *      register transcription errors or typos
54
 *      In the PLATO-IWF-PL-RS-005 Issue 0.7 (at least the one I have),
55
 *      register bits in tables and register figures are sometimes in
56
 *      conflict. Only values from tables have been used here.
57
 */
58
59
60
#include <stdlib.h>
61
#include <stdint.h>
62
#include <string.h>
63
64
#include "../common/byteorder.h"
65
#include "../common/cmp_debug.h"
66
#include "rdcu_cmd.h"
67
#include "rdcu_ctrl.h"
68
#include "rdcu_rmap.h"
69
70
71
static struct rdcu_mirror *rdcu;
72
73
74
/**
75
 * @brief get the 4 FPGA minor/major version digits
76
 * @see RDCU-FRS-FN-0522
77
 */
78
79
uint16_t rdcu_get_fpga_version(void)
80
0
{
81
0
  return (uint16_t) (rdcu->fpga_version & 0xFFFF);
82
0
}
83
84
85
/**
86
 * @brief get the RDCU board serial number
87
 * @see RDCU-FRS-FN-0532
88
 */
89
90
uint32_t rdcu_get_rdcu_status_board_serial_number(void)
91
0
{
92
0
  return (rdcu->rdcu_status >> 12) & 0xFUL;
93
0
}
94
95
96
/**
97
 * @brief get FPGA core power good bit
98
 * @see RDCU-FRS-FN-0532
99
 *
100
 * @returns 0 : FPGA core power supply failure
101
 *      1 : FPGA core power supply (1.5V) is good
102
 */
103
104
uint32_t rdcu_get_rdcu_status_fpga_core_power_good(void)
105
0
{
106
0
  return (rdcu->rdcu_status >> 6) & 0x1UL;
107
0
}
108
109
110
/**
111
 * @brief get core power good bit
112
 * @see RDCU-FRS-FN-0532
113
 *
114
 * @returns 0 : FPGA core power supply failure
115
 *      1 : FPGA core power supply (1.8V) is good
116
 */
117
118
uint32_t rdcu_get_rdcu_status_core_power_good(void)
119
0
{
120
0
  return (rdcu->rdcu_status >> 5) & 0x1UL;
121
0
}
122
123
124
/**
125
 * @brief get i/o power good bit
126
 * @see RDCU-FRS-FN-0532
127
 *
128
 * @returns 0 : FPGA core power supply failure
129
 *      1 : FPGA core power supply (3.3V) is good
130
 */
131
132
uint32_t rdcu_get_rdcu_status_io_power_good(void)
133
0
{
134
0
  return (rdcu->rdcu_status >> 4) & 0x1UL;
135
0
}
136
137
138
/**
139
 * @brief get reset by register bit
140
 * @see RDCU-FRS-FN-0532
141
 *
142
 * @returns 0 : not the reset reason
143
 *      1 : reset triggered by register bit
144
 */
145
146
uint32_t rdcu_get_rdcu_status_reset_by_register(void)
147
0
{
148
0
  return (rdcu->rdcu_status >> 1) & 0x1UL;
149
0
}
150
151
152
/**
153
 * @brief get power on reset bit
154
 * @see RDCU-FRS-FN-0532
155
 *
156
 * @returns 0 : not the reset reason
157
 *      1 : reset triggered by power on
158
 */
159
160
uint32_t rdcu_get_rdcu_status_power_on_reset(void)
161
0
{
162
0
  return rdcu->rdcu_status & 0x1UL;
163
0
}
164
165
166
/**
167
 * @brief get RMAP Target logical address
168
 * @see RDCU-FRS-FN-0542
169
 */
170
171
uint8_t rdcu_get_rmap_target_logical_address(void)
172
0
{
173
0
  return (uint8_t) ((rdcu->lvds_core_status >> 24) & 0xFFUL);
174
0
}
175
176
177
/**
178
 * @brief get RMAP Target command key
179
 * @see RDCU-FRS-FN-0542
180
 */
181
182
uint8_t rdcu_get_rmap_target_cmd_key(void)
183
0
{
184
0
  return (uint8_t) ((rdcu->lvds_core_status >> 16) & 0xFFUL);
185
0
}
186
187
188
/**
189
 * @brief get LVDS link enabled bit
190
 *
191
 * @param link the link number (0-7)
192
 *
193
 * @see RDCU-FRS-FN-0542
194
 *
195
 * @returns 0 : LVDS link disabled
196
 *      1 : LVDS link enabled
197
 *      other: invalid link argument
198
 */
199
200
uint32_t rdcu_get_lvds_link_enabled(uint32_t link)
201
0
{
202
0
  if (link > 7)
203
0
    return -1U;
204
205
0
  return (rdcu->lvds_core_status >> link) & 0x1UL;
206
0
}
207
208
209
/**
210
 * @brief get SpW empty packet count
211
 * @see RDCU-FRS-FN-0552
212
 */
213
214
uint16_t rdcu_get_spw_empty_pckt_cnt(void)
215
0
{
216
0
  return (uint16_t) ((rdcu->spw_link_status >> 16) & 0xFFUL);
217
0
}
218
219
220
/**
221
 * @brief get SpW run-state clock divisor value
222
 * @see RDCU-FRS-FN-0552
223
 */
224
225
uint8_t rdcu_get_spw_run_clk_div(void)
226
0
{
227
0
  return (uint8_t) ((rdcu->spw_link_status >> 8) & 0x3FUL);
228
0
}
229
230
231
/**
232
 * @brief get SpW link run state
233
 * @see RDCU-FRS-FN-0552
234
 *
235
 * @returns 0 : SpW link not established
236
 *      1 : SpW link is running
237
 */
238
239
uint8_t rdcu_get_spw_lnk_run_state(void)
240
0
{
241
0
  return (uint8_t) ((rdcu->spw_link_status >> 8) & 0x1UL);
242
0
}
243
244
245
/**
246
 * @brief get SpW link credit errors
247
 * @see RDCU-FRS-FN-0562
248
 */
249
250
uint8_t rdcu_get_spw_lnk_credit_errs(void)
251
0
{
252
0
  return (uint8_t) ((rdcu->spw_link_status >> 24) & 0xFFUL);
253
0
}
254
255
256
/**
257
 * @brief get SpW link escape errors
258
 * @see RDCU-FRS-FN-0562
259
 */
260
261
uint8_t rdcu_get_spw_lnk_escape_errs(void)
262
0
{
263
0
  return (uint8_t) ((rdcu->spw_link_status >> 16) & 0xFFUL);
264
0
}
265
266
267
/**
268
 * @brief get SpW link parity errors
269
 * @see RDCU-FRS-FN-0562
270
 */
271
272
uint8_t rdcu_get_spw_lnk_parity_errs(void)
273
0
{
274
0
  return (uint8_t) ((rdcu->spw_link_status >> 8) & 0xFFUL);
275
0
}
276
277
278
/**
279
 * @brief get SpW link disconnect errors
280
 * @see RDCU-FRS-FN-0562
281
 */
282
283
uint8_t rdcu_get_spw_lnk_disconnect_errs(void)
284
0
{
285
0
  return (uint8_t) (rdcu->spw_link_status & 0xFFUL);
286
0
}
287
288
289
/**
290
 * @brief get RMAP last error user code
291
 * @see RDCU-FRS-FN-0572
292
 */
293
294
uint8_t rdcu_get_rmap_last_error_user_code(void)
295
0
{
296
0
  return (uint8_t) ((rdcu->rmap_last_err >> 8) & 0xFFUL);
297
0
}
298
299
300
/**
301
 * @brief get RMAP last error standard code
302
 * @see RDCU-FRS-FN-0572
303
 */
304
305
uint8_t rdcu_get_rmap_last_error_standard_code(void)
306
0
{
307
0
  return (uint8_t) (rdcu->rmap_last_err & 0xFFUL);
308
0
}
309
310
311
/**
312
 * @brief get RMAP incomplete header error counter
313
 * @see RDCU-FRS-FN-0582
314
 */
315
316
uint8_t rdcu_get_rmap_incomplete_hdrs(void)
317
0
{
318
0
  return (uint8_t) ((rdcu->rmap_no_reply_err_cntrs >> 24) & 0xFFUL);
319
0
}
320
321
322
/**
323
 * @brief get RMAP received reply packet counter
324
 * @see RDCU-FRS-FN-0582
325
 */
326
327
uint8_t rdcu_get_rmap_recv_reply_pckts(void)
328
0
{
329
0
  return (uint8_t) ((rdcu->rmap_no_reply_err_cntrs >> 8) & 0xFFUL);
330
0
}
331
332
333
/**
334
 * @brief get received non-RMAP packet counter
335
 * @see RDCU-FRS-FN-0582
336
 */
337
338
uint8_t rdcu_get_recv_non_rmap_pckts(void)
339
0
{
340
0
  return (uint8_t) (rdcu->rmap_no_reply_err_cntrs & 0xFFUL);
341
0
}
342
343
344
/**
345
 * @brief get RMAP packet with length or content error counter
346
 * @see RDCU-FRS-FN-0592
347
 */
348
349
uint8_t rdcu_get_rmap_pckt_errs(void)
350
0
{
351
0
  return (uint8_t) ((rdcu->rmap_pckt_err_cntrs >> 24) & 0xFFUL);
352
0
}
353
354
355
/**
356
 * @brief get RMAP operation error counter
357
 * @see RDCU-FRS-FN-0592
358
 */
359
360
uint8_t rdcu_get_rmap_oper_errs(void)
361
0
{
362
0
  return (uint8_t) ((rdcu->rmap_pckt_err_cntrs >> 16) & 0xFFUL);
363
0
}
364
365
366
/**
367
 * @brief get RMAP command authorization error counter
368
 * @see RDCU-FRS-FN-0592
369
 */
370
371
uint8_t rdcu_get_rmap_cmd_auth_errs(void)
372
0
{
373
0
  return (uint8_t) ((rdcu->rmap_pckt_err_cntrs >> 8) & 0xFFUL);
374
0
}
375
376
377
/**
378
 * @brief get RMAP header error counter
379
 * @see RDCU-FRS-FN-0592
380
 */
381
382
uint8_t rdcu_get_rmap_hdr_errs(void)
383
0
{
384
0
  return (uint8_t) (rdcu->rmap_pckt_err_cntrs & 0xFFUL);
385
0
}
386
387
388
/**
389
 * @brief get an ADC value
390
 * @param id the ADC value id to get (1-8)
391
 * @see RDCU-FRS-FN-0602
392
 *
393
 * @return adc value, if 0xFFFF, id may be invalid
394
 */
395
396
uint16_t rdcu_get_adc_value(int id)
397
0
{
398
0
  switch (id) {
399
0
  case 1:
400
0
    return (uint16_t)  (rdcu->adc_values_1        & 0xFFFFUL);
401
0
  case 2:
402
0
    return (uint16_t) ((rdcu->adc_values_1 >> 16) & 0xFFFFUL);
403
0
  case 3:
404
0
    return (uint16_t)  (rdcu->adc_values_2        & 0xFFFFUL);
405
0
  case 4:
406
0
    return (uint16_t) ((rdcu->adc_values_2 >> 16) & 0xFFFFUL);
407
0
  case 5:
408
0
    return (uint16_t)  (rdcu->adc_values_3        & 0xFFFFUL);
409
0
  case 6:
410
0
    return (uint16_t) ((rdcu->adc_values_3 >> 16) & 0xFFFFUL);
411
0
  case 7:
412
0
    return (uint16_t)  (rdcu->adc_values_4        & 0xFFFFUL);
413
0
  case 8:
414
0
    return (uint16_t) ((rdcu->adc_values_4 >> 16) & 0xFFFFUL);
415
416
0
  default:
417
0
    break;
418
0
  }
419
420
0
  return 0xFFFF;
421
0
}
422
423
424
/**
425
 * @brief get valid ADC values
426
 * @see RDCU-FRS-FN-0612
427
 *
428
 * @returns 0: no valid ADC values in the ADC value registers
429
 *      1: the ADC value registers contain valid ADC results
430
 */
431
432
uint32_t rdcu_get_valid_adc_values(void)
433
0
{
434
0
  return ((rdcu->adc_status >> 4) & 0x1UL);
435
0
}
436
437
438
/**
439
 * @brief get ADC logic reset
440
 * @see RDCU-FRS-FN-0612
441
 *
442
 * @returns 0: normal ADC operation
443
 *      1: ADC logic is in reset state
444
 */
445
446
uint32_t rdcu_get_adc_logic_reset(void)
447
0
{
448
0
  return ((rdcu->adc_status >> 1) & 0x1UL);
449
0
}
450
451
452
/**
453
 * @brief get ADC logic enabled
454
 * @see RDCU-FRS-FN-0612
455
 *
456
 * @returns 0: ADC logic disabled
457
 *      1: ADC logic enabled (normal operation)
458
 */
459
460
uint32_t rdcu_get_adc_logic_enabled(void)
461
0
{
462
0
  return (rdcu->adc_status & 0x1UL);
463
0
}
464
465
466
/**
467
 * @brief get RDCU Interrupt status
468
 * @see RDCU-FRS-FN-0632
469
 *
470
 * @returns 0: Interrupt is disabled
471
 *      1: Interrupt is enabled
472
 */
473
474
uint32_t rdcu_get_rdcu_interrupt_enabled(void)
475
0
{
476
0
  return ((rdcu->compr_status >> 8) & 0x1UL);
477
0
}
478
479
480
/**
481
 * @brief get compressor status valid
482
 * @see RDCU-FRS-FN-0632
483
 *
484
 * @returns 0: Data is invalid
485
 *      1: Data is valid
486
 */
487
488
uint32_t rdcu_get_compr_status_valid(void)
489
0
{
490
0
  return ((rdcu->compr_status >> 5) & 0x1UL);
491
0
}
492
493
494
/**
495
 * @brief get data compressor ready
496
 * @see RDCU-FRS-FN-0632
497
 *
498
 * @returns 0: Compressor is busy
499
 *      1: Compressor is ready
500
 */
501
502
uint32_t rdcu_get_data_compr_ready(void)
503
0
{
504
0
  return ((rdcu->compr_status >> 4) & 0x1UL);
505
0
}
506
507
508
/**
509
 * @brief get data compressor interrupted
510
 * @see RDCU-FRS-FN-0632
511
 *
512
 * @returns 0: No compressor interruption
513
 *      1: Compressor was interrupted
514
 */
515
516
uint32_t rdcu_get_data_compr_interrupted(void)
517
0
{
518
0
  return ((rdcu->compr_status >> 1) & 0x1UL);
519
0
}
520
521
522
/**
523
 * @brief get data compressor activce
524
 * @see RDCU-FRS-FN-0632
525
 *
526
 * @returns 0: Compressor is on hold
527
 *      1: Compressor is active
528
 */
529
530
uint32_t rdcu_get_data_compr_active(void)
531
0
{
532
0
  return (rdcu->compr_status & 0x1UL);
533
0
}
534
535
536
/**
537
 * @brief set RDCU Board Reset Keyword
538
 * @see RDCU-FRS-FN-0662
539
 *
540
 * @note the valid key is 0x9A
541
 */
542
543
void rdcu_set_rdcu_board_reset_keyword(uint8_t key)
544
0
{
545
  /* clear and set */
546
0
  rdcu->rdcu_reset &= ~(0xFUL << 24);
547
0
  rdcu->rdcu_reset |= ((uint32_t) key << 24);
548
0
}
549
550
551
/**
552
 * @brief set RDCU Internal Bus Reset bit
553
 * @see RDCU-FRS-FN-0662
554
 *
555
 * @note The bit will auto-clear in the FPGA, to clear the local mirror,
556
 *   make sure to rdcu_clear_rdcu_bus_reset() so the FPGA internal bus
557
 *   is not reset every time rdcu_sync_rdcu_reset() is called, as
558
 *   write-only registers are note synced back from the RDCU
559
 */
560
561
void rdcu_set_rdcu_bus_reset(void)
562
0
{
563
0
  rdcu->rdcu_reset |= (0x1UL << 12);
564
0
}
565
566
567
/**
568
 * @brief clear RDCU Internal Bus Reset bit
569
 * @see RDCU-FRS-FN-0662
570
 */
571
572
void rdcu_clear_rdcu_bus_reset(void)
573
0
{
574
0
  rdcu->rdcu_reset &= ~(0x1UL << 12);
575
0
}
576
577
578
/**
579
 * @brief set RDCU RMAP error counter Reset bit
580
 * @see RDCU-FRS-FN-0662
581
 *
582
 * @note The bit will auto-clear in the FPGA, to clear the local mirror,
583
 *   make sure to rdcu_clear_rdcu_rmap_error_cntr_reset() so the FPGA
584
 *   does not reset the RMAP error counter every time rdcu_sync_rdcu_reset()
585
 *   is called, as write-only registers are not synced back from the RDCU.
586
 */
587
588
void rdcu_set_rdcu_rmap_error_cntr_reset(void)
589
0
{
590
0
  rdcu->rdcu_reset |= (0x1UL << 9);
591
0
}
592
593
594
/**
595
 * @brief clear RDCU RMAP error counter Reset bit
596
 * @see RDCU-FRS-FN-0662
597
 */
598
599
void rdcu_clear_rdcu_rmap_error_cntr_reset(void)
600
0
{
601
0
  rdcu->rdcu_reset &= ~(0x1UL << 9);
602
0
}
603
604
605
/**
606
 * @brief set RDCU SpaceWire error counter Reset bit
607
 * @see RDCU-FRS-FN-0662
608
 *
609
 * @note The bit will auto-clear in the FPGA, to clear the local mirror,
610
 *   make sure to rdcu_clear_rdcu_spw_error_cntr_reset() so the FPGA
611
 *   does not reset the SpW error counter every time rdcu_sync_rdcu_reset()
612
 *   is called, as write-only registers are not synced back from the RDCU.
613
 */
614
615
void rdcu_set_rdcu_spw_error_cntr_reset(void)
616
0
{
617
0
  rdcu->rdcu_reset |= (0x1UL << 8);
618
0
}
619
620
621
/**
622
 * @brief clear RDCU SpaceWire error counter Reset bit
623
 * @see RDCU-FRS-FN-0662
624
 */
625
626
void rdcu_clear_rdcu_spw_error_cntr_reset(void)
627
0
{
628
0
  rdcu->rdcu_reset &= ~(0x1UL << 8);
629
0
}
630
631
632
/**
633
 * @brief set RDCU Board Reset bit
634
 * @see RDCU-FRS-FN-0662
635
 *
636
 * @note The bit will auto-clear in the FPGA, to clear the local mirror,
637
 *   make sure to rdcu_clear_rdcu_board_reset() so the FPGA
638
 *   does not reset the SpW error counter every time rdcu_sync_rdcu_reset()
639
 *   is called, as write-only registers are not synced back from the RDCU.
640
 */
641
642
void rdcu_set_rdcu_board_reset(void)
643
0
{
644
0
  rdcu->rdcu_reset |= (0x1UL << 1);
645
0
}
646
647
648
/**
649
 * @brief clear RDCU SpaceWire error counter Reset bit
650
 * @see RDCU-FRS-FN-0662
651
 */
652
653
void rdcu_clear_rdcu_board_reset(void)
654
0
{
655
0
  rdcu->rdcu_reset &= ~(0x1UL << 1);
656
0
}
657
658
659
/**
660
 * @brief set SpW Link Control Run-State Clock Divisor
661
 * @see RDCU-FRS-FN-0672
662
 *
663
 * @note value is scaling factor minus 1
664
 */
665
666
int rdcu_set_spw_link_run_clkdiv(uint8_t divisor)
667
0
{
668
0
  if (divisor > 49)
669
0
    return -1;
670
671
  /* clear and set */
672
0
  rdcu->spw_link_ctrl &= ~(0x3FUL << 8);
673
0
  rdcu->spw_link_ctrl |= ((uint32_t) divisor << 8);
674
675
0
  return 0;
676
0
}
677
678
679
/**
680
 * @brief set LVDS link enabled
681
 *
682
 * @param link the link number (0-7)
683
 *
684
 * @see RDCU-FRS-FN-0682
685
 *
686
 * @returns 0 on success, otherwise error
687
 */
688
689
int rdcu_set_lvds_link_enabled(uint32_t link)
690
0
{
691
0
  if (link > 7)
692
0
    return -1;
693
694
0
  rdcu->lvds_ctrl |= (0x1UL << link);
695
696
0
  return 0;
697
0
}
698
699
700
/**
701
 * @brief set LVDS link disabled
702
 *
703
 * @param link the link number (0-7)
704
 *
705
 * @see RDCU-FRS-FN-0682
706
 *
707
 * @returns 0 on success, otherwise error
708
 */
709
710
int rdcu_set_lvds_link_disabled(uint32_t link)
711
0
{
712
0
  if (link > 7)
713
0
    return -1;
714
715
0
  rdcu->lvds_ctrl &= ~((0x1UL << link));
716
717
0
  return 0;
718
0
}
719
720
721
/**
722
 * @brief set RMAP Target logical address
723
 * @see RDCU-FRS-FN-0692
724
 */
725
726
void rdcu_set_rmap_target_logical_address(uint8_t addr)
727
0
{
728
0
  rdcu->core_ctrl &= ~(0xFFUL << 24);
729
0
  rdcu->core_ctrl |= ((uint32_t) addr) << 24;
730
0
}
731
732
733
/**
734
 * @brief set RMAP Target command key
735
 * @see RDCU-FRS-FN-0692
736
 */
737
738
void rdcu_set_rmap_target_cmd_key(uint8_t key)
739
0
{
740
0
  rdcu->core_ctrl &= ~(0xFFUL << 16);
741
0
  rdcu->core_ctrl |= ((uint32_t) key) << 16;
742
0
}
743
744
745
/**
746
 * @brief set the ADC logic reset bit
747
 * @see RDCU-FRS-FN-0712
748
 *
749
 * @note use rdcu_clear_adc_logic_reset(), rdcu_sync_adc_ctrl() sequence
750
 *   to clear and start normal operation
751
 */
752
753
void rdcu_set_adc_logic_reset(void)
754
0
{
755
0
  rdcu->adc_ctrl |= (0x1UL << 1);
756
0
}
757
758
759
/**
760
 * @brief clear the ADC logic reset bit
761
 * @see RDCU-FRS-FN-0712
762
 */
763
764
void rdcu_clear_adc_logic_reset(void)
765
0
{
766
0
  rdcu->adc_ctrl &= ~(0x1UL << 1);
767
0
}
768
769
770
/**
771
 * @brief set the ADC logic enabled
772
 * @see RDCU-FRS-FN-0712
773
 */
774
775
void rdcu_set_adc_logic_enabled(void)
776
0
{
777
0
  rdcu->adc_ctrl |= 0x1UL;
778
0
}
779
780
781
/**
782
 * @brief set the ADC logic disabled
783
 * @see RDCU-FRS-FN-0712
784
 */
785
786
void rdcu_set_adc_logic_disabled(void)
787
0
{
788
0
  rdcu->adc_ctrl &= ~0x1UL;
789
0
}
790
791
792
/**
793
 * @brief enable RDCU interrupt signal to the ICU
794
 * @see RDCU-FRS-FN-0732
795
 */
796
797
void rdcu_set_rdcu_interrupt(void)
798
0
{
799
0
  rdcu->compr_ctrl |= (0x1UL << 8);
800
0
}
801
802
803
/**
804
 * @brief disable RDCU interrupt signal to the ICU
805
 * @see RDCU-FRS-FN-0732
806
 */
807
808
void rdcu_clear_rdcu_interrupt(void)
809
0
{
810
0
  rdcu->compr_ctrl &= ~(0x1UL << 8);
811
0
}
812
813
814
/**
815
 * @brief set data compressor interrupt
816
 * @see RDCU-FRS-FN-0732
817
 *
818
 * @note The bit will auto-clear in the FPGA once compression is complete.
819
 *   To clear the local mirror, make sure to
820
 *   rdcu_clear_data_compr_interrupt() so the FPGA does not interrupt
821
 *   data compression unexpectedly when rdcu_sync_compr_ctrl()
822
 *   is called, as write-only registers are not synced back from the RDCU.
823
 *
824
 */
825
826
void rdcu_set_data_compr_interrupt(void)
827
0
{
828
0
  rdcu->compr_ctrl |= (0x1UL << 1);
829
0
}
830
831
832
/**
833
 * @brief clear data compressor interrupt
834
 * @see RDCU-FRS-FN-0732
835
 */
836
837
void rdcu_clear_data_compr_interrupt(void)
838
0
{
839
0
  rdcu->compr_ctrl &= ~(0x1UL << 1);
840
0
}
841
842
843
/**
844
 * @brief set data compressor start bit
845
 * @see RDCU-FRS-FN-0732
846
 *
847
 * @note The bit will auto-clear in the FPGA once compression is complete.
848
 *   To clear the local mirror, make sure to
849
 *   rdcu_clear_data_compr_start() so the FPGA does not start
850
 *   data compression unexpectedly when rdcu_sync_compr_ctrl()
851
 *   is called, as write-only registers are not synced back from the RDCU.
852
 */
853
854
void rdcu_set_data_compr_start(void)
855
0
{
856
0
  rdcu->compr_ctrl |= 0x1UL;
857
0
}
858
859
860
/**
861
 * @brief clear data compressor start bit
862
 * @see RDCU-FRS-FN-0732
863
 */
864
865
void rdcu_clear_data_compr_start(void)
866
0
{
867
0
  rdcu->compr_ctrl &= ~0x1UL;
868
0
}
869
870
871
/**
872
 * @brief set number of noise bits to be rounded
873
 * @see RDCU-FRS-FN-0772
874
 *
875
 * @returns 0 on success, otherwise error
876
 */
877
878
int rdcu_set_noise_bits_rounded(uint32_t rpar)
879
0
{
880
0
#ifndef SKIP_CMP_PAR_CHECK
881
0
  if (rpar > 3)
882
0
    return -1;
883
0
#endif /*SKIP_CMP_PAR_CHECK*/
884
885
  /* clear and set */
886
0
  rdcu->compressor_param1 &= ~(0x3UL << 16);
887
0
  rdcu->compressor_param1 |=  (rpar << 16);
888
889
0
  return 0;
890
0
}
891
892
893
/**
894
 * @brief set weighting parameter
895
 * @see RDCU-FRS-FN-0772
896
 *
897
 * @returns 0 on success, otherwise error
898
 */
899
900
int rdcu_set_weighting_param(uint32_t mval)
901
0
{
902
0
#ifndef SKIP_CMP_PAR_CHECK
903
0
  if (mval > 16)
904
0
    return -1;
905
0
#endif /*SKIP_CMP_PAR_CHECK*/
906
907
  /* clear and set */
908
0
  rdcu->compressor_param1 &= ~(0x1FUL << 8);
909
0
  rdcu->compressor_param1 |=  (mval << 8);
910
911
0
  return 0;
912
0
}
913
914
915
/**
916
 * @brief set compression mode
917
 * @see RDCU-FRS-FN-0772
918
 *
919
 * @returns 0 on success, otherwise error
920
 */
921
922
int rdcu_set_compression_mode(uint32_t cmode)
923
0
{
924
0
#ifndef SKIP_CMP_PAR_CHECK
925
0
  if (cmode > 4)
926
0
    return -1;
927
0
#endif /*SKIP_CMP_PAR_CHECK*/
928
929
  /* clear and set */
930
0
  rdcu->compressor_param1 &= ~0xFFUL;
931
0
  rdcu->compressor_param1 |= cmode;
932
933
0
  return 0;
934
0
}
935
936
937
/**
938
 * @brief set spillover threshold for encoding outliers
939
 * @see RDCU-FRS-FN-0782
940
 *
941
 * @returns 0 on success, otherwise error
942
 */
943
944
int rdcu_set_spillover_threshold(uint32_t spill)
945
0
{
946
0
#ifndef SKIP_CMP_PAR_CHECK
947
0
  if (spill < 2)
948
0
    return -1;
949
950
0
  if (spill > 0x3FFUL)
951
0
    return -1;
952
0
#endif /*SKIP_CMP_PAR_CHECK*/
953
954
  /* clear and set */
955
0
  rdcu->compressor_param2 &= ~(0x3FFUL << 8);
956
0
  rdcu->compressor_param2 |=  (spill   << 8);
957
958
0
  return 0;
959
0
}
960
961
962
/**
963
 * @brief set Golomb parameter for dictionary selection
964
 * @see RDCU-FRS-FN-0782
965
 *
966
 * @returns 0 on success, otherwise error
967
 */
968
969
int rdcu_set_golomb_param(uint32_t gpar)
970
0
{
971
0
#ifndef SKIP_CMP_PAR_CHECK
972
0
  if (!gpar)
973
0
    return -1;
974
975
0
  if (gpar > 63)
976
0
    return -1;
977
0
#endif /*SKIP_CMP_PAR_CHECK*/
978
979
  /* clear and set */
980
0
  rdcu->compressor_param2 &= ~0x3FUL;
981
0
  rdcu->compressor_param2 |= gpar;
982
983
0
  return 0;
984
0
}
985
986
987
/**
988
 * @brief set adaptive 1 spillover threshold for encoding outliers
989
 * @see RDCU-FRS-FN-0792
990
 *
991
 * @returns 0 on success, otherwise error
992
 */
993
994
int rdcu_set_adaptive_1_spillover_threshold(uint32_t spill)
995
0
{
996
0
#ifndef SKIP_CMP_PAR_CHECK
997
0
  if (spill < 2)
998
0
    return -1;
999
1000
0
  if (spill > 0x3FFUL)
1001
0
    return -1;
1002
0
#endif /*SKIP_CMP_PAR_CHECK*/
1003
1004
  /* clear and set */
1005
0
  rdcu->adaptive_param1 &= ~(0x3FFUL << 8);
1006
0
  rdcu->adaptive_param1 |=  (spill   << 8);
1007
1008
0
  return 0;
1009
0
}
1010
1011
1012
/**
1013
 * @brief set adaptive 1 Golomb parameter for dictionary selection
1014
 * @see RDCU-FRS-FN-0792
1015
 *
1016
 * @returns 0 on success, otherwise error
1017
 */
1018
1019
int rdcu_set_adaptive_1_golomb_param(uint32_t gpar)
1020
0
{
1021
0
#ifndef SKIP_CMP_PAR_CHECK
1022
0
  if (!gpar)
1023
0
    return -1;
1024
1025
0
  if (gpar > 63)
1026
0
    return -1;
1027
0
#endif /*SKIP_CMP_PAR_CHECK*/
1028
1029
  /* clear and set */
1030
0
  rdcu->adaptive_param1 &= ~0x3FUL;
1031
0
  rdcu->adaptive_param1 |= gpar;
1032
1033
0
  return 0;
1034
0
}
1035
1036
1037
1038
/**
1039
 * @brief set adaptive 2 spillover threshold for encoding outliers
1040
 * @see RDCU-FRS-FN-0802
1041
 *
1042
 * @returns 0 on success, otherwise error
1043
 */
1044
1045
int rdcu_set_adaptive_2_spillover_threshold(uint32_t spill)
1046
0
{
1047
0
#ifndef SKIP_CMP_PAR_CHECK
1048
0
  if (spill < 2)
1049
0
    return -1;
1050
1051
0
  if (spill > 0x3FFUL)
1052
0
    return -1;
1053
0
#endif /*SKIP_CMP_PAR_CHECK*/
1054
1055
  /* clear and set */
1056
0
  rdcu->adaptive_param2 &= ~(0x3FFUL << 8);
1057
0
  rdcu->adaptive_param2 |=  (spill   << 8);
1058
1059
0
  return 0;
1060
0
}
1061
1062
1063
/**
1064
 * @brief set adaptive 2 Golomb parameter for dictionary selection
1065
 * @see RDCU-FRS-FN-0802
1066
 *
1067
 * @returns 0 on success, otherwise error
1068
 */
1069
1070
int rdcu_set_adaptive_2_golomb_param(uint32_t gpar)
1071
0
{
1072
0
#ifndef SKIP_CMP_PAR_CHECK
1073
0
  if (!gpar)
1074
0
    return -1;
1075
1076
0
  if (gpar > 63)
1077
0
    return -1;
1078
0
#endif /*SKIP_CMP_PAR_CHECK*/
1079
1080
  /* clear and set */
1081
0
  rdcu->adaptive_param2 &= ~0x3FUL;
1082
0
  rdcu->adaptive_param2 |= gpar;
1083
1084
0
  return 0;
1085
0
}
1086
1087
1088
/**
1089
 * @brief set data start address
1090
 * @see RDCU-FRS-FN-0812
1091
 *
1092
 * @returns 0 on success, otherwise error
1093
 */
1094
1095
int rdcu_set_data_start_addr(uint32_t addr)
1096
0
{
1097
0
#ifndef SKIP_CMP_PAR_CHECK
1098
0
  if (addr > 0x00FFFFFFUL)
1099
0
    return -1;
1100
1101
0
  if (addr & 0x3)
1102
0
    return -1;
1103
0
#endif /*SKIP_CMP_PAR_CHECK*/
1104
1105
  /* clear and set */
1106
0
  rdcu->data_start_addr &= ~0x00FFFFFFUL;
1107
0
  rdcu->data_start_addr |= addr;
1108
1109
0
  return 0;
1110
0
}
1111
1112
1113
/**
1114
 * @brief set model start address
1115
 * @see RDCU-FRS-FN-0822
1116
 *
1117
 * @returns 0 on success, otherwise error
1118
 */
1119
1120
int rdcu_set_model_start_addr(uint32_t addr)
1121
0
{
1122
0
#ifndef SKIP_CMP_PAR_CHECK
1123
0
  if (addr > 0x00FFFFFFUL)
1124
0
    return -1;
1125
1126
0
  if (addr & 0x3)
1127
0
    return -1;
1128
0
#endif /*SKIP_CMP_PAR_CHECK*/
1129
1130
  /* clear and set */
1131
0
  rdcu->model_start_addr &= ~0x00FFFFFFUL;
1132
0
  rdcu->model_start_addr |= addr;
1133
1134
0
  return 0;
1135
0
}
1136
1137
1138
/**
1139
 * @brief set number of data samples (16 bit values) to compress
1140
 * @see RDCU-FRS-FN-0832
1141
 *
1142
 * @returns 0 on success, otherwise error
1143
 */
1144
1145
int rdcu_set_num_samples(uint32_t samples)
1146
0
{
1147
0
#ifndef SKIP_CMP_PAR_CHECK
1148
0
  if (samples > 0x00FFFFFFUL)
1149
0
    return -1;
1150
0
#endif /*SKIP_CMP_PAR_CHECK*/
1151
1152
  /* clear and set */
1153
0
  rdcu->num_samples &= ~0x00FFFFFFUL;
1154
0
  rdcu->num_samples |= samples;
1155
1156
0
  return 0;
1157
0
}
1158
1159
1160
/**
1161
 * @brief set updated_model/new model start address
1162
 * @see RDCU-FRS-FN-0842
1163
 *
1164
 * @returns 0 on success, otherwise error
1165
 */
1166
1167
int rdcu_set_new_model_start_addr(uint32_t addr)
1168
0
{
1169
0
#ifndef SKIP_CMP_PAR_CHECK
1170
0
  if (addr > 0x00FFFFFFUL)
1171
0
    return -1;
1172
1173
0
  if (addr & 0x3)
1174
0
    return -1;
1175
0
#endif /*SKIP_CMP_PAR_CHECK*/
1176
1177
  /* clear and set */
1178
0
  rdcu->new_model_start_addr &= ~0x00FFFFFFUL;
1179
0
  rdcu->new_model_start_addr |= addr;
1180
1181
0
  return 0;
1182
0
}
1183
1184
1185
/**
1186
 * @brief set compressed data buffer start address
1187
 * @see RDCU-FRS-FN-0850
1188
 *
1189
 * @returns 0 on success, otherwise error
1190
 */
1191
1192
int rdcu_set_compr_data_buf_start_addr(uint32_t addr)
1193
0
{
1194
0
#ifndef SKIP_CMP_PAR_CHECK
1195
0
  if (addr > 0x00FFFFFFUL)
1196
0
    return -1;
1197
1198
0
  if (addr & 0x3)
1199
0
    return -1;
1200
0
#endif /*SKIP_CMP_PAR_CHECK*/
1201
  /* clear and set */
1202
0
  rdcu->compr_data_buf_start_addr &= ~0x00FFFFFFUL;
1203
0
  rdcu->compr_data_buf_start_addr |= addr;
1204
1205
0
  return 0;
1206
0
}
1207
1208
1209
/**
1210
 * @brief set compressed data buffer length (in 16 bit values)
1211
 * @see RDCU-FRS-FN-0862
1212
 *
1213
 * @returns 0 on success, otherwise error
1214
 */
1215
1216
int rdcu_set_compr_data_buf_len(uint32_t samples)
1217
0
{
1218
0
  if (samples > 0x00FFFFFFUL)
1219
0
    return -1;
1220
1221
  /* clear and set */
1222
0
  rdcu->compr_data_buf_len &= ~0x00FFFFFFUL;
1223
0
  rdcu->compr_data_buf_len |= samples;
1224
1225
0
  return 0;
1226
0
}
1227
1228
1229
/**
1230
 * @brief get compression mode
1231
 * @see RDCU-FRS-FN-0892
1232
 *
1233
 * @returns the CMODE
1234
 */
1235
1236
uint32_t rdcu_get_compression_mode(void)
1237
0
{
1238
0
  return rdcu->used_param1 & 0xFFUL;
1239
0
}
1240
1241
1242
/**
1243
 * @brief get number of noise bits to be rounded
1244
 * @see RDCU-FRS-FN-0892
1245
 *
1246
 * @returns the RPAR
1247
 */
1248
1249
uint32_t rdcu_get_noise_bits_rounded(void)
1250
0
{
1251
0
  return (rdcu->used_param1 >> 16) & 0x3UL;
1252
0
}
1253
1254
1255
/**
1256
 * @brief get weighting parameter
1257
 * @see RDCU-FRS-FN-0892
1258
 *
1259
 * @returns the RPAR
1260
 */
1261
1262
uint32_t rdcu_get_weighting_param(void)
1263
0
{
1264
0
  return (rdcu->used_param1 >> 8) & 0x1FUL;
1265
0
}
1266
1267
1268
/**
1269
 * @brief get spillover threshold for encoding outliers
1270
 * @see RDCU-FRS-FN-0902
1271
 *
1272
 * @returns the SPILL
1273
 */
1274
1275
uint32_t rdcu_get_spillover_threshold(void)
1276
0
{
1277
0
  return (rdcu->used_param2 >> 8) & 0x3FFUL;
1278
0
}
1279
1280
1281
/**
1282
 * @brief get spillover threshold for encoding outliers
1283
 * @see RDCU-FRS-FN-0902
1284
 *
1285
 * @returns the GPAR
1286
 */
1287
1288
uint32_t rdcu_get_golomb_param(void)
1289
0
{
1290
0
  return rdcu->used_param2 & 0x3FUL;
1291
0
}
1292
1293
1294
/**
1295
 * @brief get compressed data start address
1296
 * @see RDCU-FRS-FN-0912
1297
 *
1298
 * @returns the output SRAM address
1299
 */
1300
1301
uint32_t rdcu_get_compr_data_start_addr(void)
1302
0
{
1303
0
  return rdcu->compr_data_start_addr & 0x00FFFFFFUL;
1304
0
}
1305
1306
1307
/**
1308
 * @brief get the need bytes for the given bits
1309
 *
1310
 * @param cmp_size_bit compressed data size, measured in bits
1311
 *
1312
 * @returns the size in bytes to store the compressed data
1313
 */
1314
1315
static uint32_t rdcu_bit_to_byte(unsigned int cmp_size_bit)
1316
0
{
1317
0
  return ((cmp_size_bit + 7) / 8);
1318
0
}
1319
1320
1321
/**
1322
 * @brief get compressed data size in bits
1323
 * @see RDCU-FRS-FN-0922
1324
 *
1325
 * @returns the compressed data size in bits
1326
 */
1327
1328
uint32_t rdcu_get_compr_data_size_bit(void)
1329
0
{
1330
0
  return rdcu->compr_data_size;
1331
0
}
1332
1333
1334
/**
1335
 * @brief get compressed data size in bytes
1336
 * @see RDCU-FRS-FN-0922
1337
 *
1338
 * @returns the compressed data size in bytes
1339
 */
1340
1341
uint32_t rdcu_get_compr_data_size_byte(void)
1342
0
{
1343
0
  return rdcu_bit_to_byte(rdcu_get_compr_data_size_bit());
1344
0
}
1345
1346
1347
/**
1348
 * @brief get compressed data adaptive 1 size in bits
1349
 * @see RDCU-FRS-FN-0932
1350
 *
1351
 * @returns the adaptive 1 compressed data size in bits
1352
 */
1353
1354
uint32_t rdcu_get_compr_data_adaptive_1_size_bit(void)
1355
0
{
1356
0
  return rdcu->compr_data_adaptive_1_size;
1357
0
}
1358
1359
1360
/**
1361
 * @brief get compressed data adaptive 1 size in bytes
1362
 * @see RDCU-FRS-FN-0932
1363
 *
1364
 * @returns the adaptive 1 compressed data size in bytes
1365
 */
1366
1367
uint32_t rdcu_get_compr_data_adaptive_1_size_byte(void)
1368
0
{
1369
0
  return rdcu_bit_to_byte(rdcu_get_compr_data_adaptive_1_size_bit());
1370
0
}
1371
1372
1373
/**
1374
 * @brief get compressed data adaptive 2 size in bits
1375
 * @see RDCU-FRS-FN-0942
1376
 *
1377
 * @returns the adaptive 2 compressed data size in bits
1378
 */
1379
1380
uint32_t rdcu_get_compr_data_adaptive_2_size_bit(void)
1381
0
{
1382
0
  return rdcu->compr_data_adaptive_2_size;
1383
0
}
1384
1385
1386
/**
1387
 * @brief get compressed data adaptive 2 size in bytes
1388
 * @see RDCU-FRS-FN-0942
1389
 *
1390
 * @returns the adaptive 2 compressed data size in bytes
1391
 */
1392
1393
uint32_t rdcu_get_compr_data_adaptive_2_size_byte(void)
1394
0
{
1395
0
  return rdcu_bit_to_byte(rdcu_get_compr_data_adaptive_2_size_bit());
1396
0
}
1397
1398
1399
/**
1400
 * @brief get compression error code
1401
 * @see RDCU-FRS-FN-0954
1402
 *
1403
 * @returns the compression error code
1404
 */
1405
1406
uint16_t rdcu_get_compr_error(void)
1407
0
{
1408
0
  return (uint16_t) (rdcu->compr_error & 0x3FFUL);
1409
0
}
1410
1411
1412
/**
1413
 * @brief get model info start address
1414
 * @see RDCU-FRS-FN-0960
1415
 *
1416
 */
1417
1418
uint32_t rdcu_get_new_model_addr_used(void)
1419
0
{
1420
0
  return rdcu->new_model_addr_used & 0x00FFFFFFUL;
1421
0
}
1422
1423
1424
/**
1425
 * @brief get model info length
1426
 * @see RDCU-FRS-FN-0972
1427
 *
1428
 * @returns the number of 16-bit samples in the model
1429
 */
1430
1431
uint32_t rdcu_get_samples_used(void)
1432
0
{
1433
0
  return rdcu->samples_used & 0x00FFFFFFUL;
1434
0
}
1435
1436
1437
/**
1438
 * @brief set EDAC sub chip die address
1439
 * @see RDCU-FRS-FN-1012
1440
 *
1441
 * @returns 0 on success, otherwise error
1442
 */
1443
1444
int rdcu_edac_set_sub_chip_die_addr(uint32_t ca)
1445
0
{
1446
0
  if (ca > 0xFUL)
1447
0
    return -1;
1448
1449
0
  rdcu->sram_edac_ctrl &= ~(0xFUL << 12);
1450
0
  rdcu->sram_edac_ctrl |=  (ca    << 12);
1451
1452
0
  return 0;
1453
0
}
1454
1455
1456
/**
1457
 * @brief set EDAC control register read operation
1458
 * @see RDCU-FRS-FN-1012
1459
 */
1460
1461
void rdcu_edac_set_ctrl_reg_read_op(void)
1462
0
{
1463
0
  rdcu->sram_edac_ctrl |= (0x1UL << 9);
1464
0
}
1465
1466
1467
/**
1468
 * @brief set EDAC control register write operation
1469
 * @see RDCU-FRS-FN-1012
1470
 */
1471
1472
void rdcu_edac_set_ctrl_reg_write_op(void)
1473
0
{
1474
0
  rdcu->sram_edac_ctrl &= ~(0x1UL << 9);
1475
0
}
1476
1477
1478
/**
1479
 * @brief set EDAC to bypass
1480
 * @see RDCU-FRS-FN-1012
1481
 */
1482
1483
void rdcu_edac_set_bypass(void)
1484
0
{
1485
0
  rdcu->sram_edac_ctrl |= (0x1UL << 8);
1486
0
}
1487
1488
1489
/**
1490
 * @brief set EDAC to normal operation
1491
 * @see RDCU-FRS-FN-1012
1492
 */
1493
1494
void rdcu_edac_clear_bypass(void)
1495
0
{
1496
0
  rdcu->sram_edac_ctrl &= ~(0x1UL << 8);
1497
0
}
1498
1499
1500
/**
1501
 * @brief set EDAC SRAM scrubbing information
1502
 * @see RDCU-FRS-FN-1012
1503
 */
1504
1505
void rdcu_edac_set_scrub_info(uint8_t nfo)
1506
0
{
1507
0
  rdcu->sram_edac_ctrl &= ~0xFFUL;
1508
0
  rdcu->sram_edac_ctrl |= (uint32_t) nfo & 0xFFUL;
1509
0
}
1510
1511
1512
/**
1513
 * @brief get EDAC sub chip die address
1514
 * @see RDCU-FRS-FN-1032
1515
 */
1516
1517
uint32_t rdcu_edac_get_sub_chip_die_addr(void)
1518
0
{
1519
0
  return (rdcu->sram_edac_status >> 12) & 0xFUL;
1520
0
}
1521
1522
1523
/**
1524
 * @brief get EDAC bypass status
1525
 * @see RDCU-FRS-FN-1032
1526
 *
1527
 * @returns 0: normal EDAC operation
1528
 *      1: EDAC function will be bypassed
1529
 */
1530
1531
uint32_t rdcu_edac_get_bypass_status(void)
1532
0
{
1533
0
  return (rdcu->sram_edac_status >> 8) & 0x1UL;
1534
0
}
1535
1536
1537
/**
1538
 * @brief get EDAC SRAM scrubbing information
1539
 * @see RDCU-FRS-FN-1032
1540
 */
1541
1542
uint8_t rdcu_edac_get_scrub_info(void)
1543
0
{
1544
0
  return (uint8_t) (rdcu->sram_edac_ctrl & 0xFFUL);
1545
0
}
1546
1547
1548
/**
1549
 * @brief read data from the local SRAM mirror
1550
 *
1551
 * @param buf the buffer to read to (if NULL, the required size is returned)
1552
 *
1553
 * @param addr an address within the RDCU SRAM
1554
 * @param size the number of bytes read
1555
 *
1556
 * @returns the number of bytes read, < 0 on error
1557
 */
1558
1559
int rdcu_read_sram(void *buf, uint32_t addr, uint32_t size)
1560
0
{
1561
0
  if (addr > RDCU_SRAM_END)
1562
0
    return -1;
1563
1564
0
  if (size > RDCU_SRAM_SIZE)
1565
0
    return -1;
1566
1567
0
  if (addr + size > RDCU_SRAM_START + RDCU_SRAM_SIZE)
1568
0
    return -1;
1569
1570
0
  if (buf)
1571
0
    memcpy(buf, &rdcu->sram[addr], size);
1572
1573
0
  return (int)size; /* lol */
1574
0
}
1575
1576
1577
/**
1578
 * @brief write arbitrary big-endian data to the local SRAM mirror
1579
 *
1580
 * @param buf the buffer to read from
1581
 *
1582
 * @param addr an address within the RDCU SRAM
1583
 * @param size the number of bytes read
1584
 *
1585
 * @returns the number of bytes written, < 0 on error
1586
 */
1587
1588
int rdcu_write_sram(const void *buf, uint32_t addr, uint32_t size)
1589
0
{
1590
0
  if (!buf)
1591
0
    return 0;
1592
1593
0
  if (addr > RDCU_SRAM_END)
1594
0
    return -1;
1595
1596
0
  if (size > RDCU_SRAM_SIZE)
1597
0
    return -1;
1598
1599
0
  if (addr + size > RDCU_SRAM_START + RDCU_SRAM_SIZE)
1600
0
    return -1;
1601
1602
0
  if (buf)
1603
0
    memcpy(&rdcu->sram[addr], buf, size);
1604
1605
0
  return (int)size; /* lol */
1606
0
}
1607
1608
1609
/**
1610
 * @brief write uint8_t formatted data to the local SRAM mirror. (This function
1611
 *  is endian-safe.)
1612
 *
1613
 * @param buf the buffer to read from
1614
 *
1615
 * @param addr an address within the RDCU SRAM
1616
 * @param size the number of bytes read
1617
 *
1618
 * @returns the number of bytes written, < 0 on error
1619
 */
1620
1621
int rdcu_write_sram_8(const uint8_t *buf, uint32_t addr, uint32_t size)
1622
0
{
1623
0
  return rdcu_write_sram(buf, addr, size);
1624
0
}
1625
1626
1627
/**
1628
 * @brief write uint16_t formatted data to the local SRAM mirror. This function
1629
 *  is endian-safe.
1630
 *
1631
 * @param buf the buffer to read from
1632
 *
1633
 * @param addr an address within the RDCU SRAM
1634
 * @param size the number of bytes read
1635
 *
1636
 * @returns the number of bytes written, < 0 on error
1637
 */
1638
1639
int rdcu_write_sram_16(const uint16_t *buf, uint32_t addr, uint32_t size)
1640
0
{
1641
0
  if (!buf)
1642
0
    return 0;
1643
1644
0
  if (size & 0x1)
1645
0
    return -1;
1646
1647
0
  if (addr > RDCU_SRAM_END)
1648
0
    return -1;
1649
1650
0
  if (size > RDCU_SRAM_SIZE)
1651
0
    return -1;
1652
1653
0
  if (addr + size > RDCU_SRAM_START + RDCU_SRAM_SIZE)
1654
0
    return -1;
1655
1656
#ifdef __BIG_ENDIAN
1657
  return rdcu_write_sram(buf, addr, size);
1658
#elif defined(__LITTLE_ENDIAN)
1659
0
  {
1660
0
    uint32_t i;
1661
1662
0
    for (i = 0; i < size/sizeof(uint16_t); i++) {
1663
0
      uint16_t tmp = cpu_to_be16(buf[i]);
1664
1665
0
      memcpy(&rdcu->sram[addr+i*sizeof(tmp)], &tmp, sizeof(tmp));
1666
0
    }
1667
0
  }
1668
0
  return (int)size; /* lol */
1669
#else
1670
#error "Unknown byte order!"
1671
#endif
1672
0
}
1673
1674
1675
/**
1676
 * @brief write uint32_t formatted data to the local SRAM mirror. This function
1677
 *  is endian-safe.
1678
 *
1679
 * @param buf the buffer to read from
1680
 *
1681
 * @param addr an address within the RDCU SRAM
1682
 * @param size the number of bytes read
1683
 *
1684
 * @returns the number of bytes written, < 0 on error
1685
 */
1686
1687
int rdcu_write_sram_32(const uint32_t *buf, uint32_t addr, uint32_t size)
1688
0
{
1689
0
  if (!buf)
1690
0
    return 0;
1691
1692
0
  if (size & 0x3)
1693
0
    return -1;
1694
1695
0
  if (addr > RDCU_SRAM_END)
1696
0
    return -1;
1697
1698
0
  if (size > RDCU_SRAM_SIZE)
1699
0
    return -1;
1700
1701
0
  if (addr + size > RDCU_SRAM_START + RDCU_SRAM_SIZE)
1702
0
    return -1;
1703
1704
#ifdef __BIG_ENDIAN
1705
  return rdcu_write_sram(buf, addr, size);
1706
#elif defined(__LITTLE_ENDIAN)
1707
0
  {
1708
0
    uint32_t i;
1709
1710
0
    for (i = 0; i < size/sizeof(uint32_t); i++) {
1711
0
      uint32_t tmp = cpu_to_be32(buf[i]);
1712
1713
0
      memcpy(&rdcu->sram[addr+i*sizeof(tmp)], &tmp, sizeof(tmp));
1714
0
    }
1715
0
  }
1716
0
  return (int)size; /* lol */
1717
#else
1718
#error "Unknown byte order!"
1719
#endif
1720
0
}
1721
1722
1723
/**
1724
 * @brief sync the FPGA version (read only)
1725
 *
1726
 * @returns 0 on success, otherwise error
1727
 */
1728
1729
int rdcu_sync_fpga_version(void)
1730
0
{
1731
0
  return rdcu_sync(rdcu_read_cmd_fpga_version, &rdcu->fpga_version, 0);
1732
0
}
1733
1734
1735
/**
1736
 * @brief sync the RDCU status register (read only)
1737
 *
1738
 * @returns 0 on success, otherwise error
1739
 */
1740
1741
int rdcu_sync_rdcu_status(void)
1742
0
{
1743
0
  return rdcu_sync(rdcu_read_cmd_rdcu_status, &rdcu->rdcu_status, 0);
1744
0
}
1745
1746
1747
/**
1748
 * @brief sync the LVDS core status register (read only)
1749
 *
1750
 * @returns 0 on success, otherwise error
1751
 */
1752
1753
int rdcu_sync_lvds_core_status(void)
1754
0
{
1755
0
  return rdcu_sync(rdcu_read_cmd_lvds_core_status,
1756
0
       &rdcu->lvds_core_status, 0);
1757
0
}
1758
1759
1760
/**
1761
 * @brief sync the SpW link status register (read only)
1762
 *
1763
 * @returns 0 on success, otherwise error
1764
 */
1765
1766
int rdcu_sync_spw_link_status(void)
1767
0
{
1768
0
  return rdcu_sync(rdcu_read_cmd_spw_link_status,
1769
0
       &rdcu->spw_link_status, 0);
1770
0
}
1771
1772
1773
/**
1774
 * @brief sync the SpW Error Counter register (read only)
1775
 *
1776
 * @returns 0 on success, otherwise error
1777
 */
1778
1779
int rdcu_sync_spw_err_cntrs(void)
1780
0
{
1781
0
  return rdcu_sync(rdcu_read_cmd_spw_err_cntrs,
1782
0
       &rdcu->spw_err_cntrs, 0);
1783
0
}
1784
1785
1786
/**
1787
 * @brief sync the RMAP Last Error register (read only)
1788
 *
1789
 * @returns 0 on success, otherwise error
1790
 */
1791
1792
int rdcu_sync_rmap_last_err(void)
1793
0
{
1794
0
  return rdcu_sync(rdcu_read_cmd_rmap_last_err,
1795
0
       &rdcu->rmap_last_err, 0);
1796
0
}
1797
1798
1799
/**
1800
 * @brief sync the RMAP No-Reply Error Counter register (read only)
1801
 *
1802
 * @returns 0 on success, otherwise error
1803
 */
1804
1805
int rdcu_sync_rmap_no_reply_err_cntrs(void)
1806
0
{
1807
0
  return rdcu_sync(rdcu_read_cmd_rmap_no_reply_err_cntrs,
1808
0
       &rdcu->rmap_no_reply_err_cntrs, 0);
1809
0
}
1810
1811
1812
/**
1813
 * @brief sync the RMAP Packet Error Counter register (read only)
1814
 *
1815
 * @returns 0 on success, otherwise error
1816
 */
1817
1818
int rdcu_sync_rmap_pckt_err_cntrs(void)
1819
0
{
1820
0
  return rdcu_sync(rdcu_read_cmd_rmap_pckt_err_cntrs,
1821
0
       &rdcu->rmap_pckt_err_cntrs, 0);
1822
0
}
1823
1824
1825
1826
/**
1827
 * @brief sync an ADC values register (read only)
1828
 *
1829
 * @param id the ADC value register id (1-4)
1830
 *
1831
 * @returns 0 on success, otherwise error
1832
 */
1833
1834
int rdcu_sync_adc_values(int id)
1835
0
{
1836
0
  switch (id) {
1837
0
  case '1':
1838
0
    return rdcu_sync(rdcu_read_cmd_adc_values_1,
1839
0
         &rdcu->adc_values_1, 0);
1840
0
  case '2':
1841
0
    return rdcu_sync(rdcu_read_cmd_adc_values_2,
1842
0
         &rdcu->adc_values_2, 0);
1843
0
  case '3':
1844
0
    return rdcu_sync(rdcu_read_cmd_adc_values_3,
1845
0
         &rdcu->adc_values_3, 0);
1846
0
  case '4':
1847
0
    return rdcu_sync(rdcu_read_cmd_adc_values_4,
1848
0
         &rdcu->adc_values_4, 0);
1849
0
  default:
1850
0
    break;
1851
0
  }
1852
1853
0
  return -1;
1854
0
}
1855
1856
1857
/**
1858
 * @brief sync the ADC Status register (read only)
1859
 *
1860
 * @returns 0 on success, otherwise error
1861
 */
1862
1863
int rdcu_sync_adc_status(void)
1864
0
{
1865
0
  return rdcu_sync(rdcu_read_cmd_adc_status,
1866
0
       &rdcu->adc_status, 0);
1867
0
}
1868
1869
1870
/**
1871
 * @brief sync the Compressor Status register (read only)
1872
 *
1873
 * @returns 0 on success, otherwise error
1874
 */
1875
1876
int rdcu_sync_compr_status(void)
1877
0
{
1878
0
  return rdcu_sync(rdcu_read_cmd_compr_status,
1879
0
       &rdcu->compr_status, 0);
1880
0
}
1881
1882
1883
/**
1884
 * @brief sync the RDCU Reset register (write only)
1885
 *
1886
 * @returns 0 on success, otherwise error
1887
 */
1888
1889
int rdcu_sync_rdcu_reset(void)
1890
0
{
1891
0
  return rdcu_sync(rdcu_write_cmd_rdcu_reset,
1892
0
       &rdcu->rdcu_reset, 4);
1893
0
}
1894
1895
1896
/**
1897
 * @brief sync the SpW Link Control register (write only)
1898
 *
1899
 * @returns 0 on success, otherwise error
1900
 */
1901
1902
int rdcu_sync_spw_link_ctrl(void)
1903
0
{
1904
0
  return rdcu_sync(rdcu_write_cmd_spw_link_ctrl,
1905
0
       &rdcu->spw_link_ctrl, 4);
1906
0
}
1907
1908
/**
1909
 * @brief sync the LVDS Control register (write only)
1910
 *
1911
 * @returns 0 on success, otherwise error
1912
 */
1913
1914
int rdcu_sync_lvds_ctrl(void)
1915
0
{
1916
0
  return rdcu_sync(rdcu_write_cmd_lvds_ctrl,
1917
0
       &rdcu->lvds_ctrl, 4);
1918
0
}
1919
1920
1921
/**
1922
 * @brief sync the Core Control register (write only)
1923
 *
1924
 * @returns 0 on success, otherwise error
1925
 */
1926
1927
int rdcu_sync_core_ctrl(void)
1928
0
{
1929
0
  return rdcu_sync(rdcu_write_cmd_core_ctrl,
1930
0
       &rdcu->core_ctrl, 4);
1931
0
}
1932
1933
1934
/**
1935
 * @brief sync the ADC Control register (write only)
1936
 *
1937
 * @returns 0 on success, otherwise error
1938
 */
1939
1940
int rdcu_sync_adc_ctrl(void)
1941
0
{
1942
0
  return rdcu_sync(rdcu_write_cmd_adc_ctrl,
1943
0
       &rdcu->adc_ctrl, 4);
1944
0
}
1945
1946
1947
/**
1948
 * @brief sync the Compressor Control register (write only)
1949
 *
1950
 * @returns 0 on success, otherwise error
1951
 */
1952
1953
int rdcu_sync_compr_ctrl(void)
1954
0
{
1955
0
  return rdcu_sync(rdcu_write_cmd_compr_ctrl,
1956
0
       &rdcu->compr_ctrl, 4);
1957
0
}
1958
1959
1960
/**
1961
 * @brief sync the Compressor Parameter 1 (write only)
1962
 *
1963
 * @returns 0 on success, otherwise error
1964
 */
1965
1966
int rdcu_sync_compressor_param1(void)
1967
0
{
1968
0
  return rdcu_sync(rdcu_write_cmd_compressor_param1,
1969
0
       &rdcu->compressor_param1, 4);
1970
0
}
1971
1972
1973
/**
1974
 * @brief sync the Compressor Parameter 2 (write only)
1975
 *
1976
 * @returns 0 on success, otherwise error
1977
 */
1978
1979
int rdcu_sync_compressor_param2(void)
1980
0
{
1981
0
  return rdcu_sync(rdcu_write_cmd_compressor_param2,
1982
0
       &rdcu->compressor_param2, 4);
1983
0
}
1984
1985
1986
/**
1987
 * @brief sync the Adaptive Parameter 1 (write only)
1988
 *
1989
 * @returns 0 on success, otherwise error
1990
 */
1991
1992
int rdcu_sync_adaptive_param1(void)
1993
0
{
1994
0
  return rdcu_sync(rdcu_write_cmd_adaptive_param1,
1995
0
       &rdcu->adaptive_param1, 4);
1996
0
}
1997
1998
1999
/**
2000
 * @brief sync the Adaptive Parameter 2 (write only)
2001
 *
2002
 * @returns 0 on success, otherwise error
2003
 */
2004
2005
int rdcu_sync_adaptive_param2(void)
2006
0
{
2007
0
  return rdcu_sync(rdcu_write_cmd_adaptive_param2,
2008
0
       &rdcu->adaptive_param2, 4);
2009
0
}
2010
2011
2012
/**
2013
 * @brief sync the Data Start Address (write only)
2014
 *
2015
 * @returns 0 on success, otherwise error
2016
 */
2017
2018
int rdcu_sync_data_start_addr(void)
2019
0
{
2020
0
  return rdcu_sync(rdcu_write_cmd_data_start_addr,
2021
0
       &rdcu->data_start_addr, 4);
2022
0
}
2023
2024
2025
/**
2026
 * @brief sync the Model Start Address (write only)
2027
 *
2028
 * @returns 0 on success, otherwise error
2029
 */
2030
2031
int rdcu_sync_model_start_addr(void)
2032
0
{
2033
0
  return rdcu_sync(rdcu_write_cmd_model_start_addr,
2034
0
       &rdcu->model_start_addr, 4);
2035
0
}
2036
2037
2038
/**
2039
 * @brief sync the Number of Samples (write only)
2040
 *
2041
 * @returns 0 on success, otherwise error
2042
 */
2043
2044
int rdcu_sync_num_samples(void)
2045
0
{
2046
0
  return rdcu_sync(rdcu_write_cmd_num_samples,
2047
0
       &rdcu->num_samples, 4);
2048
0
}
2049
2050
2051
/**
2052
 * @brief sync the Model Start Address (write only)
2053
 *
2054
 * @returns 0 on success, otherwise error
2055
 */
2056
2057
int rdcu_sync_new_model_start_addr(void)
2058
0
{
2059
0
  return rdcu_sync(rdcu_write_cmd_new_model_start_addr,
2060
0
       &rdcu->new_model_start_addr, 4);
2061
0
}
2062
2063
2064
/**
2065
 * @brief sync the Compressed Data Buffer Start Address (write only)
2066
 *
2067
 * @returns 0 on success, otherwise error
2068
 */
2069
2070
int rdcu_sync_compr_data_buf_start_addr(void)
2071
0
{
2072
0
  return rdcu_sync(rdcu_write_cmd_compr_data_buf_start_addr,
2073
0
       &rdcu->compr_data_buf_start_addr, 4);
2074
0
}
2075
2076
2077
/**
2078
 * @brief sync the Compressed Data Buffer Length (write only)
2079
 *
2080
 * @returns 0 on success, otherwise error
2081
 */
2082
2083
int rdcu_sync_compr_data_buf_len(void)
2084
0
{
2085
0
  return rdcu_sync(rdcu_write_cmd_compr_data_buf_len,
2086
0
       &rdcu->compr_data_buf_len, 4);
2087
0
}
2088
2089
2090
/**
2091
 * @brief sync the Used Parameter 1 (read only)
2092
 *
2093
 * @returns 0 on success, otherwise error
2094
 */
2095
2096
int rdcu_sync_used_param1(void)
2097
0
{
2098
0
  return rdcu_sync(rdcu_read_cmd_used_param1, &rdcu->used_param1, 0);
2099
0
}
2100
2101
2102
/**
2103
 * @brief sync the Used Parameter 2 (read only)
2104
 *
2105
 * @returns 0 on success, otherwise error
2106
 */
2107
2108
int rdcu_sync_used_param2(void)
2109
0
{
2110
0
  return rdcu_sync(rdcu_read_cmd_used_param2, &rdcu->used_param2, 0);
2111
0
}
2112
2113
2114
/**
2115
 * @brief sync the Compressed Data Start Address (read only)
2116
 *
2117
 * @returns 0 on success, otherwise error
2118
 */
2119
2120
int rdcu_sync_compr_data_start_addr(void)
2121
0
{
2122
0
  return rdcu_sync(rdcu_read_cmd_compr_data_start_addr,
2123
0
       &rdcu->compr_data_start_addr, 0);
2124
0
}
2125
2126
2127
/**
2128
 * @brief sync the Compressed Data Start Size (read only)
2129
 *
2130
 * @returns 0 on success, otherwise error
2131
 */
2132
2133
int rdcu_sync_compr_data_size(void)
2134
0
{
2135
0
  return rdcu_sync(rdcu_read_cmd_compr_data_size,
2136
0
       &rdcu->compr_data_size, 0);
2137
0
}
2138
2139
2140
/**
2141
 * @brief sync the Compressed Data Adaptive 1 Size (read only)
2142
 *
2143
 * @returns 0 on success, otherwise error
2144
 */
2145
2146
int rdcu_sync_compr_data_adaptive_1_size(void)
2147
0
{
2148
0
  return rdcu_sync(rdcu_read_cmd_compr_data_adaptive_1_size,
2149
0
       &rdcu->compr_data_adaptive_1_size, 0);
2150
0
}
2151
2152
2153
/**
2154
 * @brief sync the Compressed Data Adaptive 2 Size (read only)
2155
 *
2156
 * @returns 0 on success, otherwise error
2157
 */
2158
2159
int rdcu_sync_compr_data_adaptive_2_size(void)
2160
0
{
2161
0
  return rdcu_sync(rdcu_read_cmd_compr_data_adaptive_2_size,
2162
0
       &rdcu->compr_data_adaptive_2_size, 0);
2163
0
}
2164
2165
2166
/**
2167
 * @brief sync the Compression Error (read only)
2168
 *
2169
 * @returns 0 on success, otherwise error
2170
 */
2171
2172
int rdcu_sync_compr_error(void)
2173
0
{
2174
0
  return rdcu_sync(rdcu_read_cmd_compr_error,
2175
0
       &rdcu->compr_error, 0);
2176
0
}
2177
2178
2179
/**
2180
 * @brief sync the Model Info Start Address (read only)
2181
 *
2182
 * @returns 0 on success, otherwise error
2183
 */
2184
2185
int rdcu_sync_new_model_addr_used(void)
2186
0
{
2187
0
  return rdcu_sync(rdcu_read_cmd_new_model_addr_used,
2188
0
       &rdcu->new_model_addr_used, 0);
2189
0
}
2190
2191
2192
/**
2193
 * @brief sync the Model Info Length (read only)
2194
 *
2195
 * @returns 0 on success, otherwise error
2196
 */
2197
2198
int rdcu_sync_samples_used(void)
2199
0
{
2200
0
  return rdcu_sync(rdcu_read_cmd_samples_used,
2201
0
       &rdcu->samples_used, 0);
2202
0
}
2203
2204
2205
/**
2206
 * @brief sync the SRAM EDAC Control (write only)
2207
 *
2208
 * @returns 0 on success, otherwise error
2209
 */
2210
2211
int rdcu_sync_sram_edac_ctrl(void)
2212
0
{
2213
0
  return rdcu_sync(rdcu_write_cmd_sram_edac_ctrl,
2214
0
       &rdcu->sram_edac_ctrl, 4);
2215
0
}
2216
2217
2218
/**
2219
 * @brief sync the SRAM EDAC Status (read only)
2220
 *
2221
 * @returns 0 on success, otherwise error
2222
 */
2223
2224
int rdcu_sync_sram_edac_status(void)
2225
0
{
2226
0
  return rdcu_sync(rdcu_read_cmd_sram_edac_status,
2227
0
       &rdcu->sram_edac_status, 0);
2228
0
}
2229
2230
2231
/**
2232
 * @brief sync a range of 32 bit words of the local mirror to the remote SRAM
2233
 *
2234
 * @param addr and address within the remote SRAM
2235
 * @param size the number of bytes to sync
2236
 * @param mtu the maximum transport unit per RMAP packet; choose wisely
2237
 *
2238
 * @note due to restrictions, the number of bytes and mtu must be a multiple
2239
 *   of 4; the address must be aligned to 32-bits as well
2240
 *
2241
 * @returns 0 on success, otherwise error
2242
 */
2243
2244
int rdcu_sync_mirror_to_sram(uint32_t addr, uint32_t size, uint32_t mtu)
2245
0
{
2246
0
  int ret;
2247
2248
0
  uint32_t sent = 0;
2249
0
  uint32_t tx_bytes;
2250
2251
2252
0
  if (mtu & 0x3)
2253
0
    return -1;
2254
2255
0
  if (addr & 0x3)
2256
0
    return -1;
2257
2258
0
  if (size & 0x3)
2259
0
    return -1;
2260
2261
0
  if (addr > RDCU_SRAM_END)
2262
0
    return -1;
2263
2264
0
  if (size > RDCU_SRAM_SIZE)
2265
0
    return -1;
2266
2267
0
  if (addr + size > RDCU_SRAM_START + RDCU_SRAM_SIZE)
2268
0
    return -1;
2269
2270
2271
0
  tx_bytes = size;
2272
2273
0
  while (tx_bytes >= mtu) {
2274
2275
0
    ret = rdcu_sync_data(rdcu_write_cmd_data, addr + sent,
2276
0
             &rdcu->sram[addr + sent], mtu, 0);
2277
0
    if (ret > 0)
2278
0
      continue;
2279
2280
0
    if (ret < 0)
2281
0
      return -1;
2282
2283
2284
0
    sent     += mtu;
2285
0
    tx_bytes -= mtu;
2286
0
  }
2287
2288
0
  while (tx_bytes) {
2289
0
    ret = rdcu_sync_data(rdcu_write_cmd_data, addr + sent,
2290
0
             &rdcu->sram[addr + sent], tx_bytes, 0);
2291
0
    if (ret > 0)
2292
0
      continue;
2293
2294
0
    if (ret < 0)
2295
0
      return -1;
2296
2297
0
    tx_bytes = 0;
2298
0
  }
2299
2300
2301
0
  return 0;
2302
0
}
2303
2304
2305
/**
2306
 * @brief sync a range of 32 bit words of the remote SRAM to the local mirror
2307
 *
2308
 * @param addr an address within the remote SRAM
2309
 * @param size the number of bytes to sync
2310
 * @param mtu the maximum transport unit per RMAP packet; choose wisely
2311
 *
2312
 * @note due to restrictions, the number of bytes and mtu must be a multiple
2313
 *   of 4; the address must be aligned to 32-bits as well
2314
 *
2315
 * @returns 0 on success, otherwise error
2316
 */
2317
2318
int rdcu_sync_sram_to_mirror(uint32_t addr, uint32_t size, uint32_t mtu)
2319
0
{
2320
0
  int ret;
2321
2322
0
  uint32_t recv = 0;
2323
0
  uint32_t rx_bytes;
2324
2325
2326
0
  if (mtu & 0x3)
2327
0
    return -1;
2328
2329
0
  if (addr & 0x3)
2330
0
    return -1;
2331
2332
0
  if (size & 0x3)
2333
0
    return -1;
2334
2335
0
  if (addr > RDCU_SRAM_END)
2336
0
    return -1;
2337
2338
0
  if (size > RDCU_SRAM_SIZE)
2339
0
    return -1;
2340
2341
0
  if (addr + size > RDCU_SRAM_START + RDCU_SRAM_SIZE)
2342
0
    return -1;
2343
2344
2345
0
  rx_bytes = size;
2346
2347
0
  while (rx_bytes >= mtu) {
2348
2349
0
    ret = rdcu_sync_data(rdcu_read_cmd_data, addr + recv,
2350
0
             &rdcu->sram[addr + recv], mtu, 1);
2351
2352
#if 0
2353
    while (rdcu_rmap_sync_status() > 3)
2354
      ;
2355
#endif
2356
2357
0
    if (ret > 0)
2358
0
      continue;
2359
2360
0
    if (ret < 0)
2361
0
      return -1;
2362
2363
0
    recv     += mtu;
2364
0
    rx_bytes -= mtu;
2365
0
  }
2366
2367
0
  while (rx_bytes) {
2368
0
    ret = rdcu_sync_data(rdcu_read_cmd_data, addr + recv,
2369
0
             &rdcu->sram[addr + recv], rx_bytes, 1);
2370
0
    if (ret > 0)
2371
0
      continue;
2372
2373
0
    if (ret < 0)
2374
0
      return -1;
2375
2376
0
    rx_bytes = 0;
2377
0
  }
2378
2379
2380
0
  return 0;
2381
0
}
2382
2383
2384
/**
2385
 * @brief sync a range of 32 bit words of the remote SRAM to the local mirror
2386
 *  and form the local mirror to the remote SRAM in parallel
2387
 *
2388
 * @param rx_addr the read address within the remote SRAM
2389
 * @param rx_size the number of bytes to sync to the mirror
2390
 * @param tx_addr the write address within the remote SRAM
2391
 * @param tx_size the number of bytes to sync to the SRAM
2392
 * @param mtu the maximum transport unit per RMAP packet; choose wisely
2393
 *
2394
 * @note due to restrictions, the number of bytes and mtu must be a multiple
2395
 *   of 4; the address must be aligned to 32-bits as well
2396
 *
2397
 * @returns 0 on success, otherwise error
2398
 */
2399
2400
int rdcu_sync_sram_mirror_parallel(uint32_t rx_addr, uint32_t rx_size,
2401
           uint32_t tx_addr, uint32_t tx_size,
2402
           uint32_t mtu)
2403
0
{
2404
0
  int ret;
2405
2406
0
  uint32_t recv = 0;
2407
0
  uint32_t sent = 0;
2408
0
  uint32_t rx_bytes;
2409
0
  uint32_t tx_bytes;
2410
2411
2412
0
  if (mtu & 0x3)
2413
0
    return -1;
2414
2415
0
  if (rx_addr & 0x3)
2416
0
    return -1;
2417
2418
0
  if (tx_addr & 0x3)
2419
0
    return -1;
2420
2421
0
  if (rx_size & 0x3)
2422
0
    return -1;
2423
2424
0
  if (tx_size & 0x3)
2425
0
    return -1;
2426
2427
0
  if (rx_addr > RDCU_SRAM_END)
2428
0
    return -1;
2429
2430
0
  if (tx_addr > RDCU_SRAM_END)
2431
0
    return -1;
2432
2433
0
  if (rx_size > RDCU_SRAM_SIZE)
2434
0
    return -1;
2435
2436
0
  if (tx_size > RDCU_SRAM_SIZE)
2437
0
    return -1;
2438
2439
0
  if ((rx_addr + rx_size) > (RDCU_SRAM_END + 1))
2440
0
    return -1;
2441
2442
0
  if ((tx_addr + tx_size) > (RDCU_SRAM_END + 1))
2443
0
    return -1;
2444
2445
  /* check buffer overlap */
2446
0
  if (rx_addr < tx_addr+tx_size && rx_addr+rx_size > tx_addr) {
2447
0
    debug_print("Error: The two parallel transferring buffers overlap. Read buffer: 0x%x size: %u. Write buffer: 0x%x size: %u.",
2448
0
      rx_addr, rx_size, tx_addr, tx_size);
2449
0
    return -1;
2450
0
  }
2451
2452
2453
0
  rx_bytes = rx_size;
2454
0
  tx_bytes = tx_size;
2455
2456
0
  while (rx_bytes || tx_bytes) {
2457
0
    if (rx_bytes) {
2458
0
      if (rx_bytes >= mtu) {
2459
0
        ret = rdcu_sync_data(rdcu_read_cmd_data,
2460
0
                 rx_addr + recv,
2461
0
                 &rdcu->sram[rx_addr + recv],
2462
0
                 mtu, 1);
2463
#if 0
2464
        while (rdcu_rmap_sync_status() > 3)
2465
          ;
2466
#endif
2467
2468
0
        if (ret < 0)
2469
0
          return -1;
2470
2471
0
        if (ret == 0) {
2472
0
          recv     += mtu;
2473
0
          rx_bytes -= mtu;
2474
0
        }
2475
0
      } else {
2476
0
        ret = rdcu_sync_data(rdcu_read_cmd_data,
2477
0
                 rx_addr + recv,
2478
0
                 &rdcu->sram[rx_addr + recv],
2479
0
                 rx_bytes, 1);
2480
0
        if (ret < 0)
2481
0
          return -1;
2482
2483
0
        if (ret == 0)
2484
0
          rx_bytes = 0;
2485
0
      }
2486
0
    }
2487
2488
0
    if (tx_bytes) {
2489
0
      if (tx_bytes >= mtu) {
2490
0
        ret = rdcu_sync_data(rdcu_write_cmd_data,
2491
0
                 tx_addr + sent,
2492
0
                 &rdcu->sram[tx_addr + sent],
2493
0
                 mtu, 0);
2494
2495
0
        if (ret < 0)
2496
0
          return -1;
2497
2498
0
        if (ret == 0) {
2499
0
          sent     += mtu;
2500
0
          tx_bytes -= mtu;
2501
0
        }
2502
0
      } else {
2503
0
        ret = rdcu_sync_data(rdcu_write_cmd_data,
2504
0
                 tx_addr + sent,
2505
0
                 &rdcu->sram[tx_addr + sent],
2506
0
                 tx_bytes, 0);
2507
2508
0
        if (ret < 0)
2509
0
          return -1;
2510
2511
0
        if (ret == 0)
2512
0
          tx_bytes = 0;
2513
0
      }
2514
0
    }
2515
0
  }
2516
0
  return 0;
2517
0
}
2518
2519
2520
/**
2521
 * @brief initialise the rdcu control library
2522
 *
2523
 * @returns 0 on success, otherwise error
2524
 */
2525
2526
int rdcu_ctrl_init(void)
2527
0
{
2528
0
  rdcu = (struct rdcu_mirror *) calloc(1, sizeof(struct rdcu_mirror));
2529
0
  if (!rdcu) {
2530
0
    debug_print("Error allocating memory for the RDCU mirror");
2531
0
    return -1;
2532
0
  }
2533
2534
#if defined(__sparc__)
2535
  rdcu->sram =  (uint8_t *) 0x60000000;
2536
#else /* assume PC */
2537
2538
0
  rdcu->sram = (uint8_t *) malloc(RDCU_SRAM_SIZE);
2539
0
  if (!rdcu->sram) {
2540
0
    debug_print("Error allocating memory for the RDCU SRAM mirror");
2541
0
    return -1;
2542
0
  }
2543
0
#endif
2544
2545
0
  memset(rdcu->sram, 0, RDCU_SRAM_SIZE);  /* clear sram buffer */
2546
2547
0
  return 0;
2548
0
}