1 | //** globale Variablen ************************************************
|
2 | volatile struct
|
3 | {
|
4 | //-- Tx-Ablauf -------------------------------------
|
5 | uint8_t u8TxState;
|
6 | uint8_t u8TxStateLast;
|
7 | //-- Sende-FIFO ---------------------------------
|
8 | uint8_t au8TxData [1024]; // Datenpuffer
|
9 | uint16_t au16TxRef [ 16]; // Ref-Tabelle
|
10 | uint8_t au8TxLen [ 16]; // Länge
|
11 | uint8_t u8TxInp; // INP-Referenz
|
12 | uint8_t u8TxOut; // OUT-Referenz
|
13 | uint8_t u8TxSend; // Sendezähler;
|
14 | uint8_t u8Msg; // Anzahl der Nachrichten im FIFO
|
15 | uint16_t u16Fill; // Anzahl der Bytes im FIFO
|
16 | }
|
17 | scRs232;
|
18 |
|
19 |
|
20 | void os_rs232_send_direct( uint8_t* pau8Data, uint8_t u8Len )
|
21 | {
|
22 | //-- lokale Variablen ------------------------------------------------
|
23 | uint16_t u16Buff = (uint16_t) sizeof(scRs232.au8TxData);
|
24 | uint16_t u16Array = ( u16Buff - scRs232.u16Fill );
|
25 | uint8_t u8Max = (uint8_t) sizeof(scRs232.au8TxLen );
|
26 | uint8_t u8Idx = 0;
|
27 | //-- Eingangsvariablen prüfen -------------------------------------
|
28 | if ( pau8Data == 0 ) return;
|
29 | if ( u8Len == 0 ) return;
|
30 | //-- genügend Platz im FIFO? -------------------------------------
|
31 | if ( (uint16_t)u8Len > u16Array ) return;
|
32 | if ( scRs232.u8Msg == u8Max ) return;
|
33 | //-- ins FIFO eintragen -----------------------------------------------
|
34 | u16Array = scRs232.au16TxRef[ scRs232.u8TxInp ];
|
35 | u8Idx = 0;
|
36 | while ( u8Idx != u8Len )
|
37 | {
|
38 | scRs232.au8TxData[u16Array] = *pau8Data;
|
39 | /*-- weiter ---------------------------------*/
|
40 | pau8Data++;
|
41 | u8Idx++;
|
42 | u16Array++;
|
43 | if ( u16Array == u16Buff ) u16Array = 0;
|
44 | }
|
45 | //-- Referenz aktualisieren --------------------------------------------------
|
46 | scRs232.u16Fill += (uint16_t)u8Len;
|
47 | scRs232.au8TxLen[scRs232.u8TxInp] = u8Len;
|
48 | if ( ++scRs232.u8TxInp == u8Max ) scRs232.u8TxInp = 0;
|
49 | scRs232.au16TxRef[ scRs232.u8TxInp ] = u16Array;
|
50 | scRs232.u8Msg++;
|
51 | }
|
52 |
|
53 |
|
54 |
|
55 | ISR ( USART1_UDRE_vect )
|
56 | {
|
57 | //-- lokale Variablen ------------------------------------------------------------
|
58 | uint16_t u16Buff = (uint16_t) sizeof(scRs232.au8TxData);
|
59 | uint16_t u16Idx = scRs232.au16TxRef[scRs232.u8TxOut];
|
60 | uint8_t u8Len = scRs232.au8TxLen [scRs232.u8TxOut];
|
61 | uint8_t u8Max = (uint8_t) sizeof(scRs232.au8TxLen );
|
62 | //-- Datum senden --------------------------------------------------------------
|
63 | UDR1 = scRs232.au8TxData[u16Idx];
|
64 | if ( ++u16Idx == u16Buff )
|
65 | {
|
66 | u16Idx = 0;
|
67 | }
|
68 | scRs232.au16TxRef[scRs232.u8TxOut] = u16Idx;
|
69 | //-- vollständig gesendet? ----------------------------------------------------
|
70 | if ( ++scRs232.u8TxSend != u8Len ) return;
|
71 | //-- Msg aus FIFO entfernen ------------------------------------------------
|
72 | scRs232.u16Fill -= (uint16_t) u8Len;
|
73 | scRs232.u8Msg--;
|
74 | if ( ++scRs232.u8TxOut == u8Max ) scRs232.u8TxOut = 0;
|
75 | //-- fertig, ISR abschalten -----------------------------------------------------
|
76 | UCSR1B &= ~(1<<UDRIE1);
|
77 | }
|
78 |
|
79 |
|
80 |
|
81 |
|
82 | void os_rs232_run( void )
|
83 | {
|
84 | switch ( scRs232.u8TxState )
|
85 | {
|
86 | //-- TX: Init Ablauf -------------------------------------------------------
|
87 | case cRS232_TxInit:
|
88 | //-- ENTRY -----------------------------------
|
89 | scRs232.u8TxStateLast = scRs232.u8TxState;
|
90 | //-- ACTION -----------------------------------
|
91 | //-- TRANSITION ----------------------------
|
92 | scRs232.u8TxState = cRS232_TxIdle;
|
93 | //-- EXIT ---------------------------------------
|
94 | break;
|
95 |
|
96 | //-- TX: warten auf Msg ------------------------------------------------
|
97 | case cRS232_TxIdle:
|
98 | //-- ENTRY ------------------------------------
|
99 | if ( scRs232.u8TxStateLast != scRs232.u8TxState )
|
100 | {
|
101 | scRs232.u8TxStateLast = scRs232.u8TxState;
|
102 | }
|
103 | //-- ACTION ------------------------------------
|
104 | //-- TRANSITION -----------------------------
|
105 | if ( scRs232.u8Msg != 0 )
|
106 | {
|
107 | scRs232.u8TxState = cRS232_TxSend;
|
108 | }
|
109 | //-- EXIT ----------------------------------------
|
110 | break;
|
111 |
|
112 | //-- TX: Senden -----------------------------------------------------------
|
113 | case cRS232_TxSend:
|
114 | //-- ENTRY ------------------------------------
|
115 | if ( scRs232.u8TxStateLast != scRs232.u8TxState )
|
116 | {
|
117 | scRs232.u8TxStateLast = scRs232.u8TxState;
|
118 | //-- Senden anstoßen -----
|
119 | scRs232.u8TxSend = 0;
|
120 | UCSR1B |= (1<<UDRIE1);
|
121 | }
|
122 | //-- ACTION ------------------------------------
|
123 | //-- TRANSITION -----------------------------
|
124 | if ( !( UCSR1B & (1<<UDRIE1) ) )
|
125 | {
|
126 | scRs232.u16CntTxD++;
|
127 |
|
128 | if ( UCSR1A & (1<<TXC1) )
|
129 | {
|
130 | scRs232.u8TxState = cRS232_TxIdle;
|
131 | if ( scRs232.u8Msg != 0 )
|
132 | {
|
133 | scRs232.u8TxState = cRS232_TxWait;
|
134 | }
|
135 | }
|
136 | }
|
137 | //-- EXIT -----------------------------------------
|
138 | break;
|
139 |
|
140 | //-- TX: Pause generieren ---------------------------------------------
|
141 | case cRS232_TxWait:
|
142 | //-- ENTRY --------------------------------------
|
143 | if ( scRs232.u8TxStateLast != scRs232.u8TxState )
|
144 | {
|
145 | scRs232.u8TxStateLast = scRs232.u8TxState;
|
146 | //-- Verzögerung setzen ----
|
147 | OCR3A = ( TCNT3 + scRs232.u16Delay );
|
148 | TIFR3 |= (1<<OCF3A);
|
149 | }
|
150 | //-- ACTION ---------------------------------------
|
151 | //-- TRANSITION --------------------------------
|
152 | if ( TIFR3 & (1<<OCF3A) )
|
153 | {
|
154 | scRs232.u8TxState = cRS232_TxSend;
|
155 | }
|
156 | //-- EXIT -------------------------------------------
|
157 | break;
|
158 |
|
159 | //-- TX: ungültig ----------------------------------------------------------
|
160 | default:
|
161 | scRs232.u8TxState = cRS232_TxInit;
|
162 | }
|