📄 tx.c
字号:
/*-*-C-*- * * $Revision: 1.3.6.6 $ * $Author: rivimey $ * $Date: 1998/01/27 15:09:19 $ * * Copyright Advanced RISC Machines Limited, 1995. * All Rights Reserved. * * Project: ANGEL * * Title: Character based packet transmission engine */#include <stdarg.h> /* ANSI varargs support */#include "angel.h" /* Angel system definitions */#include "endian.h" /* Endian independant memory access macros */#include "crc.h" /* crc generation definitions and headers */#include "rxtx.h"#include "channels.h"#include "buffers.h"#include "logging.h"/* definitions to describe the engines state */#define N_STX 0x0 /* first 2 bits for N_ */#define N_BODY 0x1#define N_ETX 0x2#define N_IDLE 0x3#define N_MASK 0x3 /* mask for the Encapsulator state */#define E_PLAIN (0x0 << 2) /* 3rd bit for E_ */#define E_ESC (0x1 << 2) /* 3rd bit for E_ */#define E_MASK (0x1 << 2) /* mask for the Escaper state */#define F_HEAD (0x0 << 3) /* 4th and 5th bits for F_ */#define F_DATA (0x1 << 3)#define F_CRC (0x1 << 4)#define F_MASK (0x3 << 3) /* mask for the Escaper state */static unsigned char escape(unsigned char ch_in, struct te_state *txstate);void Angel_TxEngineInit(const struct re_config *txconfig, const struct data_packet *packet, struct te_state *txstate){ /* Note: SerialOpen passes NULL as packet here! */ IGNORE(packet); txstate->tx_state = N_STX | E_PLAIN | F_HEAD; txstate->field_c = 0; txstate->encoded = 0; txstate->config = txconfig; txstate->crc = 0;}te_status Angel_TxEngine(const struct data_packet *packet, struct te_state *txstate, unsigned char *tx_ch){ /* TODO: gaurd on long/bad packets */ /* * encapsulate the packet, framing has been moved from a seperate * function into the encapsulation routine as it needed too much * inherited state for it to be sensibly located elsewhere */ switch ((txstate->tx_state) & N_MASK) { case N_STX: LogTrace("txe-stx "); txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_BODY; *tx_ch = txstate->config->stx; txstate->field_c = 3; /* set up for the header */ txstate->crc = startCRC32; /* set up basic crc */ return TS_IN_PKT; case N_BODY: { switch (txstate->tx_state & F_MASK) { case F_HEAD: LogTrace("txe-head "); if (txstate->field_c == 3) { /* send type */ *tx_ch = escape(packet->type, txstate); return TS_IN_PKT; } else { *tx_ch = escape((packet->len >> (txstate->field_c - 1) * 8) & 0xff, txstate); if (txstate->field_c == 0) { /* move on to the next state */ txstate->tx_state = (txstate->tx_state & ~F_MASK) | F_DATA; txstate->field_c = packet->len; } return TS_IN_PKT; } case F_DATA: LogTrace("txe-data "); *tx_ch = escape(packet->data[packet->len - txstate->field_c], txstate); if (txstate->field_c == 0) { /* move on to the next state */ txstate->tx_state = (txstate->tx_state & ~F_MASK) | F_CRC; txstate->field_c = 4; } return TS_IN_PKT; case F_CRC: LogTrace("txe-crc "); *tx_ch = escape((txstate->crc >> ((txstate->field_c - 1) * 8)) & 0xff, txstate); if (txstate->field_c == 0) { LogTrace1("txe crc = 0x%x\n", txstate->crc); /* move on to the next state */ txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_ETX; } return TS_IN_PKT; } } case N_ETX: LogTrace("txe-etx\n"); txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_IDLE; *tx_ch = txstate->config->etx; return TS_DONE_PKT; case N_IDLE: LogTrace("txe-idle\n"); return TS_IDLE; default: LogTrace("tx-def\n"); txstate->tx_state = (txstate->tx_state & ~N_MASK) | N_IDLE; return TS_IDLE; } /* stop a silly -Wall warning */ return (te_status) - 1;}/* * crc generation occurs in the escape function because it is the only * place where we know that we're putting a real char into the buffer * rather than an escaped one. * We must be careful here not to update the crc when we're sending it */static unsigned char escape(unsigned char ch_in, struct te_state *txstate){ if (((txstate->tx_state) & E_MASK) == E_ESC) { /* char has been escaped so send the real char */ LogTrace("txe-echar "); txstate->tx_state = (txstate->tx_state & ~E_MASK) | E_PLAIN; txstate->field_c--; if ((txstate->tx_state & F_MASK) != F_CRC) txstate->crc = crc32(&ch_in, 1, txstate->crc); return ch_in | serial_ESCAPE; } if ((ch_in < 32) && ((txstate->config->esc_set & (1 << ch_in)) != 0)) { /* char needs escaping */ LogTrace("txe-esc "); txstate->tx_state = (txstate->tx_state & ~E_MASK) | E_ESC; return txstate->config->esc; } /* must be a char that can be sent plain */ txstate->field_c--; if ((txstate->tx_state & F_MASK) != F_CRC) txstate->crc = crc32(&ch_in, 1, txstate->crc); return ch_in;}/* EOF tx.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -