-
Notifications
You must be signed in to change notification settings - Fork 0
/
stdout_software_serial.h
98 lines (90 loc) · 2.21 KB
/
stdout_software_serial.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//
// stdout implementation using software serial port on ATtiny
// this file should be #include'd in your main start up.
// before including this file, include the following
//
// #include <avr/io.h>
// #include <string.h>
// #include <avr/interrupt.h>
// #include <stdio.h>
//
// #define STDOUT_BAUD 9600
//
// this software serial port version uses the 16 bit timer 1
// and one output pin. the output pin must be defined as well
//
// #define STDOUT_DDR DDRA
// #define STDOUT_PORT PORTA
// #define STDOUT_PIN PA5
//
static volatile char txState = 0;
static volatile char txChar = 0;
static int software_serial_putchar(char c, FILE *stream);
static FILE mystdout = FDEV_SETUP_STREAM(software_serial_putchar, NULL, _FDEV_SETUP_WRITE);
void init_stdout(void)
{
cli();
STDOUT_DDR |= (1 << STDOUT_PIN);
STDOUT_PORT |= (1 << STDOUT_PIN);
// set up timer for baud bate
TCCR1B |= (1 << CS10);
OCR1A = F_CPU / STDOUT_BAUD;
TCCR1B |= (1 << WGM12);
TIMSK1 |= (1 << OCIE1A);
stdout = &mystdout;
}
int software_serial_putchar(char value, FILE *stream)
{
if (value == '\n')
{
software_serial_putchar('\r', stream);
}
while (txState != 0);
txChar = value;
txState = 1;
return 0;
}
ISR(TIM1_COMPA_vect)
{
switch (txState)
{
case 0:
// idle - set wait for txByte
break;
case 1:
// start bit - set pin low
STDOUT_PORT &= ~(1 << STDOUT_PIN);
txState++;
break;
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
// send out data bits
if (txChar & 1)
{
STDOUT_PORT |= (1 << STDOUT_PIN);
}
else
{
STDOUT_PORT &= ~(1 << STDOUT_PIN);
}
txChar = txChar >> 1;
txState++;
break;
case 10:
// send stop bit - set pin high
STDOUT_PORT |= (1 << STDOUT_PIN);
txState++;
break;
case 11:
// reset state machine
// allow another byte to be sent
txState = 0;
break;
}
}