TEMU  4.4
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 
9 /*!
10  This is the 1553 device modelling API. It provides an interface to
11  be used for implementing bus controllers and remote terminals.
12 
13  The 1553 device interface is EXPERIMENTAL and UNSTABLE at the
14  moment.
15 
16  One limitation at the moment is that we do not support a specific
17  bus monitor interface. However, it is possible to get reports via
18  the "temu.mil1553send" event, this way you can sort of insert a
19  virtual bus monitor. It does not let you configure a terminal as a
20  bus monitor however. These events take an temu_Mil1553Msg pointer as
21  the event info argument.
22 
23  The 1553 bus is modeled on a phased message approach, this stem from
24  the capability of supporting RT->RT transfers. Without the phases,
25  each RT would need to have special logic to decode whether data is
26  from the BC or an RT (i.e. is the first word a command or a status
27  word).
28  */
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
46 } temu_Mil1553Error;
47 
48 // The bus model must register who is the BC, and who is
49 // the receiving terminal.
50 typedef enum temu_Mil1553MsgType {
54 } 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
61  temu_Mil1553MsgType
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;
72 } temu_Mil1553Msg;
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 
254 typedef struct temu_Mil1553DevIface temu_Mil1553DevIface;
255 typedef struct temu_Mil1553BusIface temu_Mil1553BusIface;
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
264 } temu_Mil1553BusResetType;
265 
266 typedef struct {
267  temu_Mil1553BusResetType ResetType;
268 } temu_Mil1553BusIdleInfo;
269 
271  //! Called after device is connected to bus
272  void (*connected)(void *Device, temu_Mil1553BusIfaceRef Bus, int RemoteTerminalAddr);
273  //! Called after device is disconnected
274  void (*disconnected)(void *Device, temu_Mil1553BusIfaceRef Bus, int RemoteTerminalAddr);
275 
276  //! Receive of 1553 message
277  void (*receive)(void *Device, temu_Mil1553Msg *Msg);
278  //! Notifies the bus controller the bus enters an idle
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
299 } temu_Mil1553Stats;
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 {
457 }
458 
459 static inline bool
460 temu_mil1553MsgInhibitBusB(const temu_Mil1553Msg *Msg)
461 {
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 */
temu_Mil1553BusIface::enableSendEvents
void(* enableSendEvents)(void *Bus)
Definition: MilStd1553.h:290
teME_NoError
@ teME_NoError
Definition: MilStd1553.h:43
temu_Mil1553Msg::Flags
uint32_t Flags
Definition: MilStd1553.h:71
temu_Mil1553BusIface::disconnect
void(* disconnect)(void *Bus, int RTAddr)
Definition: MilStd1553.h:285
teMT_Stat
@ teMT_Stat
Definition: MilStd1553.h:53
temu_Mil1553Stats::SentWords
uint64_t SentWords
Definition: MilStd1553.h:298
temu_Mil1553DevIface::receive
void(* receive)(void *Device, temu_Mil1553Msg *Msg)
Receive of 1553 message.
Definition: MilStd1553.h:277
TEMU_1553_NS_PER_WORD
#define TEMU_1553_NS_PER_WORD
Definition: MilStd1553.h:76
temu_Mil1553DevIface::connected
void(* connected)(void *Device, temu_Mil1553BusIfaceRef Bus, int RemoteTerminalAddr)
Called after device is connected to bus.
Definition: MilStd1553.h:272
TEMU_1553_MSG_FLAG_INHIBIT_B
#define TEMU_1553_MSG_FLAG_INHIBIT_B
Definition: MilStd1553.h:57
teMT_Data
@ teMT_Data
Definition: MilStd1553.h:52
temu_Mil1553DevIface::busEnteredIdle
void(* busEnteredIdle)(void *Bus, temu_Mil1553BusIdleInfo *idleInfo)
Notifies the bus controller the bus enters an idle.
Definition: MilStd1553.h:279
temu_Mil1553BusIface::setBusController
void(* setBusController)(void *Bus, temu_Mil1553DevIfaceRef Device)
Definition: MilStd1553.h:292
temu_Mil1553DevIface
struct temu_Mil1553DevIface temu_Mil1553DevIface
Definition: MilStd1553.h:254
temu_Mil1553Msg::Data
uint16_t * Data
Definition: MilStd1553.h:69
temu_Mil1553BusIface::connect
void(* connect)(void *Bus, int RTAddr, temu_Mil1553DevIfaceRef Device)
Definition: MilStd1553.h:284
temu_Mil1553BusIface
struct temu_Mil1553BusIface temu_Mil1553BusIface
Definition: MilStd1553.h:255
temu_Mil1553Msg::Err
temu_Mil1553Error Err
Definition: MilStd1553.h:64
temu_Mil1553DevIface::disconnected
void(* disconnected)(void *Device, temu_Mil1553BusIfaceRef Bus, int RemoteTerminalAddr)
Called after device is disconnected.
Definition: MilStd1553.h:274
temu_Mil1553Msg::MsgTyp
temu_Mil1553MsgType MsgTyp
Definition: MilStd1553.h:62
temu_Mil1553BusIdleInfo::ResetType
temu_Mil1553BusResetType ResetType
Definition: MilStd1553.h:267
teME_SyncError
@ teME_SyncError
Definition: MilStd1553.h:45
temu_Mil1553BusIface::reportStats
void(* reportStats)(void *Bus)
Definition: MilStd1553.h:286
temu_Mil1553MsgType
temu_Mil1553MsgType
Definition: MilStd1553.h:50
temu_Mil1553BusIface::send
void(* send)(void *Bus, void *Sender, temu_Mil1553Msg *Msg)
Definition: MilStd1553.h:287
temu_Mil1553BusIface::disableSendEvents
void(* disableSendEvents)(void *Bus)
Definition: MilStd1553.h:291
TEMU_1553_MSG_FLAG_INHIBIT_A
#define TEMU_1553_MSG_FLAG_INHIBIT_A
Definition: MilStd1553.h:56
temu_Mil1553Msg
Definition: MilStd1553.h:59
temu_Mil1553Stats::LastReportSentWords
uint64_t LastReportSentWords
Definition: MilStd1553.h:297
teMBR_Nominal
@ teMBR_Nominal
Definition: MilStd1553.h:260
teMT_Cmd
@ teMT_Cmd
Definition: MilStd1553.h:51
temu_Mil1553BusResetType
temu_Mil1553BusResetType
Definition: MilStd1553.h:259
TEMU_1553_BITS_PER_WORD
#define TEMU_1553_BITS_PER_WORD
Definition: MilStd1553.h:84
temu_Mil1553Msg::WordCount
uint8_t WordCount
Definition: MilStd1553.h:60
temu_Mil1553Error
temu_Mil1553Error
Definition: MilStd1553.h:42
teME_ParityError
@ teME_ParityError
Definition: MilStd1553.h:44