summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/shared/include/gr1553bc_list.h
blob: b717da2097e54e5120d4cfcfee918e605dad3900 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
/*
 *  GR1553B BC driver, Descriptor LIST handling
 *
 *  COPYRIGHT (c) 2010.
 *  Cobham Gaisler AB.
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 */

#ifndef __GR1553BC_LIST_H__
#define __GR1553BC_LIST_H__

/*!\file doc/gr1553bc_list.h
 * \brief GR1553B BC driver
 *
 * \section OVERVIEW
 *
 * The BC device driver can schedule synchronous and asynchronous lists
 * of descriptors. The list contains a descriptor table and a software
 * description to make some operations possible, for example translate
 * descriptor-address into descriptor-number.
 *
 * This is the LIST API. It provides functionality to create and manage
 * a BC descriptor list.
 *
 * A list is built up by the following build blocks:
 *  - Major Frame (Consists of N Minor Frames)
 *  - Minor Frame (Consists of up to 32 1553 Message Slots)
 *  - Message Slot (Transfer/Condition BC descriptor)
 *
 * The user can configure lists with different configuration of number of
 * Major Frames, Minor Frame and messages slots within a Minor Frame. The
 * List manages a strait descriptor table (may be changed) and a Frame/Slot
 * tree in order to easily find it's way through all descriptor created.
 *
 * Each Minor frame consist of up to 32 message slot and 2 message slots
 * for time management and descriptor find operations. The list can manage
 * time slots per minor frame, for example a minor frame may be programmed
 * to take 8ms and when the user allocate a message slot within that Minor
 * frame the time spcified will be subtracted from the 8ms, and when the
 * message slot is freed the time will be returned to the Minor frame again.
 *
 * A Major, Minor and Message Slots are identified using a MID (Message-ID).
 * The MID is a way for the user to avoid using pointers are talk with the
 * list API in an easier way. For example a condition Slot that should jump
 * to a transfer slot can be created by knowing "MID and Jump-To-MID". When
 * allocating a Slot (with or without time) the user may specify a certain
 * Slot or a Minor frame, when a Minor frame is given then the API will find
 * a free Slot as early in the Minor Frame as possible and return it to the
 * user.
 *
 * A MID can be created using the macros:
 *   GR1553BC_ID(major,minor,slot)      - ID of a SLOT
 *   GR1553BC_MINOR_ID(major,minor)     - ID of a MINOR (Slot=0xff)
 *   GR1553BC_MAJOR_ID(major)           - ID of a Major (Minor=0xff,Slot=0xff)
 *
 * The typical approach create lists is in the following order:
 *   -# gr1553bc_list_alloc(&list, MAJOR_CNT)
 *   -# gr1553bc_list_config(list, &listcfg)
 *   -# Create all Major Frames and Minor frame, for each major frame:
 *       a) gr1553bc_major_alloc_skel(&major, &major_minor_cfg)
 *       b) gr1553bc_list_set_major(list, &major, MAJOR_NUM)
 *   -# link end Major Frames together:
 *       a) gr1553bc_list_set_major(&major7, &major0)   // Connect Major frames
 *   -# gr1553bc_list_table_alloc()   (Allocate Descriptor Table)
 *   -# gr1553bc_list_table_build()   (Build Descriptor Table from Majors/Minors)
 *   -# Allocate and initialize Descriptors pre defined before starting:
 *      -## gr1553bc_slot_alloc(list, &MID, TIME_REQUIRED, ..)
 *      -## gr1553bc_slot_transfer(MID, ...)
 *   -# START BC HARDWARE BY SHCDULING ABOVE LIST
 *   -# Operate on List
 *
 *
 * \section bc_list_update Changing a scheduled BC list (during BC-runtime)
 *
 *  One can use the INDICATION service to avoid modifying
 *  a descriptor currently in use by the BC core. One can also in most cases
 *  do descriptor initialization in three steps: Init Descriptor as Dummy 
 *  with and allocated time (often done before starting/scheduling list),
 *  then modify transfer options and data-pointers, then clear the Dummy
 *  bit in one atomic data store. This approach will avoid potential races
 *  between software has hardware.
 *
 *
 * \section bc_memory_setup Custom Memory Setup
 *
 *  For designs where dynamically memory is not an option, or the driver
 *  is used on a AMBA-over-PCI bus (where malloc() does not work), the
 *  API allows the user to provide custom addresses for descriptor table
 *  and object descriptions (lists, major frames, minor frames). Custom
 *  descriptor table is probably the most interesting thing for most, it
 *  is setup with gr1553bc_list_table_alloc(list, CUSTOM_ADDRESS).
 *
 *  Object descriptions are normally allocated during initialization
 *  procedure by providing the API with a object configuration, for 
 *  example a Major Frame configuration enables the API to allocate
 *  the software description of a Major Frame with all it's Minor frames.
 *
 *
 * \section major Major Frame
 *
 *  Consists of multiple Minor frames. A Major frame may be connected/linked
 *  with another Major frame, this will result in a Jump Slot from last
 *  Minor frame in the first Major to the first Minor in the second Major.
 *
 *
 * \section minor Minor Frame
 *
 *  Consists of up to 32 Message Slots. The services are Time-Management and
 *  Slot allocation.
 *
 *  Time-Management is optional.
 *
 *  Time-Slot-Management can be enabled per Minor frame. A Minor frame can be
 *  assigned a time in microseconds. The BC will not continue to the next
 *  Minor frame until the time has passed. It is managed by adding an extra
 *  Dummy Message Slot with the total minor frame time. Each time a message
 *  Slot is allocated (with a certain time: Slot-Time) the Slot-Time will
 *  be decremented from the total time of the Minor frame. This way the
 *  sum of the Message Slot will always sum up to the total time of the
 *  Minor configuration. When a message slot is freed, the Dymmy Message
 *  Slot's Slot-Time is incremented with the freed Slot-Time.
 *
 *  A Message Slot can be allocated by identifying a specific free Slot
 *  by the MID (Message-ID) or by letting the API allocate the first free
 *  Slot in the Minor Frame (Set MID Slot-ID to 0xff to identify Minor
 *  Frame).
 *
 *
 * \section slot Message Slot
 *
 *  The GR1553B BC core supports two Slot (Descriptor) Types:
 *   - Transfer descriptor
 *   - Condition descriptor (Jump, unconditional-IRQ)
 *
 *  See the hardware manual for a detail description of a descriptor (Slot).
 *
 *  The BC Core is unaware of lists, it steps through executing each 
 *  descriptor as the encountered, Conditionals resulting in jumps may
 *  let us to create more complex arrangements of buffer descriptos (BDs)
 *  which we call list.
 *
 *  Transfer BDs (TBDs) may have a time slot assigned, the BC core will wait
 *  until the time has expired before executing the next descriptor. Time
 *  slots are handled by a Minor frame in the list.
 *
 *  A Message Slot is allocated using the gr1553bc_slot_alloc() function,
 *  and configured by calling one of the below functions:
 *   - gr1553bc_slot_irq_prepare   [unconditional IRQ slot]
 *   - gr1553bc_slot_jump          [unconditional jump]
 *   - gr1553bc_slot_exttrig       [Dummy transfer, wait for EXTERNAL-TRIGGER]
 *   - gr1553bc_slot_transfer      [Transfer descriptor]
 *   - gr1553bc_slot_empty         [Create Dummy Transfer descriptor]
 *   - gr1553bc_slot_raw           [Custom Descriptor handling]
 *
 *   - gr1553bc_slot_dummy         [Set existing Transfer descriptor to Dummy]
 *   - gr1553bc_slot_update        [Update DataPointer|Status of a TBD]
 *
 *
 * \section bc_IRQ Interrupt Handling
 *
 * There are different types of interrupts, Error IRQs or transfer IRQs. The
 * Error IRQs are handled by the driver can a callback function is called. 
 *
 * Transfer Descriptors can be programmed to generate interrupt, and
 * condition descriptors can be programmed to generate interrupt
 * unconditionaly (there exists more conditional types). When a Transfer
 * descriptor causes IRQ the general ISR callback of the BC driver is 
 * called to let the user handle the interrupt. When a condition descriptor
 * causes an IRQ a custom IRQ handler is called (if assigned).
 *
 * Transfers descriptor IRQ is enabled by configuring the descriptor.
 *
 * The API provides functions for placing unconditional IRQ points anywhere
 * in the list. The order:
 *   -# gr1553bc_slot_alloc(&MID, TIME=0, ..)
 *   -# gr1553bc_slot_irq_prepare(MID, funcISR, data)
 *   -# gr1553bc_slot_irq_enable(MID)
 * 
 * \verbatim
 *  void funcISR(*bd, *data)
 *  {
 *    // HANDLE ONE OR MULTIPLE DESCRIPTORS (MULTIPLE IN THIS EXAMPLE):
 *    int MID;
 *    gr1553bc_mid_from_bd(bd,&MID,NULL);
 *    printf("IRQ ON %06x\n", MID);
 *  }
 * \endverbatim
 *
 * \ingroup GR1553BC
 */

#include <stdint.h>
#include <bsp/gr1553bc.h>

/**** CONFIGURATION OPTIONS ****/

/* Define GR1553BC_TIMESLOT to make driver take care of time
 * management of minor frames.
 */
#define GR1553BC_TIMESLOT

#define GR1553BC_MINOR_MAX 256
#define GR1553BC_SLOT_MAX 32

#ifdef __cplusplus
extern "C" {
#endif

struct gr1553bc_list;
struct gr1553bc_major;
struct gr1553bc_minor;
struct gr1553bc_minor_cfg;
struct gr1553bc_major_cfg;

struct gr1553bc_minor_cfg {
	int slot_cnt;
	int timeslot;		/* Total time of minor frame in us */
};

struct gr1553bc_major_cfg {
	int minor_cnt;				/* Number of Minor Frames */
	struct gr1553bc_minor_cfg minor_cfgs[1];
};

struct gr1553bc_list_cfg {
	unsigned char rt_timeout[31];	/* Number of us timeout tolerance per RT */
	unsigned char bc_timeout;	/* Number of us timeout tolerance of 
					 * broadcast transfers */
	int tropt_irq_on_err;		/* Generate IRQ on transfer error */
	int tropt_pause_on_err;		/* Pause list on transfer error */
	int async_list;			/* Set to non-zero if asyncronous list*/
};

/* Default Configuration */
extern struct gr1553bc_list_cfg gr1553bc_def_cfg;

/* Complete list of all major frames */
struct gr1553bc_list {
	void *_table_custom;		/* Config option given by user */
	void *_table;			/* address of allocated bd-table */
	unsigned int table_hw;		/* Descriptor table base HW-ADR */
	unsigned int table_cpu;		/* Descriptor table base CPU-ADR */
	int table_size;			/* Descriptor Table Size */
	void *bc;			/* BC HW, needed for adr translation */
	unsigned char rt_timeout[32];	/* Tolerance per RT, default 20us
					 * Note: 31 is for Broadcast */
	uint32_t tropts;		/* Transfer descriptor options:
					 *  On transfer error the following bits
					 *  do affect:
					 *  - bit28 1=Generate IRQ
					 *  - bit26 1=Pause transfer list
					 *  
					 */
	int async_list;			/* async list or not */
	int major_cnt;			/* Number of Major frames */
	struct gr1553bc_major *majors[1];	/* Var-Array of Major Pointers*/
};

/* Alloc a List with a maximum number of Major frames supported */
extern int gr1553bc_list_alloc(struct gr1553bc_list **list, int max_major);

/* Free List if allocated with gr1553bc_list_alloc() */
extern void gr1553bc_list_free(struct gr1553bc_list *list);

/* Configure Global List parameters 
 *
 * \param list    List to be configured and initialized.
 * \param cfg     List Configuration
 * \param bc      The BC hardware device description
 *                  (only needed for address translation)
 */
extern int gr1553bc_list_config
	(
	struct gr1553bc_list *list,
	struct gr1553bc_list_cfg *cfg,
	void *bc
	);

/* Link a 'major' Major frame with next major frame 
 * The links affected:
 *   - major->next
 *   - major->minor[LAST]->next
 */
extern void gr1553bc_list_link_major(
	struct gr1553bc_major *major,
	struct gr1553bc_major *next
	);

/* Link in a Major frame into a BC list.
 * Calls gr1553bc_list_link_major() to link major frame with major-1 and
 * major+1. If ending or starting major frame the frame is wrapped around.
 */
extern int gr1553bc_list_set_major(
	struct gr1553bc_list *list,
	struct gr1553bc_major *major,
	int no);

/* Calculate the size required in the descriptor table by one minor frame. */
extern int gr1553bc_minor_table_size(struct gr1553bc_minor *minor);

/* Calculate the size required for the descriptor table.
 */
extern int gr1553bc_list_table_size(struct gr1553bc_list *list);

/* Allocate an empty descriptor table from list description suitable for
 * the BC given by 'bc'.
 *
 * \param bdtab_custom   Custom Descriptor Allocation options:
 *                         ZERO: Dynamically allocated by Driver (CPU near RAM)
 *                         Non-Zero: Use provided address as BASE of BD-TABLE
 *                         Non-Zero with LSB set: Same as Non-Zero but address
 *                          is given as HW address (used with AMBA-over-PCI to
 *                          to specify RAM location on PCI board).
 */
extern int gr1553bc_list_table_alloc
	(
	struct gr1553bc_list *list,
	void *bdtab_custom
	);

/* Free descriptor table allocated with gr1553bc_list_table_alloc() */
extern void gr1553bc_list_table_free(struct gr1553bc_list *list);

/* Build an empty descriptor table from list description, 
 * the minor frames will be linked together.
 */
extern int gr1553bc_list_table_build(struct gr1553bc_list *list);

/* Major Frame */
struct gr1553bc_major {
	struct gr1553bc_major *next;		/* Next Major Frame */
	struct gr1553bc_major_cfg *cfg;		/* User Config of Major frame */
	struct gr1553bc_minor *minors[1];	/* Minor frames */
};

/* Minor Frame */
struct gr1553bc_minor {
	struct gr1553bc_minor *next;	/* Next Minor Frame */
	struct gr1553bc_minor_cfg *cfg;	/* User Config of Minor frame */
	uint32_t alloc;			/* Descripts allocated */

	/* Note: THIS POINTER MUST BE ALIGNED ON A 128-bit BOUNDARY */
	union gr1553bc_bd *bds;	/* Descriptors for this minor frame (CPU ADRS)*/
};

/* Alloc a Major/Minor frame skeleton according to the configuration structure. 
 * The descriptor table is not allocated.
 */
extern int gr1553bc_major_alloc_skel
	(
	struct gr1553bc_major **major,
	struct gr1553bc_major_cfg *cfg
	);

/* Unique Message/Descriptor ID. Can be used to identify a Major or Minor 
 * Frame, or a Slot.
 *
 * - If minor_num is 0xff, the ID identifies a Major Frame
 * - If slot_num is 0xff, the ID identifies a Minor Frame
 * - If non of the above is true, the ID identifies a specific Slot
 */
#define GR1553BC_ID(major_num, minor_num, slot_num) \
		((((major_num)<<16)&0xff0000) | (((minor_num)<<8)&0xff00) | \
		((slot_num) & 0xff))
#define GR1553BC_MINOR_ID(major_num, minor_num) \
		GR1553BC_ID(major_num, minor_num, 0xff)
#define GR1553BC_MAJOR_ID(major_num) \
		GR1553BC_ID(major_num, 0xff, 0xff)

#define GR1553BC_MAJID_FROM_ID(mid) (((mid) >> 16) & 0xff)
#define GR1553BC_MINID_FROM_ID(mid) (((mid) >> 8) & 0xff)
#define GR1553BC_SLOTID_FROM_ID(mid) ((mid) & 0xff)
#define GR1553BC_ID_SET_SLOT(mid, slot_num) (((mid) & ~0xff) | ((slot_num) & 0xff))

extern struct gr1553bc_major *gr1553bc_major_from_id
	(
	struct gr1553bc_list *list,
	int mid
	);

extern struct gr1553bc_minor *gr1553bc_minor_from_id
	(
	struct gr1553bc_list *list,
	int mid
	);

/* Get free time left of minor frame identified by MID 'mid' */
extern int gr1553bc_list_freetime(struct gr1553bc_list *list, int mid);

/* Get free time left of minor frame */
extern int gr1553bc_minor_freetime(struct gr1553bc_minor *minor);

/* Allocate a time slot on a minor frame, major/minor frame is identified 
 * by MID. The 'mid' is a input/ouput parameter, the resulting slot taken
 * will be placed in 'mid', a pointer to the allocated descriptor is stored
 * into bd.
 *
 * Major/Minor must be specified by MID, if slot is specified that slot will
 * be allocated, if slot is 0xff, then the first free slot is allocated.
 *
 * The function fails (return negative) if timeslot is longer than remaining
 * time in minor frame, if no more slots are available in minor frame, if 
 * MID points to a bad major/minor or major/minor/slot.
 */
extern int gr1553bc_slot_alloc(
	struct gr1553bc_list *list,
	int *mid,
	int timeslot,
	union gr1553bc_bd **bd
	);
/* Same as gr1553bc_slot_alloc but identifies a minor instead of list.
 * The major/minor part of MID is ignored.
 */
extern int gr1553bc_slot_alloc2(
	struct gr1553bc_minor *minor,
	int *mid,
	int timeslot,
	union gr1553bc_bd **bd
	);

/* Free message slot and the time associated with it. The time taken by the
 * message slot is added to the END TIME descriptor, if managed by the driver
 * for this minor frame. The descriptor will be 
 */
extern int gr1553bc_slot_free(struct gr1553bc_list *list, int mid);
extern int gr1553bc_slot_free2(struct gr1553bc_minor *minor, int mid);

/* Find MID from Descriptor pointer
 *
 * In the end of each minor frame is a unconditional jump 
 * to next minor frame descriptor. The hardware does not
 * use the last 8 bytes of conditional descriptors, in the
 * padding area a MID is stored so that we can lookup the
 * MID of a descriptor. This function finds the jump
 * descriptor and subtracs the offset from it.
 *
 * A faster way of looking up can be implemented if the
 * list is symertical, however in the current setup we
 * allow different numbers of slots in minor frames, and
 * different number of minor frames in a major frame.
 *
 * \param bd     IN: Descriptor to lookup MID of (CPU address of BD)
 * \param mid    OUT: Pointer to where Message-ID (Slot-ID) will be stored
 * \param async  OUT: Function will store non-zero value if BD belogs to 
 *                    async list.
 */
extern int gr1553bc_mid_from_bd(
	union gr1553bc_bd *bd,
	int *mid,
	int *async
	);

/********** TRANSFER DESCRIPTOR MANIPULATION **********/

/* Get pointer to descriptor entry from MID. */
extern union gr1553bc_bd *gr1553bc_slot_bd
	(
	struct gr1553bc_list *list,
	int mid
	);

/* IRQ function */
typedef void (*bcirq_func_t)(union gr1553bc_bd *bd, void *data);

/* Create unconditional IRQ customly defined location.
 * The IRQ is disabled, enable it with gr1553bc_slot_irq_enable().
 */
extern int gr1553bc_slot_irq_prepare
	(
	struct gr1553bc_list *list,
	int mid,
	bcirq_func_t func,
	void *data
	);

/* Enable previously prepared unconditional IRQ */
extern int gr1553bc_slot_irq_enable(struct gr1553bc_list *list, int mid);

/* Disable unconditional IRQ point, changed to unconditional JUMP
 * to descriptor following.
 * After disabling it it can be enabled again, or freed.
 */
extern int gr1553bc_slot_irq_disable(struct gr1553bc_list *list, int mid);

/* Create custom jump to descriptor, conditional or unconditional, see 
 * hardware manual for conditions.
 *
 * set conditional to GR1553BC_UNCOND_JMP for unconditional jump.
 */
extern int gr1553bc_slot_jump
	(
	struct gr1553bc_list *list,
	int mid,
	uint32_t condition,
	int to_mid
	);

/* Create a dummy transfer, paused until external trigger is set. The
 * Slot is will have the dummy bit set, no transfer will take place.
 */
extern int gr1553bc_slot_exttrig(struct gr1553bc_list *list, int mid);

/* Create a transfer on a previous allocated descriptor. It is assumed
 * that the descriptor has been initialized empty before calling this
 * function, this is to avoid races.
 *
 * The settings that are controlled on a global level (and not
 * by this function):
 *  - IRQ after transfer error
 *  - IRQ after transfer (not supported, insert separate IRQ slot after this)
 *  - Pause schedule after transfer error
 *  - Pause schedule after transfer (not supported)
 *  - slot time optional (set when MID allocated), otherwise 0
 *  - (OPTIONAL) Dummy Bit, set using slot_empty() or ..._TT_DUMMY
 *  - RT timeout tolerance (managed per RT)
 *
 *  Input Parameters:
 *  - Retry Mode			(options)
 *  - Number of retires			(options)
 *  - Bus selection (A or B)		(options)
 *  - dummy bit				(options)
 *  - transfer type			(tt)
 *  - rt src/dst address		(tt)
 *  - RT subaddress			(tt)
 *  - word count			(tt)
 *  - mode code				(tt)
 *  - data pointer			(dptr)
 *
 *
 * See macros defined in this header file for creating transfer types (tt)
 * and word count etc.
 *
 * See macros defined in this header file for creating the mask of options.
 *
 * Note that if bit0 (LSB) of dptr is set, then the address is translated into
 * hardware address, otherwise the dptr is assumed to be accessible from the
 * 1553 core. This is an option only for AMBA-over-PCI.
 */
extern int gr1553bc_slot_transfer(
	struct gr1553bc_list *list,
	int mid,
	int options,
	int tt,
	uint16_t *dptr);

/* Remove or set dummy bit of a transfer descriptor
 * Bit31 of *dummy is written to the dummy bit, the 
 * old descriptor value is stored into *dummy.
 */
extern int gr1553bc_slot_dummy(
	struct gr1553bc_list *list,
	int mid,
	unsigned int *dummy);

/* Make a slot empty (BC will not generate bus transfers), time slot 
 * allocated is untouched (if assigned).
 */
extern int gr1553bc_slot_empty(struct gr1553bc_list *list, int mid);

/* Transfer descriptor status and/or update Transfer descriptor data pointer.
 *
 * Read and/or write Status of a slot. Writing the status word may be
 * used by software to indicate that result has been handled, or bit 31
 * may be written 1 telling software that when it reaches 0, then BC
 * has executed the request.
 *
 * Operation:
 *  bd->status = *stat & (bd->status 0xffffff) | (*stat & 0x80000000);
 *  *stat = Value of bd->status before rewrite.
 *
 * Note that the status word is not written when *stat is zero.
 *
 * Note that if bit0 (LSB) of dptr is set, then the address is translated into
 * hardware address, otherwise the dptr is assumed to be accessible from the
 * 1553 core. This is an option only for AMBA-over-PCI.
 */
extern int gr1553bc_slot_update(
	struct gr1553bc_list *list,
	int mid,
	uint16_t *dptr,
	unsigned int *stat);

/* Modify a transfer descriptor in any way,
 * 
 * flags:
 *  bit[N=0..3]: 1 = set BD wordN according to argument wordN,
 *               0 = do not modify BD wordN
 */
extern int gr1553bc_slot_raw
	(
	struct gr1553bc_list *list,
	int mid,
	unsigned int flags,
	uint32_t word0,
	uint32_t word1,
	uint32_t word2,
	uint32_t word3
	);


/***** Macros to create BC Transfer Types (tt) for gr1553bc_slot_transfer() *****/

/* WRITE TO RT (BC-to-RT) */
#define GR1553BC_BC2RT(rtadr, subadr, word_count) \
		((rtadr<<11) | (subadr<<5) | (0x1f<<21) | (0<<10) | \
		((word_count>=32) ? 0 : word_count))

/* READ FROM RT (RT-to-BC) */
#define GR1553BC_RT2BC(rtadr, subadr, word_count) \
		((rtadr<<11) | (subadr<<5) | (0x1f<<21) | (1<<10) | \
		((word_count>=32) ? 0 : word_count))

/* RT(TX) WRITE TO RT(RX) (RT-to-RT) */
#define GR1553BC_RT2RT(tx_rtadr, tx_subadr, rx_rtadr, rx_subadr, word_count) \
		((rx_rtadr<<11) | (rx_subadr<<5) | \
		(tx_rtadr<<21) | (tx_subadr<<16) | \
		(0<<10) | \
		((word_count>=32) ? 0 : word_count))

/* Mode command without data. (BC-to-RT)
 * Mode code: 0,1,2,3,4,5,6,7 or 8.
 */
#define GR1553BC_MC_NODATA(rtadr, modecode) \
		((rtadr<<11) | (0x1f<<5) | (0x1f<<21) | \
		(modecode<<0) | (1<<10))

/* Mode command with 4 byte data (RT-to-BC)
 * Mode code: 16, 18 or 19.
 */
#define GR1553BC_MC_RT2BC(rtadr, modecode) \
		((rtadr<<11) | (0x1f<<5) | (0x1f<<21) | \
		(modecode<<0) | (1<<10))

/* Mode command with 4 byte data (BC-to-RT)
 * Mode code: 17, 20 or 21.
 */
#define GR1553BC_MC_BC2RT(rtadr, modecode) \
		((rtadr<<11) | (0x1f<<5) | (0x1f<<21) | \
		(modecode<<0) | (0<<10))

/* Broadcast to all RTs, to a specific subaddress (BC-to-RTs) */
#define GR1553BC_BC_BC2RT(subadr, word_count) \
		((0x1f<<11) | (subadr<<5) | (0x1f<<21) | \
		(0<<10) | \
		((word_count>=32) ? 0 : word_count))

/* Request RT to broadcast to all RTs, to a specific subaddress (RT-to-RTs) */
#define GR1553BC_BC_RT2RT(tx_rtadr, tx_subadr, rx_subadr, word_count) \
		((0x1f<<11) | (rx_subadr<<5) | \
		(tx_rtadr<<21) | (tx_subadr<<16) | \
		(0<<10) | \
		((word_count>=32) ? 0 : word_count))

/* Broadcast mode command without data (BC-to-RTs) 
 * Mode code: 1,3,4,5,6,7 or 8
 */
#define GR1553BC_BC_MC_NODATA(modecode) \
		((0x1f<<11) | (0x1f<<5) | (0x1f<<21) | \
		((modecode)<<0) | (1<<10))

/* Broadcast mode command with 4 byte data (BC-to-RTs)
 * Mode code: 17, 20 or 21
 */
#define GR1553BC_BC_MC_BC2RT(modecode) \
		((0x1f<<11) | (0x1f<<5) | (0x1f<<21) | \
		((modecode)<<0) | (0<<10))


/***** Macros to create BC options (options) for gr1553bc_slot_transfer() *****/

/* Dummy (BC does no bus trasactions) */
#define GR1553BC_OPT_DUMMY (1<<1)

/* Retry modes */
#define GR1553BC_RETRY_SAME	0x0	/* Retry on the same bus only */
#define GR1553BC_RETRY_ALTER	0x1	/* Retry alternating on both busses */
#define GR1553BC_RETRY_ATTEMPT	0x2	/* Many attepts first on original 
					 * bus then on other bus */
/* Number of retires supported */
#define GR1553BC_RETRY_CNT_MAX	6

/* Dummy bit: No transfer
 * Bus bit: 0=A, 1=B
 * Exttrig bit: Wait for external trigger (used for timesync)
 * Exclusive bit: 1=Don't allow other messages in this time slot.
 */
#define GR1553BC_OPTIONS(dummy, exttrig, exclusive, retrymode, nretry, bus) \
		((((exttrig) & 0x1) << 30) | (((exclusive) & 0x1) << 29) | \
		((retrymode) << 23) | ((nretry) << 20) | \
		((bus) & 1) | (((dummy) & 0x1) << 1))

#define GR1553BC_OPTIONS_BUSA GR1553BC_OPTIONS(0,0,0,GR1553BC_RETRY_SAME,0,0)
#define GR1553BC_OPTIONS_BUSB GR1553BC_OPTIONS(0,0,0,GR1553BC_RETRY_SAME,0,1)
#define GR1553BC_OPTIONS_BUSA_DUM GR1553BC_OPTIONS(1,0,0,GR1553BC_RETRY_SAME,0,0)
#define GR1553BC_OPTIONS_BUSB_DUM GR1553BC_OPTIONS(1,0,0,GR1553BC_RETRY_SAME,0,1)

/* Show parts of a list - this is for debugging only */
extern void gr1553bc_show_list(struct gr1553bc_list *list, int options);

#ifdef __cplusplus
}
#endif

#endif /* __GR1553BC_LIST_H__ */