OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [lib/] [source/] [neorv32_slink.c] - Blame information for rev 65

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 61 zero_gravi
// #################################################################################################
2
// # << NEORV32: neorv32_slink.c - Stream Link Interface HW Driver >>                              #
3
// # ********************************************************************************************* #
4
// # BSD 3-Clause License                                                                          #
5
// #                                                                                               #
6
// # Copyright (c) 2021, Stephan Nolting. All rights reserved.                                     #
7
// #                                                                                               #
8
// # Redistribution and use in source and binary forms, with or without modification, are          #
9
// # permitted provided that the following conditions are met:                                     #
10
// #                                                                                               #
11
// # 1. Redistributions of source code must retain the above copyright notice, this list of        #
12
// #    conditions and the following disclaimer.                                                   #
13
// #                                                                                               #
14
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
15
// #    conditions and the following disclaimer in the documentation and/or other materials        #
16
// #    provided with the distribution.                                                            #
17
// #                                                                                               #
18
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
19
// #    endorse or promote products derived from this software without specific prior written      #
20
// #    permission.                                                                                #
21
// #                                                                                               #
22
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
23
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
24
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
25
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
26
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
27
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
28
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
29
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
30
// # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
31
// # ********************************************************************************************* #
32
// # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
33
// #################################################################################################
34
 
35
 
36
/**********************************************************************//**
37
 * @file neorv32_slink.h
38
 * @author Stephan Nolting
39
 * @brief Stream Link Interface HW driver source file.
40
 **************************************************************************/
41
 
42
#include "neorv32.h"
43
#include "neorv32_slink.h"
44
 
45
 
46
/**********************************************************************//**
47
 * Check if stream link interface was synthesized.
48
 *
49
 * @return 0 if SLINK was not synthesized, 1 if SLINK is available.
50
 **************************************************************************/
51
int neorv32_slink_available(void) {
52
 
53 64 zero_gravi
  if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_SLINK)) {
54 61 zero_gravi
    return 1;
55
  }
56
  else {
57
    return 0;
58
  }
59
}
60
 
61
 
62
/**********************************************************************//**
63
 * Activate stream link interface.
64
 **************************************************************************/
65
void neorv32_slink_enable(void) {
66
 
67 64 zero_gravi
  NEORV32_SLINK.CTRL |= (uint32_t)(1 << SLINK_CTRL_EN);
68 61 zero_gravi
}
69
 
70
 
71
/**********************************************************************//**
72
 * Deactivate stream link interface.
73
 *
74
 * @note This will also clear all link FIFOs.
75
 **************************************************************************/
76
void neorv32_slink_disable(void) {
77
 
78 64 zero_gravi
  NEORV32_SLINK.CTRL &= ~(uint32_t)(1 << SLINK_CTRL_EN);
79 61 zero_gravi
}
80
 
81
 
82
/**********************************************************************//**
83 65 zero_gravi
 * Configure SLINK RX interrupt.
84
 *
85
 * @param[in] link_id Link id (0..7).
86
 * @param[in] irq_en Link's IRQ enable (#NEORV32_SLINK_IRQ_EN_enum)
87
 * @param[in] irq_type Link's IRQ type (#NEORV32_SLINK_IRQ_RX_TYPE_enum)
88
 **************************************************************************/
89
void neorv32_slink_rx_irq_config(int link_id, int irq_en, int irq_type) {
90
 
91
  link_id = link_id & 7;
92
 
93
  uint32_t slink_irq_conf = NEORV32_SLINK.IRQ;
94
 
95
  // enable IRQ
96
  if (irq_en) {
97
    slink_irq_conf |=  (1 << (SLINK_IRQ_RX_EN_LSB + link_id));
98
  }
99
  else {
100
    slink_irq_conf &= ~(1 << (SLINK_IRQ_RX_EN_LSB + link_id));
101
  }
102
 
103
  // configure type
104
  if (irq_type) {
105
    slink_irq_conf |=  (1 << (SLINK_IRQ_RX_MODE_LSB + link_id));
106
  }
107
  else {
108
    slink_irq_conf &= ~(1 << (SLINK_IRQ_RX_MODE_LSB + link_id));
109
  }
110
 
111
  NEORV32_SLINK.IRQ = slink_irq_conf;
112
}
113
 
114
 
115
/**********************************************************************//**
116
 * Configure SLINK TX interrupt.
117
 *
118
 * @param[in] link_id Link id (0..7).
119
 * @param[in] irq_en Link's IRQ enable (#NEORV32_SLINK_IRQ_EN_enum)
120
 * @param[in] irq_type Link's IRQ type (#NEORV32_SLINK_IRQ_TX_TYPE_enum)
121
 **************************************************************************/
122
void neorv32_slink_tx_irq_config(int link_id, int irq_en, int irq_type) {
123
 
124
  link_id = link_id & 7;
125
 
126
  uint32_t slink_irq_conf = NEORV32_SLINK.IRQ;
127
 
128
  // enable IRQ
129
  if (irq_en) {
130
    slink_irq_conf |=  (1 << (SLINK_IRQ_TX_EN_LSB + link_id));
131
  }
132
  else {
133
    slink_irq_conf &= ~(1 << (SLINK_IRQ_TX_EN_LSB + link_id));
134
  }
135
 
136
  // configure type
137
  if (irq_type) {
138
    slink_irq_conf |=  (1 << (SLINK_IRQ_TX_MODE_LSB + link_id));
139
  }
140
  else {
141
    slink_irq_conf &= ~(1 << (SLINK_IRQ_TX_MODE_LSB + link_id));
142
  }
143
 
144
  NEORV32_SLINK.IRQ = slink_irq_conf;
145
}
146
 
147
 
148
/**********************************************************************//**
149 61 zero_gravi
 * Get number of implemented RX links
150
 *
151
 * @return Number of implemented RX link (0..8).
152
 **************************************************************************/
153
int neorv32_slink_get_rx_num(void) {
154
 
155
  if (neorv32_slink_available()) {
156 64 zero_gravi
    return (int)((NEORV32_SLINK.CTRL >> SLINK_CTRL_RX_NUM0) & 0xf);
157 61 zero_gravi
  }
158
  else {
159
    return 0;
160
  }
161
}
162
 
163
 
164
/**********************************************************************//**
165
 * Get number of implemented TX links
166
 *
167
 * @return Number of implemented TX link (0..8).
168
 **************************************************************************/
169
int neorv32_slink_get_tx_num(void) {
170
 
171
  if (neorv32_slink_available()) {
172 64 zero_gravi
    return (int)((NEORV32_SLINK.CTRL >> SLINK_CTRL_TX_NUM0) & 0xf);
173 61 zero_gravi
  }
174
  else {
175
    return 0;
176
  }
177
}
178
 
179
 
180
/**********************************************************************//**
181
 * Get FIFO depth of RX links
182
 *
183
 * @return FIFO depth of RX links (1..32768); 0 if no RX links implemented.
184
 **************************************************************************/
185
int neorv32_slink_get_rx_depth(void) {
186
 
187
  if (neorv32_slink_available()) {
188 64 zero_gravi
    uint32_t tmp = (NEORV32_SLINK.CTRL >> SLINK_CTRL_RX_FIFO_S0) & 0x0f;
189 61 zero_gravi
    return (int)(1 << tmp);
190
  }
191
  else {
192
    return 0;
193
  }
194
}
195
 
196
 
197
/**********************************************************************//**
198
 * Get FIFO depth of TX links
199
 *
200
 * @return FIFO depth of TX links (1..32768); 0 if no TX links implemented.
201
 **************************************************************************/
202
int neorv32_slink_get_tx_depth(void) {
203
 
204
  if (neorv32_slink_available()) {
205 64 zero_gravi
    uint32_t tmp = (NEORV32_SLINK.CTRL >> SLINK_CTRL_TX_FIFO_S0) & 0x0f;
206 61 zero_gravi
    return (int)(1 << tmp);
207
  }
208
  else {
209
    return 0;
210
  }
211
}
212
 
213
 
214
/**********************************************************************//**
215 62 zero_gravi
 * Check if RX link FIFO fill level is >= half-full
216
 *
217
 * @param[in] link_id Link id (0..7).
218
 * @return 1 if fill level is >= half-full.
219
 **************************************************************************/
220
int neorv32_slink_check_rx_half_full(int link_id) {
221
 
222
  const uint32_t mask = 1 << SLINK_STATUS_RX0_HALF;
223
 
224 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (mask << (link_id & 0x7))) {
225 62 zero_gravi
    return 1;
226
  }
227
  else {
228
    return 0;
229
  }
230
}
231
 
232
 
233
/**********************************************************************//**
234
 * Check if TX link FIFO fill level is > half-full
235
 *
236
 * @param[in] link_id Link id (0..7).
237
 * @return 1 if fill level is > half-full.
238
 **************************************************************************/
239
int neorv32_slink_check_tx_half_full(int link_id) {
240
 
241
  const uint32_t mask = 1 << SLINK_STATUS_TX0_HALF;
242
 
243 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (mask << (link_id & 0x7))) {
244 62 zero_gravi
    return 1;
245
  }
246
  else {
247
    return 0;
248
  }
249
}
250
 
251
 
252
/**********************************************************************//**
253 61 zero_gravi
 * Write data to TX stream link 0 (non-blocking)
254
 *
255
 * @param[in] tx_data Data to send to link.
256
 * @return 0 if data was send, 1 if link is still busy.
257
 **************************************************************************/
258
int neorv32_slink_tx0_nonblocking(uint32_t tx_data) {
259
 
260 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX0_FREE)) {
261
    NEORV32_SLINK.DATA[0] = tx_data;
262 61 zero_gravi
    return 0;
263
  }
264
  return 1;
265
}
266
 
267
 
268
/**********************************************************************//**
269
 * Write data to TX stream link 1 (non-blocking)
270
 *
271
 * @param[in] tx_data Data to send to link.
272
 * @return 0 if data was send, 1 if link is still busy.
273
 **************************************************************************/
274
int neorv32_slink_tx1_nonblocking(uint32_t tx_data) {
275
 
276 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX1_FREE)) {
277
    NEORV32_SLINK.DATA[1] = tx_data;
278 61 zero_gravi
    return 0;
279
  }
280
  return 1;
281
}
282
 
283
 
284
/**********************************************************************//**
285
 * Write data to TX stream link 2 (non-blocking)
286
 *
287
 * @param[in] tx_data Data to send to link.
288
 * @return 0 if data was send, 1 if link is still busy.
289
 **************************************************************************/
290
int neorv32_slink_tx2_nonblocking(uint32_t tx_data) {
291
 
292 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX2_FREE)) {
293
    NEORV32_SLINK.DATA[2] = tx_data;
294 61 zero_gravi
    return 0;
295
  }
296
  return 1;
297
}
298
 
299
 
300
/**********************************************************************//**
301
 * Write data to TX stream link 3 (non-blocking)
302
 *
303
 * @param[in] tx_data Data to send to link.
304
 * @return 0 if data was send, 1 if link is still busy.
305
 **************************************************************************/
306
int neorv32_slink_tx3_nonblocking(uint32_t tx_data) {
307
 
308 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX3_FREE)) {
309
    NEORV32_SLINK.DATA[3] = tx_data;
310 61 zero_gravi
    return 0;
311
  }
312
  return 1;
313
}
314
 
315
 
316
/**********************************************************************//**
317
 * Write data to TX stream link 4 (non-blocking)
318
 *
319
 * @param[in] tx_data Data to send to link.
320
 * @return 0 if data was send, 1 if link is still busy.
321
 **************************************************************************/
322
int neorv32_slink_tx4_nonblocking(uint32_t tx_data) {
323
 
324 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX4_FREE)) {
325
    NEORV32_SLINK.DATA[4] = tx_data;
326 61 zero_gravi
    return 0;
327
  }
328
  return 1;
329
}
330
 
331
 
332
/**********************************************************************//**
333
 * Write data to TX stream link 5 (non-blocking)
334
 *
335
 * @param[in] tx_data Data to send to link.
336
 * @return 0 if data was send, 1 if link is still busy.
337
 **************************************************************************/
338
int neorv32_slink_tx5_nonblocking(uint32_t tx_data) {
339
 
340 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX5_FREE)) {
341
    NEORV32_SLINK.DATA[5] = tx_data;
342 61 zero_gravi
    return 0;
343
  }
344
  return 1;
345
}
346
 
347
 
348
/**********************************************************************//**
349
 * Write data to TX stream link 6 (non-blocking)
350
 *
351
 * @param[in] tx_data Data to send to link.
352
 * @return 0 if data was send, 1 if link is still busy.
353
 **************************************************************************/
354
int neorv32_slink_tx6_nonblocking(uint32_t tx_data) {
355
 
356 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX6_FREE)) {
357
    NEORV32_SLINK.DATA[6] = tx_data;
358 61 zero_gravi
    return 0;
359
  }
360
  return 1;
361
}
362
 
363
 
364
/**********************************************************************//**
365
 * Write data to TX stream link 7 (non-blocking)
366
 *
367
 * @param[in] tx_data Data to send to link.
368
 * @return 0 if data was send, 1 if link is still busy.
369
 **************************************************************************/
370
int neorv32_slink_tx7_nonblocking(uint32_t tx_data) {
371
 
372 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX7_FREE)) {
373
    NEORV32_SLINK.DATA[7] = tx_data;
374 61 zero_gravi
    return 0;
375
  }
376
  return 1;
377
}
378
 
379
 
380
/**********************************************************************//**
381
 * Read data from RX stream link 0 (non-blocking)
382
 *
383
 * @param[in,out] rx_data Pointer to return read data. Only valid if function return value = 0.
384
 * @return 0 if data was received, 1 if there is no data to fetch.
385
 **************************************************************************/
386
int neorv32_slink_rx0_nonblocking(uint32_t *rx_data) {
387
 
388 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX0_AVAIL)) {
389
    *rx_data = NEORV32_SLINK.DATA[0];
390 61 zero_gravi
    return 0;
391
  }
392
  return 1;
393
}
394
 
395
 
396
/**********************************************************************//**
397
 * Read data from RX stream link 1 (non-blocking)
398
 *
399
 * @param[in,out] rx_data Pointer to return read data. Only valid if function return value = 0.
400
 * @return 0 if data was received, 1 if there is no data to fetch.
401
 **************************************************************************/
402
int neorv32_slink_rx1_nonblocking(uint32_t *rx_data) {
403
 
404 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX1_AVAIL)) {
405
    *rx_data = NEORV32_SLINK.DATA[1];
406 61 zero_gravi
    return 0;
407
  }
408
  return 1;
409
}
410
 
411
 
412
/**********************************************************************//**
413
 * Read data from RX stream link 2 (non-blocking)
414
 *
415
 * @param[in,out] rx_data Pointer to return read data. Only valid if function return value = 0.
416
 * @return 0 if data was received, 1 if there is no data to fetch.
417
 **************************************************************************/
418
int neorv32_slink_rx2_nonblocking(uint32_t *rx_data) {
419
 
420 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX2_AVAIL)) {
421
    *rx_data = NEORV32_SLINK.DATA[2];
422 61 zero_gravi
    return 0;
423
  }
424
  return 1;
425
}
426
 
427
 
428
/**********************************************************************//**
429
 * Read data from RX stream link 3 (non-blocking)
430
 *
431
 * @param[in,out] rx_data Pointer to return read data. Only valid if function return value = 0.
432
 * @return 0 if data was received, 1 if there is no data to fetch.
433
 **************************************************************************/
434
int neorv32_slink_rx3_nonblocking(uint32_t *rx_data) {
435
 
436 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX3_AVAIL)) {
437
    *rx_data = NEORV32_SLINK.DATA[3];
438 61 zero_gravi
    return 0;
439
  }
440
  return 1;
441
}
442
 
443
 
444
/**********************************************************************//**
445
 * Read data from RX stream link 4 (non-blocking)
446
 *
447
 * @param[in,out] rx_data Pointer to return read data. Only valid if function return value = 0.
448
 * @return 0 if data was received, 1 if there is no data to fetch.
449
 **************************************************************************/
450
int neorv32_slink_rx4_nonblocking(uint32_t *rx_data) {
451
 
452 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX4_AVAIL)) {
453
    *rx_data = NEORV32_SLINK.DATA[4];
454 61 zero_gravi
    return 0;
455
  }
456
  return 1;
457
}
458
 
459
 
460
/**********************************************************************//**
461
 * Read data from RX stream link 5 (non-blocking)
462
 *
463
 * @param[in,out] rx_data Pointer to return read data. Only valid if function return value = 0.
464
 * @return 0 if data was received, 1 if there is no data to fetch.
465
 **************************************************************************/
466
int neorv32_slink_rx5_nonblocking(uint32_t *rx_data) {
467
 
468 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX5_AVAIL)) {
469
    *rx_data = NEORV32_SLINK.DATA[5];
470 61 zero_gravi
    return 0;
471
  }
472
  return 1;
473
}
474
 
475
 
476
/**********************************************************************//**
477
 * Read data from RX stream link 6 (non-blocking)
478
 *
479
 * @param[in,out] rx_data Pointer to return read data. Only valid if function return value = 0.
480
 * @return 0 if data was received, 1 if there is no data to fetch.
481
 **************************************************************************/
482
int neorv32_slink_rx6_nonblocking(uint32_t *rx_data) {
483
 
484 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX6_AVAIL)) {
485
    *rx_data = NEORV32_SLINK.DATA[6];
486 61 zero_gravi
    return 0;
487
  }
488
  return 1;
489
}
490
 
491
 
492
/**********************************************************************//**
493
 * Read data from RX stream link 7 (non-blocking)
494
 *
495
 * @param[in,out] rx_data Pointer to return read data. Only valid if function return value = 0.
496
 * @return 0 if data was received, 1 if there is no data to fetch.
497
 **************************************************************************/
498
int neorv32_slink_rx7_nonblocking(uint32_t *rx_data) {
499
 
500 64 zero_gravi
  if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX7_AVAIL)) {
501
    *rx_data = NEORV32_SLINK.DATA[7];
502 61 zero_gravi
    return 0;
503
  }
504
  return 1;
505
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.