summaryrefslogtreecommitdiff
path: root/pic/softuart_pic.h
blob: 3d40bc8991c6f06cb236fc289d685a6366edc774 (plain)
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
                                                    W. Strobl, Bonn, March 2014
                                        
Simple minded software bit banging async RS232 implementation for Microchip XC8

http://en.wikipedia.org/wiki/Bit_banging

Tested with 2400, 9600 and 19200 baud on a 4 MHz 16F675 so far
Tested with 9600 baud on a 32 MHz 12F1840. 
19200 softuard doesn't work.

                              PIC12F1840

       ___                     __
 10k -|___|-+           Vdd -o| o|o- Vss
       ___  +-RS232in / GP5 -o|  |o- GP0 / ICSPDAT
  1k -|___|-- RS232out/ GP4 -o|  |o- GP1 / ICSPCLK
                  Vpp / GP3 -o|__|o- GP2 /

Necessary definitions (examples)

#define FCY 1000000             // cycles per second (4 MHz PIC)
#define SOFTUART_RXPIN  GPIO5   // if input is desired
#define SOFTUART_TXPIN  GPIO4   // if output is desired

Optional definitions

#define SOFTUART_BAUD 19200     // default: 9600
#define SOFTUART_STDIO 1        // if definition for getch, putch is desired
                                // default: 0
#define SOFTUART_DI 1           // if interrupts are to be disabled during IO
                                // default: 0
#define SOFTUART_MARK 0         // 0: not inverted (default: 1)


Typical:


#define SOFTUART_RXPIN  GPIO5
#define SOFTUART_TXPIN  GPIO4
#define SOFTUART_STDIO 1
#define SOFTUART_DI 1
#include "softuart.h"

#define kbhit softuartkbhit

*/

/******************************************************************************/
// Software UART 
/******************************************************************************/
// FCY == instructions per second, see system.h for xc8
#ifndef SOFTUART_BAUD           // default baudrate
#define SOFTUART_BAUD 9600
#endif
#define SOFTUART_BITLEN (FCY/SOFTUART_BAUD)
#define SOFTUART_DELAY (SOFTUART_BITLEN/5)

#ifndef SOFTUART_MARK
#define SOFTUART_MARK 1         // 0: not inverted (default: 1)
#endif


// Input Pin defined?
#ifdef SOFTUART_RXPIN
/******************************************************************************/
// Input
/******************************************************************************/

char softuartgetch(void)
{
    char rcvd,i; 
#if SOFTUART_DI
    di();
#endif
    rcvd=0;
    _delay(SOFTUART_BITLEN/2-10); // wait half a startbit
    if (SOFTUART_RXPIN != SOFTUART_MARK) 
    {
#if SOFTUART_DI
        ei();
#endif
        return 0; // glitch
    }
    _delay(SOFTUART_BITLEN/2-10); // wait half a startbit
    for (i=0;i<8;i++)
    {
        rcvd >>= 1; // shift previous bits, LSB comes first
        _delay(SOFTUART_BITLEN/2-12); // ADJUST
        rcvd |= ((SOFTUART_RXPIN != SOFTUART_MARK)?0x80:0);
        _delay(SOFTUART_BITLEN/2-10); // ADJUST
    }
#ifdef SOFTUART_DI
    ei();
#endif
    _delay(SOFTUART_BITLEN); // stopbit
    return rcvd;
}

#define softuartkbhit() (SOFTUART_RXPIN == SOFTUART_MARK)

#endif

// Output Pin defined?
#ifdef SOFTUART_TXPIN
/******************************************************************************/
// Output 
//******************************************************************************/

#if defined(SOFTUART_TXPIN) || defined(SOFTUART_STDIO)
#define softuartputch putch
#endif

void softuartputch(char c)
{
    char i;
#ifdef SOFTUART_DI
        di();
#endif
    SOFTUART_TXPIN = SOFTUART_MARK; // startbit 
    _delay(SOFTUART_BITLEN-20); // Adjust Schleifeninit braucht 
    for (i=0;i<8;i++)
    {
        SOFTUART_TXPIN = c; // checken, ob da das untere Bit verwendet wird sonst
#if SOFTUART_MARK
        SOFTUART_TXPIN = ~(c&1);
#else
        SOFTUART_TXPIN = c&1;
#endif
        c >>=1;
        _delay(SOFTUART_BITLEN-20); // Adjust
    }
    SOFTUART_TXPIN = ~SOFTUART_MARK;
    _delay(SOFTUART_BITLEN*2); // two stop bits
#ifdef SOFTUART_DI
    ei();
#endif
}
#endif

/******************************************************************************/
// Utility
/******************************************************************************/
#if defined(SOFTUART_RXPIN) || defined(SOFTUART_STDIO)
// getch with wait
char getch(void)
{
    while (!softuartkbhit()) _delay(1);
    return softuartgetch();
}
#endif