1 | #include "main.h"
|
2 | #include "suart.h"
|
3 |
|
4 |
|
5 |
|
6 | #define BIT_TIME (u8)((XTAL / BAUD) / PRESCALE)
|
7 |
|
8 |
|
9 | volatile u8 stx_count;
|
10 | u8 stx_data;
|
11 |
|
12 | volatile u8 srx_done;
|
13 | u8 srx_data;
|
14 | u8 srx_mask;
|
15 | u8 srx_tmp;
|
16 |
|
17 |
|
18 | void suart_init( void )
|
19 | {
|
20 | SBIT(PORTD,STX) = 1;
|
21 | // OCR0A = TCNT0 + 1; // force first compare
|
22 | // TCCR0A = 0; // Default: Normal port operation
|
23 | TCCR0B = 1 << CS01 | 1<<CS00; // clk/64
|
24 | // TIFR0 = 1<<ICF1; // clear pending interrupt
|
25 | TIMSK0 = 1 << OCIE0A; // enable output compare interrupt
|
26 |
|
27 | EICRA = 1 << ISC01; // falling edge
|
28 | EIMSK = 1 << INT0; // enable edge interrupt
|
29 |
|
30 | stx_count = 0; // nothing to sent
|
31 | srx_done = 0; // nothing received
|
32 | STXDDR |= 1 << STX; // TX output
|
33 | }
|
34 |
|
35 |
|
36 | u8 sgetchar (void) // get byte
|
37 | {
|
38 | while (!srx_done); // wait until byte received
|
39 | srx_done = 0;
|
40 | return srx_data;
|
41 | }
|
42 |
|
43 |
|
44 | ISR (INT0_vect) // rx start
|
45 | {
|
46 | OCR0B = TCNT0 + (u8)((BIT_TIME * 3) / 2);// scan 1.5 bits after start
|
47 |
|
48 | srx_tmp = 0; // clear bit storage
|
49 | srx_mask = 1; // bit mask
|
50 | EIMSK &= ~(1 << INT0); // disable edge interrupt
|
51 | //if( !(SRXPIN & 1<<SRX)) // still low
|
52 | TIMSK0 = 1<<OCIE0A^1<<OCIE0B; // wait for first bit
|
53 | TIFR0 = 1<<OCF0B; // clear pending interrupt ? why does that output compare int occur?
|
54 | // EIFR &= ~(1 << INTF0); // clear any pending edge interrupt
|
55 | }
|
56 |
|
57 |
|
58 | ISR (TIMER0_COMPB_vect)
|
59 | {
|
60 | u8 in = SRXPIN; // scan rx line
|
61 | PORTB = 0x00;
|
62 | if (srx_mask) {
|
63 | if (in & 1 << SRX)
|
64 | srx_tmp |= srx_mask;
|
65 | srx_mask <<= 1;
|
66 | OCR0B += BIT_TIME; // next bit slice
|
67 | } else {
|
68 | srx_done = 1; // mark rx data valid
|
69 | srx_data = srx_tmp; // store rx data
|
70 | // TIFR0 = 1<<ICF1; // clear pending interrupt
|
71 | TIMSK0 = 1<<OCIE0A; // enable tx and wait for start
|
72 | EIMSK = 1 << INT0; // reenable edge interrupt
|
73 |
|
74 | }
|
75 | PORTB = 0x02;
|
76 | }
|
77 |
|
78 |
|
79 | void sputchar (u8 val) // send byte
|
80 | {
|
81 | while (stx_count); // until last byte finished
|
82 | stx_data = ~val; // invert data for Stop bit generation
|
83 | stx_count = 10; // 10 bits: Start + data + Stop
|
84 | }
|
85 |
|
86 |
|
87 | void sputs (u8 *txt) // send string
|
88 | {
|
89 | while (*txt)
|
90 | sputchar (*txt++);
|
91 | }
|
92 |
|
93 |
|
94 | ISR (TIMER0_COMPA_vect) // tx bit
|
95 | {
|
96 | u8 dout;
|
97 | u8 count;
|
98 |
|
99 | OCR0A += BIT_TIME; // next bit slice
|
100 | count = stx_count;
|
101 |
|
102 | if (count) {
|
103 | stx_count = --count; // count down
|
104 | // ??? dout = 1<<COM0A1; // set low on next compare
|
105 | dout = 0;
|
106 | if (count != 9) { // no start bit
|
107 | if (!(stx_data & 1)) // test inverted data
|
108 | //??? dout = 1<<COM0A1^1<<COM0A0; // set high on next compare
|
109 | dout = 1;
|
110 | stx_data >>= 1; // shift zero in from left
|
111 | }
|
112 | // TCCR0A = dout;
|
113 | // STX = (dout == 0) ? 1 : 0;
|
114 | SBIT(PORTD,STX) = dout;
|
115 | }
|
116 | }
|