Subversion Repositories pentevo

Rev

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

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