TEMU  3.0
The Terma Emulator
MilStd1553.h
Go to the documentation of this file.
1 //===------------------------------------------------------------*- C++ -*-===//
2 //
3 // TEMU: The Terma Emulator
4 // (c) Terma 2015
5 // Authors: Mattias Holm <maho (at) terma.com>
6 //
7 //===----------------------------------------------------------------------===//
8 
29 #ifndef TEMU_MIL_STD_1553_H
30 #define TEMU_MIL_STD_1553_H
31 
32 #include "temu-c/Support/Objsys.h"
33 
34 #include <assert.h>
35 #include <stdbool.h>
36 #include <stdint.h>
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 typedef enum temu_Mil1553Error {
45  teME_SyncError = 1 << 1
47 
48 // The bus model must register who is the BC, and who is
49 // the receiving terminal.
50 typedef enum temu_Mil1553MsgType {
55 
56 #define TEMU_1553_MSG_FLAG_INHIBIT_A 0x1
57 #define TEMU_1553_MSG_FLAG_INHIBIT_B 0x2
58 
59 typedef struct temu_Mil1553Msg {
60  uint8_t WordCount; // Number of words in the data block
62  MsgTyp; // Pre-computed for convenience, otherwise we need
63  // to construct nasty state machines for every model
64  temu_Mil1553Error Err; // We can inject errors in every message. The
65  // interpretation is up to the model, but typically:
66  // parity error applies to command or status word if
67  // cmd or stat type message, and to the last data word,
68  // if the msg is a data transaction.
69  uint16_t *Data; // Pointer to data block (contains data, command or status)
70 
71  uint32_t Flags;
73 
74 // Compute message transfer time in nanoseconds
75 // 1553 bus is 1 Mb/sec and we have 16 + 4 bits per word.
76 #define TEMU_1553_NS_PER_WORD 20000
77 static inline uint64_t
78 temu_mil1553TransferTime(unsigned Words)
79 {
80  uint64_t Nanos = Words * TEMU_1553_NS_PER_WORD;
81  return Nanos;
82 }
83 
84 #define TEMU_1553_BITS_PER_WORD 20
85 static inline uint64_t
86 temu_mil1553BitCount(unsigned Words)
87 {
88  return Words * TEMU_1553_BITS_PER_WORD;
89 }
90 
91 // Conveniance functions to extract fields from the command word
92 
93 static inline uint16_t
94 temu_mil1553CmdRtAddr(temu_Mil1553Msg *Msg)
95 {
96  return (Msg->Data[0] >> 11) & 0x1f;
97 }
98 
99 static inline uint16_t
100 temu_mil1553CmdTR(temu_Mil1553Msg *Msg)
101 {
102  return (Msg->Data[0] >> 10) & 1;
103 }
104 
105 static inline uint16_t
106 temu_mil1553CmdSubAddr(temu_Mil1553Msg *Msg)
107 {
108  return (Msg->Data[0] >> 5) & 0x1f;
109 }
110 
111 static inline uint16_t
112 temu_mil1553CmdWCMC(temu_Mil1553Msg *Msg)
113 {
114  return Msg->Data[0] & 0x1f;
115 }
116 
117 // Return non-zero if the command is a mode command (sub addr == 0 or 0x1f)
118 
119 static inline int
120 temu_mil1553CmdIsModeCodeCmd(temu_Mil1553Msg *Msg)
121 {
122  if (temu_mil1553CmdSubAddr(Msg) == 0x00 ||
123  temu_mil1553CmdSubAddr(Msg) == 0x1f) {
124  return 1;
125  }
126 
127  return 0;
128 }
129 
130 // Construct a bus message object from a 1553 command word
131 static inline temu_Mil1553Msg
132 temu_mil1553CreateCmd(uint16_t *Cmd)
133 {
134  temu_Mil1553Msg Msg;
135  Msg.WordCount = 1;
136  Msg.Err = teME_NoError;
137  Msg.Data = Cmd;
138  Msg.MsgTyp = teMT_Cmd;
139  Msg.Flags = 0;
140  return Msg;
141 }
142 
143 // Create mode code command (with mode = 0)
144 static inline temu_Mil1553Msg
145 temu_mil1553CreateModeTransmittMsg0(uint16_t *Mode, uint16_t RTAddr,
146  uint16_t MC)
147 {
148  temu_Mil1553Msg Msg;
149  Msg.WordCount = 1;
150  Msg.MsgTyp = teMT_Cmd;
151  Msg.Err = teME_NoError;
152  *Mode = (RTAddr << 11) | (1 << 10) | MC;
153  Msg.Data = Mode;
154  Msg.Flags = 0;
155  return Msg;
156 }
157 
158 // Create mode code command (with mode = 0)
159 static inline temu_Mil1553Msg
160 temu_mil1553CreateModeRecvMsg0(uint16_t *Mode, uint16_t RTAddr, uint16_t MC)
161 {
162  temu_Mil1553Msg Msg;
163  Msg.WordCount = 1;
164  Msg.MsgTyp = teMT_Cmd;
165  Msg.Err = teME_NoError;
166  *Mode = (RTAddr << 11) | MC;
167  Msg.Data = Mode;
168  Msg.Flags = 0;
169  return Msg;
170 }
171 
172 // Create mode code command (with mode = 0x1f)
173 static inline temu_Mil1553Msg
174 temu_mil1553CreateModeTransmittMsg1(uint16_t *Mode, uint16_t RTAddr,
175  uint16_t MC)
176 {
177  temu_Mil1553Msg Msg;
178  Msg.WordCount = 1;
179  Msg.MsgTyp = teMT_Cmd;
180  Msg.Err = teME_NoError;
181  *Mode = (RTAddr << 11) | (1 << 10) | (0x1f << 5) | MC;
182  Msg.Data = Mode;
183  Msg.Flags = 0;
184  return Msg;
185 }
186 
187 // Create mode code command (with mode = 0x1f)
188 static inline temu_Mil1553Msg
189 temu_mil1553CreateModeRecvMsg1(uint16_t *Mode, uint16_t RTAddr, uint16_t MC)
190 {
191  temu_Mil1553Msg Msg;
192  Msg.WordCount = 1;
193  Msg.MsgTyp = teMT_Cmd;
194  Msg.Err = teME_NoError;
195  *Mode = (RTAddr << 11) | (0x1f << 5) | MC;
196  Msg.Data = Mode;
197  Msg.Flags = 0;
198  return Msg;
199 }
200 
201 static inline temu_Mil1553Msg
202 temu_mil1553CreateStatMsg(uint16_t *Stat, uint16_t RTAddr)
203 {
204  temu_Mil1553Msg Msg;
205  Msg.WordCount = 1;
206  Msg.MsgTyp = teMT_Stat;
207  Msg.Err = teME_NoError;
208  *Stat = RTAddr << 11;
209  Msg.Data = Stat;
210  Msg.Flags = 0;
211  return Msg;
212 }
213 
214 static inline temu_Mil1553Msg
215 temu_mil1553CreateDataMsg(uint16_t *Data, size_t Words)
216 {
217  temu_Mil1553Msg Msg;
218  Msg.WordCount = Words;
219  Msg.MsgTyp = teMT_Data;
220  Msg.Err = teME_NoError;
221  Msg.Data = Data;
222  Msg.Flags = 0;
223  return Msg;
224 }
225 
226 static inline temu_Mil1553Msg
227 temu_mil1553CreateRecvCmdMsg(uint16_t *CmdWord, uint16_t RTAddr,
228  uint16_t SubAddr, uint16_t Words)
229 {
230  temu_Mil1553Msg Msg;
231  Msg.WordCount = 1;
232  Msg.MsgTyp = teMT_Cmd;
233  Msg.Err = teME_NoError;
234  Msg.Data = CmdWord;
235  *CmdWord = (RTAddr << 11) | (SubAddr << 5) | (Words & 0x1f);
236  Msg.Flags = 0;
237  return Msg;
238 }
239 
240 static inline temu_Mil1553Msg
241 temu_mil1553CreateTransmittCmdMsg(uint16_t *CmdWord, uint16_t RTAddr,
242  uint16_t SubAddr, uint16_t Words)
243 {
244  temu_Mil1553Msg Msg;
245  Msg.WordCount = 1;
246  Msg.MsgTyp = teMT_Cmd;
247  Msg.Err = teME_NoError;
248  Msg.Data = CmdWord;
249  *CmdWord = (RTAddr << 11) | (1 << 10) | (SubAddr << 5) | (Words & 0x1f);
250  Msg.Flags = 0;
251  return Msg;
252 }
253 
256 TEMU_IFACE_REFERENCE_TYPE(temu_Mil1553Dev);
257 TEMU_IFACE_REFERENCE_TYPE(temu_Mil1553Bus);
258 
261  // To be implemented in the future:
262  // teMBR_FaultyRT = 1,
263  // teMBR_BusTimeOut = 1 << 1
265 
266 typedef struct {
269 
272  void (*connected)(void *Device, temu_Mil1553BusIfaceRef Bus, int SubAddr);
274  void (*disconnected)(void *Device, temu_Mil1553BusIfaceRef Bus, int SubAddr);
275 
277  void (*receive)(void *Device, temu_Mil1553Msg *Msg);
279  void (*busEnteredIdle)(void *Bus, temu_Mil1553BusIdleInfo *idleInfo);
280 };
281 #define TEMU_MIL1553_DEV_IFACE_TYPE "Mil1553DevIface"
282 
284  void (*connect)(void *Bus, int RTAddr, temu_Mil1553DevIfaceRef Device);
285  void (*disconnect)(void *Bus, int RTAddr);
286  void (*reportStats)(void *Bus);
287  void (*send)(void *Bus, void *Sender, temu_Mil1553Msg *Msg);
288 
289  // Controls whether events should be issued at send calls
290  void (*enableSendEvents)(void *Bus);
291  void (*disableSendEvents)(void *Bus);
292  void (*setBusController)(void *Bus, temu_Mil1553DevIfaceRef Device);
293 };
294 #define TEMU_MIL1553_BUS_IFACE_TYPE "Mil1553BusIface"
295 
296 typedef struct {
297  uint64_t LastReportSentWords; // Number of words sent during last report
298  uint64_t SentWords; // Current number of sent words
300 
301 // For accessing 16 bit words
302 static inline uint16_t
303 temu_mil1553CmdWordRa(uint16_t Msg)
304 {
305  return (Msg >> 11) & 0x1f;
306 }
307 
308 static inline uint16_t
309 temu_mil1553CmdWordSa(uint16_t Msg)
310 {
311  return (Msg >> 5) & 0x1f;
312 }
313 
314 static inline uint16_t
315 temu_mil1553CmdWordTr(uint16_t Msg)
316 {
317  return (Msg >> 10) & 0x1;
318 }
319 
320 static inline uint16_t
321 temu_mil1553CmdWordCount(uint16_t Msg)
322 {
323  return Msg & 0x1f;
324 }
325 
326 static inline uint16_t
327 temu_mil1553ModeWordCode(uint16_t Msg)
328 {
329  return Msg & 0x1f;
330 }
331 
332 static inline uint16_t
333 temu_mil1553StatWordRtAddr(uint16_t Msg)
334 {
335  return (Msg >> 11) & 0x1f;
336 }
337 
338 static inline uint16_t
339 temu_mil1553StatWordME(uint16_t Msg)
340 {
341  return (Msg >> 10) & 1;
342 }
343 
344 static inline uint16_t
345 temu_mil1553StatWordInst(uint16_t Msg)
346 {
347  return (Msg >> 9) & 1;
348 }
349 
350 static inline uint16_t
351 temu_mil1553StatWordSR(uint16_t Msg)
352 {
353  return (Msg >> 8) & 1;
354 }
355 
356 static inline uint16_t
357 temu_mil1553StatWordBC(uint16_t Msg)
358 {
359  return (Msg >> 4) & 1;
360 }
361 
362 static inline uint16_t
363 temu_mil1553StatWordBusy(uint16_t Msg)
364 {
365  return (Msg >> 3) & 1;
366 }
367 
368 static inline uint16_t
369 temu_mil1553StatWordSubFlag(uint16_t Msg)
370 {
371  return (Msg >> 2) & 1;
372 }
373 
374 static inline uint16_t
375 temu_mil1553StatWordDynBusCtrl(uint16_t Msg)
376 {
377  return (Msg >> 1) & 1;
378 }
379 
380 static inline uint16_t
381 temu_mil1553StatWordTermFlag(uint16_t Msg)
382 {
383  return Msg & 1;
384 }
385 
386 // Accessing messages
387 static inline uint16_t
388 temu_mil1553CmdCount(temu_Mil1553Msg *Msg)
389 {
390  return Msg->Data[0] & 0x1f;
391 }
392 
393 static inline uint16_t
394 temu_mil1553ModeCode(temu_Mil1553Msg *Msg)
395 {
396  return Msg->Data[0] & 0x1f;
397 }
398 
399 static inline uint16_t
400 temu_mil1553StatRtAddr(temu_Mil1553Msg *Msg)
401 {
402  return (Msg->Data[0] >> 11) & 0x1f;
403 }
404 
405 static inline uint16_t
406 temu_mil1553StatME(temu_Mil1553Msg *Msg)
407 {
408  return (Msg->Data[0] >> 10) & 1;
409 }
410 
411 static inline uint16_t
412 temu_mil1553StatInst(temu_Mil1553Msg *Msg)
413 {
414  return (Msg->Data[0] >> 9) & 1;
415 }
416 
417 static inline uint16_t
418 temu_mil1553StatSR(temu_Mil1553Msg *Msg)
419 {
420  return (Msg->Data[0] >> 8) & 1;
421 }
422 
423 static inline uint16_t
424 temu_mil1553StatBC(temu_Mil1553Msg *Msg)
425 {
426  return (Msg->Data[0] >> 4) & 1;
427 }
428 
429 static inline uint16_t
430 temu_mil1553StatBusy(temu_Mil1553Msg *Msg)
431 {
432  return (Msg->Data[0] >> 3) & 1;
433 }
434 
435 static inline uint16_t
436 temu_mil1553StatSubFlag(temu_Mil1553Msg *Msg)
437 {
438  return (Msg->Data[0] >> 2) & 1;
439 }
440 
441 static inline uint16_t
442 temu_mil1553StatDynBusCtrl(temu_Mil1553Msg *Msg)
443 {
444  return (Msg->Data[0] >> 1) & 1;
445 }
446 
447 static inline uint16_t
448 temu_mil1553StatTermFlag(temu_Mil1553Msg *Msg)
449 {
450  return Msg->Data[0] & 1;
451 }
452 
453 static inline bool
454 temu_mil1553MsgInhibitBusA(const temu_Mil1553Msg *Msg)
455 {
456  return Msg->Flags & TEMU_1553_MSG_FLAG_INHIBIT_A;
457 }
458 
459 static inline bool
460 temu_mil1553MsgInhibitBusB(const temu_Mil1553Msg *Msg)
461 {
462  return Msg->Flags & TEMU_1553_MSG_FLAG_INHIBIT_B;
463 }
464 
465 // Useful constants, use temu_mil1553CmdMode() to extract bits,
466 // these constants are used for the optional mode control codes that
467 // are defined in the 1553 standard.
468 
469 #define TEMU_1553_TR_BIT 0x20
470 
471 #define TEMU_1553_DYN_BUS_CTRL 0x00
472 #define TEMU_1553_SYNC_NO_DATA 0x01
473 #define TEMU_1553_TRANSMIT_STATUS_WORD 0x02
474 #define TEMU_1553_INITIATE_SELF_TEST 0x03
475 #define TEMU_1553_TRANSMITTER_SHUTDOWN 0x04
476 #define TEMU_1553_OVERRIDE_TRANSMITTER 0x05
477 #define TEMU_1553_INHIBIT_TERM_FLAG_BIT 0x06
478 #define TEMU_1553_OVERRIDE_INHIBIT_TERM_FLAG_BIT 0x07
479 #define TEMU_1553_RESET_RT 0x08
480 #define TEMU_1553_TRANSMIT_VECTOR_WORD 0x10
481 #define TEMU_1553_SYNC_WITH_DATA 0x11
482 #define TEMU_1553_TRANSMIT_LAST_CMD 0x12
483 #define TEMU_1553_TRANSMIT_BIT_WORD 0x13
484 #define TEMU_1553_SELECTED_TRANSMITTER 0x14
485 #define TEMU_1553_OVERRIDE_SELECTED_TRANSMITTER 0x15
486 
487 #ifdef __cplusplus
488 }
489 #endif
490 
491 #endif /* ! TEMU_MIL_STD_1553_H */
struct temu_Mil1553Msg temu_Mil1553Msg
Definition: MilStd1553.h:44
void(* disableSendEvents)(void *Bus)
Definition: MilStd1553.h:291
uint32_t Flags
Definition: MilStd1553.h:71
Definition: MilStd1553.h:43
Definition: MilStd1553.h:270
Definition: MilStd1553.h:266
Definition: MilStd1553.h:53
void(* enableSendEvents)(void *Bus)
Definition: MilStd1553.h:290
#define TEMU_1553_NS_PER_WORD
Definition: MilStd1553.h:76
uint16_t * Data
Definition: MilStd1553.h:69
void(* connect)(void *Bus, int RTAddr, temu_Mil1553DevIfaceRef Device)
Definition: MilStd1553.h:284
Definition: MilStd1553.h:52
#define TEMU_1553_MSG_FLAG_INHIBIT_B
Definition: MilStd1553.h:57
void(* reportStats)(void *Bus)
Definition: MilStd1553.h:286
TEMU_IFACE_REFERENCE_TYPE(temu_Mil1553Dev)
void(* disconnected)(void *Device, temu_Mil1553BusIfaceRef Bus, int SubAddr)
Called after device is disconnected.
Definition: MilStd1553.h:274
temu_Mil1553MsgType
Definition: MilStd1553.h:50
void(* busEnteredIdle)(void *Bus, temu_Mil1553BusIdleInfo *idleInfo)
Notifies the bus controller the bus enters an idle.
Definition: MilStd1553.h:279
uint8_t WordCount
Definition: MilStd1553.h:60
temu_Mil1553MsgType MsgTyp
Definition: MilStd1553.h:62
temu_Mil1553Error Err
Definition: MilStd1553.h:64
Definition: MilStd1553.h:45
void(* setBusController)(void *Bus, temu_Mil1553DevIfaceRef Device)
Definition: MilStd1553.h:292
Definition: MilStd1553.h:296
#define TEMU_1553_MSG_FLAG_INHIBIT_A
Definition: MilStd1553.h:56
#define TEMU_1553_BITS_PER_WORD
Definition: MilStd1553.h:84
Definition: MilStd1553.h:59
Definition: MilStd1553.h:260
uint64_t LastReportSentWords
Definition: MilStd1553.h:297
void(* disconnect)(void *Bus, int RTAddr)
Definition: MilStd1553.h:285
void(* receive)(void *Device, temu_Mil1553Msg *Msg)
Receive of 1553 message.
Definition: MilStd1553.h:277
temu_Mil1553BusResetType
Definition: MilStd1553.h:259
temu_Mil1553BusResetType ResetType
Definition: MilStd1553.h:267
Definition: MilStd1553.h:51
uint64_t SentWords
Definition: MilStd1553.h:298
void(* send)(void *Bus, void *Sender, temu_Mil1553Msg *Msg)
Definition: MilStd1553.h:287
temu_Mil1553Error
Definition: MilStd1553.h:42
void(* connected)(void *Device, temu_Mil1553BusIfaceRef Bus, int SubAddr)
Called after device is connected to bus.
Definition: MilStd1553.h:272
Definition: MilStd1553.h:283