Subversion Repositories pentevo

Rev

Rev 910 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
910 dimkam 1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
 
4
#include "mytypes.h"
5
#include "rs232.h"
6
#include "pins.h"
7
 
8
//if want Log than comment next string
9
#undef LOGENABLE
10
 
11
#define BAUD115200 115200
12
#define BAUD256000 256000
13
#define UBRR115200 (((F_CPU/16)/BAUD115200)-1)
14
#define UBRR256000 (((F_CPU/16)/BAUD256000)-1)
15
 
16
//Registers for 16550 emulation:
17
 
18
//Divisor Latch LSB
19
static UBYTE rs232_DLL;
20
//Divisor Latch MSB
21
static UBYTE rs232_DLM;
22
//Interrupt Enable
23
static UBYTE rs232_IER;
24
//Interrupt Identification
25
static UBYTE rs232_ISR;
26
//FIFO Control
27
static UBYTE rs232_FCR;
28
//Line Control
29
static UBYTE rs232_LCR;
30
//Modem Control
31
static UBYTE rs232_MCR;
32
//Line Status
33
static UBYTE rs232_LSR;
34
//Modem Status
35
static UBYTE rs232_MSR;
36
//Scratch Pad
37
static UBYTE rs232_SCR;
38
//Fifo In
39
static UBYTE rs232_FI[16];
40
static UBYTE rs232_FI_start;
41
static UBYTE rs232_FI_end;
42
//Fifo Out
43
static UBYTE rs232_FO[16];
44
static UBYTE rs232_FO_start;
45
static UBYTE rs232_FO_end;
46
 
47
void rs232_init(void)
48
{
49
        // Set baud rate
50
        UBRR1H = (UBYTE)(UBRR115200>>8);
51
        UBRR1L = (UBYTE)UBRR115200;
52
        // Clear reg
53
        UCSR1A = 0;
54
        // Enable receiver and transmitter
55
        UCSR1B = _BV(RXEN)|_BV(TXEN);
56
        // Set frame format: 8data, 1stop bit
57
        UCSR1C = _BV(USBS)|_BV(UCSZ0)|_BV(UCSZ1);
58
 
59
        //Set default values:
60
        rs232_DLM = 0;
61
        rs232_DLL = 0x01;
62
        rs232_IER = 0;
63
        rs232_FCR = 0x01; //FIFO always enable
64
        rs232_ISR = 0x01;
65
        rs232_LCR = 0;
66
        rs232_MCR = 0;
67
        rs232_LSR = 0x60;
68
        rs232_MSR = 0xA0; //DSR=CD=1, RI=0
69
        rs232_SCR = 0xFF;
70
        rs232_FI_start = rs232_FI_end = 0;
71
        rs232_FO_start = rs232_FO_end = 0;
72
}
73
 
74
void rs232_transmit( UBYTE data )
75
{
76
        // Wait for empty transmit buffer
77
        while ( !( UCSR1A & (1<<UDRE)) );
78
        // Put data into buffer, sends the data
79
        UDR1 = data;
80
}
920 dimkam 81
UBYTE rs232_receive( void )
82
{
83
        if(UCSR1A & (1<<RXC)) return UDR1;
84
        else return 0x00;
85
}
910 dimkam 86
 
87
//#ifdef LOGENABLE
88
void to_log(char* ptr)
89
{
90
        while( (*ptr)!=0 )
91
        {
92
                rs232_transmit(*ptr);
93
                ptr++;
94
        }
95
}
96
//#endif
97
 
98
 
99
//after DLL or DLM changing
100
void rs232_set_baud(void)
101
{
102
        if ( rs232_DLM | rs232_DLL )
103
        {
104
                if( (rs232_DLM&0x80)!=0 )
105
                {
106
                        //AVR mode - direct load UBRR
107
                        UBRR1H = 0x7F&rs232_DLM;
108
                        UBRR1L = rs232_DLL;
109
                }
110
                else
111
                {
112
                        //default mode - like 16550
113
                        ULONG i = BAUD115200/ ((((UWORD)rs232_DLM)<<8) + rs232_DLL);
114
                        UWORD rate = ((F_CPU/16)/i)-1;
115
                        // Set baud rate
116
                        UBRR1H = (UBYTE)(rate>>8);
117
                        UBRR1L = (UBYTE)rate;
118
                }
119
        }
120
        else
121
        {
122
                // If( ( rs232_DLM==0 ) && ( rs232_DLL==0 ) )
123
                // set rate to 256000 baud
124
                UBRR1H = (UBYTE)(UBRR256000>>8);
125
                UBRR1L = (UBYTE)UBRR256000;
126
        }
127
}
128
 
129
//after LCR changing
130
void rs232_set_format(void)
131
{
132
        //set word length and stopbits
133
        UBYTE format = ((rs232_LCR&0x07)<<1);
134
 
135
        //set parity (only "No parity","Odd","Even" supported)
136
        switch( rs232_LCR&0x38 )
137
        {
138
                case 0x08:
139
                        //odd parity
140
                        format |= _BV(UPM0)|_BV(UPM1);
141
                        break;
142
                case 0x18:
143
                        //even parity
144
                        format |= _BV(UPM1);
145
                        break;
146
                //default - parity not used
147
        }
148
 
149
        UCSR1C = format;
150
}
151
 
152
void rs232_zx_write(UBYTE index, UBYTE data)
153
{
154
#ifdef LOGENABLE
155
        char log_write[] = "A..D..W\r\n";
156
        log_write[1] = ((index >> 4) <= 9 )?'0'+(index >> 4):'A'+((index >> 4)-10);
157
        log_write[2] = ((index & 0x0F) <= 9 )?'0'+(index & 0x0F):'A'+(index & 0x0F)-10;
158
        log_write[4] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+((data >> 4)-10);
159
        log_write[5] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+((data & 0x0F)-10);
160
        to_log(log_write);
161
#endif
162
        switch( index )
163
        {
164
        case 0:
165
                if ( rs232_LCR & 0x80 )
166
                {
167
                        rs232_DLL = data;
168
                        rs232_set_baud();
169
                }
170
                else
171
                {
172
                        //place byte to fifo out
173
                        if ( ( rs232_FO_end != rs232_FO_start ) ||
174
                             ( rs232_LSR&0x20 ) )
175
                        {
176
                                rs232_FO[rs232_FO_end] = data;
177
                                rs232_FO_end = (rs232_FO_end + 1) & 0x0F;
178
 
179
                                //clear fifo empty flag
180
                                rs232_LSR &= ~(0x60);
181
                        }
182
                        else
183
                        {
184
                                //fifo overload
185
                        }
186
                }
187
                break;
188
 
189
        case 1:
190
                if ( rs232_LCR & 0x80 )
191
                {
192
                        //write to DLM
193
                        rs232_DLM = data;
194
                        rs232_set_baud();
195
                }
196
                else
197
                {
198
                        //bit 7-4 not used and set to '0'
199
                        rs232_IER = data & 0x0F;
200
                }
201
                break;
202
 
203
        case 2:
204
                if( data&1 )
205
                {
206
                        //FIFO always enable
207
                        if( data&(1<<1) )
208
                        {
209
                                //receive FIFO reset
210
                                rs232_FI_start = rs232_FI_end = 0;
211
                                //set empty FIFO flag and clear overrun flag
212
                                rs232_LSR &= ~(0x03);
213
                        }
214
                        if( data&(1<<2) )
215
                        {
216
                                //tramsmit FIFO reset
217
                                rs232_FO_start = rs232_FO_end = 0;
218
                                //set fifo is empty flag
219
                                rs232_LSR |= 0x60;
220
                        }
221
                        rs232_FCR = data&0xC9;
222
                }
223
                break;
224
 
225
        case 3:
226
                rs232_LCR = data;
227
                rs232_set_format();
228
                break;
229
 
230
        case 4:
231
                //bit 7-5 not used and set to '0'
232
                rs232_MCR = data & 0x1F;
233
                if ( data&(1<<1) )
234
                {
235
                        //clear RTS
236
                        RS232RTS_PORT &= ~(_BV(RS232RTS));
237
                }
238
                else
239
                {
240
                        //set RTS
241
                        RS232RTS_PORT |= _BV(RS232RTS);
242
                }
243
                break;
244
 
245
        case 5:
246
                //rs232_LSR = data;
247
                break;
248
 
249
        case 6:
250
                //rs232_MSR = data;
251
                break;
252
 
253
        case 7:
254
                rs232_SCR = data;
255
                break;
256
        }
257
}
258
 
259
UBYTE rs232_zx_read(UBYTE index)
260
{
261
        UBYTE data = 0;
262
        switch( index )
263
        {
264
        case 0:
265
                if ( rs232_LCR & 0x80 )
266
                {
267
                        data = rs232_DLL;
268
                }
269
                else
270
                {
271
                        //get byte from fifo in
272
                        if ( rs232_LSR&0x01 )
273
                        {
274
                                data = rs232_FI[rs232_FI_start];
275
                                rs232_FI_start = ( rs232_FI_start + 1 ) & 0x0F;
276
 
277
                                if( rs232_FI_start == rs232_FI_end )
278
                                {
279
                                        //set empty FIFO flag
280
                                        rs232_LSR &= ~(0x01);
281
                                }
282
                        }
283
                }
284
                break;
285
 
286
        case 1:
287
                if ( rs232_LCR & 0x80 )
288
                {
289
                        data = rs232_DLM;
290
                }
291
                else
292
                {
293
                        data = rs232_IER;
294
                }
295
                break;
296
 
297
        case 2:
298
                data = rs232_ISR;
299
                break;
300
 
301
        case 3:
302
                data = rs232_LCR;
303
                break;
304
 
305
        case 4:
306
                data = rs232_MCR;
307
                break;
308
 
309
        case 5:
310
                data = rs232_LSR;
311
                break;
312
 
313
        case 6:
314
                //DSR=CD=1
315
                data = rs232_MSR;
316
                //clear flags
317
                rs232_MSR &= 0xF0;
318
                break;
319
 
320
        case 7:
321
                data = rs232_SCR;
322
                break;
323
        }
324
#ifdef LOGENABLE
325
        static UBYTE last = 0;
326
        if ( last!=index )
327
        {
328
                char log_read[] = "A..D..R\r\n";
329
                log_read[1] = ((index >> 4) <= 9 )?'0'+(index >> 4):'A'+((index >> 4)-10);
330
                log_read[2] = ((index & 0x0F) <= 9 )?'0'+(index & 0x0F):'A'+(index & 0x0F)-10;
331
                log_read[4] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+((data >> 4)-10);
332
                log_read[5] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+((data & 0x0F)-10);
333
                to_log(log_read);
334
                last = index;
335
        }
336
#endif
337
        return data;
338
}
339
 
340
void rs232_task(void)
341
{
342
        //send data
343
        if( (rs232_LSR&0x20)==0 )
344
        {
345
                if ( UCSR1A&_BV(UDRE) )
346
                {
347
                        UDR1 = rs232_FO[rs232_FO_start];
348
                        rs232_FO_start = (rs232_FO_start+1)&0x0F;
349
 
350
                        if( rs232_FO_start == rs232_FO_end )
351
                        {
352
                                //set fifo is empty flag
353
                                rs232_LSR |= 0x60;
354
                        }
355
                }
356
        }
357
 
358
        //receive data
359
        if( UCSR1A&_BV(RXC) )
360
        {
361
                BYTE b = UDR1;
362
                if( (rs232_FI_end == rs232_FI_start) &&
363
                    (rs232_LSR&0x01) )
364
                {
365
                        //set overrun flag
366
                        rs232_LSR|=0x02;
367
                }
368
                else
369
                {
370
                        //receive data
371
                        rs232_FI[rs232_FI_end] = b;
372
                        rs232_FI_end = (rs232_FI_end+1)&0x0F;
373
                        //set data received flag
374
                        rs232_LSR |= 0x01;
375
                }
376
        }
377
 
378
        //statuses
379
        if( UCSR1A&_BV(FE) )
380
        {
381
                //frame error
382
                rs232_LSR |= 0x08;
383
        }
384
        else
385
        {
386
                rs232_LSR &= ~(0x08);
387
        }
388
 
389
        if( UCSR1A&_BV(UPE) )
390
        {
391
                //parity error
392
                rs232_LSR |= 0x04;
393
        }
394
        else
395
        {
396
                rs232_LSR &= ~(0x04);
397
        }
398
 
399
        if( RS232CTS_PIN&_BV(RS232CTS) )
400
        {
401
                //CTS clear
402
                if( (rs232_MSR&0x10)!=0 )
403
                {
404
#ifdef LOGENABLE
405
                        to_log("CTS\r\n");
406
#endif
407
                        //CTS changed - set flag
408
                        rs232_MSR |= 0x01;
409
                }
410
                rs232_MSR &= ~(0x10);
411
        }
412
        else
413
        {
414
                //CTS set
415
                if( (rs232_MSR&0x10)==0 )
416
                {
417
#ifdef LOGENABLE
418
                        to_log("CTS\r\n");
419
#endif
420
                        //CTS changed - set flag
421
                        rs232_MSR |= 0x01;
422
                }
423
                rs232_MSR |= 0x10;
424
        }
425
}