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