2 * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
4 * This software may be freely used, copied, modified, and distributed
5 * provided that the above copyright notice is preserved in all copies of the
16 * Title: Character based packet transmission engine
19 #include <stdarg.h> /* ANSI varargs support */
20 #include "angel.h" /* Angel system definitions */
21 #include "angel_endian.h" /* Endian independant memory access macros */
22 #include "crc.h" /* crc generation definitions and headers */
28 /* definitions to describe the engines state */
29 #define N_STX 0x0 /* first 2 bits for N_ */
33 #define N_MASK 0x3 /* mask for the Encapsulator state */
35 #define E_PLAIN (0x0 << 2) /* 3rd bit for E_ */
36 #define E_ESC (0x1 << 2) /* 3rd bit for E_ */
37 #define E_MASK (0x1 << 2) /* mask for the Escaper state */
39 #define F_HEAD (0x0 << 3) /* 4th and 5th bits for F_ */
40 #define F_DATA (0x1 << 3)
41 #define F_CRC (0x1 << 4)
42 #define F_MASK (0x3 << 3) /* mask for the Escaper state */
44 static unsigned char escape(unsigned char ch_in
, struct te_state
*txstate
);
46 void Angel_TxEngineInit(const struct re_config
*txconfig
,
47 const struct data_packet
*packet
,
48 struct te_state
*txstate
){
50 txstate
->tx_state
= N_STX
| E_PLAIN
| F_HEAD
;
53 txstate
->config
= txconfig
;
57 te_status
Angel_TxEngine(const struct data_packet
*packet
,
58 struct te_state
*txstate
,
59 unsigned char *tx_ch
){
60 /* TODO: gaurd on long/bad packets */
62 * encapsulate the packet, framing has been moved from a seperate
63 * function into the encapsulation routine as it needed too much
64 * inherited state for it to be sensibly located elsewhere
66 switch ((txstate
->tx_state
) & N_MASK
){
69 __rt_trace("txe-stx ");
71 txstate
->tx_state
= (txstate
->tx_state
& ~N_MASK
) | N_BODY
;
72 *tx_ch
= txstate
->config
->stx
;
73 txstate
->field_c
= 3; /* set up for the header */
74 txstate
->crc
= startCRC32
; /* set up basic crc */
77 switch (txstate
->tx_state
& F_MASK
) {
80 __rt_trace("txe-head ");
82 if (txstate
->field_c
== 3) {
84 *tx_ch
= escape(packet
->type
, txstate
);
88 *tx_ch
= escape((packet
->len
>> (txstate
->field_c
- 1) * 8) & 0xff,
90 if (txstate
->field_c
== 0) {
91 /* move on to the next state */
92 txstate
->tx_state
= (txstate
->tx_state
& ~F_MASK
) | F_DATA
;
93 txstate
->field_c
= packet
->len
;
99 __rt_trace("txe-data ");
101 *tx_ch
= escape(packet
->data
[packet
->len
- txstate
->field_c
], txstate
);
102 if (txstate
->field_c
== 0) {
103 /* move on to the next state */
104 txstate
->tx_state
= (txstate
->tx_state
& ~F_MASK
) | F_CRC
;
105 txstate
->field_c
= 4;
110 __rt_trace("txe-crc ");
112 *tx_ch
= escape((txstate
->crc
>> ((txstate
->field_c
- 1) * 8)) & 0xff,
115 if (txstate
->field_c
== 0) {
117 __rt_trace("txe crc = 0x%x\n", txstate
->crc
);
119 /* move on to the next state */
120 txstate
->tx_state
= (txstate
->tx_state
& ~N_MASK
) | N_ETX
;
127 __rt_trace("txe-etx\n");
129 txstate
->tx_state
= (txstate
->tx_state
& ~N_MASK
) | N_IDLE
;
130 *tx_ch
= txstate
->config
->etx
;
134 __rt_info("tx default\n");
136 txstate
->tx_state
= (txstate
->tx_state
& ~N_MASK
) | N_IDLE
;
139 /* stop a silly -Wall warning */
140 return (te_status
)-1;
144 * crc generation occurs in the escape function because it is the only
145 * place where we know that we're putting a real char into the buffer
146 * rather than an escaped one.
147 * We must be careful here not to update the crc when we're sending it
149 static unsigned char escape(unsigned char ch_in
, struct te_state
*txstate
) {
150 if (((txstate
->tx_state
) & E_MASK
) == E_ESC
) {
151 /* char has been escaped so send the real char */
153 __rt_trace("txe-echar ");
155 txstate
->tx_state
= (txstate
->tx_state
& ~E_MASK
) | E_PLAIN
;
157 if ((txstate
->tx_state
& F_MASK
) != F_CRC
)
158 txstate
->crc
= crc32( &ch_in
, 1, txstate
->crc
);
159 return ch_in
| serial_ESCAPE
;
161 if ((ch_in
< 32) && ((txstate
->config
->esc_set
& (1 << ch_in
)) != 0)) {
162 /* char needs escaping */
164 __rt_trace("txe-esc ");
166 txstate
->tx_state
= (txstate
->tx_state
& ~E_MASK
) | E_ESC
;
167 return txstate
->config
->esc
;
169 /* must be a char that can be sent plain */
171 if ((txstate
->tx_state
& F_MASK
) != F_CRC
)
172 txstate
->crc
= crc32(&ch_in
, 1, txstate
->crc
);
This page took 0.031962 seconds and 4 git commands to generate.