ESP8266-based WiFi serial modem emulator ROM
1/*
2 * WiFiPPP
3 * Copyright (c) 2021 joshua stein <jcs@jcs.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include "wifippp.h"
19
20const unsigned long ok_bauds[] = {
21 110,
22 300,
23 1200,
24 2400,
25 4800,
26 9600,
27 14400,
28 19200,
29 28800,
30 38400,
31 57600,
32 115200,
33 0,
34};
35
36void
37serial_setup(void)
38{
39 /* DCE mode, acting as a modem */
40
41 serial_start(settings->baud);
42
43 pinMode(pRI, OUTPUT);
44 serial_ri(false);
45
46 pinMode(pDSR, OUTPUT);
47 serial_dsr(false);
48
49 pinMode(pRTS, INPUT);
50
51 pinMode(pCTS, OUTPUT);
52 serial_cts(false);
53
54 pinMode(pDCD, OUTPUT);
55 serial_dcd(false);
56
57 pinMode(pDTR, INPUT);
58}
59
60void
61serial_start(int baud)
62{
63 Serial.begin(baud);
64}
65
66void
67serial_write(unsigned char b)
68{
69 serial_write(&b, 1);
70}
71
72void
73serial_write(unsigned char *data, size_t len)
74{
75 size_t i;
76 for (i = 0; i < len; i++) {
77 if (i % 8 == 0 && settings->reg_r == REG_R_RTS_ON) {
78 while (!serial_rts())
79 yield();
80 }
81 Serial.write(data[i]);
82 }
83}
84
85void
86serial_flush(void)
87{
88 Serial.flush();
89}
90
91bool
92serial_available(void)
93{
94 return Serial.available();
95}
96
97uint8_t
98serial_read(void)
99{
100 return Serial.read();
101}
102
103int16_t
104serial_peek(void)
105{
106 return Serial.peek();
107}
108
109long
110serial_autobaud(void)
111{
112 unsigned long abaud, baud = 0;
113 int i;
114
115 Serial.begin(115200);
116
117 abaud = Serial.detectBaudrate(30000);
118 if (abaud) {
119 for (i = 0; ; i++) {
120 if (ok_bauds[i] == 0)
121 break;
122 else if (ok_bauds[i] == abaud) {
123 baud = abaud;
124 break;
125 }
126 }
127
128 if (baud)
129 syslog.logf(LOG_INFO, "auto-detected baud rate of %lu",
130 baud);
131 else {
132 syslog.logf(LOG_INFO, "auto-detected bogus baud %lu, "
133 "using %d", abaud, settings->baud);
134 baud = settings->baud;
135 }
136 } else {
137 syslog.logf(LOG_INFO, "couldn't auto-detect baud rate, "
138 "using %d", settings->baud);
139 baud = settings->baud;
140 }
141
142 Serial.begin(baud);
143
144 /* terminal program will probably look for an AT */
145 if (!settings->quiet) {
146 if (settings->verbal)
147 output("\r\nOK\r\n");
148 else
149 output("\r0\r");
150 }
151
152 return baud;
153}
154
155/* Clear to Send */
156void
157serial_cts(bool clear)
158{
159 digitalWrite(pCTS, clear ? LOW : HIGH); /* inverted */
160}
161
162/* Data Carrier Detect */
163void
164serial_dcd(bool carrier)
165{
166 digitalWrite(pDCD, carrier ? LOW : HIGH); /* inverted */
167}
168
169/* Data Set Ready */
170void
171serial_dsr(bool ready)
172{
173 digitalWrite(pDSR, ready ? LOW : HIGH); /* inverted */
174}
175
176/* Data Terminal Ready */
177bool
178serial_dtr(void)
179{
180 return (digitalRead(pDTR) == LOW); /* inverted */
181}
182
183/* Ring Indicator */
184void
185serial_ri(bool ringing)
186{
187 digitalWrite(pRI, ringing ? LOW : HIGH); /* inverted */
188}
189
190/* Ready to Send */
191bool
192serial_rts(void)
193{
194 return (digitalRead(pRTS) == LOW); /* inverted */
195}