├── LICENSE.txt
├── README.md
├── case
├── .gitignore
├── back_panel.scad
├── back_panel.stl
├── front_panel.ods
├── front_panel.pdf
├── front_panel.scad
└── front_panel.stl
├── images
├── Back panel.jpg
├── Builtin help.png
├── Front panel.jpg
├── Interior.jpg
├── PicoWifiModem.sch.png
└── Prototype.jpg
├── kicad
├── .gitignore
├── Pico_Wifi_modem-bom.csv
├── Pico_Wifi_modem.kicad_pcb
├── Pico_Wifi_modem.net
├── Pico_Wifi_modem.pro
├── Pico_Wifi_modem.sch
├── fp-info-cache
├── fp-lib-table
├── gerbers
│ ├── Pico_Wifi_modem-B.Cu.gbl
│ ├── Pico_Wifi_modem-B.Mask.gbs
│ ├── Pico_Wifi_modem-B.Paste.gbp
│ ├── Pico_Wifi_modem-B.SilkS.gbo
│ ├── Pico_Wifi_modem-Edge.Cuts.gm1
│ ├── Pico_Wifi_modem-F.Cu.gtl
│ ├── Pico_Wifi_modem-F.Mask.gts
│ ├── Pico_Wifi_modem-F.Paste.gtp
│ ├── Pico_Wifi_modem-F.SilkS.gto
│ ├── Pico_Wifi_modem-NPTH-drl_map.gbr
│ ├── Pico_Wifi_modem-NPTH.drl
│ ├── Pico_Wifi_modem-drl_map.gbr
│ ├── Pico_Wifi_modem.drl
│ └── Pico_Wifi_modem.zip
├── library
│ └── Pico_Wifi_modem.lib
├── modules.pretty
│ ├── BARREL_JACK.kicad_mod
│ ├── C_Disc_D3_P2.5.kicad_mod
│ ├── C_Disc_D3_P5.kicad_mod
│ ├── DIP-20_W7.62mm_LongPads.kicad_mod
│ ├── DIP-8_W7.62mm_LongPads.kicad_mod
│ ├── Diode_DO-41_SOD81_Horizontal_RM10.kicad_mod
│ ├── IDC_Header_Straight_10pins.kicad_mod
│ ├── LED-3MM.kicad_mod
│ ├── MountingHole_3.2mm_Hammond_1593.kicad_mod
│ ├── R3.kicad_mod
│ ├── RPi_PicoW.kicad_mod
│ ├── SOIC-28W_7.5x17.9mm_Pitch1.27mm.kicad_mod
│ └── TO-92_Inline_Narrow_Oval.kicad_mod
└── sym-lib-table
└── src
├── CMakeLists.txt
├── at_basic.h
├── at_extended.h
├── at_proprietary.h
├── build
└── .gitignore
├── eeprom.h
├── globals.h
├── lwipopts.h
├── support.h
├── tcp_support.h
├── wifi_modem.cpp
└── wifi_modem.h
/README.md:
--------------------------------------------------------------------------------
1 | # Pico WiFi modem
2 |
3 | ## A Pico W based RS232 \<-\> WiFi modem with Hayes AT style commands and LED indicators
4 |
5 | |  |
6 | |:--:|
7 | | The Pico WiFi modem |
8 |
9 | This project began as an exercise to learn about the Pico W and lwIP.
10 | Then, as I figured things out, it sort of took on a life of its own...
11 |
12 | The code was ported from my
13 | [Retro WiFi Modem](https://github.com/mecparts/RetroWiFiModem).
14 | One look at it will betray its Arduino IDE origin! It's definitely not
15 | the most efficient way to do things in the Pico world, but it worked
16 | well enough for my purposes in learning "okay, I know what I want to do
17 | here, but how does the Pico C/C++ SDK do it?"
18 |
19 | It likely would have been much faster to install one of the Pico-Arduino
20 | cores. I imagine there would have been far fewer code changes. But I
21 | don't think I would have learned anywhere near as much about the
22 | workings of the Pico W and lwIP as I did by using the Pico SDK.
23 |
24 | ## The Hardware
25 |
26 | |  |
27 | |:--:|
28 | | The prototype |
29 |
30 | As with the code, I re-up'd a lot of the original hardware decisions.
31 | But, since this time around it wasn't a pandemic project that I was
32 | trying to do as much as possible with parts on hand, I used a MAX3237
33 | instead of a MAX3232.
34 |
35 | |  |
36 | |:--:|
37 | | The interior |
38 |
39 | The modem still uses the classic Hayes style blinking LEDs and a DE-9F
40 | for the RS-232 connector. Everything is displayed: RTS, CTS, DSR, DTR,
41 | DCD, RI, TxD and RxD. And this time, since I used a MAX3237, they're all
42 | brought out to the DE-9F connector. So things like using a change in the
43 | DTR line to go to command mode or end a call are supported (on a system
44 | that brings DTR out to the serial port, of course).
45 |
46 | Since the Pico W doesn't have EEPROM on board, I added a small 4K I2C
47 | EEPROM to the mix. I could have used a block of the Pico's flash, but I
48 | wanted to get a feel for I2C on the Pico as well.
49 |
50 | The Pico is socketed on this first board due to the lack of OTA
51 | programming. The PCB is set up to allow it to be soldered directly on
52 | the board once I have that figured out.
53 |
54 | |  |
55 | |:--:|
56 | | The back panel |
57 |
58 | The power connector expects a 2.1mm I.D. x 5.5mm O.D. barrel plug,
59 | delivering 5 volts, centre positive. I used a Tri-Mag L6R06H-050 (5V,
60 | 1.2A), [DigiKey part# 364-1251-ND](https://www.digikey.com/product-detail/en/tri-mag-llc/L6R06H-050/364-1251-ND/7682614).
61 | If you plug in a 9V adapter like you'd use for an Arduino, you *will*
62 | let the magic smoke out and have an ex-modem on your hands.
63 |
64 | |  |
65 | |:--:|
66 | | The schematic |
67 |
68 | On the off chance that there's someone else out there with a well
69 | stocked parts box and a burning desire to put together their own Pico
70 | WiFi modem, there's a [BOM](kicad/Pico_WiFi_Modem-bom.csv) in the
71 | kicad sub directory. As was true with the original ESP8266 design, if
72 | you actually had to go out and buy all the parts, it really wouldn't be
73 | cost effective.
74 |
75 | ## The case
76 |
77 | I re-used the same case, a Hammond 1593N case (DigiKey part #
78 | [HM963-ND](https://www.digikey.com/en/products/detail/hammond-manufacturing/1593NBK/1090774)
79 | or [HM964-ND](https://www.digikey.com/en/products/detail/hammond-manufacturing/1593NGY/1090775)
80 | depending on whether you like black or grey). STL and OpenSCAD
81 | files are included for the front and back panels. You could use the
82 | proper Hammond red panel for the front (DigiKey part #
83 | [HM965-ND](https://www.digikey.com/en/products/detail/hammond-manufacturing/1593NIR10/1090776)),
84 | *but* they're only available in 10 packs and their price is highway robbery.
85 | I ended up using a slightly smaller red panel (DigiKey part #
86 | [HM889-ND](https://www.digikey.com/en/products/detail/hammond-manufacturing/1593SIR10/409899))
87 | that was ~much~ cheaper (it has recently increased in price by 500%)
88 | and available in single units.
89 |
90 | The labels are unbelievably low tech. I print them on a piece of inkjet
91 | transparency film. I then cut that down to size so that it will fit
92 | under the LED opening. Then I attach the trimmed down transparency piece
93 | to a length of matte finish, invisible tape and carefully position it in
94 | place. A bit of careful work with an x-acto knife and you've got
95 | yourself a label that looks like it's part of the panel. If you look
96 | closely at the front panel image you can see the edges of the
97 | transparency film and the tape, but in practice they both essentially
98 | disappear.
99 |
100 | ## The PCB
101 |
102 | The PCB includes cutouts for the two columns that join the case
103 | together, and mounting holes for the 6 standoffs. Also, there's an oddly
104 | shaped cutout in back end to allow a particular IDC DE-9F I had on hand.
105 | It's available from DigiKey (or a very close clone is) but it's fairly
106 | pricey. But there's plenty of room for an ordinary solder cup DE-9F.
107 | You'd most likely want to omit the 10 pin header and just wire the DE-9F
108 | right to the board.
109 |
110 | Unlike the original Retro Wifi Modem, I made no attempt to make this
111 | board by hand. Instead, I took advantage of an introductory offer by a
112 | well known PCB house and had PCBs made. 5 boards for under 20 bucks, and
113 | delivered in under a week? Who could say no?
114 |
115 | ## The Software
116 |
117 | |  |
118 | |:--:|
119 | | Modem command list |
120 |
121 | The software is naturally quite similar to the original ESP8266 Wifi
122 | modem. There are a few changes (and one fairly major omission):
123 |
124 | * DTR signal handling (AT&D)
125 | * Escape sequence character definition (ATS2)
126 | * no OTA reprogramming (yet!)
127 |
128 | ### First time setup
129 |
130 | The default serial configuration is 9600bps, 8 data bits, no parity, 1
131 | stop bit.
132 |
133 | Here's the commands you need to set up the modem to automatically
134 | connect to your WiFi network:
135 |
136 | 1. `AT$SSID=your WiFi network name` to set the WiFi network that the
137 | modem will connect to when it powers up.
138 | 2. `AT$PASS=your WiFi network password` to set the password for the
139 | network.
140 | 3. `ATC1` to connect to the network.
141 | 4. Optional stuff:
142 | * `AT$SB=speed` to set the default serial speed.
143 | * `AT$SU=dps` to set the data bits, parity and stop bits.
144 | * `ATNETn` to select whether or not to use Telnet protocol.
145 | * `AT&Kn` to use RTS/CTS flow control or not.
146 | * `AT&Dn` to set up DTR handling.
147 | 5. `AT&W` to save the settings.
148 |
149 | Once you've done that, the modem will automatically connect to your WiFi
150 | network on power up and will be ready to "dial up" a connection with
151 | ATDT.
152 |
153 | ### Command Reference
154 |
155 | Multiple AT commands can be typed in on a single line. Spaces between
156 | commands are allowed, but not within commands (i.e. AT S0=1 X1 Q0 is
157 | fine; ATS 0= 1 is not). Commands that take a string as an argument
158 | (e.g. AT$SSID=, AT$TTY=) assume that *everything* that follows is a part
159 | of the string, so no commands are allowed after them.
160 |
161 | Command | Details
162 | ------- | -------
163 | +++ | Online escape code. Once your modem is connected to another device, the only command it recognises is an escape code of a one second pause followed by three typed plus signs and another one second pause, which puts the modem back into local command mode.
164 | A/ | Repeats the last command entered. Do not type AT or press Enter.
165 | AT | The attention prefix that precedes all command except A/ and +++.
166 | AT? | Displays a help cheatsheet.
167 | ATA | Force the modem to answer an incoming connection when the conditions for auto answer have not been satisfied.
168 | ATC?
ATC*n* | Query or change the current WiFi connection status. A result of 0 means that the modem is not connected to WiFi, 1 means the modem is connected. The command ATC0 disconnects the modem from a WiFi connection. ATC1 connects the modem to the WiFi.
169 | ATDS*n* | Calls the host specified in speed dial slot *n* (0-9).
170 | ATDT[+=-]host[:port] | Tries to establish a WiFi TCP connection to the specified host name or IP address. If no port number is given, 23 (Telnet) is assumed. You can also use ATDT to dial one of the speed dial slots in one of two ways:
- The alias in each speed dial slot is checked to see if it matches the specified hostname.
- A host specified as 7 identical digits dials the slot indicated by the digit. (i.e. 2222222 would speed dial the host in slot 2).
Preceding the host name or IP address with a +, = or - character overrides the ATNET setting for the period of the connection.
- **+** forces NET2 (fake Telnet)
- **=** forces NET1 (real Telnet)
- **-** forces NET0 (no Telnet)
Once the dial attempt has begun, pressing any key before the connection is established will abort the attempt.
171 | ATE?
ATE*n* | Command mode echo. Enables or disables the display of your typed commands.
- E0 Command mode echo OFF. Your typing will not appear on the screen.
- E1 Command mode echo ON. Your typing will appear on the screen.
172 | ATGET*http://host[/page]* | Displays the contents of a website page. **https** connections are not supported. Once the contents have been displayed, the connection will automatically terminate.
173 | ATH | Hangs up (ends) the current connection.
174 | ATI | Displays the current network status, including sketch build date, WiFi and call connection state, SSID name, IP address, and bytes transferred.
175 | ATNET?
ATNET*n* | Query or change whether telnet protocol is enabled. A result of 0 means that telnet protocol is disabled; 1 is *Real* telnet protocol and 2 is *Fake* telnet protocol. If you are connecting to a telnet server, it may expect the modem to respond to various telnet commands, such as terminal name (set with `AT$TTY`), terminal window size (set with `AT$TTS`) or terminal speed. Telnet protocol should be enabled for these sites, or you will at best see occasional garbage characters on your screen, or at worst the connection may fail.
The difference between *real* and *fake* telnet protocol is this: with *real* telnet protocol, a carriage return (CR) character being sent from the modem to the telnet server always has a NUL character added after it. The implementation of the telnet protocol used by some BBSes doesn't properly strip out the NUL character. When connecting to such BBSes (Particles! is one), use *fake* telnet.
When using *real* telnet protocol, when the telnet server sends a CR character followed by a NUL character, only the CR character will be sent to the serial port; the NUL character will be silently stripped out. With *fake* telnet protocol, the NUL will be passed through.
176 | ATO | Return online. Use with the escape code (+++) to toggle between command and online modes.
177 | ATQ?
ATQ*n* | Enable or disable the display of result codes. The default is Q0.
- Q0 Display result codes.
- Q1 Suppress result codes (quiet).
178 | ATRD
ATRT | Displays the current UTC date and time from NIST in the format *YY-MM-DD HH:MM:SS*. A WiFi connection is required and you cannot be connected to another site.
179 | ATS0?
ATS0=*n* | Display or set the number of "rings" before answering an incoming connection. Setting `S0=0` means "don't answer".
180 | ATS2?
ATS2=*n* | Display or set the ASCII code used in the online escape sequence. The default value is 43 (the + plus character). Setting it to any value between 128 and 255 will disable the online escape function.
181 | ATV?
ATV*n* | Display result codes in words or numbers. The default is V1.
- V0 Display result codes in numeric form.
- V1 Display result codes in text form.
182 | ATX?
ATX*n* | Control the amount of information displayed in the result codes. The default is X1 (extended codes).
- X0 Display basic codes (CONNECT, NO CARRIER)
- X1 Display extended codes (CONNECT speed, NO CARRIER (connect time))
183 | ATZ | Resets the modem.
184 | AT&D?
AT&D*n* | Display or set the handling of DTR going inactive. The default is &D0 (ignored).
- &D0 Ignore
- &D1 Go to command mode
- &D2 End call
- &D3 Reset modem
185 | AT&F | Reset the NVRAM contents and current settings to the sketch defaults. All settings, including SSID name, password and speed dial slots are affected.
186 | AT&K?
AT&K*n* | Data flow control. Prevents the modem's buffers for received and transmitted from overflowing.
- &K0 Disable data flow control.
- &K1 Use hardware flow control. Requires that your computer and software support Clear to Send (CTS) and Request to Send (RTS) at the RS-232 interface.
187 | AT&R?
AT&R=*server pwd* | Query or change the password for incoming connections. If set, the user has 3 chances in 60 seconds to enter the correct password or the modem will end the connection.
188 | AT&V*n* | Display current or stored settings.
- &V0 Display current settings.
- &V1 Display stored settings.
189 | AT&W | Save current settings to NVRAM.
190 | AT&Zn?
AT&Z*n*=*host[:port],alias* | Store up to 10 numbers in NVRAM, where *n* is the position 0-9 in NVRAM, and *host[:port]* is the host string, and *alias* is the speed dial alias name. The host string may be up to 50 characters long, and the alias string may be up to 16 characters long.
Example: `AT&Z2=particlesbbs.dyndns.org:6400,particles`
This number can then be dialed in any of the following ways:
- `ATDS2`
- `ATDTparticles`
- `ATDT2222222`
191 | AT$AE?
AT$AE=*startup AT cmd* | Query or change the command line to be executed when the modem starts up.
192 | AT$AYT | Sends a Telnet "Are You There?" command if connected to a Telnet remote.
193 | AT$BM?
AT$BM=*server busy msg* | Query or change a message to be returned to an incoming connection if the modem is busy (i.e. already has a connection established).
194 | AT$MDNS
AT$MDNS=*mDNS name* | Query or change the mDNS network name (defaults to "espmodem"). When a non zero TCP port is defined, you can telnet to that port with **telnet mdnsname.local port**.
195 | AT$PASS?
AT$PASS=*WiFi pwd* | Query or change the current WiFi password. The password is case sensitive. Clear the password by issuing the set command with no password. The maximum length of the password is 64 characters.
196 | AT$SB?
AT$SB=*n* | Query or change the current baud rate. Valid values for "n" are 110, 300, 450, 600, 710, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 76800 and 115200. Any other value will return an ERROR message. The default baud rate is 1200. The Pico WiFi modem does not automatically detect baud rate like a dial-up modem. The baud rate setting must match that of your terminal to operate properly. It will display garbage in your terminal otherwise.
197 | AT$SP?
AT$SP=*n* | TCP server port to listen on. A value of 0 means that the TCP server is disabled, and no incoming connections are allowed.
198 | AT$SSID?
AT$SSID=*ssid name* | Query or change the current SSID to the specified name. The given SSID name is case sensitive. Clear the SSID by issuing the set command with no SSID. The maximum length of the SSID name is 32 characters.
199 | AT$SU?
AT$SU=*dps* | Query or change the current number of data bits ('d'), parity ('p') and stop bits ('s") of the serial UART. Valid values for 'd' are 5, 6, 7 or 8 bits. Valid values for 'p' are (N)one, (O)dd or (E)ven parity. Valid values for 's' are 1 or 2 bits. The default settings are 8N1. The UART setting must match your terminal to work properly.
200 | AT$TTL?
AT$TTL=*telnet location* | Query or change the Telnet location value to be returned when the Telnet server issues a SEND-LOCATION request. The default value is "Computer Room".
201 | AT$TTS?
AT$TTS=*WxH* | Query or change the window size (columns x rows) to be returned when the Telnet server issues a NAWS (Negotiate About Window Size) request. The default value is 80x24. For terminals that are smaller than 80x24, setting these values appropriately will enable paging on the help (AT?) and network status (ATI) commands.
202 | AT$TTY?
AT$TTY=*terminal type* | Query or change the terminal type to be returned when the Telnet server issues a TERMINAL-TYPE request. The default value is "ansi".
203 | AT$W?
AT$W=*n* | Startup wait.
- $W=0 Startup with no wait.
- $W=1 Wait for the return key to be pressed at startup.
204 |
205 | ### Updating the Code
206 |
207 | As I'm writing this, I haven't settled on an OTA programming method that
208 | I like. But I will figure something out; taking the modem apart to do a
209 | code update will get old the very first time I have to do it. Plus,
210 | it means that the Pico W can't be soldered down to the PCB, and that'd
211 | be a nice to have as well.
212 |
213 | ## Status
214 |
215 | It's a work in progress at the moment. The lack of OTA programming is
216 | the big "needs to be done" item.
217 |
218 | As this is my first Pico project, and the first time I've written lwIP
219 | stuff (and the first time I've really had to make changes to CMake
220 | stuff), I've run headlong into all the usual beginner gotchas. And I'm
221 | completely, absolutely sure that I haven't found them all yet.
222 |
223 | The code works reasonably well at the moment; it can call out, you can
224 | call in, Ymodem and Zmodem transfers work, I've figured out why it used
225 | to appear to lock up when I left it alone for 10 minutes (Wifi power
226 | management, if you're wondering)... but I'm under no illusion that there
227 | aren't bugs aplenty yet to be squashed. After all, I found a handful of
228 | problems in the original ESP8266 Retro Wifi modem code while I was
229 | getting the Pico code working, and the ESP code had been pretty much
230 | stable for over two years.
231 |
232 | And I think I may have also discovered why every once in a while, the
233 | modem would get behind a few (or many) characters either on receive or
234 | transmit. The 'volatile' qualifier isn't of as much use with variables
235 | modified by two threads as it is with memory mapped I/O or hardware
236 | registers. To make a long story short, '++var' and '--var' aren't
237 | atomic operations; they're read/modify/write. And every once in a great
238 | while the main thread would be updated a buffer length at the same time
239 | the lwIP thread was updating the same buffer length and whackiness
240 | ensued.
241 |
242 | For the moment, I've taken the naive approach of surrounding the buffer
243 | length writes with disable/re-enable interrupt calls. I think that will
244 | work reasonably well (though if I ever decided to make use of the second
245 | core, it'll fail because interrupts are only disabled on the calling
246 | core). If not, it'll be time to bone up on mutexes and semaphores and
247 | critical sections.
248 |
249 | ### Linux, Telnet, Zmodem and downloading binary files
250 |
251 | Have you used the modem to 'dial' into a Linux box? And have you done a
252 | `sz binary_file` on the Linux box? And at a completely reproducible
253 | point in the file, has the connection dropped? But other binary files
254 | work just fine? Then read on.
255 |
256 | This drove me slightly batty for months on the original Retro modem. I
257 | finally narrowed it down to trying to send blocks of binary data with a
258 | large number of FF bytes. eventually created a test file consisting of
259 | 2K of FF and used that to test with. I could download it through the
260 | modem with Xmodem just fine. Ymodem also worked if I kept the block size
261 | down to 128 bytes - but the connection would drop instantly if I tried
262 | sending 1K blocks. Same thing with Zmodem.
263 |
264 | In fact, if I just tried `cat binary_file`, the connection would
265 | drop. Which eventually got me thinking. Sitting at the console on my
266 | main Linux box, I telnet'd to the same box and logged in. No WiFi modem
267 | involved anywhere, just a telnet session on the console to the same box.
268 | I then did a `cat binary_file`. The telnet connection dropped, and I
269 | was back in my original session.
270 |
271 | It's the Linux telnet daemon. Not the modem at all.
272 |
273 | To prove it to myself, I hooked up WiFi modems to two systems on their
274 | serial ports and had one dial into the other. I could send the all FF
275 | binary file back and forth with Zmodem and Ymodem, no trouble at all.
276 |
277 | But you really, really need to download that binary file through the
278 | modem from a telnet connection to a Linux box? You're not going to be
279 | able to use Zmodem. Ymodem will work (the sy command defaults to 128
280 | byte blocks), as will Xmodem. But not Zmodem.
281 |
282 | Oddly enough, the telnet daemon has no trouble *receiving* the all FF
283 | binary file. Only sending it. Your guess as to why is probably better
284 | than mine.
285 |
286 | ## References
287 |
288 | * [Retro WiFi Modem](https://github.com/mecparts/RetroWiFiModem)
289 | * [WiFi232 - An Internet Hayes Modem for your Retro Computer](http://biosrhythm.com/?page_id=1453)
290 | * [WiFi232's Evil Clone](https://forum.vcfed.org/index.php?threads/wifi232s-evil-clone.1070412/)
291 | * [Jussi Salin's Virtual modem for ESP8266](https://github.com/jsalin/esp8266_modem)
292 | * [Stardot's ESP8266 based virtual modem](https://github.com/stardot/esp8266_modem)
293 | * [Roland Juno's ESP8266 based virtual modem](https://github.com/RolandJuno/esp8266_modem)
294 |
295 | ## Acknowledgements
296 |
297 | * A whole lot of people owe a big vote of thanks to Jussi Salin for
298 | releasing their virtual modem code for the ESP8266 and starting the
299 | ball rolling.
300 | * Paul Rickards for an amazing bit of hardware to draw inspiration from.
301 | * All the Stardot contributors for their work.
302 | * And, of course, Dennis C. Hayes for creating something so simple and
303 | elegant that has stood the test of time.
304 |
--------------------------------------------------------------------------------
/case/.gitignore:
--------------------------------------------------------------------------------
1 | *.gcode
2 | dimension_test.scad
3 | pcb_test.*
4 |
--------------------------------------------------------------------------------
/case/back_panel.scad:
--------------------------------------------------------------------------------
1 | $fn=64;
2 | eps = 0.04;
3 | inch = 25.4;
4 |
5 | panel_x = 68.76;
6 | panel_y = 19.84;
7 | panel_z = 1.5;
8 | panel_r = 0.05 * inch;
9 |
10 | barrel_x = 0.354*inch;
11 | barrel_y = 0.428*inch;
12 |
13 | module dsub(c,e,a)
14 | {
15 | r=3.35;
16 | h=3.96;
17 | md=3.05;
18 | hull() {
19 | translate([-c/2,h/2,0])
20 | circle(r=r);
21 | translate([c/2,h/2,0])
22 | circle(r=r);
23 | translate([-e/2,-h/2,0])
24 | circle(r=r);
25 | translate([e/2,-h/2,0])
26 | circle(r=r);
27 | }
28 | translate([-a/2,0,0])
29 | circle(d=md);
30 | translate([a/2,0,0])
31 | circle(d=md);
32 | }
33 |
34 | module dsub9() {
35 | dsub(c=13.77,e=12.01,a=24.99);
36 | }
37 |
38 | difference() {
39 | linear_extrude(height=panel_z) {
40 | hull() {
41 | translate([panel_r, panel_r, 0]) {
42 | circle(r=panel_r);
43 | }
44 | translate([panel_x-panel_r, panel_r, 0]) {
45 | circle(r=panel_r);
46 | }
47 | translate([panel_x-panel_r, panel_y-panel_r, 0]) {
48 | circle(r=panel_r);
49 | }
50 | translate([panel_r, panel_y-panel_r, 0]) {
51 | circle(r=panel_r);
52 | }
53 | }
54 | }
55 | translate([panel_x/2 - 12.015, panel_y/2, -eps] ) {
56 | linear_extrude(height=panel_z+2*eps) {
57 | dsub9();
58 | }
59 | }
60 | translate([panel_x/2+13.33,6.17+barrel_y/2,-eps]) {
61 | linear_extrude(height=panel_z+2*eps) {
62 | square([barrel_x, barrel_y],center=true);
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/case/front_panel.ods:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mecparts/PicoWiFiModem/12148fc6f5a816a76dc473e19f7c6679ca7caa85/case/front_panel.ods
--------------------------------------------------------------------------------
/case/front_panel.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mecparts/PicoWiFiModem/12148fc6f5a816a76dc473e19f7c6679ca7caa85/case/front_panel.pdf
--------------------------------------------------------------------------------
/case/front_panel.scad:
--------------------------------------------------------------------------------
1 | $fn=64;
2 | eps = 0.04;
3 | inch = 25.4;
4 |
5 | panel_x = 68.76;
6 | panel_y = 19.84;
7 | panel_z = 1.5;
8 | panel_r = 0.05 * inch;
9 |
10 | lens_x = 2.363 * inch;
11 | lens_y = 0.592 * inch;
12 | lens_z = 0.062 * inch;
13 |
14 | bezel_x = 2.258 * inch;
15 | bezel_y = 0.487 * inch;
16 | bezel_r = 1/16 * inch;
17 |
18 | difference() {
19 | linear_extrude(height=panel_z) {
20 | hull() {
21 | translate([panel_r, panel_r, 0]) {
22 | circle(r=panel_r);
23 | }
24 | translate([panel_x-panel_r, panel_r, 0]) {
25 | circle(r=panel_r);
26 | }
27 | translate([panel_x-panel_r, panel_y-panel_r, 0]) {
28 | circle(r=panel_r);
29 | }
30 | translate([panel_r, panel_y-panel_r, 0]) {
31 | circle(r=panel_r);
32 | }
33 | }
34 | }
35 | translate([panel_x/2,panel_y-1.27-lens_y/2,0.4]) {
36 | linear_extrude(height=panel_z+2*eps) {
37 | square([lens_x+2*eps, lens_y+2*eps],center=true);
38 | }
39 | }
40 | translate([panel_x/2,panel_y-1.27-lens_y/2,-eps]) {
41 | linear_extrude(height=panel_z+2*eps) {
42 | hull() {
43 | translate([-bezel_x/2+bezel_r, -bezel_y/2+bezel_r, 0]) {
44 | circle(r=bezel_r);
45 | }
46 | translate([bezel_x/2-bezel_r, -bezel_y/2+bezel_r, 0]) {
47 | circle(r=bezel_r);
48 | }
49 | translate([bezel_x/2-bezel_r, bezel_y/2-bezel_r, 0]) {
50 | circle(r=bezel_r);
51 | }
52 | translate([-bezel_x/2+bezel_r, bezel_y/2-bezel_r, 0]) {
53 | circle(r=bezel_r);
54 | }
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/images/Back panel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mecparts/PicoWiFiModem/12148fc6f5a816a76dc473e19f7c6679ca7caa85/images/Back panel.jpg
--------------------------------------------------------------------------------
/images/Builtin help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mecparts/PicoWiFiModem/12148fc6f5a816a76dc473e19f7c6679ca7caa85/images/Builtin help.png
--------------------------------------------------------------------------------
/images/Front panel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mecparts/PicoWiFiModem/12148fc6f5a816a76dc473e19f7c6679ca7caa85/images/Front panel.jpg
--------------------------------------------------------------------------------
/images/Interior.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mecparts/PicoWiFiModem/12148fc6f5a816a76dc473e19f7c6679ca7caa85/images/Interior.jpg
--------------------------------------------------------------------------------
/images/PicoWifiModem.sch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mecparts/PicoWiFiModem/12148fc6f5a816a76dc473e19f7c6679ca7caa85/images/PicoWifiModem.sch.png
--------------------------------------------------------------------------------
/images/Prototype.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mecparts/PicoWiFiModem/12148fc6f5a816a76dc473e19f7c6679ca7caa85/images/Prototype.jpg
--------------------------------------------------------------------------------
/kicad/.gitignore:
--------------------------------------------------------------------------------
1 | Pico_Wifi_modem-cache.lib
2 | Pico_Wifi_modem.bak
3 | Pico_Wifi_modem-cache.dcm
4 | Pico_Wifi_modem.kicad_pcb-bak
5 |
--------------------------------------------------------------------------------
/kicad/Pico_Wifi_modem-bom.csv:
--------------------------------------------------------------------------------
1 | Reference,Quantity, Value, Price, DigiKey PN
2 | P1,1,CONN_02X05,0.41,ED1543-ND
3 | D1-D8,8,TLPR5600,6.4,TLPR5600-ND
4 | C1-C5,5,100nF,1.55,399-9859-1-ND
5 | C6,1,100nF,0.33,399-9843-ND
6 | C7,1,1uF,2.54,399-3529-ND
7 | CON1,1,BARREL_JACK,1.09,839-54-00166-ND
8 | R1-R8,8,560R,1.28,CF18JT560RCT-ND
9 | U3,1,Pico W,8.88,2648-SC0918CT-ND
10 | U4,1,LM2950ACZ-3.3,1.26,LP2950ACZ-3.3GOS-ND
11 | U1,1,MAX3237ECDWR,5.37,296-36945-1-ND
12 | D12,1,1N5817,0.47,N5817-TPCT-ND
13 | U5,1,AT24C32E-PUM,0.98,AT24C32E-PUM-ND
14 | R12-R13,2,3.9K,0.32,CF18JT3K90CT-ND
15 | U2,1,74HCT245,1.42,296-1612-5-ND
16 | ,1,Hammond 1593NBK case,9.26,HM963-ND
17 | ,1,Hammond red panel,0.88,HM889-ND
18 | ,50,PCB screws,12.46,HM1442-ND
19 | ,1,5V wall adapter,8.92,364-1251-ND
20 | ,1,DE-9F IDC connector,19.9,5746861-4-ND
21 | ,2,D-sub jackscrew,0.94,2057-JS-02-ND
22 | ,1,8 pin DIP socket,0.44,1175-1475-ND
23 | ,1,20 pin DIP socket,0.67,1175-1479-ND
24 | ,1,10 pos IDC socket,0.69,1175-1443-ND
25 | ,1,10 cond ribbon cable,0.95,3M157815-1-ND
26 |
--------------------------------------------------------------------------------
/kicad/Pico_Wifi_modem.pro:
--------------------------------------------------------------------------------
1 | update=Thu 10 Nov 2022 03:22:54 PM MST
2 | version=1
3 | last_client=kicad
4 | [pcbnew]
5 | version=1
6 | LastNetListRead=
7 | UseCmpFile=1
8 | PadDrill=0.600000000000
9 | PadDrillOvalY=0.600000000000
10 | PadSizeH=1.500000000000
11 | PadSizeV=1.500000000000
12 | PcbTextSizeV=1.500000000000
13 | PcbTextSizeH=1.500000000000
14 | PcbTextThickness=0.300000000000
15 | ModuleTextSizeV=1.000000000000
16 | ModuleTextSizeH=1.000000000000
17 | ModuleTextSizeThickness=0.150000000000
18 | SolderMaskClearance=0.000000000000
19 | SolderMaskMinWidth=0.000000000000
20 | DrawSegmentWidth=0.200000000000
21 | BoardOutlineThickness=0.100000000000
22 | ModuleOutlineThickness=0.150000000000
23 | [cvpcb]
24 | version=1
25 | NetIExt=net
26 | [general]
27 | version=1
28 | [eeschema]
29 | version=1
30 | LibDir=
31 |
--------------------------------------------------------------------------------
/kicad/fp-info-cache:
--------------------------------------------------------------------------------
1 | 0
2 |
--------------------------------------------------------------------------------
/kicad/fp-lib-table:
--------------------------------------------------------------------------------
1 | (fp_lib_table
2 | (lib (name modules)(type KiCad)(uri "$(KIPRJMOD)/modules.pretty")(options "")(descr ""))
3 | )
4 |
--------------------------------------------------------------------------------
/kicad/gerbers/Pico_Wifi_modem-B.Mask.gbs:
--------------------------------------------------------------------------------
1 | G04 #@! TF.FileFunction,Soldermask,Bot*
2 | %FSLAX46Y46*%
3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
4 | G04 Created by KiCad (PCBNEW 4.0.5+dfsg1-4) date Sat Oct 15 20:35:36 2022*
5 | %MOMM*%
6 | %LPD*%
7 | G01*
8 | G04 APERTURE LIST*
9 | %ADD10C,0.150000*%
10 | %ADD11C,3.600000*%
11 | %ADD12R,1.700000X1.700000*%
12 | %ADD13C,1.700000*%
13 | %ADD14R,3.900120X3.900120*%
14 | %ADD15R,2.400000X2.400000*%
15 | %ADD16C,2.400000*%
16 | %ADD17C,2.398980*%
17 | %ADD18R,2.398980X2.398980*%
18 | %ADD19R,2.127200X2.127200*%
19 | %ADD20O,2.127200X2.127200*%
20 | %ADD21C,1.797000*%
21 | %ADD22O,2.700000X2.000000*%
22 | %ADD23O,2.100000X2.100000*%
23 | %ADD24R,2.100000X2.100000*%
24 | %ADD25O,2.200000X2.200000*%
25 | %ADD26O,1.900000X1.900000*%
26 | %ADD27O,1.299160X1.901140*%
27 | G04 APERTURE END LIST*
28 | D10*
29 | D11*
30 | X119450000Y-85770000D03*
31 | X119450000Y-132020000D03*
32 | X159450000Y-132020000D03*
33 | X159450000Y-85770000D03*
34 | X189450000Y-85770000D03*
35 | X189450000Y-132020000D03*
36 | D12*
37 | X129286000Y-82042000D03*
38 | D13*
39 | X129286000Y-84542000D03*
40 | D12*
41 | X133858000Y-85471000D03*
42 | D13*
43 | X133858000Y-82971000D03*
44 | D12*
45 | X149733000Y-84582000D03*
46 | D13*
47 | X149733000Y-82082000D03*
48 | D12*
49 | X142748000Y-78359000D03*
50 | D13*
51 | X140248000Y-78359000D03*
52 | D12*
53 | X186182000Y-78359000D03*
54 | D13*
55 | X186182000Y-80859000D03*
56 | D12*
57 | X153162000Y-80772000D03*
58 | D13*
59 | X153162000Y-85852000D03*
60 | D12*
61 | X111760000Y-138176000D03*
62 | D13*
63 | X114260000Y-138176000D03*
64 | D14*
65 | X119610140Y-122230000D03*
66 | X113610660Y-122230000D03*
67 | X116610400Y-126929000D03*
68 | D15*
69 | X205740000Y-84516000D03*
70 | D16*
71 | X205740000Y-87056000D03*
72 | D15*
73 | X205740000Y-91120000D03*
74 | D16*
75 | X205740000Y-93660000D03*
76 | D15*
77 | X205740000Y-97724000D03*
78 | D16*
79 | X205740000Y-100264000D03*
80 | D15*
81 | X205740000Y-104328000D03*
82 | D16*
83 | X205740000Y-106868000D03*
84 | D15*
85 | X205740000Y-110932000D03*
86 | D16*
87 | X205740000Y-113472000D03*
88 | D15*
89 | X205740000Y-117536000D03*
90 | D16*
91 | X205740000Y-120076000D03*
92 | D15*
93 | X205740000Y-124140000D03*
94 | D16*
95 | X205740000Y-126680000D03*
96 | D15*
97 | X205740000Y-130744000D03*
98 | D16*
99 | X205740000Y-133284000D03*
100 | D17*
101 | X172593000Y-133098540D03*
102 | D18*
103 | X182753000Y-133098540D03*
104 | D19*
105 | X128905000Y-101965000D03*
106 | D20*
107 | X126365000Y-101965000D03*
108 | X128905000Y-99425000D03*
109 | X126365000Y-99425000D03*
110 | X128905000Y-96885000D03*
111 | X126365000Y-96885000D03*
112 | X128905000Y-94345000D03*
113 | X126365000Y-94345000D03*
114 | X128905000Y-91805000D03*
115 | X126365000Y-91805000D03*
116 | D21*
117 | X195045000Y-84516000D03*
118 | X202665000Y-84516000D03*
119 | X195045000Y-91120000D03*
120 | X202665000Y-91120000D03*
121 | X195045000Y-97724000D03*
122 | X202665000Y-97724000D03*
123 | X195045000Y-104328000D03*
124 | X202665000Y-104328000D03*
125 | X195045000Y-110932000D03*
126 | X202665000Y-110932000D03*
127 | X195045000Y-117536000D03*
128 | X202665000Y-117536000D03*
129 | X195045000Y-124140000D03*
130 | X202665000Y-124140000D03*
131 | X195045000Y-130744000D03*
132 | X202665000Y-130744000D03*
133 | X147193000Y-131572000D03*
134 | X139573000Y-131572000D03*
135 | X147193000Y-134366000D03*
136 | X139573000Y-134366000D03*
137 | D22*
138 | X174879000Y-79121000D03*
139 | X174879000Y-81661000D03*
140 | X174879000Y-84201000D03*
141 | X174879000Y-86741000D03*
142 | X174879000Y-89281000D03*
143 | X174879000Y-91821000D03*
144 | X174879000Y-94361000D03*
145 | X174879000Y-96901000D03*
146 | X174879000Y-99441000D03*
147 | X174879000Y-101981000D03*
148 | X182499000Y-101981000D03*
149 | X182499000Y-99441000D03*
150 | X182499000Y-96901000D03*
151 | X182499000Y-94361000D03*
152 | X182499000Y-91821000D03*
153 | X182499000Y-89281000D03*
154 | X182499000Y-86741000D03*
155 | X182499000Y-84201000D03*
156 | X182499000Y-81661000D03*
157 | X182499000Y-79121000D03*
158 | D23*
159 | X185293000Y-108331000D03*
160 | X182753000Y-108331000D03*
161 | D24*
162 | X180213000Y-108331000D03*
163 | D23*
164 | X177673000Y-108331000D03*
165 | X175133000Y-108331000D03*
166 | X172593000Y-108331000D03*
167 | X170053000Y-108331000D03*
168 | D24*
169 | X167513000Y-108331000D03*
170 | D23*
171 | X164973000Y-108331000D03*
172 | X162433000Y-108331000D03*
173 | X159893000Y-108331000D03*
174 | X157353000Y-108331000D03*
175 | D24*
176 | X154813000Y-108331000D03*
177 | D23*
178 | X152273000Y-108331000D03*
179 | X149733000Y-108331000D03*
180 | X147193000Y-108331000D03*
181 | X144653000Y-108331000D03*
182 | D24*
183 | X142113000Y-108331000D03*
184 | D23*
185 | X139573000Y-108331000D03*
186 | X137033000Y-108331000D03*
187 | X137033000Y-126111000D03*
188 | X139573000Y-126111000D03*
189 | D24*
190 | X142113000Y-126111000D03*
191 | D23*
192 | X144653000Y-126111000D03*
193 | X147193000Y-126111000D03*
194 | X149733000Y-126111000D03*
195 | X152273000Y-126111000D03*
196 | D24*
197 | X154813000Y-126111000D03*
198 | D23*
199 | X157353000Y-126111000D03*
200 | X159893000Y-126111000D03*
201 | X162433000Y-126111000D03*
202 | X164973000Y-126111000D03*
203 | D24*
204 | X167513000Y-126111000D03*
205 | D23*
206 | X170053000Y-126111000D03*
207 | X172593000Y-126111000D03*
208 | X175133000Y-126111000D03*
209 | X177673000Y-126111000D03*
210 | D24*
211 | X180213000Y-126111000D03*
212 | D23*
213 | X182753000Y-126111000D03*
214 | X185293000Y-126111000D03*
215 | D25*
216 | X185163000Y-119946000D03*
217 | X185163000Y-114496000D03*
218 | D26*
219 | X182133000Y-114796000D03*
220 | X182133000Y-119646000D03*
221 | D23*
222 | X155563000Y-117805100D03*
223 | D24*
224 | X155563000Y-120345100D03*
225 | D23*
226 | X155563000Y-122885100D03*
227 | D27*
228 | X113030000Y-133858000D03*
229 | X114300000Y-133858000D03*
230 | X111760000Y-133858000D03*
231 | D22*
232 | X125095000Y-125730000D03*
233 | X125095000Y-128270000D03*
234 | X125095000Y-130810000D03*
235 | X125095000Y-133350000D03*
236 | X132715000Y-133350000D03*
237 | X132715000Y-130810000D03*
238 | X132715000Y-128270000D03*
239 | X132715000Y-125730000D03*
240 | M02*
241 |
--------------------------------------------------------------------------------
/kicad/gerbers/Pico_Wifi_modem-B.Paste.gbp:
--------------------------------------------------------------------------------
1 | G04 #@! TF.FileFunction,Paste,Bot*
2 | %FSLAX46Y46*%
3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
4 | G04 Created by KiCad (PCBNEW 4.0.5+dfsg1-4) date Sat Oct 15 20:35:36 2022*
5 | %MOMM*%
6 | %LPD*%
7 | G01*
8 | G04 APERTURE LIST*
9 | %ADD10C,0.150000*%
10 | G04 APERTURE END LIST*
11 | D10*
12 | M02*
13 |
--------------------------------------------------------------------------------
/kicad/gerbers/Pico_Wifi_modem-B.SilkS.gbo:
--------------------------------------------------------------------------------
1 | G04 #@! TF.FileFunction,Legend,Bot*
2 | %FSLAX46Y46*%
3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
4 | G04 Created by KiCad (PCBNEW 4.0.5+dfsg1-4) date Sat Oct 15 20:35:36 2022*
5 | %MOMM*%
6 | %LPD*%
7 | G01*
8 | G04 APERTURE LIST*
9 | %ADD10C,0.150000*%
10 | %ADD11C,0.300000*%
11 | %ADD12C,3.600000*%
12 | %ADD13R,1.700000X1.700000*%
13 | %ADD14C,1.700000*%
14 | %ADD15R,3.900120X3.900120*%
15 | %ADD16R,2.400000X2.400000*%
16 | %ADD17C,2.400000*%
17 | %ADD18C,2.398980*%
18 | %ADD19R,2.398980X2.398980*%
19 | %ADD20R,2.127200X2.127200*%
20 | %ADD21O,2.127200X2.127200*%
21 | %ADD22C,1.797000*%
22 | %ADD23O,2.700000X2.000000*%
23 | %ADD24O,2.100000X2.100000*%
24 | %ADD25R,2.100000X2.100000*%
25 | %ADD26O,2.200000X2.200000*%
26 | %ADD27O,1.900000X1.900000*%
27 | %ADD28O,1.299160X1.901140*%
28 | G04 APERTURE END LIST*
29 | D10*
30 | D11*
31 | X173171286Y-112301571D02*
32 | X173171286Y-110801571D01*
33 | X172599858Y-110801571D01*
34 | X172457000Y-110873000D01*
35 | X172385572Y-110944429D01*
36 | X172314143Y-111087286D01*
37 | X172314143Y-111301571D01*
38 | X172385572Y-111444429D01*
39 | X172457000Y-111515857D01*
40 | X172599858Y-111587286D01*
41 | X173171286Y-111587286D01*
42 | X171671286Y-112301571D02*
43 | X171671286Y-111301571D01*
44 | X171671286Y-110801571D02*
45 | X171742715Y-110873000D01*
46 | X171671286Y-110944429D01*
47 | X171599858Y-110873000D01*
48 | X171671286Y-110801571D01*
49 | X171671286Y-110944429D01*
50 | X170314143Y-112230143D02*
51 | X170457000Y-112301571D01*
52 | X170742714Y-112301571D01*
53 | X170885572Y-112230143D01*
54 | X170957000Y-112158714D01*
55 | X171028429Y-112015857D01*
56 | X171028429Y-111587286D01*
57 | X170957000Y-111444429D01*
58 | X170885572Y-111373000D01*
59 | X170742714Y-111301571D01*
60 | X170457000Y-111301571D01*
61 | X170314143Y-111373000D01*
62 | X169457000Y-112301571D02*
63 | X169599858Y-112230143D01*
64 | X169671286Y-112158714D01*
65 | X169742715Y-112015857D01*
66 | X169742715Y-111587286D01*
67 | X169671286Y-111444429D01*
68 | X169599858Y-111373000D01*
69 | X169457000Y-111301571D01*
70 | X169242715Y-111301571D01*
71 | X169099858Y-111373000D01*
72 | X169028429Y-111444429D01*
73 | X168957000Y-111587286D01*
74 | X168957000Y-112015857D01*
75 | X169028429Y-112158714D01*
76 | X169099858Y-112230143D01*
77 | X169242715Y-112301571D01*
78 | X169457000Y-112301571D01*
79 | X167314143Y-110801571D02*
80 | X166957000Y-112301571D01*
81 | X166671286Y-111230143D01*
82 | X166385572Y-112301571D01*
83 | X166028429Y-110801571D01*
84 | X165457000Y-112301571D02*
85 | X165457000Y-111301571D01*
86 | X165457000Y-110801571D02*
87 | X165528429Y-110873000D01*
88 | X165457000Y-110944429D01*
89 | X165385572Y-110873000D01*
90 | X165457000Y-110801571D01*
91 | X165457000Y-110944429D01*
92 | X164957000Y-111301571D02*
93 | X164385571Y-111301571D01*
94 | X164742714Y-112301571D02*
95 | X164742714Y-111015857D01*
96 | X164671286Y-110873000D01*
97 | X164528428Y-110801571D01*
98 | X164385571Y-110801571D01*
99 | X163885571Y-112301571D02*
100 | X163885571Y-111301571D01*
101 | X163885571Y-110801571D02*
102 | X163957000Y-110873000D01*
103 | X163885571Y-110944429D01*
104 | X163814143Y-110873000D01*
105 | X163885571Y-110801571D01*
106 | X163885571Y-110944429D01*
107 | X162028428Y-112301571D02*
108 | X162028428Y-111301571D01*
109 | X162028428Y-111444429D02*
110 | X161957000Y-111373000D01*
111 | X161814142Y-111301571D01*
112 | X161599857Y-111301571D01*
113 | X161457000Y-111373000D01*
114 | X161385571Y-111515857D01*
115 | X161385571Y-112301571D01*
116 | X161385571Y-111515857D02*
117 | X161314142Y-111373000D01*
118 | X161171285Y-111301571D01*
119 | X160957000Y-111301571D01*
120 | X160814142Y-111373000D01*
121 | X160742714Y-111515857D01*
122 | X160742714Y-112301571D01*
123 | X159814142Y-112301571D02*
124 | X159957000Y-112230143D01*
125 | X160028428Y-112158714D01*
126 | X160099857Y-112015857D01*
127 | X160099857Y-111587286D01*
128 | X160028428Y-111444429D01*
129 | X159957000Y-111373000D01*
130 | X159814142Y-111301571D01*
131 | X159599857Y-111301571D01*
132 | X159457000Y-111373000D01*
133 | X159385571Y-111444429D01*
134 | X159314142Y-111587286D01*
135 | X159314142Y-112015857D01*
136 | X159385571Y-112158714D01*
137 | X159457000Y-112230143D01*
138 | X159599857Y-112301571D01*
139 | X159814142Y-112301571D01*
140 | X158028428Y-112301571D02*
141 | X158028428Y-110801571D01*
142 | X158028428Y-112230143D02*
143 | X158171285Y-112301571D01*
144 | X158456999Y-112301571D01*
145 | X158599857Y-112230143D01*
146 | X158671285Y-112158714D01*
147 | X158742714Y-112015857D01*
148 | X158742714Y-111587286D01*
149 | X158671285Y-111444429D01*
150 | X158599857Y-111373000D01*
151 | X158456999Y-111301571D01*
152 | X158171285Y-111301571D01*
153 | X158028428Y-111373000D01*
154 | X156742714Y-112230143D02*
155 | X156885571Y-112301571D01*
156 | X157171285Y-112301571D01*
157 | X157314142Y-112230143D01*
158 | X157385571Y-112087286D01*
159 | X157385571Y-111515857D01*
160 | X157314142Y-111373000D01*
161 | X157171285Y-111301571D01*
162 | X156885571Y-111301571D01*
163 | X156742714Y-111373000D01*
164 | X156671285Y-111515857D01*
165 | X156671285Y-111658714D01*
166 | X157385571Y-111801571D01*
167 | X156028428Y-112301571D02*
168 | X156028428Y-111301571D01*
169 | X156028428Y-111444429D02*
170 | X155957000Y-111373000D01*
171 | X155814142Y-111301571D01*
172 | X155599857Y-111301571D01*
173 | X155457000Y-111373000D01*
174 | X155385571Y-111515857D01*
175 | X155385571Y-112301571D01*
176 | X155385571Y-111515857D02*
177 | X155314142Y-111373000D01*
178 | X155171285Y-111301571D01*
179 | X154957000Y-111301571D01*
180 | X154814142Y-111373000D01*
181 | X154742714Y-111515857D01*
182 | X154742714Y-112301571D01*
183 | X168528428Y-113351571D02*
184 | X168028428Y-114851571D01*
185 | X167528428Y-113351571D01*
186 | X166457000Y-114780143D02*
187 | X166599857Y-114851571D01*
188 | X166885571Y-114851571D01*
189 | X167028428Y-114780143D01*
190 | X167099857Y-114637286D01*
191 | X167099857Y-114065857D01*
192 | X167028428Y-113923000D01*
193 | X166885571Y-113851571D01*
194 | X166599857Y-113851571D01*
195 | X166457000Y-113923000D01*
196 | X166385571Y-114065857D01*
197 | X166385571Y-114208714D01*
198 | X167099857Y-114351571D01*
199 | X165742714Y-114851571D02*
200 | X165742714Y-113851571D01*
201 | X165742714Y-114137286D02*
202 | X165671286Y-113994429D01*
203 | X165599857Y-113923000D01*
204 | X165457000Y-113851571D01*
205 | X165314143Y-113851571D01*
206 | X164885572Y-114780143D02*
207 | X164742715Y-114851571D01*
208 | X164457000Y-114851571D01*
209 | X164314143Y-114780143D01*
210 | X164242715Y-114637286D01*
211 | X164242715Y-114565857D01*
212 | X164314143Y-114423000D01*
213 | X164457000Y-114351571D01*
214 | X164671286Y-114351571D01*
215 | X164814143Y-114280143D01*
216 | X164885572Y-114137286D01*
217 | X164885572Y-114065857D01*
218 | X164814143Y-113923000D01*
219 | X164671286Y-113851571D01*
220 | X164457000Y-113851571D01*
221 | X164314143Y-113923000D01*
222 | X162171286Y-113351571D02*
223 | X162028429Y-113351571D01*
224 | X161885572Y-113423000D01*
225 | X161814143Y-113494429D01*
226 | X161742714Y-113637286D01*
227 | X161671286Y-113923000D01*
228 | X161671286Y-114280143D01*
229 | X161742714Y-114565857D01*
230 | X161814143Y-114708714D01*
231 | X161885572Y-114780143D01*
232 | X162028429Y-114851571D01*
233 | X162171286Y-114851571D01*
234 | X162314143Y-114780143D01*
235 | X162385572Y-114708714D01*
236 | X162457000Y-114565857D01*
237 | X162528429Y-114280143D01*
238 | X162528429Y-113923000D01*
239 | X162457000Y-113637286D01*
240 | X162385572Y-113494429D01*
241 | X162314143Y-113423000D01*
242 | X162171286Y-113351571D01*
243 | X161028429Y-114708714D02*
244 | X160957001Y-114780143D01*
245 | X161028429Y-114851571D01*
246 | X161099858Y-114780143D01*
247 | X161028429Y-114708714D01*
248 | X161028429Y-114851571D01*
249 | X160385572Y-113494429D02*
250 | X160314143Y-113423000D01*
251 | X160171286Y-113351571D01*
252 | X159814143Y-113351571D01*
253 | X159671286Y-113423000D01*
254 | X159599857Y-113494429D01*
255 | X159528429Y-113637286D01*
256 | X159528429Y-113780143D01*
257 | X159599857Y-113994429D01*
258 | X160457000Y-114851571D01*
259 | X159528429Y-114851571D01*
260 | X170599856Y-115901571D02*
261 | X170314142Y-115901571D01*
262 | X170171284Y-115973000D01*
263 | X170028427Y-116115857D01*
264 | X169956999Y-116401571D01*
265 | X169956999Y-116901571D01*
266 | X170028427Y-117187286D01*
267 | X170171284Y-117330143D01*
268 | X170314142Y-117401571D01*
269 | X170599856Y-117401571D01*
270 | X170742713Y-117330143D01*
271 | X170885570Y-117187286D01*
272 | X170956999Y-116901571D01*
273 | X170956999Y-116401571D01*
274 | X170885570Y-116115857D01*
275 | X170742713Y-115973000D01*
276 | X170599856Y-115901571D01*
277 | X168671284Y-117330143D02*
278 | X168814141Y-117401571D01*
279 | X169099855Y-117401571D01*
280 | X169242713Y-117330143D01*
281 | X169314141Y-117258714D01*
282 | X169385570Y-117115857D01*
283 | X169385570Y-116687286D01*
284 | X169314141Y-116544429D01*
285 | X169242713Y-116473000D01*
286 | X169099855Y-116401571D01*
287 | X168814141Y-116401571D01*
288 | X168671284Y-116473000D01*
289 | X168242713Y-116401571D02*
290 | X167671284Y-116401571D01*
291 | X168028427Y-115901571D02*
292 | X168028427Y-117187286D01*
293 | X167956999Y-117330143D01*
294 | X167814141Y-117401571D01*
295 | X167671284Y-117401571D01*
296 | X165242713Y-117401571D02*
297 | X166099856Y-117401571D01*
298 | X165671284Y-117401571D02*
299 | X165671284Y-115901571D01*
300 | X165814141Y-116115857D01*
301 | X165956999Y-116258714D01*
302 | X166099856Y-116330143D01*
303 | X163885570Y-115901571D02*
304 | X164599856Y-115901571D01*
305 | X164671285Y-116615857D01*
306 | X164599856Y-116544429D01*
307 | X164456999Y-116473000D01*
308 | X164099856Y-116473000D01*
309 | X163956999Y-116544429D01*
310 | X163885570Y-116615857D01*
311 | X163814142Y-116758714D01*
312 | X163814142Y-117115857D01*
313 | X163885570Y-117258714D01*
314 | X163956999Y-117330143D01*
315 | X164099856Y-117401571D01*
316 | X164456999Y-117401571D01*
317 | X164599856Y-117330143D01*
318 | X164671285Y-117258714D01*
319 | X162099857Y-116044429D02*
320 | X162028428Y-115973000D01*
321 | X161885571Y-115901571D01*
322 | X161528428Y-115901571D01*
323 | X161385571Y-115973000D01*
324 | X161314142Y-116044429D01*
325 | X161242714Y-116187286D01*
326 | X161242714Y-116330143D01*
327 | X161314142Y-116544429D01*
328 | X162171285Y-117401571D01*
329 | X161242714Y-117401571D01*
330 | X160314143Y-115901571D02*
331 | X160171286Y-115901571D01*
332 | X160028429Y-115973000D01*
333 | X159957000Y-116044429D01*
334 | X159885571Y-116187286D01*
335 | X159814143Y-116473000D01*
336 | X159814143Y-116830143D01*
337 | X159885571Y-117115857D01*
338 | X159957000Y-117258714D01*
339 | X160028429Y-117330143D01*
340 | X160171286Y-117401571D01*
341 | X160314143Y-117401571D01*
342 | X160457000Y-117330143D01*
343 | X160528429Y-117258714D01*
344 | X160599857Y-117115857D01*
345 | X160671286Y-116830143D01*
346 | X160671286Y-116473000D01*
347 | X160599857Y-116187286D01*
348 | X160528429Y-116044429D01*
349 | X160457000Y-115973000D01*
350 | X160314143Y-115901571D01*
351 | X159242715Y-116044429D02*
352 | X159171286Y-115973000D01*
353 | X159028429Y-115901571D01*
354 | X158671286Y-115901571D01*
355 | X158528429Y-115973000D01*
356 | X158457000Y-116044429D01*
357 | X158385572Y-116187286D01*
358 | X158385572Y-116330143D01*
359 | X158457000Y-116544429D01*
360 | X159314143Y-117401571D01*
361 | X158385572Y-117401571D01*
362 | X157814144Y-116044429D02*
363 | X157742715Y-115973000D01*
364 | X157599858Y-115901571D01*
365 | X157242715Y-115901571D01*
366 | X157099858Y-115973000D01*
367 | X157028429Y-116044429D01*
368 | X156957001Y-116187286D01*
369 | X156957001Y-116330143D01*
370 | X157028429Y-116544429D01*
371 | X157885572Y-117401571D01*
372 | X156957001Y-117401571D01*
373 | %LPC*%
374 | D12*
375 | X119450000Y-85770000D03*
376 | X119450000Y-132020000D03*
377 | X159450000Y-132020000D03*
378 | X159450000Y-85770000D03*
379 | X189450000Y-85770000D03*
380 | X189450000Y-132020000D03*
381 | D13*
382 | X129286000Y-82042000D03*
383 | D14*
384 | X129286000Y-84542000D03*
385 | D13*
386 | X133858000Y-85471000D03*
387 | D14*
388 | X133858000Y-82971000D03*
389 | D13*
390 | X149733000Y-84582000D03*
391 | D14*
392 | X149733000Y-82082000D03*
393 | D13*
394 | X142748000Y-78359000D03*
395 | D14*
396 | X140248000Y-78359000D03*
397 | D13*
398 | X186182000Y-78359000D03*
399 | D14*
400 | X186182000Y-80859000D03*
401 | D13*
402 | X153162000Y-80772000D03*
403 | D14*
404 | X153162000Y-85852000D03*
405 | D13*
406 | X111760000Y-138176000D03*
407 | D14*
408 | X114260000Y-138176000D03*
409 | D15*
410 | X119610140Y-122230000D03*
411 | X113610660Y-122230000D03*
412 | X116610400Y-126929000D03*
413 | D16*
414 | X205740000Y-84516000D03*
415 | D17*
416 | X205740000Y-87056000D03*
417 | D16*
418 | X205740000Y-91120000D03*
419 | D17*
420 | X205740000Y-93660000D03*
421 | D16*
422 | X205740000Y-97724000D03*
423 | D17*
424 | X205740000Y-100264000D03*
425 | D16*
426 | X205740000Y-104328000D03*
427 | D17*
428 | X205740000Y-106868000D03*
429 | D16*
430 | X205740000Y-110932000D03*
431 | D17*
432 | X205740000Y-113472000D03*
433 | D16*
434 | X205740000Y-117536000D03*
435 | D17*
436 | X205740000Y-120076000D03*
437 | D16*
438 | X205740000Y-124140000D03*
439 | D17*
440 | X205740000Y-126680000D03*
441 | D16*
442 | X205740000Y-130744000D03*
443 | D17*
444 | X205740000Y-133284000D03*
445 | D18*
446 | X172593000Y-133098540D03*
447 | D19*
448 | X182753000Y-133098540D03*
449 | D20*
450 | X128905000Y-101965000D03*
451 | D21*
452 | X126365000Y-101965000D03*
453 | X128905000Y-99425000D03*
454 | X126365000Y-99425000D03*
455 | X128905000Y-96885000D03*
456 | X126365000Y-96885000D03*
457 | X128905000Y-94345000D03*
458 | X126365000Y-94345000D03*
459 | X128905000Y-91805000D03*
460 | X126365000Y-91805000D03*
461 | D22*
462 | X195045000Y-84516000D03*
463 | X202665000Y-84516000D03*
464 | X195045000Y-91120000D03*
465 | X202665000Y-91120000D03*
466 | X195045000Y-97724000D03*
467 | X202665000Y-97724000D03*
468 | X195045000Y-104328000D03*
469 | X202665000Y-104328000D03*
470 | X195045000Y-110932000D03*
471 | X202665000Y-110932000D03*
472 | X195045000Y-117536000D03*
473 | X202665000Y-117536000D03*
474 | X195045000Y-124140000D03*
475 | X202665000Y-124140000D03*
476 | X195045000Y-130744000D03*
477 | X202665000Y-130744000D03*
478 | X147193000Y-131572000D03*
479 | X139573000Y-131572000D03*
480 | X147193000Y-134366000D03*
481 | X139573000Y-134366000D03*
482 | D23*
483 | X174879000Y-79121000D03*
484 | X174879000Y-81661000D03*
485 | X174879000Y-84201000D03*
486 | X174879000Y-86741000D03*
487 | X174879000Y-89281000D03*
488 | X174879000Y-91821000D03*
489 | X174879000Y-94361000D03*
490 | X174879000Y-96901000D03*
491 | X174879000Y-99441000D03*
492 | X174879000Y-101981000D03*
493 | X182499000Y-101981000D03*
494 | X182499000Y-99441000D03*
495 | X182499000Y-96901000D03*
496 | X182499000Y-94361000D03*
497 | X182499000Y-91821000D03*
498 | X182499000Y-89281000D03*
499 | X182499000Y-86741000D03*
500 | X182499000Y-84201000D03*
501 | X182499000Y-81661000D03*
502 | X182499000Y-79121000D03*
503 | D24*
504 | X185293000Y-108331000D03*
505 | X182753000Y-108331000D03*
506 | D25*
507 | X180213000Y-108331000D03*
508 | D24*
509 | X177673000Y-108331000D03*
510 | X175133000Y-108331000D03*
511 | X172593000Y-108331000D03*
512 | X170053000Y-108331000D03*
513 | D25*
514 | X167513000Y-108331000D03*
515 | D24*
516 | X164973000Y-108331000D03*
517 | X162433000Y-108331000D03*
518 | X159893000Y-108331000D03*
519 | X157353000Y-108331000D03*
520 | D25*
521 | X154813000Y-108331000D03*
522 | D24*
523 | X152273000Y-108331000D03*
524 | X149733000Y-108331000D03*
525 | X147193000Y-108331000D03*
526 | X144653000Y-108331000D03*
527 | D25*
528 | X142113000Y-108331000D03*
529 | D24*
530 | X139573000Y-108331000D03*
531 | X137033000Y-108331000D03*
532 | X137033000Y-126111000D03*
533 | X139573000Y-126111000D03*
534 | D25*
535 | X142113000Y-126111000D03*
536 | D24*
537 | X144653000Y-126111000D03*
538 | X147193000Y-126111000D03*
539 | X149733000Y-126111000D03*
540 | X152273000Y-126111000D03*
541 | D25*
542 | X154813000Y-126111000D03*
543 | D24*
544 | X157353000Y-126111000D03*
545 | X159893000Y-126111000D03*
546 | X162433000Y-126111000D03*
547 | X164973000Y-126111000D03*
548 | D25*
549 | X167513000Y-126111000D03*
550 | D24*
551 | X170053000Y-126111000D03*
552 | X172593000Y-126111000D03*
553 | X175133000Y-126111000D03*
554 | X177673000Y-126111000D03*
555 | D25*
556 | X180213000Y-126111000D03*
557 | D24*
558 | X182753000Y-126111000D03*
559 | X185293000Y-126111000D03*
560 | D26*
561 | X185163000Y-119946000D03*
562 | X185163000Y-114496000D03*
563 | D27*
564 | X182133000Y-114796000D03*
565 | X182133000Y-119646000D03*
566 | D24*
567 | X155563000Y-117805100D03*
568 | D25*
569 | X155563000Y-120345100D03*
570 | D24*
571 | X155563000Y-122885100D03*
572 | D28*
573 | X113030000Y-133858000D03*
574 | X114300000Y-133858000D03*
575 | X111760000Y-133858000D03*
576 | D23*
577 | X125095000Y-125730000D03*
578 | X125095000Y-128270000D03*
579 | X125095000Y-130810000D03*
580 | X125095000Y-133350000D03*
581 | X132715000Y-133350000D03*
582 | X132715000Y-130810000D03*
583 | X132715000Y-128270000D03*
584 | X132715000Y-125730000D03*
585 | M02*
586 |
--------------------------------------------------------------------------------
/kicad/gerbers/Pico_Wifi_modem-Edge.Cuts.gm1:
--------------------------------------------------------------------------------
1 | G04 #@! TF.FileFunction,Profile,NP*
2 | %FSLAX46Y46*%
3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
4 | G04 Created by KiCad (PCBNEW 4.0.5+dfsg1-4) date Sat Oct 15 20:35:36 2022*
5 | %MOMM*%
6 | %LPD*%
7 | G01*
8 | G04 APERTURE LIST*
9 | %ADD10C,0.150000*%
10 | G04 APERTURE END LIST*
11 | D10*
12 | X109720000Y-75830000D02*
13 | X162485000Y-75830000D01*
14 | X162485000Y-75830000D02*
15 | X162485000Y-80975000D01*
16 | X162485000Y-80975000D02*
17 | G75*
18 | G03X169115000Y-80975000I3315000J0D01*
19 | G01*
20 | X169115000Y-80975000D02*
21 | X169115000Y-75830000D01*
22 | X169115000Y-75830000D02*
23 | X209720000Y-75830000D01*
24 | X209720000Y-75830000D02*
25 | X209720000Y-141970000D01*
26 | X209720000Y-141970000D02*
27 | X169115000Y-141970000D01*
28 | X169115000Y-141970000D02*
29 | X169115000Y-136825000D01*
30 | X169115000Y-136825000D02*
31 | G75*
32 | G03X162485000Y-136825000I-3315000J0D01*
33 | G01*
34 | X162485000Y-136825000D02*
35 | X162485000Y-141970000D01*
36 | X162485000Y-141970000D02*
37 | X109720000Y-141970000D01*
38 | X109720000Y-141970000D02*
39 | X109720000Y-112629000D01*
40 | X109720000Y-112629000D02*
41 | X111980600Y-112629000D01*
42 | X111980600Y-112629000D02*
43 | X111980600Y-106498900D01*
44 | X111980600Y-106498900D02*
45 | X116832000Y-106498900D01*
46 | X116832000Y-106498900D02*
47 | X116832000Y-87271100D01*
48 | X116832000Y-87271100D02*
49 | X111980600Y-87271100D01*
50 | X111980600Y-87271100D02*
51 | X111980600Y-81141000D01*
52 | X111980600Y-81141000D02*
53 | X109720000Y-81141000D01*
54 | X109720000Y-81141000D02*
55 | X109720000Y-75830000D01*
56 | M02*
57 |
--------------------------------------------------------------------------------
/kicad/gerbers/Pico_Wifi_modem-F.Mask.gts:
--------------------------------------------------------------------------------
1 | G04 #@! TF.FileFunction,Soldermask,Top*
2 | %FSLAX46Y46*%
3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
4 | G04 Created by KiCad (PCBNEW 4.0.5+dfsg1-4) date Sat Oct 15 20:35:36 2022*
5 | %MOMM*%
6 | %LPD*%
7 | G01*
8 | G04 APERTURE LIST*
9 | %ADD10C,0.150000*%
10 | %ADD11C,3.600000*%
11 | %ADD12R,1.700000X1.700000*%
12 | %ADD13C,1.700000*%
13 | %ADD14R,3.900120X3.900120*%
14 | %ADD15R,2.400000X2.400000*%
15 | %ADD16C,2.400000*%
16 | %ADD17C,2.398980*%
17 | %ADD18R,2.398980X2.398980*%
18 | %ADD19R,2.127200X2.127200*%
19 | %ADD20O,2.127200X2.127200*%
20 | %ADD21C,1.797000*%
21 | %ADD22R,2.400000X1.000000*%
22 | %ADD23O,2.700000X2.000000*%
23 | %ADD24O,2.100000X2.100000*%
24 | %ADD25R,2.100000X2.100000*%
25 | %ADD26O,2.200000X2.200000*%
26 | %ADD27O,1.900000X1.900000*%
27 | %ADD28R,2.100000X3.900000*%
28 | %ADD29O,1.299160X1.901140*%
29 | G04 APERTURE END LIST*
30 | D10*
31 | D11*
32 | X119450000Y-85770000D03*
33 | X119450000Y-132020000D03*
34 | X159450000Y-132020000D03*
35 | X159450000Y-85770000D03*
36 | X189450000Y-85770000D03*
37 | X189450000Y-132020000D03*
38 | D12*
39 | X129286000Y-82042000D03*
40 | D13*
41 | X129286000Y-84542000D03*
42 | D12*
43 | X133858000Y-85471000D03*
44 | D13*
45 | X133858000Y-82971000D03*
46 | D12*
47 | X149733000Y-84582000D03*
48 | D13*
49 | X149733000Y-82082000D03*
50 | D12*
51 | X142748000Y-78359000D03*
52 | D13*
53 | X140248000Y-78359000D03*
54 | D12*
55 | X186182000Y-78359000D03*
56 | D13*
57 | X186182000Y-80859000D03*
58 | D12*
59 | X153162000Y-80772000D03*
60 | D13*
61 | X153162000Y-85852000D03*
62 | D12*
63 | X111760000Y-138176000D03*
64 | D13*
65 | X114260000Y-138176000D03*
66 | D14*
67 | X119610140Y-122230000D03*
68 | X113610660Y-122230000D03*
69 | X116610400Y-126929000D03*
70 | D15*
71 | X205740000Y-84516000D03*
72 | D16*
73 | X205740000Y-87056000D03*
74 | D15*
75 | X205740000Y-91120000D03*
76 | D16*
77 | X205740000Y-93660000D03*
78 | D15*
79 | X205740000Y-97724000D03*
80 | D16*
81 | X205740000Y-100264000D03*
82 | D15*
83 | X205740000Y-104328000D03*
84 | D16*
85 | X205740000Y-106868000D03*
86 | D15*
87 | X205740000Y-110932000D03*
88 | D16*
89 | X205740000Y-113472000D03*
90 | D15*
91 | X205740000Y-117536000D03*
92 | D16*
93 | X205740000Y-120076000D03*
94 | D15*
95 | X205740000Y-124140000D03*
96 | D16*
97 | X205740000Y-126680000D03*
98 | D15*
99 | X205740000Y-130744000D03*
100 | D16*
101 | X205740000Y-133284000D03*
102 | D17*
103 | X172593000Y-133098540D03*
104 | D18*
105 | X182753000Y-133098540D03*
106 | D19*
107 | X128905000Y-101965000D03*
108 | D20*
109 | X126365000Y-101965000D03*
110 | X128905000Y-99425000D03*
111 | X126365000Y-99425000D03*
112 | X128905000Y-96885000D03*
113 | X126365000Y-96885000D03*
114 | X128905000Y-94345000D03*
115 | X126365000Y-94345000D03*
116 | X128905000Y-91805000D03*
117 | X126365000Y-91805000D03*
118 | D21*
119 | X195045000Y-84516000D03*
120 | X202665000Y-84516000D03*
121 | X195045000Y-91120000D03*
122 | X202665000Y-91120000D03*
123 | X195045000Y-97724000D03*
124 | X202665000Y-97724000D03*
125 | X195045000Y-104328000D03*
126 | X202665000Y-104328000D03*
127 | X195045000Y-110932000D03*
128 | X202665000Y-110932000D03*
129 | X195045000Y-117536000D03*
130 | X202665000Y-117536000D03*
131 | X195045000Y-124140000D03*
132 | X202665000Y-124140000D03*
133 | X195045000Y-130744000D03*
134 | X202665000Y-130744000D03*
135 | X147193000Y-131572000D03*
136 | X139573000Y-131572000D03*
137 | X147193000Y-134366000D03*
138 | X139573000Y-134366000D03*
139 | D22*
140 | X136905000Y-81661000D03*
141 | X136905000Y-82931000D03*
142 | X136905000Y-84201000D03*
143 | X136905000Y-85471000D03*
144 | X136905000Y-86741000D03*
145 | X136905000Y-88011000D03*
146 | X136905000Y-89281000D03*
147 | X136905000Y-90551000D03*
148 | X136905000Y-91821000D03*
149 | X136905000Y-93091000D03*
150 | X136905000Y-94361000D03*
151 | X136905000Y-95631000D03*
152 | X136905000Y-96901000D03*
153 | X136905000Y-98171000D03*
154 | X146305000Y-98171000D03*
155 | X146305000Y-96901000D03*
156 | X146305000Y-95631000D03*
157 | X146305000Y-94361000D03*
158 | X146305000Y-93091000D03*
159 | X146305000Y-91821000D03*
160 | X146305000Y-90551000D03*
161 | X146305000Y-89281000D03*
162 | X146305000Y-88011000D03*
163 | X146305000Y-86741000D03*
164 | X146305000Y-85471000D03*
165 | X146305000Y-84201000D03*
166 | X146305000Y-82931000D03*
167 | X146305000Y-81661000D03*
168 | D23*
169 | X174879000Y-79121000D03*
170 | X174879000Y-81661000D03*
171 | X174879000Y-84201000D03*
172 | X174879000Y-86741000D03*
173 | X174879000Y-89281000D03*
174 | X174879000Y-91821000D03*
175 | X174879000Y-94361000D03*
176 | X174879000Y-96901000D03*
177 | X174879000Y-99441000D03*
178 | X174879000Y-101981000D03*
179 | X182499000Y-101981000D03*
180 | X182499000Y-99441000D03*
181 | X182499000Y-96901000D03*
182 | X182499000Y-94361000D03*
183 | X182499000Y-91821000D03*
184 | X182499000Y-89281000D03*
185 | X182499000Y-86741000D03*
186 | X182499000Y-84201000D03*
187 | X182499000Y-81661000D03*
188 | X182499000Y-79121000D03*
189 | D24*
190 | X185293000Y-108331000D03*
191 | X182753000Y-108331000D03*
192 | D25*
193 | X180213000Y-108331000D03*
194 | D24*
195 | X177673000Y-108331000D03*
196 | X175133000Y-108331000D03*
197 | X172593000Y-108331000D03*
198 | X170053000Y-108331000D03*
199 | D25*
200 | X167513000Y-108331000D03*
201 | D24*
202 | X164973000Y-108331000D03*
203 | X162433000Y-108331000D03*
204 | X159893000Y-108331000D03*
205 | X157353000Y-108331000D03*
206 | D25*
207 | X154813000Y-108331000D03*
208 | D24*
209 | X152273000Y-108331000D03*
210 | X149733000Y-108331000D03*
211 | X147193000Y-108331000D03*
212 | X144653000Y-108331000D03*
213 | D25*
214 | X142113000Y-108331000D03*
215 | D24*
216 | X139573000Y-108331000D03*
217 | X137033000Y-108331000D03*
218 | X137033000Y-126111000D03*
219 | X139573000Y-126111000D03*
220 | D25*
221 | X142113000Y-126111000D03*
222 | D24*
223 | X144653000Y-126111000D03*
224 | X147193000Y-126111000D03*
225 | X149733000Y-126111000D03*
226 | X152273000Y-126111000D03*
227 | D25*
228 | X154813000Y-126111000D03*
229 | D24*
230 | X157353000Y-126111000D03*
231 | X159893000Y-126111000D03*
232 | X162433000Y-126111000D03*
233 | X164973000Y-126111000D03*
234 | D25*
235 | X167513000Y-126111000D03*
236 | D24*
237 | X170053000Y-126111000D03*
238 | X172593000Y-126111000D03*
239 | X175133000Y-126111000D03*
240 | X177673000Y-126111000D03*
241 | D25*
242 | X180213000Y-126111000D03*
243 | D24*
244 | X182753000Y-126111000D03*
245 | X185293000Y-126111000D03*
246 | D26*
247 | X185163000Y-119946000D03*
248 | X185163000Y-114496000D03*
249 | D27*
250 | X182133000Y-114796000D03*
251 | X182133000Y-119646000D03*
252 | D24*
253 | X155563000Y-117805100D03*
254 | D25*
255 | X155563000Y-120345100D03*
256 | D24*
257 | X155563000Y-122885100D03*
258 | D28*
259 | X185293000Y-107431000D03*
260 | X182753000Y-107431000D03*
261 | X180213000Y-107431000D03*
262 | X177673000Y-107431000D03*
263 | X175133000Y-107431000D03*
264 | X172593000Y-107431000D03*
265 | X170053000Y-107431000D03*
266 | X167513000Y-107431000D03*
267 | X164973000Y-107431000D03*
268 | X162433000Y-107431000D03*
269 | X159893000Y-107431000D03*
270 | X157353000Y-107431000D03*
271 | X154813000Y-107431000D03*
272 | X152273000Y-107431000D03*
273 | X149733000Y-107431000D03*
274 | X147193000Y-107431000D03*
275 | X144653000Y-107431000D03*
276 | X142113000Y-107431000D03*
277 | X139573000Y-107431000D03*
278 | X137033000Y-107431000D03*
279 | X137033000Y-127011000D03*
280 | X139573000Y-127011000D03*
281 | X142113000Y-127011000D03*
282 | X144653000Y-127011000D03*
283 | X147193000Y-127011000D03*
284 | X149733000Y-127011000D03*
285 | X152273000Y-127011000D03*
286 | X154813000Y-127011000D03*
287 | X157353000Y-127011000D03*
288 | X159893000Y-127011000D03*
289 | X162433000Y-127011000D03*
290 | X164973000Y-127011000D03*
291 | X167513000Y-127011000D03*
292 | X170053000Y-127011000D03*
293 | X172593000Y-127011000D03*
294 | X175133000Y-127011000D03*
295 | X177673000Y-127011000D03*
296 | X180213000Y-127011000D03*
297 | X182753000Y-127011000D03*
298 | X185293000Y-127011000D03*
299 | D29*
300 | X113030000Y-133858000D03*
301 | X114300000Y-133858000D03*
302 | X111760000Y-133858000D03*
303 | D23*
304 | X125095000Y-125730000D03*
305 | X125095000Y-128270000D03*
306 | X125095000Y-130810000D03*
307 | X125095000Y-133350000D03*
308 | X132715000Y-133350000D03*
309 | X132715000Y-130810000D03*
310 | X132715000Y-128270000D03*
311 | X132715000Y-125730000D03*
312 | M02*
313 |
--------------------------------------------------------------------------------
/kicad/gerbers/Pico_Wifi_modem-F.Paste.gtp:
--------------------------------------------------------------------------------
1 | G04 #@! TF.FileFunction,Paste,Top*
2 | %FSLAX46Y46*%
3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
4 | G04 Created by KiCad (PCBNEW 4.0.5+dfsg1-4) date Sat Oct 15 20:35:36 2022*
5 | %MOMM*%
6 | %LPD*%
7 | G01*
8 | G04 APERTURE LIST*
9 | %ADD10C,0.150000*%
10 | %ADD11R,2.000000X0.600000*%
11 | G04 APERTURE END LIST*
12 | D10*
13 | D11*
14 | X136905000Y-81661000D03*
15 | X136905000Y-82931000D03*
16 | X136905000Y-84201000D03*
17 | X136905000Y-85471000D03*
18 | X136905000Y-86741000D03*
19 | X136905000Y-88011000D03*
20 | X136905000Y-89281000D03*
21 | X136905000Y-90551000D03*
22 | X136905000Y-91821000D03*
23 | X136905000Y-93091000D03*
24 | X136905000Y-94361000D03*
25 | X136905000Y-95631000D03*
26 | X136905000Y-96901000D03*
27 | X136905000Y-98171000D03*
28 | X146305000Y-98171000D03*
29 | X146305000Y-96901000D03*
30 | X146305000Y-95631000D03*
31 | X146305000Y-94361000D03*
32 | X146305000Y-93091000D03*
33 | X146305000Y-91821000D03*
34 | X146305000Y-90551000D03*
35 | X146305000Y-89281000D03*
36 | X146305000Y-88011000D03*
37 | X146305000Y-86741000D03*
38 | X146305000Y-85471000D03*
39 | X146305000Y-84201000D03*
40 | X146305000Y-82931000D03*
41 | X146305000Y-81661000D03*
42 | M02*
43 |
--------------------------------------------------------------------------------
/kicad/gerbers/Pico_Wifi_modem-NPTH.drl:
--------------------------------------------------------------------------------
1 | M48
2 | ;DRILL file {KiCad 4.0.5+dfsg1-4} date Sat Oct 15 20:35:42 2022
3 | ;FORMAT={-:-/ absolute / metric / decimal}
4 | FMAT,2
5 | METRIC,TZ
6 | T1C1.500
7 | T2C1.800
8 | T3C3.200
9 | %
10 | G90
11 | G05
12 | M71
13 | T1
14 | X182.133Y-114.796
15 | X182.133Y-119.646
16 | T2
17 | X185.163Y-114.496
18 | X185.163Y-119.946
19 | T3
20 | X119.45Y-85.77
21 | X119.45Y-132.02
22 | X159.45Y-85.77
23 | X159.45Y-132.02
24 | X189.45Y-85.77
25 | X189.45Y-132.02
26 | T0
27 | M30
28 |
--------------------------------------------------------------------------------
/kicad/gerbers/Pico_Wifi_modem.drl:
--------------------------------------------------------------------------------
1 | M48
2 | ;DRILL file {KiCad 4.0.5+dfsg1-4} date Sat Oct 15 20:35:42 2022
3 | ;FORMAT={-:-/ absolute / metric / decimal}
4 | FMAT,2
5 | METRIC,TZ
6 | T1C0.400
7 | T2C0.600
8 | T3C0.800
9 | T4C0.800
10 | T5C0.813
11 | T6C1.001
12 | T7C1.016
13 | T8C1.020
14 | T9C1.270
15 | %
16 | G90
17 | G05
18 | M71
19 | T1
20 | X111.76Y-136.398
21 | X130.429Y-125.73
22 | X130.429Y-136.398
23 | X131.826Y-86.741
24 | X131.826Y-99.441
25 | X132.461Y-88.011
26 | X132.461Y-98.171
27 | X133.096Y-89.281
28 | X133.096Y-101.981
29 | X133.731Y-90.551
30 | X133.731Y-96.901
31 | X134.366Y-91.821
32 | X134.366Y-100.711
33 | X135.001Y-93.218
34 | X135.001Y-103.632
35 | X137.033Y-134.366
36 | X142.748Y-84.201
37 | X142.748Y-98.171
38 | X147.193Y-136.271
39 | X149.987Y-86.741
40 | X149.987Y-98.171
41 | X156.083Y-88.011
42 | X156.083Y-97.028
43 | X161.036Y-91.821
44 | X161.036Y-99.441
45 | X162.433Y-91.821
46 | X162.433Y-95.631
47 | X164.973Y-85.217
48 | X164.973Y-94.234
49 | X167.767Y-86.741
50 | X167.767Y-90.551
51 | X170.053Y-81.661
52 | X170.053Y-93.091
53 | X171.323Y-90.551
54 | X171.323Y-98.171
55 | X172.593Y-89.281
56 | X172.593Y-94.361
57 | X177.673Y-99.441
58 | X178.562Y-86.741
59 | X178.562Y-104.775
60 | X179.578Y-89.281
61 | X179.578Y-103.886
62 | X182.753Y-104.775
63 | X185.293Y-103.886
64 | T2
65 | X111.76Y-133.858
66 | X113.03Y-133.858
67 | X114.3Y-133.858
68 | T3
69 | X111.76Y-138.176
70 | X125.095Y-125.73
71 | X125.095Y-128.27
72 | X125.095Y-130.81
73 | X125.095Y-133.35
74 | X129.286Y-82.042
75 | X132.715Y-125.73
76 | X132.715Y-128.27
77 | X132.715Y-130.81
78 | X132.715Y-133.35
79 | X133.858Y-85.471
80 | X142.748Y-78.359
81 | X149.733Y-84.582
82 | X153.162Y-80.772
83 | X174.879Y-79.121
84 | X174.879Y-81.661
85 | X174.879Y-84.201
86 | X174.879Y-86.741
87 | X174.879Y-89.281
88 | X174.879Y-91.821
89 | X174.879Y-94.361
90 | X174.879Y-96.901
91 | X174.879Y-99.441
92 | X174.879Y-101.981
93 | X182.499Y-79.121
94 | X182.499Y-81.661
95 | X182.499Y-84.201
96 | X182.499Y-86.741
97 | X182.499Y-89.281
98 | X182.499Y-91.821
99 | X182.499Y-94.361
100 | X182.499Y-96.901
101 | X182.499Y-99.441
102 | X182.499Y-101.981
103 | X186.182Y-78.359
104 | T4
105 | X114.26Y-138.176
106 | X129.286Y-84.542
107 | X133.858Y-82.971
108 | X140.248Y-78.359
109 | X149.733Y-82.082
110 | X153.162Y-85.852
111 | X186.182Y-80.859
112 | T5
113 | X139.573Y-131.572
114 | X139.573Y-134.366
115 | X147.193Y-131.572
116 | X147.193Y-134.366
117 | X195.045Y-84.516
118 | X195.045Y-91.12
119 | X195.045Y-97.724
120 | X195.045Y-104.328
121 | X195.045Y-110.932
122 | X195.045Y-117.536
123 | X195.045Y-124.14
124 | X195.045Y-130.744
125 | X202.665Y-84.516
126 | X202.665Y-91.12
127 | X202.665Y-97.724
128 | X202.665Y-104.328
129 | X202.665Y-110.932
130 | X202.665Y-117.536
131 | X202.665Y-124.14
132 | X202.665Y-130.744
133 | T6
134 | X182.753Y-133.099
135 | X205.74Y-84.516
136 | X205.74Y-87.056
137 | X205.74Y-91.12
138 | X205.74Y-93.66
139 | X205.74Y-97.724
140 | X205.74Y-100.264
141 | X205.74Y-104.328
142 | X205.74Y-106.868
143 | X205.74Y-110.932
144 | X205.74Y-113.472
145 | X205.74Y-117.536
146 | X205.74Y-120.076
147 | X205.74Y-124.14
148 | X205.74Y-126.68
149 | X205.74Y-130.744
150 | X205.74Y-133.284
151 | T7
152 | X126.365Y-91.805
153 | X126.365Y-94.345
154 | X126.365Y-96.885
155 | X126.365Y-99.425
156 | X126.365Y-101.965
157 | X128.905Y-91.805
158 | X128.905Y-94.345
159 | X128.905Y-96.885
160 | X128.905Y-99.425
161 | X128.905Y-101.965
162 | T8
163 | X137.033Y-108.331
164 | X137.033Y-126.111
165 | X139.573Y-108.331
166 | X139.573Y-126.111
167 | X142.113Y-108.331
168 | X142.113Y-126.111
169 | X144.653Y-108.331
170 | X144.653Y-126.111
171 | X147.193Y-108.331
172 | X147.193Y-126.111
173 | X149.733Y-108.331
174 | X149.733Y-126.111
175 | X152.273Y-108.331
176 | X152.273Y-126.111
177 | X154.813Y-108.331
178 | X154.813Y-126.111
179 | X155.563Y-117.805
180 | X155.563Y-120.345
181 | X155.563Y-122.885
182 | X157.353Y-108.331
183 | X157.353Y-126.111
184 | X159.893Y-108.331
185 | X159.893Y-126.111
186 | X162.433Y-108.331
187 | X162.433Y-126.111
188 | X164.973Y-108.331
189 | X164.973Y-126.111
190 | X167.513Y-108.331
191 | X167.513Y-126.111
192 | X170.053Y-108.331
193 | X170.053Y-126.111
194 | X172.593Y-108.331
195 | X172.593Y-126.111
196 | X175.133Y-108.331
197 | X175.133Y-126.111
198 | X177.673Y-108.331
199 | X177.673Y-126.111
200 | X180.213Y-108.331
201 | X180.213Y-126.111
202 | X182.753Y-108.331
203 | X182.753Y-126.111
204 | X185.293Y-108.331
205 | X185.293Y-126.111
206 | T9
207 | X172.593Y-133.099
208 | T6
209 | X113.611Y-121.231G85X113.611Y-123.229
210 | G05
211 | X115.611Y-126.929G85X117.61Y-126.929
212 | G05
213 | X119.61Y-121.231G85X119.61Y-123.229
214 | G05
215 | T0
216 | M30
217 |
--------------------------------------------------------------------------------
/kicad/gerbers/Pico_Wifi_modem.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mecparts/PicoWiFiModem/12148fc6f5a816a76dc473e19f7c6679ca7caa85/kicad/gerbers/Pico_Wifi_modem.zip
--------------------------------------------------------------------------------
/kicad/library/Pico_Wifi_modem.lib:
--------------------------------------------------------------------------------
1 | EESchema-LIBRARY Version 2.3
2 | #encoding utf-8
3 | #
4 | # +3V3
5 | #
6 | DEF +3V3 #PWR 0 0 Y Y 1 F P
7 | F0 "#PWR" 0 -150 50 H I C CNN
8 | F1 "+3V3" 0 140 50 H V C CNN
9 | F2 "" 0 0 50 H V C CNN
10 | F3 "" 0 0 50 H V C CNN
11 | ALIAS +3.3V
12 | DRAW
13 | P 2 0 1 0 -30 50 0 100 N
14 | P 2 0 1 0 0 0 0 100 N
15 | P 2 0 1 0 0 100 30 50 N
16 | X +3V3 1 0 0 0 U 50 50 1 1 W N
17 | ENDDRAW
18 | ENDDEF
19 | #
20 | # +5V
21 | #
22 | DEF +5V #PWR 0 0 Y Y 1 F P
23 | F0 "#PWR" 0 -150 50 H I C CNN
24 | F1 "+5V" 0 140 50 H V C CNN
25 | F2 "" 0 0 50 H V C CNN
26 | F3 "" 0 0 50 H V C CNN
27 | DRAW
28 | P 2 0 1 0 -30 50 0 100 N
29 | P 2 0 1 0 0 0 0 100 N
30 | P 2 0 1 0 0 100 30 50 N
31 | X +5V 1 0 0 0 U 50 50 1 1 W N
32 | ENDDRAW
33 | ENDDEF
34 | #
35 | # 24LC16
36 | #
37 | DEF ~24LC16 U 0 30 Y Y 1 F N
38 | F0 "U" -250 250 50 H V C CNN
39 | F1 "24LC16" 200 250 50 H I C CNN
40 | F2 "DIP-8" 50 -250 50 H I L CNN
41 | F3 "" 0 -100 50 H V C CNN
42 | ALIAS 24LC00 24LC01 24LC02 24LC04 24LC08 24LC32 24LC64 24LC128 24LC256 24LC512 24LC1025
43 | $FPLIST
44 | SOIC*
45 | $ENDFPLIST
46 | DRAW
47 | X GND 4 0 -300 100 U 50 50 0 0 W
48 | X VCC 8 0 300 100 D 50 50 0 0 W
49 | S -300 200 300 -200 1 1 0 f
50 | X A0 1 -400 100 100 R 50 50 1 1 I
51 | X A1 2 -400 0 100 R 50 50 1 1 I
52 | X A2 3 -400 -100 100 R 50 50 1 1 I
53 | X SDA 5 400 -100 100 L 50 50 1 1 B
54 | X SCL 6 400 0 100 L 50 50 1 1 I
55 | X WP 7 400 100 100 L 50 50 1 1 I
56 | ENDDRAW
57 | ENDDEF
58 | #
59 | # 74LS245A
60 | #
61 | DEF 74LS245A U 0 10 Y Y 1 F N
62 | F0 "U" 100 575 50 H V L BNN
63 | F1 "74LS245A" 50 -575 50 H V L TNN
64 | F2 "" 0 0 50 H V C CNN
65 | F3 "" 0 0 50 H V C CNN
66 | ALIAS 74LS245 74HC245
67 | DRAW
68 | X GND 10 0 -650 100 U 50 50 0 0 W
69 | X VCC 20 0 650 100 D 50 50 0 0 W
70 | S -400 550 400 -550 0 1 0 f
71 | P 3 0 1 0 50 100 0 -100 -100 -100 N
72 | P 4 0 1 0 100 100 -50 100 -100 -100 -150 -100 N
73 | X A->B 1 -500 -400 100 R 50 50 1 1 I
74 | X A0 2 500 500 100 L 50 50 1 1 B
75 | X A1 3 500 400 100 L 50 50 1 1 B
76 | X A2 4 500 300 100 L 50 50 1 1 B
77 | X A3 5 500 200 100 L 50 50 1 1 B
78 | X A4 6 500 100 100 L 50 50 1 1 B
79 | X A5 7 500 0 100 L 50 50 1 1 B
80 | X A6 8 500 -100 100 L 50 50 1 1 B
81 | X A7 9 500 -200 100 L 50 50 1 1 B
82 | X B7 11 -500 -200 100 R 50 50 1 1 B
83 | X B6 12 -500 -100 100 R 50 50 1 1 B
84 | X B5 13 -500 0 100 R 50 50 1 1 B
85 | X B4 14 -500 100 100 R 50 50 1 1 B
86 | X B3 15 -500 200 100 R 50 50 1 1 B
87 | X B2 16 -500 300 100 R 50 50 1 1 B
88 | X B1 17 -500 400 100 R 50 50 1 1 B
89 | X B0 18 -500 500 100 R 50 50 1 1 B
90 | X CE 19 -500 -500 100 R 50 50 1 1 I I
91 | ENDDRAW
92 | ENDDEF
93 | #
94 | # BARREL_JACK
95 | #
96 | DEF BARREL_JACK CON 0 40 Y Y 1 F N
97 | F0 "CON" 0 250 50 H V C CNN
98 | F1 "BARREL_JACK" 0 -200 50 H V C CNN
99 | F2 "" 0 0 50 H V C CNN
100 | F3 "" 0 0 50 H V C CNN
101 | DRAW
102 | A -300 99 49 -900 1788 0 1 0 N -300 50 -350 100
103 | A -300 101 49 900 -1788 0 1 0 N -300 150 -350 100
104 | S 100 150 0 50 0 1 0 N
105 | P 2 0 1 0 -300 50 0 50 N
106 | P 2 0 1 0 0 150 -300 150 N
107 | P 3 0 1 0 100 0 -50 0 -50 -100 N
108 | P 5 0 1 0 100 -100 -150 -100 -200 -50 -250 -100 -350 -100 N
109 | X ~ 1 300 100 200 L 50 50 1 1 P
110 | X ~ 2 300 -100 200 L 50 50 1 1 P
111 | X ~ 3 300 0 200 L 50 50 1 1 P
112 | ENDDRAW
113 | ENDDEF
114 | #
115 | # CONN_02X05
116 | #
117 | DEF CONN_02X05 P 0 1 Y N 1 F N
118 | F0 "P" 0 300 50 H V C CNN
119 | F1 "CONN_02X05" 0 -300 50 H V C CNN
120 | F2 "" 0 -1200 50 H V C CNN
121 | F3 "" 0 -1200 50 H V C CNN
122 | $FPLIST
123 | Pin_Header_Straight_2X05
124 | Pin_Header_Angled_2X05
125 | Socket_Strip_Straight_2X05
126 | Socket_Strip_Angled_2X05
127 | $ENDFPLIST
128 | DRAW
129 | S -100 -195 -50 -205 0 1 0 N
130 | S -100 -95 -50 -105 0 1 0 N
131 | S -100 5 -50 -5 0 1 0 N
132 | S -100 105 -50 95 0 1 0 N
133 | S -100 205 -50 195 0 1 0 N
134 | S -100 250 100 -250 0 1 0 N
135 | S 50 -195 100 -205 0 1 0 N
136 | S 50 -95 100 -105 0 1 0 N
137 | S 50 5 100 -5 0 1 0 N
138 | S 50 105 100 95 0 1 0 N
139 | S 50 205 100 195 0 1 0 N
140 | X P1 1 -250 200 150 R 50 50 1 1 P
141 | X P2 2 250 200 150 L 50 50 1 1 P
142 | X P3 3 -250 100 150 R 50 50 1 1 P
143 | X P4 4 250 100 150 L 50 50 1 1 P
144 | X P5 5 -250 0 150 R 50 50 1 1 P
145 | X P6 6 250 0 150 L 50 50 1 1 P
146 | X P7 7 -250 -100 150 R 50 50 1 1 P
147 | X P8 8 250 -100 150 L 50 50 1 1 P
148 | X P9 9 -250 -200 150 R 50 50 1 1 P
149 | X P10 10 250 -200 150 L 50 50 1 1 P
150 | ENDDRAW
151 | ENDDEF
152 | #
153 | # C_Small
154 | #
155 | DEF C_Small C 0 10 N N 1 F N
156 | F0 "C" 10 70 50 H V L CNN
157 | F1 "C_Small" 10 -80 50 H V L CNN
158 | F2 "" 0 0 50 H V C CNN
159 | F3 "" 0 0 50 H V C CNN
160 | $FPLIST
161 | C?
162 | C_????_*
163 | C_????
164 | SMD*_c
165 | Capacitor*
166 | $ENDFPLIST
167 | DRAW
168 | P 2 0 1 13 -60 -20 60 -20 N
169 | P 2 0 1 12 -60 20 60 20 N
170 | X ~ 1 0 100 80 D 50 50 1 1 P
171 | X ~ 2 0 -100 80 U 50 50 1 1 P
172 | ENDDRAW
173 | ENDDEF
174 | #
175 | # D
176 | #
177 | DEF D D 0 40 N N 1 F N
178 | F0 "D" 0 100 50 H V C CNN
179 | F1 "D" 0 -100 50 H V C CNN
180 | F2 "" 0 0 50 H V C CNN
181 | F3 "" 0 0 50 H V C CNN
182 | $FPLIST
183 | Diode_*
184 | D-*
185 | *SingleDiode
186 | *_Diode_*
187 | *SingleDiode*
188 | D_*
189 | $ENDFPLIST
190 | DRAW
191 | P 2 0 1 8 -25 25 -25 -25 N
192 | P 2 0 1 0 25 0 -25 0 N
193 | P 5 0 1 8 25 25 25 -25 -25 0 -25 0 25 25 N
194 | X K 1 -100 0 75 R 50 50 1 1 P
195 | X A 2 100 0 75 L 50 50 1 1 P
196 | ENDDRAW
197 | ENDDEF
198 | #
199 | # GND
200 | #
201 | DEF GND #PWR 0 0 Y Y 1 F P
202 | F0 "#PWR" 0 -250 50 H I C CNN
203 | F1 "GND" 0 -150 50 H V C CNN
204 | F2 "" 0 0 50 H V C CNN
205 | F3 "" 0 0 50 H V C CNN
206 | DRAW
207 | P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
208 | X GND 1 0 0 0 D 50 50 1 1 W N
209 | ENDDRAW
210 | ENDDEF
211 | #
212 | # LED
213 | #
214 | DEF LED D 0 40 Y N 1 F N
215 | F0 "D" 0 100 50 H V C CNN
216 | F1 "LED" 0 -100 50 H V C CNN
217 | F2 "" 0 0 50 H V C CNN
218 | F3 "" 0 0 50 H V C CNN
219 | $FPLIST
220 | LED*
221 | $ENDFPLIST
222 | DRAW
223 | P 2 0 1 8 -50 -50 -50 50 N
224 | P 4 0 1 8 50 -50 50 50 -50 0 50 -50 N
225 | P 5 0 1 0 -120 -30 -180 -90 -150 -90 -180 -90 -180 -60 N
226 | P 5 0 1 0 -70 -30 -130 -90 -100 -90 -130 -90 -130 -60 N
227 | X K 1 -150 0 100 R 50 50 1 1 P
228 | X A 2 150 0 100 L 50 50 1 1 P
229 | ENDDRAW
230 | ENDDEF
231 | #
232 | # LM2931AZ-3.3/5.0
233 | #
234 | DEF LM2931AZ-3.3/5.0 U 0 30 Y Y 1 F N
235 | F0 "U" 0 250 50 H V C CNN
236 | F1 "LM2931AZ-3.3/5.0" 0 200 50 H V C CNN
237 | F2 "TO92-123" 0 100 50 H V C CIN
238 | F3 "" 0 0 50 H V C CNN
239 | ALIAS LM2931Z-3.3/5.0
240 | $FPLIST
241 | TO92-123
242 | $ENDFPLIST
243 | DRAW
244 | S -250 -150 250 150 0 1 10 f
245 | X VO 1 400 50 150 L 50 50 1 1 w
246 | X GND 2 0 -250 100 U 50 50 1 1 W
247 | X VI 3 -400 50 150 R 50 50 1 1 W
248 | ENDDRAW
249 | ENDDEF
250 | #
251 | # MAX3237CAI+
252 | #
253 | DEF MAX3237CAI+ U 0 10 Y Y 1 L N
254 | F0 "U" -400 950 60 H V C CNN
255 | F1 "MAX3237CAI+" -350 850 60 H V C CNN
256 | F2 "21-0056C_28_MXM" -500 750 60 H I C CNN
257 | F3 "" -750 600 60 H V C CNN
258 | $FPLIST
259 | 21-0056C_28_MXM
260 | 21-0056C_28_MXM-M
261 | 21-0056C_28_MXM-L
262 | $ENDFPLIST
263 | DRAW
264 | S -450 700 450 -900 0 1 0 f
265 | X C2+ 1 -550 600 100 R 59 59 1 1 P
266 | X GND 2 0 -1000 100 U 59 59 1 1 W
267 | X C2- 3 -550 500 100 R 59 59 1 1 P
268 | X V- 4 -550 400 100 R 59 59 1 1 P
269 | X T1OUT 5 -550 200 100 R 59 59 1 1 O
270 | X T2OUT 6 -550 100 100 R 59 59 1 1 O
271 | X T3OUT 7 -550 0 100 R 59 59 1 1 O
272 | X R1IN 8 -550 -100 100 R 59 59 1 1 I
273 | X R2IN 9 -550 -200 100 R 59 59 1 1 I
274 | X T4OUT 10 -550 -300 100 R 59 59 1 1 O
275 | X R2OUT 20 550 -200 100 L 59 59 1 1 O
276 | X R3IN 11 -550 -400 100 R 59 59 1 1 I
277 | X R1OUT 21 550 -100 100 L 59 59 1 1 O
278 | X T5OUT 12 -550 -500 100 R 59 59 1 1 O
279 | X T3IN 22 550 0 100 L 59 59 1 1 I
280 | X EN 13 -550 -700 100 R 59 59 1 1 I I
281 | X T2IN 23 550 100 100 L 59 59 1 1 I
282 | X SHDN 14 -550 -800 100 R 59 59 1 1 I I
283 | X T1IN 24 550 200 100 L 59 59 1 1 I
284 | X MBAUD 15 550 -800 100 L 59 59 1 1 I
285 | X C1- 25 550 400 100 L 59 59 1 1 P
286 | X R1OUTB 16 550 -700 100 L 59 59 1 1 O
287 | X VCC 26 0 800 100 D 59 59 1 1 W
288 | X T5IN 17 550 -500 100 L 59 59 1 1 I
289 | X V+ 27 550 500 100 L 59 59 1 1 P
290 | X R3OUT 18 550 -400 100 L 59 59 1 1 O
291 | X C1+ 28 550 600 100 L 59 59 1 1 P
292 | X T4IN 19 550 -300 100 L 59 59 1 1 I
293 | ENDDRAW
294 | ENDDEF
295 | #
296 | # PWR_FLAG
297 | #
298 | DEF PWR_FLAG #FLG 0 0 N N 1 F P
299 | F0 "#FLG" 0 95 50 H I C CNN
300 | F1 "PWR_FLAG" 0 180 50 H V C CNN
301 | F2 "" 0 0 50 H V C CNN
302 | F3 "" 0 0 50 H V C CNN
303 | DRAW
304 | X pwr 1 0 0 0 U 50 50 0 0 w
305 | P 6 0 1 0 0 0 0 50 -75 100 0 150 75 100 0 50 N
306 | ENDDRAW
307 | ENDDEF
308 | #
309 | # Pico
310 | #
311 | DEF Pico U 0 40 Y Y 1 F N
312 | F0 "U" -550 1100 50 H V C CNN
313 | F1 "Pico" 0 750 50 H V C CNN
314 | F2 "RPi_Pico:RPi_Pico_SMD_TH" 0 0 50 V I C CNN
315 | F3 "" 0 0 50 H I C CNN
316 | DRAW
317 | T 0 0 850 50 0 0 0 Raspberry~Pi Normal 0 C C
318 | S -600 1050 600 -1050 0 1 0 f
319 | X GPIO0 1 -700 950 100 R 50 50 1 1 B
320 | X GPIO1 2 -700 850 100 R 50 50 1 1 B
321 | X GND 3 -700 750 100 R 50 50 1 1 W
322 | X GPIO2 4 -700 650 100 R 50 50 1 1 B
323 | X GPIO3 5 -700 550 100 R 50 50 1 1 B
324 | X GPIO4 6 -700 450 100 R 50 50 1 1 B
325 | X GPIO5 7 -700 350 100 R 50 50 1 1 B
326 | X GND 8 -700 250 100 R 50 50 1 1 W
327 | X GPIO6 9 -700 150 100 R 50 50 1 1 B
328 | X GPIO7 10 -700 50 100 R 50 50 1 1 B
329 | X GPIO15 20 -700 -950 100 R 50 50 1 1 B
330 | X RUN 30 700 -50 100 L 50 50 1 1 I
331 | X VBUS 40 700 950 100 L 50 50 1 1 P
332 | X GPIO8 11 -700 -50 100 R 50 50 1 1 B
333 | X GPIO16 21 700 -950 100 L 50 50 1 1 B
334 | X GPIO26_ADC0 31 700 50 100 L 50 50 1 1 B
335 | X SWCLK 41 -100 -1150 100 U 50 50 1 1 I
336 | X GPIO9 12 -700 -150 100 R 50 50 1 1 B
337 | X GPIO17 22 700 -850 100 L 50 50 1 1 B
338 | X GPIO27_ADC1 32 700 150 100 L 50 50 1 1 B
339 | X GND 42 0 -1150 100 U 50 50 1 1 W
340 | X GND 13 -700 -250 100 R 50 50 1 1 W
341 | X GND 23 700 -750 100 L 50 50 1 1 W
342 | X AGND 33 700 250 100 L 50 50 1 1 W
343 | X SWDIO 43 100 -1150 100 U 50 50 1 1 B
344 | X GPIO10 14 -700 -350 100 R 50 50 1 1 B
345 | X GPIO18 24 700 -650 100 L 50 50 1 1 B
346 | X GPIO28_ADC2 34 700 350 100 L 50 50 1 1 B
347 | X GPIO11 15 -700 -450 100 R 50 50 1 1 B
348 | X GPIO19 25 700 -550 100 L 50 50 1 1 B
349 | X ADC_VREF 35 700 450 100 L 50 50 1 1 P
350 | X GPIO12 16 -700 -550 100 R 50 50 1 1 B
351 | X GPIO20 26 700 -450 100 L 50 50 1 1 B
352 | X 3V3 36 700 550 100 L 50 50 1 1 w
353 | X GPIO13 17 -700 -650 100 R 50 50 1 1 B
354 | X GPIO21 27 700 -350 100 L 50 50 1 1 B
355 | X 3V3_EN 37 700 650 100 L 50 50 1 1 I
356 | X GND 18 -700 -750 100 R 50 50 1 1 W
357 | X GND 28 700 -250 100 L 50 50 1 1 W
358 | X GND 38 700 750 100 L 50 50 1 1 W
359 | X GPIO14 19 -700 -850 100 R 50 50 1 1 B
360 | X GPIO22 29 700 -150 100 L 50 50 1 1 B
361 | X VSYS 39 700 850 100 L 50 50 1 1 P
362 | ENDDRAW
363 | ENDDEF
364 | #
365 | # R_US
366 | #
367 | DEF R_US R 0 40 N N 1 F N
368 | F0 "R" 80 0 50 V V C CNN
369 | F1 "R_US" -80 0 50 V V C CNN
370 | F2 "Discret:R3-LARGE_PADS" 0 150 60 H I C CNN
371 | F3 "" 0 0 60 H I C CNN
372 | $FPLIST
373 | R?
374 | R_*
375 | $ENDFPLIST
376 | DRAW
377 | P 10 0 1 10 0 -70 0 -60 -30 -50 30 -30 -30 -10 30 10 -30 30 30 50 0 60 0 70 N
378 | X ~ 1 0 100 25 D 40 40 1 1 P
379 | X ~ 2 0 -100 25 U 40 40 1 1 P
380 | ENDDRAW
381 | ENDDEF
382 | #
383 | #End Library
384 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/BARREL_JACK.kicad_mod:
--------------------------------------------------------------------------------
1 | (module Connectors:BARREL_JACK locked (layer F.Cu) (tedit 633E1C44)
2 | (descr "DC Barrel Jack")
3 | (tags "Power Jack")
4 | (fp_text reference CON1 (at -1.269 6.421 180) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value BARREL_JACK (at 2.033 -6.152) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_line (start -4.0005 -4.50088) (end -4.0005 4.50088) (layer F.SilkS) (width 0.15))
11 | (fp_line (start -7.50062 -4.50088) (end -7.50062 4.50088) (layer F.SilkS) (width 0.15))
12 | (fp_line (start -7.50062 4.50088) (end 7.00024 4.50088) (layer F.SilkS) (width 0.15))
13 | (fp_line (start 7.00024 4.50088) (end 7.00024 -4.50088) (layer F.SilkS) (width 0.15))
14 | (fp_line (start 7.00024 -4.50088) (end -7.50062 -4.50088) (layer F.SilkS) (width 0.15))
15 | (pad 1 thru_hole rect (at 6.20014 0) (size 3.50012 3.50012) (drill oval 1 3) (layers *.Cu *.Mask))
16 | (pad 2 thru_hole rect (at 0.20066 0) (size 3.50012 3.50012) (drill oval 1 3) (layers *.Cu *.Mask))
17 | (pad 3 thru_hole rect (at 3.2004 4.699) (size 3.50012 3.50012) (drill oval 3 1) (layers *.Cu *.Mask))
18 | )
19 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/C_Disc_D3_P2.5.kicad_mod:
--------------------------------------------------------------------------------
1 | (module Capacitors_THT:C_Disc_D3_P2.5 (layer F.Cu) (tedit 633E75D6)
2 | (descr "Capacitor 3mm Disc, Pitch 2.5mm")
3 | (tags Capacitor)
4 | (fp_text reference C7 (at 4.445 -0.127 90) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value 1uF (at 1.25 2.5) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_line (start -0.9 -1.5) (end 3.4 -1.5) (layer F.CrtYd) (width 0.05))
11 | (fp_line (start 3.4 -1.5) (end 3.4 1.5) (layer F.CrtYd) (width 0.05))
12 | (fp_line (start 3.4 1.5) (end -0.9 1.5) (layer F.CrtYd) (width 0.05))
13 | (fp_line (start -0.9 1.5) (end -0.9 -1.5) (layer F.CrtYd) (width 0.05))
14 | (fp_line (start -0.25 -1.25) (end 2.75 -1.25) (layer F.SilkS) (width 0.15))
15 | (fp_line (start 2.75 1.25) (end -0.25 1.25) (layer F.SilkS) (width 0.15))
16 | (pad 1 thru_hole rect (at 0 0) (size 1.3 1.3) (drill 0.8) (layers *.Cu *.Mask))
17 | (pad 2 thru_hole circle (at 2.5 0) (size 1.3 1.3) (drill 0.8) (layers *.Cu *.Mask))
18 | (model Capacitors_ThroughHole.3dshapes/C_Disc_D3_P2.5.wrl
19 | (at (xyz 0.0492126 0 0))
20 | (scale (xyz 1 1 1))
21 | (rotate (xyz 0 0 0))
22 | )
23 | )
24 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/C_Disc_D3_P5.kicad_mod:
--------------------------------------------------------------------------------
1 | (module Capacitors_THT:C_Disc_D3_P5 (layer F.Cu) (tedit 633E2480)
2 | (descr "Capacitor 3mm Disc, Pitch 5.08mm")
3 | (tags Capacitor)
4 | (fp_text reference C6 (at -4.191 0.254 90) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value 100nF (at 0 2.5) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_line (start -3.42 -1.5) (end 3.42 -1.5) (layer F.CrtYd) (width 0.05))
11 | (fp_line (start 3.42 -1.5) (end 3.42 1.5) (layer F.CrtYd) (width 0.05))
12 | (fp_line (start 3.42 1.5) (end -3.42 1.5) (layer F.CrtYd) (width 0.05))
13 | (fp_line (start -3.42 1.5) (end -3.42 -1.5) (layer F.CrtYd) (width 0.05))
14 | (fp_line (start -2.77 -1.25) (end 2.77 -1.25) (layer F.SilkS) (width 0.15))
15 | (fp_line (start 2.77 1.25) (end -2.77 1.25) (layer F.SilkS) (width 0.15))
16 | (pad 1 thru_hole rect (at -2.54 0) (size 1.3 1.3) (drill 0.8) (layers *.Cu *.Mask))
17 | (pad 2 thru_hole circle (at 2.54 0) (size 1.3 1.3) (drill 0.8) (layers *.Cu *.Mask))
18 | )
19 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/DIP-20_W7.62mm_LongPads.kicad_mod:
--------------------------------------------------------------------------------
1 | (module Housings_DIP:DIP-20_W7.62mm_LongPads locked (layer F.Cu) (tedit 633E456C)
2 | (descr "20-lead dip package, row spacing 7.62 mm (300 mils), longer pads")
3 | (tags "dil dip 2.54 300")
4 | (fp_text reference U2 (at -2.921 -1.651 180) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value 74HCT245 (at -2.413 3.048 270) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_line (start -1.4 -2.45) (end -1.4 25.35) (layer F.CrtYd) (width 0.05))
11 | (fp_line (start 9 -2.45) (end 9 25.35) (layer F.CrtYd) (width 0.05))
12 | (fp_line (start -1.4 -2.45) (end 9 -2.45) (layer F.CrtYd) (width 0.05))
13 | (fp_line (start -1.4 25.35) (end 9 25.35) (layer F.CrtYd) (width 0.05))
14 | (fp_line (start 0.135 -2.295) (end 0.135 -1.025) (layer F.SilkS) (width 0.15))
15 | (fp_line (start 7.485 -2.295) (end 7.485 -1.025) (layer F.SilkS) (width 0.15))
16 | (fp_line (start 7.485 25.155) (end 7.485 23.885) (layer F.SilkS) (width 0.15))
17 | (fp_line (start 0.135 25.155) (end 0.135 23.885) (layer F.SilkS) (width 0.15))
18 | (fp_line (start 0.135 -2.295) (end 7.485 -2.295) (layer F.SilkS) (width 0.15))
19 | (fp_line (start 0.135 25.155) (end 7.485 25.155) (layer F.SilkS) (width 0.15))
20 | (fp_line (start 0.135 -1.025) (end -1.15 -1.025) (layer F.SilkS) (width 0.15))
21 | (pad 1 thru_hole oval (at 0 0 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
22 | (pad 2 thru_hole oval (at 0 2.54 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
23 | (pad 3 thru_hole oval (at 0 5.08 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
24 | (pad 4 thru_hole oval (at 0 7.62 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
25 | (pad 5 thru_hole oval (at 0 10.16 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
26 | (pad 6 thru_hole oval (at 0 12.7 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
27 | (pad 7 thru_hole oval (at 0 15.24 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
28 | (pad 8 thru_hole oval (at 0 17.78 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
29 | (pad 9 thru_hole oval (at 0 20.32 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
30 | (pad 10 thru_hole oval (at 0 22.86 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
31 | (pad 11 thru_hole oval (at 7.62 22.86 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
32 | (pad 12 thru_hole oval (at 7.62 20.32 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
33 | (pad 13 thru_hole oval (at 7.62 17.78 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
34 | (pad 14 thru_hole oval (at 7.62 15.24 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
35 | (pad 15 thru_hole oval (at 7.62 12.7 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
36 | (pad 16 thru_hole oval (at 7.62 10.16 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
37 | (pad 17 thru_hole oval (at 7.62 7.62 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
38 | (pad 18 thru_hole oval (at 7.62 5.08 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
39 | (pad 19 thru_hole oval (at 7.62 2.54 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
40 | (pad 20 thru_hole oval (at 7.62 0 180) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
41 | (model Housings_DIP.3dshapes/DIP-20_W7.62mm_LongPads.wrl
42 | (at (xyz 0 0 0))
43 | (scale (xyz 1 1 1))
44 | (rotate (xyz 0 0 0))
45 | )
46 | )
47 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/DIP-8_W7.62mm_LongPads.kicad_mod:
--------------------------------------------------------------------------------
1 | (module Housings_DIP:DIP-8_W7.62mm_LongPads (layer F.Cu) (tedit 633E75C8)
2 | (descr "8-lead dip package, row spacing 7.62 mm (300 mils), longer pads")
3 | (tags "dil dip 2.54 300")
4 | (fp_text reference U5 (at 6.35 -3.556 180) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value 24LC32 (at 3.683 11.684) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_line (start -1.4 -2.45) (end -1.4 10.1) (layer F.CrtYd) (width 0.05))
11 | (fp_line (start 9 -2.45) (end 9 10.1) (layer F.CrtYd) (width 0.05))
12 | (fp_line (start -1.4 -2.45) (end 9 -2.45) (layer F.CrtYd) (width 0.05))
13 | (fp_line (start -1.4 10.1) (end 9 10.1) (layer F.CrtYd) (width 0.05))
14 | (fp_line (start 0.135 -2.295) (end 0.135 -1.025) (layer F.SilkS) (width 0.15))
15 | (fp_line (start 7.485 -2.295) (end 7.485 -1.025) (layer F.SilkS) (width 0.15))
16 | (fp_line (start 7.485 9.915) (end 7.485 8.645) (layer F.SilkS) (width 0.15))
17 | (fp_line (start 0.135 9.915) (end 0.135 8.645) (layer F.SilkS) (width 0.15))
18 | (fp_line (start 0.135 -2.295) (end 7.485 -2.295) (layer F.SilkS) (width 0.15))
19 | (fp_line (start 0.135 9.915) (end 7.485 9.915) (layer F.SilkS) (width 0.15))
20 | (fp_line (start 0.135 -1.025) (end -1.15 -1.025) (layer F.SilkS) (width 0.15))
21 | (pad 1 thru_hole oval (at 0 0) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
22 | (pad 2 thru_hole oval (at 0 2.54) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
23 | (pad 3 thru_hole oval (at 0 5.08) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
24 | (pad 4 thru_hole oval (at 0 7.62) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
25 | (pad 5 thru_hole oval (at 7.62 7.62) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
26 | (pad 6 thru_hole oval (at 7.62 5.08) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
27 | (pad 7 thru_hole oval (at 7.62 2.54) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
28 | (pad 8 thru_hole oval (at 7.62 0) (size 2.3 1.6) (drill 0.8) (layers *.Cu *.Mask))
29 | (model Housings_DIP.3dshapes/DIP-8_W7.62mm_LongPads.wrl
30 | (at (xyz 0 0 0))
31 | (scale (xyz 1 1 1))
32 | (rotate (xyz 0 0 0))
33 | )
34 | )
35 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/Diode_DO-41_SOD81_Horizontal_RM10.kicad_mod:
--------------------------------------------------------------------------------
1 | (module Diodes_THT:Diode_DO-41_SOD81_Horizontal_RM10 (layer F.Cu) (tedit 633E1C52)
2 | (descr "Diode, DO-41, SOD81, Horizontal, RM 10mm,")
3 | (tags "Diode, DO-41, SOD81, Horizontal, RM 10mm, 1N4007, SB140,")
4 | (fp_text reference D12 (at 5.334 -2.159) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value 1N5817 (at 4.37134 -3.55854) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_line (start 7.62 -0.00254) (end 8.636 -0.00254) (layer F.SilkS) (width 0.15))
11 | (fp_line (start 2.794 -0.00254) (end 1.524 -0.00254) (layer F.SilkS) (width 0.15))
12 | (fp_line (start 3.048 -1.27254) (end 3.048 1.26746) (layer F.SilkS) (width 0.15))
13 | (fp_line (start 3.302 -1.27254) (end 3.302 1.26746) (layer F.SilkS) (width 0.15))
14 | (fp_line (start 3.556 -1.27254) (end 3.556 1.26746) (layer F.SilkS) (width 0.15))
15 | (fp_line (start 2.794 -1.27254) (end 2.794 1.26746) (layer F.SilkS) (width 0.15))
16 | (fp_line (start 3.81 -1.27254) (end 2.54 1.26746) (layer F.SilkS) (width 0.15))
17 | (fp_line (start 2.54 -1.27254) (end 3.81 1.26746) (layer F.SilkS) (width 0.15))
18 | (fp_line (start 3.81 -1.27254) (end 3.81 1.26746) (layer F.SilkS) (width 0.15))
19 | (fp_line (start 3.175 -1.27254) (end 3.175 1.26746) (layer F.SilkS) (width 0.15))
20 | (fp_line (start 2.54 1.26746) (end 2.54 -1.27254) (layer F.SilkS) (width 0.15))
21 | (fp_line (start 2.54 -1.27254) (end 7.62 -1.27254) (layer F.SilkS) (width 0.15))
22 | (fp_line (start 7.62 -1.27254) (end 7.62 1.26746) (layer F.SilkS) (width 0.15))
23 | (fp_line (start 7.62 1.26746) (end 2.54 1.26746) (layer F.SilkS) (width 0.15))
24 | (pad 2 thru_hole circle (at 10.16 -0.00254 180) (size 2 2) (drill 1) (layers *.Cu *.Mask))
25 | (pad 1 thru_hole rect (at 0 -0.00254 180) (size 2 2) (drill 1) (layers *.Cu *.Mask))
26 | )
27 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/IDC_Header_Straight_10pins.kicad_mod:
--------------------------------------------------------------------------------
1 | (module Connectors:IDC_Header_Straight_10pins locked (layer F.Cu) (tedit 633E017C)
2 | (descr "10 pins through hole IDC header")
3 | (tags "IDC header socket VASCH")
4 | (fp_text reference P1 (at 5.08 -7.62 270) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value CONN_02X05 (at 11.795 -7.366) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_line (start -5.08 -5.82) (end 15.24 -5.82) (layer F.SilkS) (width 0.15))
11 | (fp_line (start -4.54 -5.27) (end 14.68 -5.27) (layer F.SilkS) (width 0.15))
12 | (fp_line (start -5.08 3.28) (end 15.24 3.28) (layer F.SilkS) (width 0.15))
13 | (fp_line (start -4.54 2.73) (end 2.83 2.73) (layer F.SilkS) (width 0.15))
14 | (fp_line (start 7.33 2.73) (end 14.68 2.73) (layer F.SilkS) (width 0.15))
15 | (fp_line (start 2.83 2.73) (end 2.83 3.28) (layer F.SilkS) (width 0.15))
16 | (fp_line (start 7.33 2.73) (end 7.33 3.28) (layer F.SilkS) (width 0.15))
17 | (fp_line (start -5.08 -5.82) (end -5.08 3.28) (layer F.SilkS) (width 0.15))
18 | (fp_line (start -4.54 -5.27) (end -4.54 2.73) (layer F.SilkS) (width 0.15))
19 | (fp_line (start 15.24 -5.82) (end 15.24 3.28) (layer F.SilkS) (width 0.15))
20 | (fp_line (start 14.68 -5.27) (end 14.68 2.73) (layer F.SilkS) (width 0.15))
21 | (fp_line (start -5.08 -5.82) (end -4.54 -5.27) (layer F.SilkS) (width 0.15))
22 | (fp_line (start 15.24 -5.82) (end 14.68 -5.27) (layer F.SilkS) (width 0.15))
23 | (fp_line (start -5.08 3.28) (end -4.54 2.73) (layer F.SilkS) (width 0.15))
24 | (fp_line (start 15.24 3.28) (end 14.68 2.73) (layer F.SilkS) (width 0.15))
25 | (fp_line (start -5.35 -6.05) (end 15.5 -6.05) (layer F.CrtYd) (width 0.05))
26 | (fp_line (start 15.5 -6.05) (end 15.5 3.55) (layer F.CrtYd) (width 0.05))
27 | (fp_line (start 15.5 3.55) (end -5.35 3.55) (layer F.CrtYd) (width 0.05))
28 | (fp_line (start -5.35 3.55) (end -5.35 -6.05) (layer F.CrtYd) (width 0.05))
29 | (pad 1 thru_hole rect (at 0 0 270) (size 1.7272 1.7272) (drill 1) (layers *.Cu *.Mask))
30 | (pad 2 thru_hole oval (at 0 -2.54 270) (size 1.7272 1.7272) (drill 1) (layers *.Cu *.Mask))
31 | (pad 3 thru_hole oval (at 2.54 0 270) (size 1.7272 1.7272) (drill 1) (layers *.Cu *.Mask))
32 | (pad 4 thru_hole oval (at 2.54 -2.54 270) (size 1.7272 1.7272) (drill 1) (layers *.Cu *.Mask))
33 | (pad 5 thru_hole oval (at 5.08 0 270) (size 1.7272 1.7272) (drill 1) (layers *.Cu *.Mask))
34 | (pad 6 thru_hole oval (at 5.08 -2.54 270) (size 1.7272 1.7272) (drill 1) (layers *.Cu *.Mask))
35 | (pad 7 thru_hole oval (at 7.62 0 270) (size 1.7272 1.7272) (drill 1) (layers *.Cu *.Mask))
36 | (pad 8 thru_hole oval (at 7.62 -2.54 270) (size 1.7272 1.7272) (drill 1) (layers *.Cu *.Mask))
37 | (pad 9 thru_hole oval (at 10.16 0 270) (size 1.7272 1.7272) (drill 1) (layers *.Cu *.Mask))
38 | (pad 10 thru_hole oval (at 10.16 -2.54 270) (size 1.7272 1.7272) (drill 1) (layers *.Cu *.Mask))
39 | )
40 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/LED-3MM.kicad_mod:
--------------------------------------------------------------------------------
1 | (module LEDs:LED-3MM locked (layer F.Cu) (tedit 633E16BA)
2 | (descr "LED 3mm round vertical")
3 | (tags "LED 3mm round vertical")
4 | (fp_text reference D8 (at 1.91 3.06 90) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value TLPR5600 (at 3.495 6.096 90) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_line (start -1.2 2.3) (end 3.8 2.3) (layer F.CrtYd) (width 0.05))
11 | (fp_line (start 3.8 2.3) (end 3.8 -2.2) (layer F.CrtYd) (width 0.05))
12 | (fp_line (start 3.8 -2.2) (end -1.2 -2.2) (layer F.CrtYd) (width 0.05))
13 | (fp_line (start -1.2 -2.2) (end -1.2 2.3) (layer F.CrtYd) (width 0.05))
14 | (fp_line (start -0.199 1.314) (end -0.199 1.114) (layer F.SilkS) (width 0.15))
15 | (fp_line (start -0.199 -1.28) (end -0.199 -1.1) (layer F.SilkS) (width 0.15))
16 | (fp_arc (start 1.301 0.034) (end -0.199 -1.286) (angle 108.5) (layer F.SilkS) (width 0.15))
17 | (fp_arc (start 1.301 0.034) (end 0.25 -1.1) (angle 85.7) (layer F.SilkS) (width 0.15))
18 | (fp_arc (start 1.311 0.034) (end 3.051 0.994) (angle 110) (layer F.SilkS) (width 0.15))
19 | (fp_arc (start 1.301 0.034) (end 2.335 1.094) (angle 87.5) (layer F.SilkS) (width 0.15))
20 | (fp_text user K (at -1.69 1.74 90) (layer F.SilkS)
21 | (effects (font (size 1 1) (thickness 0.15)))
22 | )
23 | (pad 1 thru_hole rect (at 0 0 180) (size 2 2) (drill 1) (layers *.Cu *.Mask))
24 | (pad 2 thru_hole circle (at 2.54 0 90) (size 2 2) (drill 1) (layers *.Cu *.Mask))
25 | (model LEDs.3dshapes/LED-3MM.wrl
26 | (at (xyz 0.05 0 0))
27 | (scale (xyz 1 1 1))
28 | (rotate (xyz 0 0 90))
29 | )
30 | )
31 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/MountingHole_3.2mm_Hammond_1593.kicad_mod:
--------------------------------------------------------------------------------
1 | (module Mounting_Holes:MountingHole_3.2mm_Hammond_1593 locked (layer F.Cu) (tedit 5E753046)
2 | (descr "Mounting Hole 3.2mm, no annular, Hammond 1593")
3 | (tags "mounting hole 3.2mm no annular Hammond 1593")
4 | (fp_text reference "" (at 0 -4.2) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value "" (at 0 4.2) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_circle (center 0 0) (end 2.71 0) (layer Cmts.User) (width 0.15))
11 | (fp_circle (center 0 0) (end 2.96 0) (layer F.CrtYd) (width 0.05))
12 | (pad 1 np_thru_hole circle (at 0 0) (size 3.2 3.2) (drill 3.2) (layers *.Cu *.Mask))
13 | )
14 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/R3.kicad_mod:
--------------------------------------------------------------------------------
1 | (module Discret:R3 (layer F.Cu) (tedit 0)
2 | (descr "Resitance 3 pas")
3 | (tags R)
4 | (fp_text reference R13 (at 0 0.127) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value 3.9K (at 0 0.127) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_line (start -3.81 0) (end -3.302 0) (layer F.SilkS) (width 0.15))
11 | (fp_line (start 3.81 0) (end 3.302 0) (layer F.SilkS) (width 0.15))
12 | (fp_line (start 3.302 0) (end 3.302 -1.016) (layer F.SilkS) (width 0.15))
13 | (fp_line (start 3.302 -1.016) (end -3.302 -1.016) (layer F.SilkS) (width 0.15))
14 | (fp_line (start -3.302 -1.016) (end -3.302 1.016) (layer F.SilkS) (width 0.15))
15 | (fp_line (start -3.302 1.016) (end 3.302 1.016) (layer F.SilkS) (width 0.15))
16 | (fp_line (start 3.302 1.016) (end 3.302 0) (layer F.SilkS) (width 0.15))
17 | (fp_line (start -3.302 -0.508) (end -2.794 -1.016) (layer F.SilkS) (width 0.15))
18 | (pad 1 thru_hole circle (at -3.81 0) (size 1.397 1.397) (drill 0.8) (layers *.Cu *.Mask))
19 | (pad 2 thru_hole circle (at 3.81 0) (size 1.397 1.397) (drill 0.8) (layers *.Cu *.Mask))
20 | (model Discret.3dshapes/R3.wrl
21 | (at (xyz 0 0 0))
22 | (scale (xyz 0.3 0.3 0.3))
23 | (rotate (xyz 0 0 0))
24 | )
25 | )
26 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/RPi_PicoW.kicad_mod:
--------------------------------------------------------------------------------
1 | (module RPi_PicoW (layer F.Cu) (tedit 633F045B)
2 | (descr "Through hole straight pin header, 2x20, 2.54mm pitch, double rows")
3 | (tags "Through hole pin header THT 2x20 2.54mm double row")
4 | (fp_text reference U3 (at 0 0) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value Pico (at 0 2.159) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_line (start 1.1 25.5) (end 1.5 25.5) (layer F.SilkS) (width 0.12))
11 | (fp_line (start 10.5 -12.9) (end 10.5 -12.5) (layer F.SilkS) (width 0.12))
12 | (fp_line (start 10.5 -15.4) (end 10.5 -15) (layer F.SilkS) (width 0.12))
13 | (fp_line (start -10.5 12.5) (end -10.5 12.9) (layer F.SilkS) (width 0.12))
14 | (fp_line (start 10.5 10) (end 10.5 10.4) (layer F.SilkS) (width 0.12))
15 | (fp_line (start -10.5 2.3) (end -10.5 2.7) (layer F.SilkS) (width 0.12))
16 | (fp_line (start 10.5 4.9) (end 10.5 5.3) (layer F.SilkS) (width 0.12))
17 | (fp_line (start 10.5 2.3) (end 10.5 2.7) (layer F.SilkS) (width 0.12))
18 | (fp_line (start 10.5 25.5) (end 3.7 25.5) (layer F.SilkS) (width 0.12))
19 | (fp_line (start -10.5 10) (end -10.5 10.4) (layer F.SilkS) (width 0.12))
20 | (fp_line (start -10.5 4.9) (end -10.5 5.3) (layer F.SilkS) (width 0.12))
21 | (fp_line (start 10.5 -20.5) (end 10.5 -20.1) (layer F.SilkS) (width 0.12))
22 | (fp_line (start -1.5 25.5) (end -1.1 25.5) (layer F.SilkS) (width 0.12))
23 | (fp_line (start 10.5 20.1) (end 10.5 20.5) (layer F.SilkS) (width 0.12))
24 | (fp_line (start -10.5 -23.1) (end -10.5 -22.7) (layer F.SilkS) (width 0.12))
25 | (fp_line (start 10.5 15.1) (end 10.5 15.5) (layer F.SilkS) (width 0.12))
26 | (fp_line (start 10.5 -5.3) (end 10.5 -4.9) (layer F.SilkS) (width 0.12))
27 | (fp_line (start -10.5 -0.2) (end -10.5 0.2) (layer F.SilkS) (width 0.12))
28 | (fp_line (start -10.5 -20.5) (end -10.5 -20.1) (layer F.SilkS) (width 0.12))
29 | (fp_line (start -10.5 20.1) (end -10.5 20.5) (layer F.SilkS) (width 0.12))
30 | (fp_line (start 10.5 12.5) (end 10.5 12.9) (layer F.SilkS) (width 0.12))
31 | (fp_line (start -10.5 -12.9) (end -10.5 -12.5) (layer F.SilkS) (width 0.12))
32 | (fp_line (start 10.5 -23.1) (end 10.5 -22.7) (layer F.SilkS) (width 0.12))
33 | (fp_line (start -10.5 -2.7) (end -10.5 -2.3) (layer F.SilkS) (width 0.12))
34 | (fp_line (start 10.5 -0.2) (end 10.5 0.2) (layer F.SilkS) (width 0.12))
35 | (fp_line (start -10.5 -10.4) (end -10.5 -10) (layer F.SilkS) (width 0.12))
36 | (fp_line (start 10.5 -2.7) (end 10.5 -2.3) (layer F.SilkS) (width 0.12))
37 | (fp_line (start 10.5 7.4) (end 10.5 7.8) (layer F.SilkS) (width 0.12))
38 | (fp_line (start -10.5 -18) (end -10.5 -17.6) (layer F.SilkS) (width 0.12))
39 | (fp_line (start 10.5 -7.8) (end 10.5 -7.4) (layer F.SilkS) (width 0.12))
40 | (fp_line (start -3.7 25.5) (end -10.5 25.5) (layer F.SilkS) (width 0.12))
41 | (fp_line (start -10.5 -7.8) (end -10.5 -7.4) (layer F.SilkS) (width 0.12))
42 | (fp_line (start -10.5 22.7) (end -10.5 23.1) (layer F.SilkS) (width 0.12))
43 | (fp_line (start 10.5 17.6) (end 10.5 18) (layer F.SilkS) (width 0.12))
44 | (fp_line (start -10.5 -25.5) (end 10.5 -25.5) (layer F.SilkS) (width 0.12))
45 | (fp_line (start -10.5 -15.4) (end -10.5 -15) (layer F.SilkS) (width 0.12))
46 | (fp_line (start 10.5 -10.4) (end 10.5 -10) (layer F.SilkS) (width 0.12))
47 | (fp_line (start -7.493 -22.833) (end -7.493 -25.5) (layer F.SilkS) (width 0.12))
48 | (fp_line (start 10.5 22.7) (end 10.5 23.1) (layer F.SilkS) (width 0.12))
49 | (fp_line (start 10.5 -18) (end 10.5 -17.6) (layer F.SilkS) (width 0.12))
50 | (fp_line (start -10.5 15.1) (end -10.5 15.5) (layer F.SilkS) (width 0.12))
51 | (fp_line (start -10.5 -22.833) (end -7.493 -22.833) (layer F.SilkS) (width 0.12))
52 | (fp_line (start 10.5 -25.5) (end 10.5 -25.2) (layer F.SilkS) (width 0.12))
53 | (fp_line (start -10.5 -5.3) (end -10.5 -4.9) (layer F.SilkS) (width 0.12))
54 | (fp_line (start -10.5 -25.5) (end -10.5 -25.2) (layer F.SilkS) (width 0.12))
55 | (fp_line (start -10.5 17.6) (end -10.5 18) (layer F.SilkS) (width 0.12))
56 | (fp_line (start -10.5 7.4) (end -10.5 7.8) (layer F.SilkS) (width 0.12))
57 | (fp_line (start -7.1 25.5) (end -7.1 17) (layer Dwgs.User) (width 0.12))
58 | (fp_line (start -7.1 17) (end 7.1 17) (layer Dwgs.User) (width 0.12))
59 | (fp_line (start 7.1 17) (end 7.1 25.5) (layer Dwgs.User) (width 0.12))
60 | (fp_text user %R (at 0 0 180) (layer F.Fab)
61 | (effects (font (size 1 1) (thickness 0.15)))
62 | )
63 | (fp_poly (pts (xy -1.5 -9.9) (xy -3.5 -9.9) (xy -3.5 -11.9) (xy -1.5 -11.9)) (layer Dwgs.User) (width 0.1))
64 | (fp_poly (pts (xy 3.7 -20.2) (xy -3.7 -20.2) (xy -3.7 -24.9) (xy 3.7 -24.9)) (layer Dwgs.User) (width 0.1))
65 | (fp_poly (pts (xy -1.5 -14.9) (xy -3.5 -14.9) (xy -3.5 -16.9) (xy -1.5 -16.9)) (layer Dwgs.User) (width 0.1))
66 | (fp_poly (pts (xy -1.5 -12.4) (xy -3.5 -12.4) (xy -3.5 -14.4) (xy -1.5 -14.4)) (layer Dwgs.User) (width 0.1))
67 | (fp_text user "Copper Keepouts shown on Dwgs layer" (at 0.1 -30.2) (layer Cmts.User)
68 | (effects (font (size 1 1) (thickness 0.15)))
69 | )
70 | (fp_line (start 11 26) (end -11 26) (layer F.CrtYd) (width 0.12))
71 | (fp_line (start -11 26) (end -11 -26) (layer F.CrtYd) (width 0.12))
72 | (fp_line (start 11 -26) (end 11 26) (layer F.CrtYd) (width 0.12))
73 | (fp_line (start -11 -26) (end 11 -26) (layer F.CrtYd) (width 0.12))
74 | (fp_line (start 10.5 -25.5) (end 10.5 25.5) (layer F.Fab) (width 0.12))
75 | (fp_line (start -10.5 -24.2) (end -9.2 -25.5) (layer F.Fab) (width 0.12))
76 | (fp_line (start -10.5 -25.5) (end 10.5 -25.5) (layer F.Fab) (width 0.12))
77 | (fp_line (start -10.5 25.5) (end -10.5 -25.5) (layer F.Fab) (width 0.12))
78 | (fp_line (start 10.5 25.5) (end -10.5 25.5) (layer F.Fab) (width 0.12))
79 | (pad 1 thru_hole oval (at -8.89 -24.13) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
80 | (pad 2 thru_hole oval (at -8.89 -21.59) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
81 | (pad 3 thru_hole rect (at -8.89 -19.05) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
82 | (pad 4 thru_hole oval (at -8.89 -16.51) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
83 | (pad 5 thru_hole oval (at -8.89 -13.97) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
84 | (pad 6 thru_hole oval (at -8.89 -11.43) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
85 | (pad 7 thru_hole oval (at -8.89 -8.89) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
86 | (pad 8 thru_hole rect (at -8.89 -6.35) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
87 | (pad 9 thru_hole oval (at -8.89 -3.81) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
88 | (pad 10 thru_hole oval (at -8.89 -1.27) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
89 | (pad 11 thru_hole oval (at -8.89 1.27) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
90 | (pad 12 thru_hole oval (at -8.89 3.81) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
91 | (pad 13 thru_hole rect (at -8.89 6.35) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
92 | (pad 14 thru_hole oval (at -8.89 8.89) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
93 | (pad 15 thru_hole oval (at -8.89 11.43) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
94 | (pad 16 thru_hole oval (at -8.89 13.97) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
95 | (pad 17 thru_hole oval (at -8.89 16.51) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
96 | (pad 18 thru_hole rect (at -8.89 19.05) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
97 | (pad 19 thru_hole oval (at -8.89 21.59) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
98 | (pad 20 thru_hole oval (at -8.89 24.13) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
99 | (pad 21 thru_hole oval (at 8.89 24.13) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
100 | (pad 22 thru_hole oval (at 8.89 21.59) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
101 | (pad 23 thru_hole rect (at 8.89 19.05) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
102 | (pad 24 thru_hole oval (at 8.89 16.51) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
103 | (pad 25 thru_hole oval (at 8.89 13.97) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
104 | (pad 26 thru_hole oval (at 8.89 11.43) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
105 | (pad 27 thru_hole oval (at 8.89 8.89) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
106 | (pad 28 thru_hole rect (at 8.89 6.35) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
107 | (pad 29 thru_hole oval (at 8.89 3.81) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
108 | (pad 30 thru_hole oval (at 8.89 1.27) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
109 | (pad 31 thru_hole oval (at 8.89 -1.27) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
110 | (pad 32 thru_hole oval (at 8.89 -3.81) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
111 | (pad 33 thru_hole rect (at 8.89 -6.35) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
112 | (pad 34 thru_hole oval (at 8.89 -8.89) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
113 | (pad 35 thru_hole oval (at 8.89 -11.43) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
114 | (pad 36 thru_hole oval (at 8.89 -13.97) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
115 | (pad 37 thru_hole oval (at 8.89 -16.51) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
116 | (pad 38 thru_hole rect (at 8.89 -19.05) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
117 | (pad 39 thru_hole oval (at 8.89 -21.59) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
118 | (pad 40 thru_hole oval (at 8.89 -24.13) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
119 | (pad "" np_thru_hole oval (at 2.725 -24) (size 1.8 1.8) (drill 1.8) (layers *.Cu *.Mask))
120 | (pad "" np_thru_hole oval (at -2.725 -24) (size 1.8 1.8) (drill 1.8) (layers *.Cu *.Mask))
121 | (pad "" np_thru_hole oval (at -2.425 -20.97) (size 1.5 1.5) (drill 1.5) (layers *.Cu *.Mask))
122 | (pad "" np_thru_hole oval (at 2.425 -20.97) (size 1.5 1.5) (drill 1.5) (layers *.Cu *.Mask))
123 | (pad 41 thru_hole oval (at 0.5841 5.6) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
124 | (pad 42 thru_hole rect (at 3.1241 5.6) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
125 | (pad 43 thru_hole oval (at 5.6641 5.6) (size 1.7 1.7) (drill 1.02) (layers *.Cu *.Mask))
126 | (pad 1 smd rect (at -8.89 -24.13) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
127 | (pad 2 smd rect (at -8.89 -21.59) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
128 | (pad 3 smd rect (at -8.89 -19.05) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
129 | (pad 4 smd rect (at -8.89 -16.51) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
130 | (pad 5 smd rect (at -8.89 -13.97) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
131 | (pad 6 smd rect (at -8.89 -11.43) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
132 | (pad 7 smd rect (at -8.89 -8.89) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
133 | (pad 8 smd rect (at -8.89 -6.35) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
134 | (pad 9 smd rect (at -8.89 -3.81) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
135 | (pad 10 smd rect (at -8.89 -1.27) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
136 | (pad 11 smd rect (at -8.89 1.27) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
137 | (pad 12 smd rect (at -8.89 3.81) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
138 | (pad 13 smd rect (at -8.89 6.35) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
139 | (pad 14 smd rect (at -8.89 8.89) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
140 | (pad 15 smd rect (at -8.89 11.43) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
141 | (pad 16 smd rect (at -8.89 13.97) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
142 | (pad 17 smd rect (at -8.89 16.51) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
143 | (pad 18 smd rect (at -8.89 19.05) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
144 | (pad 19 smd rect (at -8.89 21.59) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
145 | (pad 20 smd rect (at -8.89 24.13) (size 3.5 1.7) (drill (offset -0.9 0)) (layers F.Cu F.Mask))
146 | (pad 21 smd rect (at 8.89 24.13) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
147 | (pad 22 smd rect (at 8.89 21.59) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
148 | (pad 23 smd rect (at 8.89 19.05) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
149 | (pad 24 smd rect (at 8.89 16.51) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
150 | (pad 25 smd rect (at 8.89 13.97) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
151 | (pad 26 smd rect (at 8.89 11.43) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
152 | (pad 27 smd rect (at 8.89 8.89) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
153 | (pad 28 smd rect (at 8.89 6.35) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
154 | (pad 29 smd rect (at 8.89 3.81) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
155 | (pad 30 smd rect (at 8.89 1.27) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
156 | (pad 31 smd rect (at 8.89 -1.27) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
157 | (pad 32 smd rect (at 8.89 -3.81) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
158 | (pad 33 smd rect (at 8.89 -6.35) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
159 | (pad 34 smd rect (at 8.89 -8.89) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
160 | (pad 35 smd rect (at 8.89 -11.43) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
161 | (pad 36 smd rect (at 8.89 -13.97) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
162 | (pad 37 smd rect (at 8.89 -16.51) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
163 | (pad 38 smd rect (at 8.89 -19.05) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
164 | (pad 39 smd rect (at 8.89 -21.59) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
165 | (pad 40 smd rect (at 8.89 -24.13) (size 3.5 1.7) (drill (offset 0.9 0)) (layers F.Cu F.Mask))
166 | )
167 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/SOIC-28W_7.5x17.9mm_Pitch1.27mm.kicad_mod:
--------------------------------------------------------------------------------
1 | (module Housings_SOIC:SOIC-28W_7.5x17.9mm_Pitch1.27mm (layer F.Cu) (tedit 57503567)
2 | (descr "28-Lead Plastic Small Outline (SO) - Wide, 7.50 mm Body [SOIC] (see Microchip Packaging Specification 00000049BS.pdf)")
3 | (tags "SOIC 1.27")
4 | (attr smd)
5 | (fp_text reference U1 (at 0 -10.05) (layer F.SilkS)
6 | (effects (font (size 1 1) (thickness 0.15)))
7 | )
8 | (fp_text value MAX3237CAI+ (at 0 10.05) (layer F.Fab)
9 | (effects (font (size 1 1) (thickness 0.15)))
10 | )
11 | (fp_line (start -2.75 -8.95) (end 3.75 -8.95) (layer F.Fab) (width 0.15))
12 | (fp_line (start 3.75 -8.95) (end 3.75 8.95) (layer F.Fab) (width 0.15))
13 | (fp_line (start 3.75 8.95) (end -3.75 8.95) (layer F.Fab) (width 0.15))
14 | (fp_line (start -3.75 8.95) (end -3.75 -7.95) (layer F.Fab) (width 0.15))
15 | (fp_line (start -3.75 -7.95) (end -2.75 -8.95) (layer F.Fab) (width 0.15))
16 | (fp_line (start -5.95 -9.3) (end -5.95 9.3) (layer F.CrtYd) (width 0.05))
17 | (fp_line (start 5.95 -9.3) (end 5.95 9.3) (layer F.CrtYd) (width 0.05))
18 | (fp_line (start -5.95 -9.3) (end 5.95 -9.3) (layer F.CrtYd) (width 0.05))
19 | (fp_line (start -5.95 9.3) (end 5.95 9.3) (layer F.CrtYd) (width 0.05))
20 | (fp_line (start -3.875 -9.125) (end -3.875 -8.875) (layer F.SilkS) (width 0.15))
21 | (fp_line (start 3.875 -9.125) (end 3.875 -8.78) (layer F.SilkS) (width 0.15))
22 | (fp_line (start 3.875 9.125) (end 3.875 8.78) (layer F.SilkS) (width 0.15))
23 | (fp_line (start -3.875 9.125) (end -3.875 8.78) (layer F.SilkS) (width 0.15))
24 | (fp_line (start -3.875 -9.125) (end 3.875 -9.125) (layer F.SilkS) (width 0.15))
25 | (fp_line (start -3.875 9.125) (end 3.875 9.125) (layer F.SilkS) (width 0.15))
26 | (fp_line (start -3.875 -8.875) (end -5.7 -8.875) (layer F.SilkS) (width 0.15))
27 | (pad 1 smd rect (at -4.7 -8.255) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
28 | (pad 2 smd rect (at -4.7 -6.985) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
29 | (pad 3 smd rect (at -4.7 -5.715) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
30 | (pad 4 smd rect (at -4.7 -4.445) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
31 | (pad 5 smd rect (at -4.7 -3.175) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
32 | (pad 6 smd rect (at -4.7 -1.905) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
33 | (pad 7 smd rect (at -4.7 -0.635) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
34 | (pad 8 smd rect (at -4.7 0.635) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
35 | (pad 9 smd rect (at -4.7 1.905) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
36 | (pad 10 smd rect (at -4.7 3.175) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
37 | (pad 11 smd rect (at -4.7 4.445) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
38 | (pad 12 smd rect (at -4.7 5.715) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
39 | (pad 13 smd rect (at -4.7 6.985) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
40 | (pad 14 smd rect (at -4.7 8.255) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
41 | (pad 15 smd rect (at 4.7 8.255) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
42 | (pad 16 smd rect (at 4.7 6.985) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
43 | (pad 17 smd rect (at 4.7 5.715) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
44 | (pad 18 smd rect (at 4.7 4.445) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
45 | (pad 19 smd rect (at 4.7 3.175) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
46 | (pad 20 smd rect (at 4.7 1.905) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
47 | (pad 21 smd rect (at 4.7 0.635) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
48 | (pad 22 smd rect (at 4.7 -0.635) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
49 | (pad 23 smd rect (at 4.7 -1.905) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
50 | (pad 24 smd rect (at 4.7 -3.175) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
51 | (pad 25 smd rect (at 4.7 -4.445) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
52 | (pad 26 smd rect (at 4.7 -5.715) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
53 | (pad 27 smd rect (at 4.7 -6.985) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
54 | (pad 28 smd rect (at 4.7 -8.255) (size 2 0.6) (layers F.Cu F.Paste F.Mask))
55 | (model Housings_SOIC.3dshapes/SOIC-28_7.5x17.9mm_Pitch1.27mm.wrl
56 | (at (xyz 0 0 0))
57 | (scale (xyz 1 1 1))
58 | (rotate (xyz 0 0 0))
59 | )
60 | )
61 |
--------------------------------------------------------------------------------
/kicad/modules.pretty/TO-92_Inline_Narrow_Oval.kicad_mod:
--------------------------------------------------------------------------------
1 | (module TO_SOT_Packages_THT:TO-92_Inline_Narrow_Oval (layer F.Cu) (tedit 633E1C3E)
2 | (descr "TO-92 leads in-line, narrow, oval pads, drill 0.6mm (see NXP sot054_po.pdf)")
3 | (tags "to-92 sc-43 sc-43a sot54 PA33 transistor")
4 | (fp_text reference U4 (at 4.826 -0.127 90) (layer F.SilkS)
5 | (effects (font (size 1 1) (thickness 0.15)))
6 | )
7 | (fp_text value LM2950ACZ-3.3 (at 6.731 -0.254 90) (layer F.Fab)
8 | (effects (font (size 1 1) (thickness 0.15)))
9 | )
10 | (fp_line (start -1.4 1.95) (end -1.4 -2.65) (layer F.CrtYd) (width 0.05))
11 | (fp_line (start -1.4 1.95) (end 3.95 1.95) (layer F.CrtYd) (width 0.05))
12 | (fp_line (start -0.43 1.7) (end 2.97 1.7) (layer F.SilkS) (width 0.15))
13 | (fp_arc (start 1.27 0) (end 1.27 -2.4) (angle -135) (layer F.SilkS) (width 0.15))
14 | (fp_arc (start 1.27 0) (end 1.27 -2.4) (angle 135) (layer F.SilkS) (width 0.15))
15 | (fp_line (start -1.4 -2.65) (end 3.95 -2.65) (layer F.CrtYd) (width 0.05))
16 | (fp_line (start 3.95 1.95) (end 3.95 -2.65) (layer F.CrtYd) (width 0.05))
17 | (pad 2 thru_hole oval (at 1.27 0 180) (size 0.89916 1.50114) (drill 0.6) (layers *.Cu *.Mask))
18 | (pad 3 thru_hole oval (at 2.54 0 180) (size 0.89916 1.50114) (drill 0.6) (layers *.Cu *.Mask))
19 | (pad 1 thru_hole oval (at 0 0 180) (size 0.89916 1.50114) (drill 0.6) (layers *.Cu *.Mask))
20 | (model TO_SOT_Packages_THT.3dshapes/TO-92_Inline_Narrow_Oval.wrl
21 | (at (xyz 0.05 0 0))
22 | (scale (xyz 1 1 1))
23 | (rotate (xyz 0 0 -90))
24 | )
25 | )
26 |
--------------------------------------------------------------------------------
/kicad/sym-lib-table:
--------------------------------------------------------------------------------
1 | (sym_lib_table
2 | (lib (name Pico_Wifi_modem)(type Legacy)(uri ${KIPRJMOD}/library/Pico_Wifi_modem.lib)(options "")(descr ""))
3 | )
4 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Generated Cmake Pico project file
2 |
3 | cmake_minimum_required(VERSION 3.13)
4 |
5 | set(CMAKE_C_STANDARD 11)
6 | set(CMAKE_CXX_STANDARD 17)
7 | set(CMAKE_BUILD_TYPE Debug)
8 | set(PICO_BOARD pico_w)
9 | set(PICO_PLATFORM rp2040)
10 | set(PICO_COMPILER pico_arm_gcc)
11 | set(PROJECT_NAME wifi_modem)
12 | set(CYW43_HOST_NAME "PicoW2")
13 |
14 | # Pull in Raspberry Pi Pico SDK (must be before project)
15 | include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
16 |
17 | project(${PROJECT_NAME})
18 |
19 | # Initialise the Raspberry Pi Pico SDK
20 | pico_sdk_init()
21 |
22 | add_executable(${PROJECT_NAME}
23 | ${PROJECT_NAME}.cpp
24 | )
25 | target_compile_definitions(${PROJECT_NAME} PRIVATE
26 | CYW43_HOST_NAME=\"${CYW43_HOST_NAME}\"
27 | )
28 | target_include_directories(${PROJECT_NAME} PRIVATE
29 | ${CMAKE_CURRENT_LIST_DIR}
30 | )
31 | target_link_libraries(${PROJECT_NAME}
32 | pico_cyw43_arch_lwip_threadsafe_background
33 | pico_stdlib
34 | hardware_i2c
35 | )
36 |
37 | pico_add_extra_outputs(${PROJECT_NAME})
38 |
39 | # enable usb output, disable uart output
40 | pico_enable_stdio_usb(${PROJECT_NAME} 0)
41 | pico_enable_stdio_uart(${PROJECT_NAME} 1)
42 |
--------------------------------------------------------------------------------
/src/at_basic.h:
--------------------------------------------------------------------------------
1 | //
2 | // ATA manually answer an incoming call
3 | //
4 | char *answerCall(char *atCmd) {
5 | tcpClient = serverGetClient(&tcpServer, &tcpClient0);
6 | gpio_put(RI, !ACTIVE); // we've picked up so ringing stops
7 | ringing = false;
8 | ringCount = 0;
9 | if( settings.telnet != NO_TELNET ) {
10 | // send incantation to switch from line mode to character mode
11 | bytesOut += tcpWriteBuf(tcpClient, toCharModeMagic, sizeof toCharModeMagic);
12 | }
13 | sendResult(R_RING_IP);
14 | sleep_ms(1000);
15 | connectTime = millis();
16 | dtrWentInactive = false;
17 | sendResult(R_CONNECT);
18 | gpio_put(DCD, ACTIVE); // we've got a carrier signal
19 | amClient = false;
20 | state = ONLINE;
21 | uart_tx_wait_blocking(uart0); // drain the UART's Tx FIFO
22 | return atCmd;
23 | }
24 |
25 | //
26 | // ATC? query WiFi connection status
27 | // ATC0 disconnect from WiFi network
28 | // ATC1 connect to WiFi network
29 | //
30 | char *wifiConnection(char *atCmd) {
31 | switch( atCmd[0] ) {
32 | case '?':
33 | ++atCmd;
34 | printf("%c\r\n", cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) == CYW43_LINK_UP ? '1' : '0');
35 | if( !atCmd[0] ) {
36 | sendResult(R_OK);
37 | }
38 | break;
39 | case '0':
40 | ++atCmd;
41 | case NUL:
42 | cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA);
43 | if( !atCmd[0] ) {
44 | sendResult(R_OK);
45 | }
46 | gpio_put(DSR, !ACTIVE); // modem is not ready
47 | break;
48 | case '1':
49 | ++atCmd;
50 | if( settings.ssid[0] && settings.wifiPassword[0] ) {
51 | if( !settings.quiet && settings.extendedCodes ) {
52 | printf("CONNECTING TO SSID %s", settings.ssid);
53 | }
54 | cyw43_arch_wifi_connect_async(settings.ssid, settings.wifiPassword, CYW43_AUTH_WPA2_AES_PSK);
55 | for( int i = 0; i < 50; ++i ) {
56 | sleep_ms(500);
57 | if( !settings.quiet && settings.extendedCodes ) {
58 | uart_putc(uart0, '.');
59 | }
60 | if( cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) == CYW43_LINK_UP ) {
61 | break;
62 | }
63 | }
64 | if( !settings.quiet && settings.extendedCodes ) {
65 | crlf();
66 | }
67 | if( cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) != CYW43_LINK_UP ) {
68 | sendResult(R_ERROR);
69 | } else {
70 | gpio_put(DSR, ACTIVE); // modem is ready
71 | dns_init();
72 | if( !settings.quiet && settings.extendedCodes ) {
73 | printf("CONNECTED TO %s IP ADDRESS: %s\r\n",
74 | settings.ssid, ip4addr_ntoa(netif_ip4_addr(&cyw43_state.netif[0])));
75 | }
76 | if( !atCmd[0] ) {
77 | sendResult(R_OK);
78 | }
79 | }
80 | } else {
81 | if( !settings.quiet && settings.extendedCodes ) {
82 | printf("Configure SSID and password. Type AT? for help.\r\n");
83 | }
84 | sendResult(R_ERROR);
85 | }
86 | break;
87 | default:
88 | sendResult(R_ERROR);
89 | break;
90 | }
91 | return atCmd;
92 | }
93 |
94 | //
95 | // ATDSn speed dial a number
96 | //
97 | char *dialNumber(char *atCmd);
98 |
99 | char *speedDialNumber(char *atCmd) {
100 | char number[MAX_SPEED_DIAL_LEN + 1];
101 | char slot = atCmd[0];
102 |
103 | if( isdigit(slot) && settings.speedDial[slot - '0'][0] ) {
104 | ++atCmd;
105 | strncpy(number, settings.speedDial[slot - '0'], MAX_SPEED_DIAL_LEN);
106 | number[MAX_SPEED_DIAL_LEN] = NUL;
107 | dialNumber(number);
108 | } else {
109 | sendResult(R_ERROR);
110 | }
111 | return atCmd;
112 | }
113 |
114 | //
115 | // ATDThost[:port] dial a number
116 | //
117 | char *dialNumber(char *atCmd) {
118 | char *host, *port, *ptr;
119 | char tempNumber[MAX_SPEED_DIAL_LEN + 1];
120 | int portNum;
121 | ip_addr_t remoteAddr;
122 |
123 | getHostAndPort(atCmd, host, port, portNum);
124 | if( !port ) {
125 | // check for host names that are 7 identical digits long
126 | // and dial from the corresponding speed dial slot
127 | bool speedDial = true;
128 | if( strlen(host) == MAGIC_SPEED_LEN && isdigit(host[0]) ) {
129 | for( int i = 0; i < MAGIC_SPEED_LEN; ++i ) {
130 | if( host[0] != host[i] ) {
131 | speedDial = false;
132 | break;
133 | }
134 | }
135 | } else {
136 | speedDial = false;
137 | }
138 | if( speedDial && settings.speedDial[host[0] - '0'][0] ) {
139 | strncpy(tempNumber, settings.speedDial[host[0] - '0'], MAX_SPEED_DIAL_LEN);
140 | tempNumber[MAX_SPEED_DIAL_LEN] = NUL;
141 | getHostAndPort(tempNumber, host, port, portNum);
142 | } else {
143 | // now check all the speed dial aliases for a match
144 | for( int i = 0; i < SPEED_DIAL_SLOTS; ++i ) {
145 | if( !strcasecmp(host, settings.alias[i]) ) {
146 | strncpy(tempNumber, settings.speedDial[i], MAX_SPEED_DIAL_LEN);
147 | tempNumber[MAX_SPEED_DIAL_LEN] = NUL;
148 | getHostAndPort(tempNumber, host, port, portNum);
149 | break;
150 | }
151 | }
152 | }
153 | }
154 |
155 | sessionTelnetType = settings.telnet;
156 | switch( host[0] ) {
157 | case '-':
158 | ++host;
159 | sessionTelnetType = NO_TELNET;
160 | break;
161 | case '=':
162 | ++host;
163 | sessionTelnetType = REAL_TELNET;
164 | break;
165 | case '+':
166 | ++host;
167 | sessionTelnetType = FAKE_TELNET;
168 | break;
169 | }
170 |
171 | if( !settings.quiet && settings.extendedCodes ) {
172 | printf("DIALLING %s:%u\r\n", host, portNum);
173 | uart_tx_wait_blocking(uart0);
174 | }
175 | sleep_ms(2000); // delay for ZMP to be able to detect CONNECT
176 | if( !uart_is_readable(uart0) ) {
177 | tcpClient = tcpConnect( &tcpClient0, host, portNum);
178 | if( tcpClient ) {
179 | connectTime = millis();
180 | dtrWentInactive = false;
181 | sendResult(R_CONNECT);
182 | gpio_put(DCD, ACTIVE);
183 | state = ONLINE;
184 | amClient = true;
185 | } else {
186 | sendResult(R_NO_CARRIER);
187 | gpio_put(DCD, !ACTIVE);
188 | }
189 | } else {
190 | sendResult(R_NO_CARRIER);
191 | gpio_put(DCD, !ACTIVE);
192 | }
193 | atCmd[0] = NUL;
194 | return atCmd;
195 | }
196 |
197 | //
198 | // ATE? query command mode echo status
199 | // ATE0 disable command mode local echo
200 | // ATE1 enable command mode local echo
201 | //
202 | char *doEcho(char *atCmd) {
203 | switch( atCmd[0] ) {
204 | case '?':
205 | ++atCmd;
206 | printf("%u\r\n", settings.echo);
207 | if( !atCmd[0] ) {
208 | sendResult(R_OK);
209 | }
210 | break;
211 | case '0':
212 | case '1':
213 | case NUL:
214 | settings.echo = atCmd[0] == '1';
215 | if( atCmd[0] ) {
216 | ++atCmd;
217 | }
218 | if( !atCmd[0] ) {
219 | sendResult(R_OK);
220 | }
221 | break;
222 | default:
223 | sendResult(R_ERROR);
224 | break;
225 | }
226 | return atCmd;
227 | }
228 |
229 | //
230 | // ATGEThttp://host[/path]: fetch a web page
231 | //
232 | // NOTE: http only: no https support
233 | //
234 | char *httpGet(char *atCmd) {
235 | char *host, *path, *port;
236 | int portNum;
237 | port = strrchr(atCmd, ':');
238 | host = strstr(atCmd, "http://");
239 | if( !port || port == host + 4) {
240 | portNum = HTTP_PORT;
241 | } else {
242 | portNum = atoi(port + 1);
243 | *port = NUL;
244 | }
245 | if( !host ) {
246 | sendResult(R_ERROR);
247 | return atCmd;
248 | } else {
249 | host += 7; // skip over http://
250 | path = strchr(host, '/');
251 | }
252 | if( path ) {
253 | *path = NUL;
254 | ++path;
255 | }
256 | #if DEBUG
257 | printf("Getting path /");
258 | if( path ) {
259 | printf("%s", path);
260 | }
261 | printf(" from port %u of host %s...\r\n", portNum, host);
262 | #endif
263 | // Establish connection
264 | tcpClient = tcpConnect(&tcpClient0, host, portNum);
265 | if( !tcpClient ) {
266 | sendResult(R_NO_CARRIER);
267 | gpio_put(DCD, !ACTIVE);
268 | } else {
269 | connectTime = millis();
270 | dtrWentInactive = false;
271 | sendResult(R_CONNECT);
272 | gpio_put(DCD, ACTIVE);
273 | amClient = true;
274 | state = ONLINE;
275 |
276 | // Send a HTTP request before continuing the connection as usual
277 | bytesOut += tcpWriteStr(tcpClient, "GET /");
278 | if( path ) {
279 | bytesOut += tcpWriteStr(tcpClient, path);
280 | }
281 | bytesOut += tcpWriteStr(tcpClient, " HTTP/1.1\r\nHost: ");
282 | bytesOut += tcpWriteStr(tcpClient, host);
283 | bytesOut += tcpWriteStr(tcpClient, "\r\nConnection: close\r\n\r\n");
284 | }
285 | atCmd[0] = NUL;
286 | return atCmd;
287 | }
288 |
289 | //
290 | // ATH go offline (if connected to a host)
291 | //
292 | char *hangup(char *atCmd) {
293 | if( tcpIsConnected(tcpClient) ) {
294 | endCall();
295 | } else {
296 | sendResult(R_OK);
297 | }
298 | return atCmd;
299 | }
300 |
301 | //
302 | // AT? help: paged output, uses dual columns if defined screen width
303 | // is at least 80 characters, single columns if less.
304 | //
305 | // There must be an even number of help strings defined. If you end up
306 | // with an odd number of strings, add an empty string ("") at the end
307 | // to pad things out.
308 | //
309 | const char helpStr01[] = "Help..........: AT?";
310 | const char helpStr02[] = "Repeat command: A/";
311 | const char helpStr03[] = "Answer call...: ATA";
312 | const char helpStr04[] = "WiFi connect..: ATCn";
313 | const char helpStr05[] = "Speed dial....: ATDSn";
314 | const char helpStr06[] = "Dial host.....: ATDThost[:port]";
315 | const char helpStr07[] = "Command echo..: ATEn";
316 | const char helpStr08[] = "HTTP get......: ATGEThttp://host[/page]";
317 | const char helpStr09[] = "Hang up.......: ATH";
318 | const char helpStr10[] = "Network info..: ATI";
319 | const char helpStr11[] = "Handle Telnet.: ATNETn";
320 | const char helpStr12[] = "Leave cmd mode: ATO";
321 | const char helpStr13[] = "Quiet mode....: ATQn";
322 | const char helpStr14[] = "NIST date.time: ATRD/ATRT";
323 | const char helpStr15[] = "Auto answer...: ATS0=n";
324 | const char helpStr16[] = "Verbose mode..: ATVn";
325 | const char helpStr17[] = "Extended codes: ATXn";
326 | const char helpStr18[] = "Modem reset...: ATZ";
327 | const char helpStr19[] = "DTR handling..: AT&D";
328 | const char helpStr20[] = "Fact. defaults: AT&F";
329 | const char helpStr21[] = "Flow control..: AT&Kn";
330 | const char helpStr22[] = "Server passwd.: AT&R=server password";
331 | const char helpStr23[] = "Show settings.: AT&Vn";
332 | const char helpStr24[] = "Update NVRAM..: AT&W";
333 | const char helpStr25[] = "Set speed dial: AT&Zn=host[:port],alias";
334 | const char helpStr26[] = "Auto execute..: AT$AE=AT command";
335 | const char helpStr27[] = "Are You There?: AT$AYT";
336 | const char helpStr28[] = "Busy message..: AT$BM=busy message";
337 | const char helpStr29[] = "mDNS name.....: AT$MDNS=mDNS name";
338 | const char helpStr30[] = "WiFi password.: AT$PASS=WiFi password";
339 | const char helpStr31[] = "Serial speed..: AT$SB=n";
340 | const char helpStr32[] = "Server port...: AT$SP=n";
341 | const char helpStr33[] = "WiFi SSID.....: AT$SSID=ssid";
342 | const char helpStr34[] = "Data config...: AT$SU=dps";
343 | const char helpStr35[] = "Location......: AT$TTL=telnet location";
344 | const char helpStr36[] = "Terminal size.: AT$TTS=WxH";
345 | const char helpStr37[] = "Terminal type.: AT$TTY=terminal type";
346 | const char helpStr38[] = "Startup wait..: AT$W=n";
347 | const char helpStr39[] = "Query most commands followed by '?'";
348 | const char helpStr40[] = "e.g. ATQ?, AT&K?, AT$SSID?";
349 |
350 | const char* const helpStrs[] = {
351 | helpStr01, helpStr02, helpStr03, helpStr04, helpStr05, helpStr06,
352 | helpStr07, helpStr08, helpStr09, helpStr10, helpStr11, helpStr12,
353 | helpStr13, helpStr14, helpStr15, helpStr16, helpStr17, helpStr18,
354 | helpStr19, helpStr20, helpStr21, helpStr22, helpStr23, helpStr24,
355 | helpStr25, helpStr26, helpStr27, helpStr28, helpStr29, helpStr30,
356 | helpStr31, helpStr32, helpStr33, helpStr34, helpStr35, helpStr36,
357 | helpStr37, helpStr38, helpStr39, helpStr40
358 | };
359 | #define NUM_HELP_STRS (sizeof(helpStrs) / sizeof(helpStrs[0]))
360 |
361 | char *showHelp(char *atCmd) {
362 | char helpLine[80];
363 |
364 | PagedOut("AT Command Summary:", true);
365 | if( settings.width >= 80 ) {
366 | // dual columns
367 | for( int i=0; ipcb->remote_ip));
487 | if( PagedOut(infoLine) ) break;
488 | snprintf(infoLine, sizeof infoLine, "Call length: %s", connectTimeString());
489 | if( PagedOut(infoLine) ) break;
490 | } else {
491 | if( PagedOut("Call status: NOT CONNECTED") ) break;
492 | }
493 | } while( false );
494 | if( !atCmd[0] ) {
495 | sendResult(R_OK);
496 | }
497 | return atCmd;
498 | }
499 |
500 | //
501 | // ATNET? query Telnet handling status
502 | // ATNET0 turn off Telnet handling
503 | // ATNET1 turn on true Telnet handling
504 | // ATNET2 turn on BBS (fake) Telnet handling
505 | //
506 | char *doTelnetMode(char* atCmd) {
507 | switch( atCmd[0] ) {
508 | case '?':
509 | ++atCmd;
510 | printf("%u\r\n", settings.telnet);
511 | if( !atCmd[0] ) {
512 | sendResult(R_OK);
513 | }
514 | break;
515 | case NUL:
516 | case '0': // no Telnet processing
517 | case '1': // real Telnet (double IACs, add NUL after CR)
518 | case '2': // fake (BBS) Telnet (double IACs)
519 | if( atCmd[0] ) {
520 | settings.telnet = atCmd[0] - '0';
521 | ++atCmd;
522 | } else {
523 | settings.telnet = NO_TELNET;
524 | }
525 | if( !atCmd[0] ) {
526 | sendResult(R_OK);
527 | }
528 | break;
529 | default:
530 | sendResult(R_ERROR);
531 | break;
532 | }
533 | return atCmd;
534 | }
535 |
536 | //
537 | // ATO go online (if connected to a host)
538 | //
539 | char *goOnline(char *atCmd) {
540 | if( tcpIsConnected(tcpClient) ) {
541 | state = ONLINE;
542 | dtrWentInactive = false;
543 | sendResult(R_CONNECT);
544 | } else {
545 | sendResult(R_ERROR);
546 | }
547 | return atCmd;
548 | }
549 |
550 | //
551 | // ATQ? query quiet mode status
552 | // ATQ0 disable quiet mode (results issued)
553 | // ATQ1 enable quiet mode (no results issued)
554 | //
555 | char *doQuiet(char *atCmd) {
556 | switch( atCmd[0] ) {
557 | case '?':
558 | ++atCmd;
559 | printf("%u\r\n", settings.quiet);
560 | if( !atCmd[0] ) {
561 | sendResult(R_OK);
562 | }
563 | break;
564 | case '0':
565 | case '1':
566 | case NUL:
567 | settings.quiet = atCmd[0] == '1';
568 | if( atCmd[0] ) {
569 | ++atCmd;
570 | }
571 | if( !atCmd[0] ) {
572 | sendResult(R_OK);
573 | }
574 | break;
575 | default:
576 | sendResult(R_ERROR);
577 | break;
578 | }
579 | return atCmd;
580 | }
581 |
582 | //
583 | // ATRD Displays the UTC date and time from NIST in the format
584 | // ATRT "YY-MM-DD HH:MM:SS"
585 | //
586 | char *doDateTime(char *atCmd) {
587 | bool ok = false;
588 | uint16_t len;
589 |
590 | if( !tcpIsConnected(tcpClient) ) {
591 | char result[80], *ptr;
592 | tcpClient = tcpConnect(&tcpClient0, NIST_HOST, NIST_PORT);
593 | if( tcpClient ) {
594 | gpio_put(DCD, ACTIVE);
595 | // read date/time from NIST
596 | result[0] = tcpReadByte(tcpClient, 1000);
597 | if( result[0] == '\n' ) { // leading LF
598 | len = tcpReadBytesUntil(tcpClient, '\n', result, (sizeof result) - 1);
599 | if( len ) { // string read?
600 | result[len] = NUL;
601 | ptr = strtok(result, " ");
602 | if( ptr ) { // found Julian day?
603 | ptr = strtok(NULL, " ");
604 | if( ptr ) { // found date?
605 | printf("%s ", ptr);
606 | ptr = strtok(NULL, " ");
607 | if( ptr ) { // found time?
608 | printf("%s\r\n", ptr);
609 | ok = true;
610 | }
611 | }
612 | }
613 | }
614 | }
615 | tcpClientClose(tcpClient);
616 | gpio_put(DCD, !ACTIVE);
617 | }
618 | }
619 | if( ok ) {
620 | if( !atCmd[0] ) {
621 | sendResult(R_OK);
622 | }
623 | } else {
624 | sendResult(R_ERROR);
625 | }
626 | return atCmd;
627 | }
628 |
629 | //
630 | // ATS0? query auto answer configuration
631 | // ATS0=0 disable auto answer
632 | // ATS0=n enable auto answer after n rings
633 | //
634 | char *doAutoAnswerConfig(char *atCmd) {
635 | switch( atCmd[0] ) {
636 | case '?':
637 | ++atCmd;
638 | printf("%u\r\n", settings.autoAnswer);
639 | if( !atCmd[0] ) {
640 | sendResult(R_OK);
641 | }
642 | break;
643 | case '=':
644 | ++atCmd;
645 | if( isdigit(atCmd[0]) ) {
646 | settings.autoAnswer = atoi(atCmd);
647 | while( isdigit(atCmd[0]) ) {
648 | ++atCmd;
649 | }
650 | if( !atCmd[0] ) {
651 | sendResult(R_OK);
652 | }
653 | } else {
654 | sendResult(R_ERROR);
655 | }
656 | break;
657 | default:
658 | sendResult(R_ERROR);
659 | break;
660 | }
661 | return atCmd;
662 | }
663 |
664 | //
665 | // ATS2? query escape character
666 | // ATS2=[128..255] disable escape character
667 | // ATS2=[0..127] set and enable escape character
668 | //
669 | char *doEscapeCharConfig(char *atCmd) {
670 | switch( atCmd[0] ) {
671 | case '?':
672 | ++atCmd;
673 | printf("%u\r\n", settings.escChar);
674 | if( !atCmd[0] ) {
675 | sendResult(R_OK);
676 | }
677 | break;
678 | case '=':
679 | ++atCmd;
680 | if( isdigit(atCmd[0]) ) {
681 | settings.escChar = atoi(atCmd);
682 | while( isdigit(atCmd[0]) ) {
683 | ++atCmd;
684 | }
685 | if( !atCmd[0] ) {
686 | sendResult(R_OK);
687 | }
688 | } else {
689 | sendResult(R_ERROR);
690 | }
691 | break;
692 | default:
693 | sendResult(R_ERROR);
694 | break;
695 | }
696 | return atCmd;
697 | }
698 |
699 | //
700 | // ATV? query verbose mode status
701 | // ATV0 disable verbose mode (results are shown as numbers)
702 | // ATV1 enable verbose nmode (results are shown as text)
703 | //
704 | char *doVerbose(char* atCmd) {
705 | switch( atCmd[0] ) {
706 | case '?':
707 | ++atCmd;
708 | printf("%u\r\n", settings.verbose);
709 | if( !atCmd[0] ) {
710 | sendResult(R_OK);
711 | }
712 | break;
713 | case '0':
714 | case '1':
715 | case NUL:
716 | settings.verbose = atCmd[0] == '1';
717 | if( atCmd[0] ) {
718 | ++atCmd;
719 | }
720 | if( !atCmd[0] ) {
721 | sendResult(R_OK);
722 | }
723 | break;
724 | default:
725 | sendResult(R_ERROR);
726 | break;
727 | }
728 | return atCmd;
729 | }
730 |
731 | //
732 | // ATX? query extended results
733 | // ATX0 disable extended results
734 | // ATX1 enable extended results
735 | //
736 | char *doExtended(char *atCmd) {
737 | switch( atCmd[0] ) {
738 | case '?':
739 | ++atCmd;
740 | printf("%u\r\n", settings.extendedCodes);
741 | if( !atCmd[0] ) {
742 | sendResult(R_OK);
743 | }
744 | break;
745 | case '0':
746 | case '1':
747 | case NUL:
748 | settings.extendedCodes = atCmd[0] == '1';
749 | if( atCmd[0] ) {
750 | ++atCmd;
751 | }
752 | if( !atCmd[0] ) {
753 | sendResult(R_OK);
754 | }
755 | break;
756 | default:
757 | sendResult(R_ERROR);
758 | break;
759 | }
760 | return atCmd;
761 | }
762 |
763 | //
764 | // ATZ restart the sketch
765 | //
766 | char *resetToNvram(char *atCmd) {
767 | uart_tx_wait_blocking(uart0); // allow for CR/LF to finish
768 | watchdog_enable(1, false);
769 | while( true ) {
770 | tight_loop_contents();
771 | }
772 | return atCmd; // should never actually get here...
773 | }
774 |
775 |
--------------------------------------------------------------------------------
/src/at_extended.h:
--------------------------------------------------------------------------------
1 | //
2 | // AT&F reset NVRAM to defaults and load them into current settings
3 | //
4 | char *factoryDefaults(char *atCmd) {
5 | settings.magicNumber = MAGIC_NUMBER;
6 | settings.ssid[0] = NUL;
7 | settings.wifiPassword[0] = NUL;
8 | settings.serialSpeed = DEFAULT_SPEED;
9 | settings.dataBits = 8;
10 | settings.parity = UART_PARITY_NONE;
11 | settings.stopBits = 1;
12 | settings.rtsCts = false;
13 | settings.width = 80;
14 | settings.height = 24;
15 | settings.escChar = ESC_CHAR;
16 | for( int i=0; i < SPEED_DIAL_SLOTS; ++i ) {
17 | settings.alias[i][0] = NUL;
18 | settings.speedDial[i][0] = NUL;
19 | }
20 | strcpy(settings.mdnsName, "picomodem");
21 | settings.autoAnswer = 0;
22 | settings.listenPort = 0;
23 | strcpy(settings.busyMsg, "Sorry, the system is currently busy. Please try again later.");
24 | settings.serverPassword[0] = NUL;
25 | settings.echo = true;
26 | settings.telnet = REAL_TELNET;
27 | settings.autoExecute[0] = NUL;
28 | strcpy(settings.terminal, "ansi");
29 | strcpy(settings.location, "Computer Room");
30 | settings.startupWait = false;
31 | settings.extendedCodes = true;
32 | settings.verbose = true;
33 | settings.quiet = false;
34 | settings.dtrHandling = DTR_IGNORE;
35 |
36 | strcpy(settings.alias[0], "particles");
37 | strcpy(settings.speedDial[0], "+particlesbbs.dyndns.org:6400");
38 | strcpy(settings.alias[1], "altair");
39 | strcpy(settings.speedDial[1], "altair.virtualaltair.com:4667");
40 | strcpy(settings.alias[2], "heatwave");
41 | strcpy(settings.speedDial[2], "heatwave.ddns.net:9640");
42 |
43 | bool ok = writeSettings(&settings);
44 |
45 | if( cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) == CYW43_LINK_UP ) {
46 | cyw43_wifi_leave(&cyw43_state, CYW43_ITF_STA);
47 | }
48 |
49 | if( atCmd ) {
50 | atCmd += 2;
51 | if( !atCmd[0] && ok) {
52 | sendResult(R_OK);
53 | } else if( !ok ) {
54 | sendResult(R_ERROR);
55 | }
56 | }
57 | return atCmd;
58 | }
59 |
60 | //
61 | // AT&D? DTR handling setting
62 | // AT&D0 ignore DTR
63 | // AT&D1 go offline when DTR transitions to off
64 | // AT&D2 hang up when DTR transitions to off
65 | // AT&D3 reset when DTR transitions to off
66 | //
67 | char *doDtrHandling(char *atCmd) {
68 | switch( atCmd[0] ) {
69 | case '?':
70 | ++atCmd;
71 | printf("%u\r\n", (uint8_t)settings.dtrHandling);
72 | if( !atCmd[0] ) {
73 | sendResult(R_OK);
74 | }
75 | break;
76 | case NUL:
77 | case '0':
78 | case '1':
79 | case '2':
80 | case '3':
81 | switch( atCmd[0] ) {
82 | case NUL:
83 | case '0':
84 | settings.dtrHandling = DTR_IGNORE;
85 | break;
86 | case '1':
87 | settings.dtrHandling = DTR_GOTO_COMMAND;
88 | break;
89 | case '2':
90 | settings.dtrHandling = DTR_END_CALL;
91 | break;
92 | case '3':
93 | settings.dtrHandling = DTR_RESET;
94 | break;
95 | }
96 | gpio_set_irq_enabled(DTR, GPIO_IRQ_EDGE_RISE, settings.dtrHandling != DTR_IGNORE);
97 | if( atCmd[0] ) {
98 | ++atCmd;
99 | }
100 | if( !atCmd[0] ) {
101 | sendResult(R_OK);
102 | }
103 | break;
104 | default:
105 | sendResult(R_ERROR);
106 | break;
107 | }
108 | return atCmd;
109 | }
110 |
111 | //
112 | // AT&K? query flow control setting
113 | // AT&K0 disable RTS/CTS flow control
114 | // AT&K1 enable RTS/CTS flow control
115 | //
116 | char *doFlowControl(char *atCmd) {
117 | switch( atCmd[0] ) {
118 | case '?':
119 | ++atCmd;
120 | printf("%u\r\n", settings.rtsCts);
121 | if( !atCmd[0] ) {
122 | sendResult(R_OK);
123 | }
124 | break;
125 | case '0':
126 | case '1':
127 | case NUL:
128 | settings.rtsCts = atCmd[0] == '1';
129 | if( atCmd[0] ) {
130 | ++atCmd;
131 | }
132 | if( !atCmd[0] ) {
133 | sendResult(R_OK);
134 | }
135 | break;
136 | default:
137 | sendResult(R_ERROR);
138 | break;
139 | }
140 | return atCmd;
141 | }
142 |
143 | //
144 | // AT&R? query incoming password
145 | // AT&R=set incoming password
146 | //
147 | char *doServerPassword(char *atCmd) {
148 | switch( atCmd[0] ) {
149 | case '?':
150 | ++atCmd;
151 | printf("%s\r\n", settings.serverPassword);
152 | if( !atCmd[0] ) {
153 | sendResult(R_OK);
154 | }
155 | break;
156 | case '=':
157 | ++atCmd;
158 | strncpy(settings.serverPassword, atCmd, MAX_PWD_LEN);
159 | settings.serverPassword[MAX_PWD_LEN] = NUL;
160 | atCmd[0] = NUL;
161 | sendResult(R_OK);
162 | break;
163 | default:
164 | sendResult(R_ERROR);
165 | break;
166 | }
167 | return atCmd;
168 | }
169 |
170 | //
171 | // AT&V display current settings
172 | // AT&V0 display current settings
173 | // AT&V1 display NVRAM settings
174 | //
175 | char *displayAllSettings(char* atCmd) {
176 | switch( atCmd[0]) {
177 | case '0':
178 | ++atCmd;
179 | case NUL:
180 | displayCurrentSettings();
181 | if( !atCmd[0] ) {
182 | sendResult(R_OK);
183 | }
184 | break;
185 | case '1':
186 | ++atCmd;
187 | displayStoredSettings();
188 | if( !atCmd[0] ) {
189 | sendResult(R_OK);
190 | }
191 | break;
192 | default:
193 | sendResult(R_ERROR);
194 | break;
195 | }
196 | return atCmd;
197 | }
198 |
199 | //
200 | // AT&W: update NVRAM from current settings
201 | //
202 | char *updateNvram(char *atCmd) {
203 | writeSettings(&settings);
204 | if( !atCmd[0] ) {
205 | sendResult(R_OK);
206 | }
207 | return atCmd;
208 | }
209 |
210 | //
211 | // AT&Zn? show contents of speed dial slot n
212 | // AT&Zn=host,alias set speed dial slot n
213 | //
214 | char *doSpeedDialSlot(char *atCmd) {
215 | int slot;
216 |
217 | if( isdigit(atCmd[0]) ) {
218 | slot = atCmd[0] - '0';
219 | ++atCmd;
220 | switch( atCmd[0] ) {
221 | case '?':
222 | ++atCmd;
223 | if( settings.speedDial[slot][0] ) {
224 | printf("%s,%s\r\n",
225 | settings.speedDial[slot], settings.alias[slot]);
226 | if( !atCmd[0] ) {
227 | sendResult(R_OK);
228 | }
229 | } else {
230 | sendResult(R_ERROR);
231 | }
232 | break;
233 | case '=':
234 | ++atCmd;
235 | if( !atCmd[0] ) {
236 | // erase slot
237 | settings.speedDial[slot][0] = NUL;
238 | settings.alias[slot][0] = NUL;
239 | sendResult(R_OK);
240 | } else {
241 | char *comma = strchr(atCmd, ',');
242 | if( !comma ) {
243 | sendResult(R_ERROR);
244 | } else {
245 | *comma++ = NUL;
246 | strncpy(settings.speedDial[slot], atCmd, MAX_SPEED_DIAL_LEN);
247 | settings.speedDial[slot][MAX_SPEED_DIAL_LEN] = NUL;
248 | strncpy(settings.alias[slot], comma, MAX_ALIAS_LEN);
249 | settings.alias[slot][MAX_ALIAS_LEN] = NUL;
250 | atCmd[0] = NUL;
251 | sendResult(R_OK);
252 | }
253 | }
254 | break;
255 | default:
256 | sendResult(R_ERROR);
257 | break;
258 | }
259 | } else {
260 | sendResult(R_ERROR);
261 | }
262 | return atCmd;
263 | }
264 |
--------------------------------------------------------------------------------
/src/at_proprietary.h:
--------------------------------------------------------------------------------
1 | //
2 | // AT$AE? query auto execute command string
3 | // AT$AE=auto execute command string
4 | //
5 | char *doAutoExecute(char *atCmd) {
6 | switch( atCmd[0] ) {
7 | case '?':
8 | ++atCmd;
9 | printf("%s\r\n", settings.autoExecute);
10 | if( !atCmd[0] ) {
11 | sendResult(R_OK);
12 | }
13 | break;
14 | case '=':
15 | ++atCmd;
16 | strncpy(settings.autoExecute, atCmd, MAX_AUTOEXEC_LEN);
17 | settings.busyMsg[MAX_AUTOEXEC_LEN] = NUL;
18 | atCmd[0] = NUL;
19 | sendResult(R_OK);
20 | break;
21 | default:
22 | sendResult(R_ERROR);
23 | break;
24 | }
25 | return atCmd;
26 | }
27 |
28 | //
29 | // AT$AYT send "Are you there?" if in a Telnet session
30 | //
31 | char *doAreYouThere(char *atCmd) {
32 |
33 | static const uint8_t areYouThere[] = {IAC, AYT};
34 |
35 | if( tcpIsConnected(tcpClient) && settings.telnet != NO_TELNET ) {
36 | state = ONLINE;
37 | dtrWentInactive = false;
38 | bytesOut += tcpWriteBuf(tcpClient, areYouThere, sizeof areYouThere);
39 | } else {
40 | sendResult(R_ERROR);
41 | }
42 | return atCmd;
43 | }
44 |
45 | //
46 | // AT$BM? query busy message
47 | // AT$BM=busy message set busy message
48 | //
49 | char *doBusyMessage(char *atCmd) {
50 | switch( atCmd[0] ) {
51 | case '?':
52 | ++atCmd;
53 | printf("%s\r\n", settings.busyMsg);
54 | if( !atCmd[0] ) {
55 | sendResult(R_OK);
56 | }
57 | break;
58 | case '=':
59 | ++atCmd;
60 | strncpy(settings.busyMsg, atCmd, MAX_BUSYMSG_LEN);
61 | settings.busyMsg[MAX_BUSYMSG_LEN] = NUL;
62 | atCmd[0] = NUL;
63 | sendResult(R_OK);
64 | break;
65 | default:
66 | sendResult(R_ERROR);
67 | break;
68 | }
69 | return atCmd;
70 | }
71 |
72 | //
73 | // AT$MDNS? query mDNS network name
74 | // AT$MDNS=mdnsname set mDNS network name
75 | //
76 | char *doMdnsName(char *atCmd) {
77 | switch( atCmd[0] ) {
78 | case '?':
79 | ++atCmd;
80 | printf("%s\r\n", settings.mdnsName);
81 | if( !atCmd[0] ) {
82 | sendResult(R_OK);
83 | }
84 | break;
85 |
86 | case '=':
87 | ++atCmd;
88 | strncpy(settings.mdnsName , atCmd, MAX_MDNSNAME_LEN);
89 | settings.mdnsName[MAX_MDNSNAME_LEN] = NUL;
90 | atCmd[0] = NUL;
91 | sendResult(R_OK);
92 | break;
93 |
94 | default:
95 | sendResult(R_ERROR);
96 | lastCmd[0] = NUL;
97 | break;
98 | }
99 | return atCmd;
100 | }
101 |
102 | //
103 | // AT$PASS? query WiFi password
104 | // AT$PASS=password set WiFi password
105 | //
106 | char *doWiFiPassword(char *atCmd) {
107 | switch( atCmd[0] ) {
108 | case '?':
109 | ++atCmd;
110 | printf("%s\r\n", settings.wifiPassword);
111 | if( !atCmd[0] ) {
112 | sendResult(R_OK);
113 | }
114 | break;
115 | case '=':
116 | ++atCmd;
117 | strncpy(settings.wifiPassword, atCmd, MAX_WIFI_PWD_LEN);
118 | settings.wifiPassword[MAX_WIFI_PWD_LEN] = NUL;
119 | atCmd[0] = NUL;
120 | sendResult(R_OK);
121 | break;
122 | default:
123 | sendResult(R_ERROR);
124 | break;
125 | }
126 | return atCmd;
127 | }
128 |
129 | //
130 | // AT$SB? query serial speed
131 | // AT$SB=n set serial speed
132 | //
133 | char *doSpeedChange(char *atCmd) {
134 | long newSerialSpeed;
135 |
136 | switch( atCmd[0] ) {
137 | case '?':
138 | ++atCmd;
139 | printf("%u\r\n", settings.serialSpeed);
140 | if( !atCmd[0] ) {
141 | sendResult(R_OK);
142 | }
143 | break;
144 | case '=':
145 | ++atCmd;
146 | newSerialSpeed = atol(atCmd);
147 | while( isdigit(*atCmd) ) {
148 | ++atCmd;
149 | }
150 | if( newSerialSpeed != settings.serialSpeed ) {
151 | switch( newSerialSpeed ) {
152 | case 110L: // 110 thru 76.8K are the
153 | case 300L: // standard 'BYE' rates, if
154 | case 450L: // you're wondering why
155 | case 600L: // unusual rates like 110, 450
156 | case 710L: // and 710 are in this list
157 | case 1200L:
158 | case 2400L:
159 | case 4800L:
160 | case 9600L:
161 | case 19200L:
162 | case 38400L:
163 | case 57600L:
164 | case 76800L:
165 | case 115200L:
166 | sendResult(R_OK);
167 | uart_tx_wait_blocking(uart0); // wait for transmit to finish
168 | uart_set_baudrate(uart0, newSerialSpeed);
169 | settings.serialSpeed = newSerialSpeed;
170 | break;
171 |
172 | default:
173 | sendResult(R_ERROR);
174 | break;
175 | }
176 | } else {
177 | sendResult(R_OK);
178 | }
179 | break;
180 | default:
181 | sendResult(R_ERROR);
182 | break;
183 | }
184 | return atCmd;
185 | }
186 |
187 | //
188 | // AT$SP? query inbound TCP port #
189 | // AT$SP=n set inbound TCP port #
190 | // NOTE: n=0 will disable the inbound TCP port
191 | // and a RING message will never be displayed
192 | //
193 | char *doServerPort(char *atCmd) {
194 | switch( atCmd[0] ) {
195 | case '?':
196 | ++atCmd;
197 | printf("%u\r\n", settings.listenPort);
198 | if( !atCmd[0] ) {
199 | sendResult(R_OK);
200 | }
201 | break;
202 | case '=':
203 | ++atCmd;
204 | settings.listenPort = atoi(atCmd);
205 | while( isdigit(atCmd[0]) ) {
206 | ++atCmd;
207 | }
208 | if( !atCmd[0] ) {
209 | sendResult(R_OK);
210 | }
211 | break;
212 | default:
213 | sendResult(R_ERROR);
214 | break;
215 | }
216 | return atCmd;
217 | }
218 |
219 | //
220 | // AT$SSID? query WiFi SSID
221 | // AT$SSID=ssid set WiFi SSID
222 | //
223 | char *doSSID(char *atCmd) {
224 | switch( atCmd[0] ) {
225 | case '?':
226 | ++atCmd;
227 | printf("%s\r\n", settings.ssid);
228 | if( !atCmd[0] ) {
229 | sendResult(R_OK);
230 | }
231 | break;
232 | case '=':
233 | ++atCmd;
234 | strncpy(settings.ssid, atCmd, MAX_SSID_LEN);
235 | settings.ssid[MAX_SSID_LEN] = NUL;
236 | atCmd[0] = NUL;
237 | sendResult(R_OK);
238 | break;
239 | default:
240 | sendResult(R_ERROR);
241 | break;
242 | }
243 | return atCmd;
244 | }
245 |
246 | //
247 | // AT$SU? query data configuration
248 | // AT$SU=nps set data configuration
249 | // n=7/8 data bits
250 | // p=N/E/O parity
251 | // s=1/2 stop bits
252 | //
253 | char *doDataConfig(char *atCmd) {
254 | bool ok = true;
255 | switch( atCmd[0] ) {
256 | case '?':
257 | ++atCmd;
258 | printf("%u", settings.dataBits);
259 | switch( settings.parity ) {
260 | case UART_PARITY_NONE:
261 | uart_putc(uart0, 'N');
262 | break;
263 | case UART_PARITY_ODD:
264 | uart_putc(uart0, 'O');
265 | break;
266 | case UART_PARITY_EVEN:
267 | uart_putc(uart0, 'E');
268 | break;
269 | default:
270 | uart_putc(uart0, '?');
271 | break;
272 | }
273 | printf("%u\r\n", settings.stopBits);
274 | if( !atCmd[0] ) {
275 | sendResult(R_OK);
276 | }
277 | break;
278 | case '=':
279 | switch( atCmd[1] ) {
280 | case '5':
281 | case '6':
282 | case '7':
283 | case '8':
284 | break;
285 | default:
286 | ok = false;
287 | break;
288 | }
289 | switch( toupper(atCmd[2]) ) {
290 | case 'N':
291 | case 'O':
292 | case 'E':
293 | break;
294 | default:
295 | ok = false;
296 | break;
297 | }
298 | switch( atCmd[3] ) {
299 | case '1':
300 | case '2':
301 | break;
302 | default:
303 | ok = false;
304 | break;
305 | }
306 | if( ok ) {
307 | settings.dataBits = atCmd[1] - '0';
308 | switch( toupper(atCmd[2]) ) {
309 | case 'N':
310 | settings.parity = UART_PARITY_NONE;
311 | break;
312 | case 'O':
313 | settings.parity = UART_PARITY_ODD;
314 | break;
315 | case 'E':
316 | settings.parity = UART_PARITY_EVEN;
317 | break;
318 | }
319 | settings.stopBits = atCmd[3] - '0';
320 | atCmd += 4; // skip over =dps
321 | if( !atCmd[0] ) {
322 | sendResult(R_OK);
323 | }
324 | } else {
325 | sendResult(R_ERROR);
326 | }
327 | break;
328 | default:
329 | sendResult(R_ERROR);
330 | break;
331 | }
332 | return atCmd;
333 | }
334 |
335 | //
336 | // AT$TTL? query Telnet location
337 | // AT$TTL=location set Telnet location
338 | //
339 | char *doLocation(char *atCmd) {
340 | switch( atCmd[0] ) {
341 | case '?':
342 | ++atCmd;
343 | printf("%s\r\n", settings.location);
344 | if( !atCmd[0] ) {
345 | sendResult(R_OK);
346 | }
347 | break;
348 | case '=':
349 | ++atCmd;
350 | strncpy(settings.location, atCmd, MAX_LOCATION_LEN);
351 | settings.location[MAX_LOCATION_LEN] = NUL;
352 | atCmd[0] = NUL;
353 | sendResult(R_OK);
354 | break;
355 | default:
356 | sendResult(R_ERROR);
357 | break;
358 | }
359 | return atCmd;
360 | }
361 |
362 | //
363 | // AT$TTS? query Telnet window size
364 | // AT$TTS=WxH set Telnet window size (width x height)
365 | //
366 | char *doWindowSize(char *atCmd) {
367 | switch( atCmd[0] ) {
368 | case '?':
369 | ++atCmd;
370 | printf("%ux%u\r\n", settings.width, settings.height);
371 | if( !atCmd[0] ) {
372 | sendResult(R_OK);
373 | }
374 | break;
375 | case '=':
376 | {
377 | char *width = atCmd + 1;
378 | char *height = strpbrk(width, "xX");
379 | if( !width || !height ) {
380 | sendResult(R_ERROR);
381 | } else {
382 | ++height; // point to 1st char past X
383 | settings.width = atoi(width);
384 | settings.height = atoi(height);
385 | atCmd = height;
386 | while( isdigit(atCmd[0]) ) {
387 | ++atCmd;
388 | }
389 | if( !atCmd[0] ) {
390 | sendResult(R_OK);
391 | }
392 | }
393 | }
394 | break;
395 | default:
396 | sendResult(R_ERROR);
397 | break;
398 | }
399 | return atCmd;
400 | }
401 |
402 | //
403 | // AT$TTY? query Telnet terminal type
404 | // AT$TTY=terminal set Telnet terminal type
405 | //
406 | char *doTerminalType(char *atCmd) {
407 | switch( atCmd[0] ) {
408 | case '?':
409 | ++atCmd;
410 | printf("%s\r\n", settings.terminal);
411 | if( !atCmd[0] ) {
412 | sendResult(R_OK);
413 | }
414 | break;
415 | case '=':
416 | ++atCmd;
417 | strncpy(settings.terminal, atCmd, MAX_TERMINAL_LEN);
418 | settings.location[MAX_TERMINAL_LEN] = NUL;
419 | atCmd[0] = NUL;
420 | sendResult(R_OK);
421 | break;
422 | default:
423 | sendResult(R_ERROR);
424 | break;
425 | }
426 | return atCmd;
427 | }
428 |
429 | //
430 | // AT$W? query startup wait status
431 | // AT$W=0 disable startup wait
432 | // AT$W=1 enable startup wait (wait for a CR on startup)
433 | //
434 | char *doStartupWait(char *atCmd) {
435 | switch( atCmd[0] ) {
436 | case '?':
437 | ++atCmd;
438 | printf("%u\r\n", settings.startupWait);
439 | if( !atCmd[0] ) {
440 | sendResult(R_OK);
441 | }
442 | break;
443 | case '=':
444 | ++atCmd;
445 | switch( atCmd[0] ) {
446 | case '0':
447 | case '1':
448 | settings.startupWait = atCmd[0] == '1';
449 | atCmd[0] = NUL;
450 | sendResult(R_OK);
451 | break;
452 | default:
453 | sendResult(R_ERROR);
454 | break;
455 | }
456 | break;
457 | default:
458 | sendResult(R_ERROR);
459 | break;
460 | }
461 | return atCmd;
462 | }
463 |
--------------------------------------------------------------------------------
/src/build/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
5 |
--------------------------------------------------------------------------------
/src/eeprom.h:
--------------------------------------------------------------------------------
1 | //
2 | // External EEPROM routines
3 | //
4 | // I2C_xxx constants defined in wifi_modem.h
5 | //
6 | void initEEPROM(void) {
7 | i2c_init(i2c0, I2C_BAUD);
8 | gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
9 | gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
10 | }
11 |
12 | bool readSettings(SETTINGS_T *p) {
13 | const uint8_t addr[2] = {0,0};
14 | int err;
15 | bool ok = false;
16 |
17 | if( i2c_write_blocking(i2c0, I2C_ADDR, addr, 2, true) == 2 ) {
18 | ok = i2c_read_blocking(i2c0, I2C_ADDR, (uint8_t *)p, sizeof(SETTINGS_T), false) == sizeof(SETTINGS_T);
19 | }
20 | return ok;
21 | }
22 |
23 | bool writeSettings(SETTINGS_T *p) {
24 | uint8_t data[3];
25 | struct Settings current;
26 | bool ok = true;
27 |
28 | readSettings(¤t);
29 |
30 | for( int i=0; i> 8;
34 | data[1] = i & 0xFF;
35 | data[2] = ((uint8_t *)p)[i];
36 | ok = i2c_write_blocking(i2c0, I2C_ADDR, data, 3, false) == 3;
37 | sleep_ms(5);
38 | }
39 | }
40 | return ok;
41 | }
42 |
--------------------------------------------------------------------------------
/src/globals.h:
--------------------------------------------------------------------------------
1 | #ifndef _GLOBALS_H
2 | #define _GLOBALS_H
3 |
4 | // globals
5 | const char okStr[] = {"OK"};
6 | const char connectStr[] = {"CONNECT"};
7 | const char ringStr[] = {"RING"};
8 | const char noCarrierStr[] = {"NO CARRIER"};
9 | const char errorStr[] = {"ERROR"};
10 | const char noAnswerStr[] = {"NO ANSWER"};
11 | enum ResultCodes { R_OK, R_CONNECT, R_RING, R_NO_CARRIER, R_ERROR, R_NO_ANSWER, R_RING_IP };
12 | const char * const resultCodes[] = { okStr, connectStr, ringStr, noCarrierStr, errorStr, noAnswerStr, ringStr};
13 | enum DtrStates { DTR_IGNORE, DTR_GOTO_COMMAND, DTR_END_CALL, DTR_RESET};
14 |
15 | typedef struct Settings {
16 | uint16_t magicNumber;
17 | char ssid[MAX_SSID_LEN + 1];
18 | char wifiPassword[MAX_WIFI_PWD_LEN + 1];
19 | uint32_t serialSpeed;
20 | uint8_t dataBits;
21 | uart_parity_t parity;
22 | uint8_t stopBits;
23 | bool rtsCts;
24 | uint8_t width, height;
25 | char escChar;
26 | char alias[SPEED_DIAL_SLOTS][MAX_ALIAS_LEN + 1];
27 | char speedDial[SPEED_DIAL_SLOTS][MAX_SPEED_DIAL_LEN + 1];
28 | char mdnsName[MAX_MDNSNAME_LEN + 1];
29 | uint8_t autoAnswer;
30 | uint16_t listenPort;
31 | char busyMsg[MAX_BUSYMSG_LEN + 1];
32 | char serverPassword[MAX_PWD_LEN + 1];
33 | bool echo;
34 | uint8_t telnet;
35 | char autoExecute[MAX_AUTOEXEC_LEN + 1];
36 | char terminal[MAX_TERMINAL_LEN + 1];
37 | char location[MAX_LOCATION_LEN + 1];
38 | bool startupWait;
39 | bool extendedCodes;
40 | bool verbose;
41 | bool quiet;
42 | DtrStates dtrHandling;
43 | } SETTINGS_T;
44 |
45 | typedef struct TCP_CLIENT_T_ {
46 | struct tcp_pcb *pcb;
47 | ip_addr_t remoteAddr;
48 | volatile bool connected;
49 | volatile bool connectFinished;
50 | volatile bool waitingForAck;
51 | volatile uint8_t rxBuff[TCP_CLIENT_RX_BUF_SIZE];
52 | volatile uint16_t rxBuffLen;
53 | volatile uint16_t rxBuffHead;
54 | volatile uint16_t rxBuffTail;
55 | volatile uint16_t totLen;
56 | volatile uint8_t txBuff[TCP_CLIENT_TX_BUF_SIZE];
57 | volatile uint16_t txBuffLen;
58 | volatile uint16_t txBuffHead;
59 | volatile uint16_t txBuffTail;
60 | } TCP_CLIENT_T;
61 |
62 | typedef struct TCP_SERVER_T_ {
63 | struct tcp_pcb *pcb;
64 | struct tcp_pcb *clientPcb;
65 | } TCP_SERVER_T;
66 |
67 | SETTINGS_T settings;
68 | TCP_CLIENT_T *tcpClient,tcpClient0,tcpDroppedClient;
69 | TCP_SERVER_T tcpServer;
70 | // incantation to switch from line mode to character mode
71 | const uint8_t toCharModeMagic[] = {IAC,WILL,SUP_GA,IAC,WILL,ECHO,IAC,WONT,LINEMODE};
72 | uint32_t bytesIn = 0, bytesOut = 0;
73 | unsigned long connectTime = 0;
74 | char atCmd[MAX_CMD_LEN + 1], lastCmd[MAX_CMD_LEN + 1];
75 | unsigned atCmdLen = 0;
76 | enum {CMD_NOT_IN_CALL, CMD_IN_CALL, ONLINE, PASSWORD} state = CMD_NOT_IN_CALL;
77 | bool ringing = false; // no incoming call
78 | uint8_t ringCount = 0; // current incoming call ring count
79 | uint32_t nextRingMs = 0; // time of mext RING result
80 | uint8_t escCount = 0; // Go to AT mode at "+++" sequence, that has to be counted
81 | uint32_t guardTime = 0; // When did we last receive a "+++" sequence
82 | char password[MAX_PWD_LEN + 1];
83 | uint8_t passwordTries = 0; // # of unsuccessful tries at incoming password
84 | uint8_t passwordLen = 0;
85 | uint8_t txBuf[TX_BUF_SIZE]; // Transmit Buffer
86 | uint8_t sessionTelnetType;
87 | volatile bool dtrWentInactive = false;
88 | bool amClient = false; // true if we've connected TO a remote server
89 | #ifndef NDEBUG
90 | volatile uint16_t maxTotLen = 0;
91 | volatile uint16_t maxRxBuffLen = 0;
92 | uint16_t maxTxBuffLen = 0;
93 | err_t lastTcpWriteErr = ERR_OK;
94 | #endif
95 |
96 | #endif
97 |
--------------------------------------------------------------------------------
/src/lwipopts.h:
--------------------------------------------------------------------------------
1 | #ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
2 | #define _LWIPOPTS_EXAMPLE_COMMONH_H
3 |
4 |
5 | // Common settings used in most of the pico_w examples
6 | // (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)
7 |
8 | // allow override in some examples
9 | #ifndef NO_SYS
10 | #define NO_SYS 1
11 | #endif
12 | // allow override in some examples
13 | #ifndef LWIP_SOCKET
14 | #define LWIP_SOCKET 0
15 | #endif
16 | #if PICO_CYW43_ARCH_POLL
17 | #define MEM_LIBC_MALLOC 1
18 | #else
19 | // MEM_LIBC_MALLOC is incompatible with non polling versions
20 | #define MEM_LIBC_MALLOC 0
21 | #endif
22 | #define MEM_ALIGNMENT 4
23 | #define MEM_SIZE 4000
24 | #define MEMP_NUM_TCP_SEG 32
25 | #define MEMP_NUM_ARP_QUEUE 10
26 | #define PBUF_POOL_SIZE 24
27 | #define LWIP_ARP 1
28 | #define LWIP_ETHERNET 1
29 | #define LWIP_ICMP 1
30 | #define LWIP_RAW 1
31 | #define TCP_WND (8 * TCP_MSS)
32 | #define TCP_MSS 1460
33 | #define TCP_SND_BUF (8 * TCP_MSS)
34 | #define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
35 | #define LWIP_NETIF_STATUS_CALLBACK 1
36 | #define LWIP_NETIF_LINK_CALLBACK 1
37 | #define LWIP_NETIF_HOSTNAME 1
38 | #define LWIP_NETCONN 0
39 | #define MEM_STATS 0
40 | #define SYS_STATS 0
41 | #define MEMP_STATS 0
42 | #define LINK_STATS 0
43 | // #define ETH_PAD_SIZE 2
44 | #define LWIP_CHKSUM_ALGORITHM 3
45 | #define LWIP_DHCP 1
46 | #define LWIP_IPV4 1
47 | #define LWIP_TCP 1
48 | #define LWIP_UDP 1
49 | #define LWIP_DNS 1
50 | #define LWIP_TCP_KEEPALIVE 1
51 | #define LWIP_NETIF_TX_SINGLE_PBUF 1
52 | #define DHCP_DOES_ARP_CHECK 0
53 | #define LWIP_DHCP_DOES_ACD_CHECK 0
54 |
55 | #ifndef NDEBUG
56 | #define LWIP_DEBUG 1
57 | #define LWIP_STATS 1
58 | #define LWIP_STATS_DISPLAY 1
59 | #endif
60 |
61 | #define ETHARP_DEBUG LWIP_DBG_OFF
62 | #define NETIF_DEBUG LWIP_DBG_OFF
63 | #define PBUF_DEBUG LWIP_DBG_OFF
64 | #define API_LIB_DEBUG LWIP_DBG_OFF
65 | #define API_MSG_DEBUG LWIP_DBG_OFF
66 | #define SOCKETS_DEBUG LWIP_DBG_OFF
67 | #define ICMP_DEBUG LWIP_DBG_OFF
68 | #define INET_DEBUG LWIP_DBG_OFF
69 | #define IP_DEBUG LWIP_DBG_OFF
70 | #define IP_REASS_DEBUG LWIP_DBG_OFF
71 | #define RAW_DEBUG LWIP_DBG_OFF
72 | #define MEM_DEBUG LWIP_DBG_OFF
73 | #define MEMP_DEBUG LWIP_DBG_OFF
74 | #define SYS_DEBUG LWIP_DBG_OFF
75 | #define TCP_DEBUG LWIP_DBG_OFF
76 | #define TCP_INPUT_DEBUG LWIP_DBG_OFF
77 | #define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
78 | #define TCP_RTO_DEBUG LWIP_DBG_OFF
79 | #define TCP_CWND_DEBUG LWIP_DBG_OFF
80 | #define TCP_WND_DEBUG LWIP_DBG_OFF
81 | #define TCP_FR_DEBUG LWIP_DBG_OFF
82 | #define TCP_QLEN_DEBUG LWIP_DBG_OFF
83 | #define TCP_RST_DEBUG LWIP_DBG_OFF
84 | #define UDP_DEBUG LWIP_DBG_OFF
85 | #define TCPIP_DEBUG LWIP_DBG_OFF
86 | #define PPP_DEBUG LWIP_DBG_OFF
87 | #define SLIP_DEBUG LWIP_DBG_OFF
88 | #define DHCP_DEBUG LWIP_DBG_OFF
89 |
90 | #endif /* __LWIPOPTS_H__ */
91 |
--------------------------------------------------------------------------------
/src/tcp_support.h:
--------------------------------------------------------------------------------
1 | //
2 | // lwIP interface functions
3 | //
4 | static volatile bool dnsLookupFinished = false;
5 |
6 | static void dnsLookupDone(const char *name, const ip_addr_t *ipaddr, void *arg) {
7 | ip_addr_t *resolved = (ip_addr_t *)arg;
8 | if( ipaddr && ipaddr->addr) {
9 | resolved->addr = ipaddr->addr;
10 | }
11 | dnsLookupFinished = true;
12 | }
13 |
14 | bool dnsLookup(const char *name, ip_addr_t *resolved) {
15 |
16 | dnsLookupFinished = false;
17 | ip4_addr_set_any(resolved);
18 |
19 | switch( dns_gethostbyname(name, resolved, dnsLookupDone, resolved) ) {
20 | case ERR_OK:
21 | return true;
22 | break;
23 | case ERR_INPROGRESS:
24 | break;
25 | default:
26 | return false;
27 | }
28 | while( !dnsLookupFinished ) {
29 | tight_loop_contents();
30 | }
31 | return !ip4_addr_isany(resolved);
32 | }
33 |
34 | uint32_t millis(void) {
35 | return to_ms_since_boot(get_absolute_time());
36 | }
37 |
38 | bool tcpIsConnected(TCP_CLIENT_T *client) {
39 | if( client && client->pcb && client->pcb->callback_arg ) {
40 | return client->connected;
41 | }
42 | return false;
43 | }
44 |
45 | err_t tcpClientClose(TCP_CLIENT_T *client) {
46 | err_t err = ERR_OK;
47 |
48 | cyw43_arch_lwip_begin();
49 | if( client ) {
50 | client->connected = false;
51 | if( client->pcb ) {
52 | tcp_err( client->pcb, NULL);
53 | tcp_sent(client->pcb, NULL);
54 | tcp_poll(client->pcb, NULL, 0);
55 | tcp_recv(client->pcb, NULL);
56 | tcp_arg( client->pcb, NULL);
57 | err = tcp_close(client->pcb);
58 | if( err != ERR_OK ) {
59 | tcp_abort(client->pcb);
60 | err = ERR_ABRT;
61 | }
62 | client->pcb = NULL;
63 | }
64 | }
65 | cyw43_arch_lwip_end();
66 | return err;
67 | }
68 |
69 | // NB: the PCB may have already been freed when this function is called
70 | static void tcpClientErr(void *arg, err_t err) {
71 | TCP_CLIENT_T *client = (TCP_CLIENT_T *)arg;
72 |
73 | if( client ) {
74 | client->connectFinished = true;
75 | client->connected = false;
76 | client->pcb = NULL;
77 | }
78 | }
79 |
80 | static err_t tcpSend(TCP_CLIENT_T *client) {
81 | err_t err = ERR_OK;
82 | uint32_t ints;
83 |
84 | if( client->txBuffLen ) {
85 | uint16_t maxLen = tcp_sndbuf(client->pcb);
86 | if( maxLen > 0 && tcp_sndqueuelen(client->pcb) < TCP_SND_QUEUELEN ) {
87 | if( client->txBuffLen < maxLen ) {
88 | maxLen = client->txBuffLen;
89 | }
90 | uint8_t tmp[maxLen];
91 | // make copies of the head and length and work
92 | // with those in case tcp_write fails and we
93 | // have to re-send the same data later
94 | uint16_t tmpTxBuffHead = client->txBuffHead;
95 | uint16_t tmpTxBuffLen = client->txBuffLen;
96 | for( int i = 0; i < maxLen; ++i ) {
97 | tmp[i] = client->txBuff[tmpTxBuffHead++];
98 | if( tmpTxBuffHead == TCP_CLIENT_TX_BUF_SIZE ) {
99 | tmpTxBuffHead = 0;
100 | }
101 | --tmpTxBuffLen;
102 | }
103 | err = tcp_write(client->pcb, tmp, maxLen, TCP_WRITE_FLAG_COPY);
104 | client->waitingForAck = err == ERR_OK;
105 | tcp_output(client->pcb);
106 | if( err == ERR_OK ) {
107 | client->txBuffHead = tmpTxBuffHead;
108 | ints = save_and_disable_interrupts();
109 | client->txBuffLen = tmpTxBuffLen;
110 | restore_interrupts(ints);
111 | #ifndef NDEBUG
112 | } else {
113 | lastTcpWriteErr = err;
114 | #endif
115 | }
116 | }
117 | }
118 | return err;
119 | }
120 |
121 | static err_t tcpSent(void *arg, struct tcp_pcb *tpcb, u16_t len) {
122 | TCP_CLIENT_T *client = (TCP_CLIENT_T *)arg;
123 | err_t err = ERR_OK;
124 |
125 | if( client->txBuffLen ) {
126 | err = tcpSend(client);
127 | } else {
128 | client->waitingForAck = false;
129 | }
130 | return err;
131 | }
132 |
133 | // in the event that the tcp_write call in tcpSend failed earlier,
134 | // and there weren't any other packets waiting to be ACKed, try
135 | // sending any data in the txBuff again.
136 | static err_t tcpPoll(void *arg, struct tcp_pcb *tpcb) {
137 | TCP_CLIENT_T *client = (TCP_CLIENT_T *)arg;
138 | err_t err = ERR_OK;
139 | #ifndef NDEBUG
140 | static bool pollState = false;
141 |
142 | gpio_put(POLL_STATE_LED, pollState);
143 | pollState = !pollState;
144 | #endif
145 | if( !client->waitingForAck && client->txBuffLen ) {
146 | err = tcpSend(client);
147 | }
148 | return err;
149 | }
150 |
151 | static err_t tcpRecv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
152 | TCP_CLIENT_T *client = (TCP_CLIENT_T *)arg;
153 |
154 | if( !p ) {
155 | return tcpClientClose(client);
156 | }
157 | if( p->tot_len > 0 && client ) {
158 | for( struct pbuf *q = p; q; q = q->next ) {
159 | for( int i = 0; i < q->len; ++i ) {
160 | client->rxBuff[client->rxBuffTail++] = ((uint8_t *)q->payload)[i];
161 | if( client->rxBuffTail == TCP_CLIENT_RX_BUF_SIZE ) {
162 | client->rxBuffTail = 0;
163 | }
164 | ++client->rxBuffLen;
165 | }
166 | }
167 | #ifndef NDEBUG
168 | if( client->rxBuffLen > TCP_CLIENT_RX_BUF_SIZE ) {
169 | gpio_put(RXBUFF_OVFL, HIGH);
170 | }
171 | if( client->rxBuffLen > maxRxBuffLen ) {
172 | maxRxBuffLen = client->rxBuffLen;
173 | }
174 | #endif
175 | if( client->rxBuffLen <= TCP_MSS ) {
176 | tcp_recved(client->pcb, p->tot_len);
177 | } else {
178 | client->totLen += p->tot_len;
179 | #ifndef NDEBUG
180 | if( client->totLen > maxTotLen ) {
181 | maxTotLen = client->totLen;
182 | }
183 | #endif
184 | }
185 | }
186 | pbuf_free(p);
187 | return ERR_OK;
188 | }
189 |
190 | static err_t tcpHasConnected(void *arg, struct tcp_pcb *tpcb, err_t err) {
191 | TCP_CLIENT_T *client = (TCP_CLIENT_T*)arg;
192 |
193 | client->connectFinished = true;
194 | client->connected = err == ERR_OK;
195 | if( err != ERR_OK ) {
196 | tcpClientClose(client);
197 | }
198 | return ERR_OK;
199 | }
200 |
201 | TCP_CLIENT_T *tcpConnect(TCP_CLIENT_T *client, const char *host, int portNum) {
202 | if( !dnsLookup(host, &client->remoteAddr) ) {
203 | return NULL;
204 | } else {
205 | client->pcb = tcp_new_ip_type(IP_GET_TYPE(client->remoteAddr));
206 | if( !client->pcb ) {
207 | return NULL;
208 | }
209 | }
210 | tcp_arg( client->pcb, client);
211 | tcp_recv(client->pcb, tcpRecv);
212 | tcp_sent(client->pcb, tcpSent);
213 | tcp_poll(client->pcb, tcpPoll, 2);
214 | tcp_err( client->pcb, tcpClientErr);
215 | tcp_nagle_disable(client->pcb); // disable Nalge algorithm by default
216 |
217 | client->rxBuffLen = 0;
218 | client->rxBuffHead = 0;
219 | client->rxBuffTail = 0;
220 | client->totLen = 0;
221 |
222 | client->txBuffLen = 0;
223 | client->txBuffHead = 0;
224 | client->txBuffTail = 0;
225 |
226 | client->connected = false;
227 | client->connectFinished = false;
228 | client->waitingForAck = false;
229 |
230 | cyw43_arch_lwip_begin();
231 | err_t err = tcp_connect(client->pcb, &client->remoteAddr, portNum, tcpHasConnected);
232 | cyw43_arch_lwip_end();
233 |
234 | if( err != ERR_OK ) {
235 | client->pcb = NULL;
236 | return NULL;
237 | }
238 |
239 | while( client->pcb && client->pcb->callback_arg && !client->connectFinished && !uart_is_readable(uart0)) {
240 | tight_loop_contents();
241 | }
242 | if( !client->connected ) {
243 | client->pcb = NULL;
244 | return NULL;
245 | }
246 | return client;
247 | }
248 |
249 | // NB: the PCB may have already been freed when this function is called
250 | static void tcpServerErr(void *arg, err_t err) {
251 | TCP_SERVER_T *server = (TCP_SERVER_T *)arg;
252 |
253 | if( server ) {
254 | server->pcb = NULL;
255 | server->clientPcb = NULL;
256 | }
257 | }
258 |
259 | static err_t tcpServerAccept(void *arg, struct tcp_pcb *clientPcb, err_t err) {
260 | TCP_SERVER_T *server = (TCP_SERVER_T*)arg;
261 |
262 | if( err != ERR_OK || !clientPcb ) {
263 | //### printf("Failure in accept: %d\n",err); //###
264 | server->clientPcb = NULL;
265 | tcp_close(server->pcb);
266 | return ERR_VAL;
267 | }
268 | //### if( server->clientPcb ) {
269 | //### printf("Overwriting server->clientPcb\n"); //###
270 | //### }
271 | server->clientPcb = clientPcb;
272 | return ERR_OK;
273 | }
274 |
275 | bool tcpServerStart(TCP_SERVER_T *server, int portNum) {
276 | server->pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
277 | if( !server->pcb ) {
278 | return false;
279 | }
280 |
281 | if( tcp_bind(server->pcb, NULL, portNum) != ERR_OK ) {
282 | return false;
283 | }
284 |
285 | server->clientPcb = NULL;
286 |
287 | struct tcp_pcb *pcb = tcp_listen_with_backlog(server->pcb, 1);
288 | if( !pcb ) {
289 | if( server->pcb ) {
290 | tcp_close(server->pcb);
291 | server->pcb = NULL;
292 | }
293 | return false;
294 | }
295 | server->pcb = pcb;
296 |
297 | tcp_arg( server->pcb, server);
298 | tcp_accept(server->pcb, tcpServerAccept);
299 | tcp_err( server->pcb, tcpServerErr);
300 |
301 | return true;
302 | }
303 |
304 | uint16_t tcpWriteBuf(TCP_CLIENT_T *client, const uint8_t *buf, uint16_t len) {
305 | uint32_t ints;
306 |
307 | if( client && client->pcb && client->pcb->callback_arg ) {
308 |
309 | if( client->txBuffLen + len > TCP_CLIENT_TX_BUF_SIZE && client->connected ) {
310 | #ifndef NDEBUG
311 | gpio_put(TXBUFF_OVFL, HIGH);
312 | #endif
313 | while( client->txBuffLen + len > TCP_CLIENT_TX_BUF_SIZE && client->connected ) {
314 | tight_loop_contents();
315 | }
316 | #ifndef NDEBUG
317 | gpio_put(TXBUFF_OVFL, LOW);
318 | #endif
319 | }
320 | // lock out the lwIP thread now so that it can't end up calling
321 | // tcpSend until we're done with it... really don't want two
322 | // threads messing with txBuff at the same time.
323 | cyw43_arch_lwip_begin();
324 | for( uint16_t i = 0; i < len; ++i ) {
325 | client->txBuff[client->txBuffTail++] = buf[i];
326 | if( client->txBuffTail == TCP_CLIENT_TX_BUF_SIZE ) {
327 | client->txBuffTail = 0;
328 | }
329 | ints = save_and_disable_interrupts();
330 | ++client->txBuffLen;
331 | restore_interrupts(ints);
332 | }
333 | #ifndef NDEBUG
334 | if( client->txBuffLen > maxTxBuffLen ) {
335 | maxTxBuffLen = client->txBuffLen;
336 | }
337 | #endif
338 | if( client->txBuffLen && client->pcb && client->pcb->callback_arg && !client->waitingForAck ) {
339 | tcpSend(client);
340 | }
341 | cyw43_arch_lwip_end();
342 | return len;
343 | }
344 | return 0;
345 | }
346 |
347 | uint16_t tcpWriteStr(TCP_CLIENT_T *client, const char *str) {
348 | return tcpWriteBuf(client, (uint8_t *)str, strlen(str));
349 | }
350 |
351 | uint16_t tcpWriteByte(TCP_CLIENT_T *client, uint8_t c) {
352 | return tcpWriteBuf(client, (uint8_t *)&c, 1);
353 | }
354 |
355 | uint16_t tcpBytesAvailable(TCP_CLIENT_T *client) {
356 | if( client ) {
357 | return client->rxBuffLen;
358 | }
359 | return 0;
360 | }
361 |
362 | int tcpReadByte(TCP_CLIENT_T *client, int rqstTimeout = -1) {
363 | int c;
364 | uint32_t timeout = 0;
365 | uint32_t ints;
366 |
367 | if( client ) {
368 | if( rqstTimeout > 0 ) {
369 | timeout = millis() + rqstTimeout;
370 | }
371 | do {
372 | if( client->rxBuffLen ) {
373 | c = client->rxBuff[client->rxBuffHead++];
374 | if( client->rxBuffHead == TCP_CLIENT_RX_BUF_SIZE ) {
375 | client->rxBuffHead = 0;
376 | }
377 | ints = save_and_disable_interrupts();
378 | --client->rxBuffLen;
379 | restore_interrupts(ints);
380 | if( !client->rxBuffLen && client->totLen && client->pcb) {
381 | cyw43_arch_lwip_begin();
382 | tcp_recved(client->pcb, client->totLen);
383 | client->totLen = 0;
384 | cyw43_arch_lwip_end();
385 | }
386 | return c;
387 | } else {
388 | tight_loop_contents();
389 | }
390 | } while( timeout > millis() );
391 | }
392 | return -1;
393 | }
394 |
395 | uint16_t tcpReadBytesUntil(TCP_CLIENT_T *client, uint8_t terminator, char *buf, uint16_t max_len) {
396 | char *p = buf;
397 | uint16_t c;
398 |
399 | uint32_t timeout = millis() + 1000;
400 | if( max_len > 0 ) {
401 | do {
402 | if( client->rxBuffLen ) {
403 | c = tcpReadByte(client);
404 | if( c != terminator ) {
405 | *p++ = (char)c;
406 | --max_len;
407 | timeout = millis() + 1000;
408 | } else {
409 | break;
410 | }
411 | } else {
412 | tight_loop_contents();
413 | }
414 | } while( max_len > 0 && timeout > millis() );
415 | return p - buf;
416 | }
417 | return 0;
418 | }
419 |
420 | void tcpTxFlush(TCP_CLIENT_T *client) {
421 | if( client ) {
422 | while( client->pcb && client->connected && client->txBuffLen ) {
423 | tight_loop_contents();
424 | }
425 | }
426 | }
427 |
428 | bool serverHasClient(TCP_SERVER_T *server) {
429 | return server->clientPcb != NULL;
430 | }
431 |
432 | TCP_CLIENT_T *serverGetClient(TCP_SERVER_T *server, TCP_CLIENT_T *client) {
433 | client->pcb = server->clientPcb;
434 | server->clientPcb = NULL;
435 |
436 | client->rxBuffLen = 0;
437 | client->rxBuffHead = 0;
438 | client->rxBuffTail = 0;
439 | client->totLen = 0;
440 |
441 | client->txBuffLen = 0;
442 | client->txBuffHead = 0;
443 | client->txBuffTail = 0;
444 |
445 | client->waitingForAck = false;
446 |
447 | tcp_arg( client->pcb, client);
448 | tcp_err( client->pcb, tcpClientErr);
449 | tcp_sent(client->pcb, tcpSent);
450 | tcp_poll(client->pcb, tcpPoll, 2);
451 | tcp_recv(client->pcb, tcpRecv);
452 | tcp_nagle_disable(client->pcb); // disable Nalge algorithm by default
453 |
454 | client->connected = true;
455 | client->connectFinished = true;
456 |
457 | return client;
458 | }
459 |
--------------------------------------------------------------------------------
/src/wifi_modem.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Pico WiFi modem: a Pico W based RS232<->WiFi modem
3 | // with Hayes style AT commands and blinking LEDs.
4 | //
5 | // A "let's learn about the Pico W and lwIP" project. It
6 | // betrays its ESP8266 + Arduino IDE roots in its
7 | // structure; certainly no one would start a Pico
8 | // project from scratch and write it this way!
9 | //
10 | // Originally based on
11 | // Original Source Copyright (C) 2016 Jussi Salin
12 | // Additions (C) 2018 Daniel Jameson, Stardot Contributors
13 | // Additions (C) 2018 Paul Rickards
14 | // Additions 2020-2022 Wayne Hortensius
15 | //
16 | // This program is free software: you can redistribute it and/or modify
17 | // it under the tertms of the GNU General Public License as published by
18 | // the Free Software Foundation, either version 3 of the License, or
19 | // (at your option) any later version.
20 | //
21 | // This program is distributed in the hope that it will be useful,
22 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | // GNU General Public License for more details.
25 | //
26 | // You should have received a copy of the GNU General Public License
27 | // along with this program. If not, see .
28 | //
29 | #include
30 | #include
31 | #include
32 |
33 | #include "pico/stdlib.h"
34 | #include "pico/cyw43_arch.h"
35 | #include "hardware/watchdog.h"
36 | #include "hardware/i2c.h"
37 | #include "hardware/sync.h"
38 |
39 | #include "lwip/pbuf.h"
40 | #include "lwip/tcp.h"
41 | #include "lwip/dns.h"
42 |
43 |
44 | #include "wifi_modem.h"
45 | #include "globals.h"
46 | #include "eeprom.h"
47 | #include "tcp_support.h"
48 | #include "support.h"
49 | #include "at_basic.h"
50 | #include "at_extended.h"
51 | #include "at_proprietary.h"
52 |
53 | // =============================================================
54 | void setup(void) {
55 | bool ok = true;
56 |
57 | stdio_init_all();
58 |
59 | gpio_init(DTR);
60 | gpio_set_dir(DTR, INPUT);
61 |
62 | gpio_init(RI);
63 | gpio_set_dir(RI, OUTPUT);
64 | gpio_put(RI, !ACTIVE); // not ringing
65 |
66 | gpio_init(DCD);
67 | gpio_set_dir(DCD, OUTPUT);
68 | gpio_put(DCD, !ACTIVE); // not connected
69 |
70 | gpio_init(DSR);
71 | gpio_set_dir(DSR, OUTPUT);
72 | gpio_put(DSR, !ACTIVE); // modem is not ready
73 | #ifndef NDEBUG
74 | gpio_init(POLL_STATE_LED);
75 | gpio_set_dir(POLL_STATE_LED, OUTPUT);
76 | gpio_put(POLL_STATE_LED, LOW);
77 |
78 | gpio_init(RXBUFF_OVFL);
79 | gpio_set_dir(RXBUFF_OVFL, OUTPUT);
80 | gpio_put(RXBUFF_OVFL, LOW);
81 |
82 | gpio_init(TXBUFF_OVFL);
83 | gpio_set_dir(TXBUFF_OVFL, OUTPUT);
84 | gpio_put(TXBUFF_OVFL, LOW);
85 | #endif
86 | initEEPROM();
87 | readSettings(&settings);
88 |
89 | if( settings.magicNumber != MAGIC_NUMBER ) {
90 | // no valid data in EEPROM/NVRAM, populate with defaults
91 | factoryDefaults(NULL);
92 | }
93 | sessionTelnetType = settings.telnet;
94 |
95 | uart_set_baudrate(uart0, settings.serialSpeed);
96 | uart_set_format(uart0, settings.dataBits, settings.stopBits, settings.parity);
97 | uart_set_translate_crlf(uart0, false);
98 | setHardwareFlow(settings.rtsCts);
99 |
100 | // enable interrupt when DTR goes inactive if we're not ignoring it
101 | gpio_set_irq_enabled_with_callback(DTR, GPIO_IRQ_EDGE_RISE, settings.dtrHandling != DTR_IGNORE, dtrIrq );
102 |
103 | if( settings.startupWait ) {
104 | while( true ) { // wait for a CR
105 | if( uart_is_readable(uart0) ) {
106 | if( uart_getc(uart0) == CR ) {
107 | break;
108 | }
109 | }
110 | }
111 | }
112 |
113 | cyw43_arch_init();
114 | cyw43_arch_enable_sta_mode();
115 | // disable Wifi power management
116 | // if this is not done, after 5-10 minutes the Pico W does not
117 | // respond to incoming packets and can only be awoken by the
118 | // arrival of serial data
119 | cyw43_wifi_pm(&cyw43_state, CYW43_DEFAULT_PM & ~0xf);
120 | if( settings.ssid[0] ) {
121 | for( int i = 0; i < 4; ++i ) {
122 | cyw43_arch_wifi_connect_timeout_ms(settings.ssid, settings.wifiPassword, CYW43_AUTH_WPA2_AES_PSK, 10000);
123 | if( cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) == CYW43_LINK_UP ) {
124 | break;
125 | }
126 | }
127 | }
128 |
129 | if( settings.listenPort ) {
130 | tcpServerStart(&tcpServer, settings.listenPort);
131 | }
132 |
133 | #if OTA_UPDATE_ENABLED
134 | if( settings.ssid[0] && cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) == CYW43_LINK_UP ) {
135 | setupOTAupdates();
136 | }
137 | #endif
138 |
139 | if( cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) == CYW43_LINK_UP || !settings.ssid[0] ) {
140 | if( cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) == CYW43_LINK_UP ) {
141 | gpio_put(DSR, ACTIVE); // modem is finally ready or SSID not configured
142 | dns_init();
143 | }
144 | if( settings.autoExecute[0] ) {
145 | strncpy(atCmd, settings.autoExecute, MAX_CMD_LEN);
146 | atCmd[MAX_CMD_LEN] = NUL;
147 | if( settings.echo ) {
148 | printf("%s\r\n", atCmd);
149 | }
150 | doAtCmds(atCmd); // auto execute command
151 | } else {
152 | sendResult(R_OK);
153 | }
154 | } else {
155 | sendResult(R_ERROR); // SSID configured, but not connected
156 | }
157 | }
158 |
159 | // =============================================================
160 | void loop(void) {
161 |
162 | checkForIncomingCall();
163 |
164 | if( settings.dtrHandling == DTR_RESET && checkDtrIrq() ) {
165 | resetToNvram(NULL);
166 | }
167 |
168 | switch( state ) {
169 |
170 | case CMD_NOT_IN_CALL:
171 | #if OTA_UPDATE_ENABLED
172 | if( cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA) == CYW43_LINK_UP ) {
173 | ArduinoOTA.handle();
174 | }
175 | #endif
176 | inAtCommandMode();
177 | break;
178 |
179 | case CMD_IN_CALL:
180 | inAtCommandMode();
181 | if( state == CMD_IN_CALL && !tcpIsConnected(tcpClient) ) {
182 | endCall(); // hang up if not in a call
183 | }
184 | break;
185 |
186 | case PASSWORD:
187 | inPasswordMode();
188 | break;
189 |
190 | case ONLINE:
191 | if( uart_is_readable(uart0) ) { // data from RS-232 to Wifi
192 | sendSerialData();
193 | }
194 |
195 | while( tcpBytesAvailable(tcpClient) && !uart_is_readable(uart0) ) {
196 | // data from WiFi to RS-232
197 | int c = receiveTcpData();
198 | if( c != -1 ) {
199 | uart_putc_raw(uart0, (char)c);
200 | }
201 | }
202 |
203 | if( escCount == ESC_COUNT && millis() > guardTime ) {
204 | state = CMD_IN_CALL; // +++ detected, back to command mode
205 | sendResult(R_OK);
206 | escCount = 0;
207 | }
208 |
209 | if( settings.dtrHandling != DTR_IGNORE && checkDtrIrq() ) {
210 | switch( settings.dtrHandling ) {
211 |
212 | case DTR_GOTO_COMMAND:
213 | state = CMD_IN_CALL;
214 | sendResult(R_OK);
215 | escCount = 0;
216 | break;
217 |
218 | case DTR_END_CALL:
219 | endCall();
220 | break;
221 |
222 | case DTR_RESET:
223 | resetToNvram(NULL);
224 | break;
225 | }
226 | }
227 |
228 | if( !tcpIsConnected(tcpClient) ) { // no client?
229 | endCall(); // then hang up
230 | }
231 | break;
232 | }
233 | }
234 |
235 | // =============================================================
236 | void doAtCmds(char *atCmd) {
237 | size_t len;
238 |
239 | trim(atCmd); // get rid of leading and trailing spaces
240 | if( atCmd[0] ) {
241 | // is it an AT command?
242 | if( strncasecmp(atCmd, "AT", 2) ) {
243 | sendResult(R_ERROR); // nope, time to die
244 | } else {
245 | // save command for possible future A/
246 | strncpy(lastCmd, atCmd, MAX_CMD_LEN);
247 | lastCmd[MAX_CMD_LEN] = NUL;
248 | atCmd += 2; // skip over AT prefix
249 | len = strlen(atCmd);
250 |
251 | if( !atCmd[0] ) {
252 | // plain old AT
253 | sendResult(R_OK);
254 | } else {
255 | trim(atCmd);
256 | while( atCmd[0] ) {
257 | if( !strncasecmp(atCmd, "?", 1) ) { // help message
258 | // help
259 | atCmd = showHelp(atCmd + 1);
260 | } else if( !strncasecmp(atCmd, "$AYT", 4) ) {
261 | // send Telnet "Are You There?"
262 | atCmd = doAreYouThere(atCmd + 4);
263 | } else if( !strncasecmp(atCmd, "$SB", 3) ) {
264 | // query/set serial speed
265 | atCmd = doSpeedChange(atCmd + 3);
266 | } else if( !strncasecmp(atCmd, "$SU", 3) ) {
267 | // query/set serial data configuration
268 | atCmd = doDataConfig(atCmd + 3);
269 | } else if( !strncasecmp(atCmd, "$SSID", 5) ) {
270 | // query/set WiFi SSID
271 | atCmd = doSSID(atCmd + 5);
272 | } else if( !strncasecmp(atCmd, "$PASS", 5) ) {
273 | // query/set WiFi password
274 | atCmd = doWiFiPassword(atCmd + 5);
275 | } else if( !strncasecmp(atCmd, "C", 1) ) {
276 | // connect/disconnect to WiFi
277 | atCmd = wifiConnection(atCmd + 1);
278 | } else if( !strncasecmp(atCmd, "D", 1) && len > 2 && strchr("TPI", toupper(atCmd[1])) ) {
279 | // dial a number
280 | atCmd = dialNumber(atCmd + 2);
281 | } else if( !strncasecmp(atCmd, "DS", 2) && len == 3 ) {
282 | // speed dial a number
283 | atCmd = speedDialNumber(atCmd + 2);
284 | } else if( !strncasecmp(atCmd, "H0", 2) ) {
285 | // hang up call
286 | atCmd = hangup(atCmd + 2);
287 | } else if( !strncasecmp(atCmd, "H", 1) && !isdigit(atCmd[1]) ) {
288 | // hang up call
289 | atCmd = hangup(atCmd + 1);
290 | } else if( !strncasecmp(atCmd, "&Z", 2) && isdigit(atCmd[2]) ) {
291 | // speed dial query or set
292 | atCmd = doSpeedDialSlot(atCmd + 2);
293 | } else if( !strncasecmp(atCmd, "O", 1) ) {
294 | // go online
295 | atCmd = goOnline(atCmd + 1);
296 | } else if( !strncasecmp(atCmd, "GET", 3) ) {
297 | // get a web page (http only, no https)
298 | atCmd = httpGet(atCmd + 3);
299 | } else if( settings.listenPort && !strncasecmp(atCmd, "A", 1) && serverHasClient(&tcpServer) ) {
300 | // manually answer incoming connection
301 | atCmd = answerCall(atCmd + 1);
302 | } else if( !strncasecmp(atCmd, "S0", 2) ) {
303 | // query/set auto answer
304 | atCmd = doAutoAnswerConfig(atCmd + 2);
305 | } else if( !strncasecmp(atCmd, "S2", 2) ) {
306 | // query/set escape character
307 | atCmd = doEscapeCharConfig(atCmd + 2);
308 | } else if( !strncasecmp(atCmd, "$SP", 3) ) {
309 | // query set inbound TCP port
310 | atCmd = doServerPort(atCmd + 3);
311 | } else if( !strncasecmp(atCmd, "$BM", 3) ) {
312 | // query/set busy message
313 | atCmd = doBusyMessage(atCmd + 3);
314 | } else if( !strncasecmp(atCmd, "&R", 2) ) {
315 | // query/set require password
316 | atCmd = doServerPassword(atCmd + 2);
317 | } else if( !strncasecmp(atCmd, "I", 1) ) {
318 | // show network information
319 | atCmd = showNetworkInfo(atCmd + 1);
320 | } else if( !strncasecmp(atCmd, "Z", 1) ) {
321 | // reset to NVRAM
322 | atCmd = resetToNvram(atCmd + 1);
323 | } else if( !strncasecmp(atCmd, "&V", 2) ) {
324 | // display current and stored settings
325 | atCmd = displayAllSettings(atCmd + 2);
326 | } else if( !strncasecmp(atCmd, "&W", 2) ) {
327 | // write settings to EEPROM
328 | atCmd = updateNvram(atCmd + 2);
329 | } else if( !strncasecmp(atCmd, "&D", 2) ) {
330 | // DTR transition handling
331 | atCmd = doDtrHandling(atCmd + 2);
332 | } else if( !strncasecmp(atCmd, "&F", 2) ) {
333 | // factory defaults
334 | atCmd = factoryDefaults(atCmd);
335 | } else if( !strncasecmp(atCmd, "E", 1) ) {
336 | // query/set command mode echo
337 | atCmd = doEcho(atCmd + 1);
338 | } else if( !strncasecmp(atCmd, "Q", 1) ) {
339 | // query/set quiet mode
340 | atCmd = doQuiet(atCmd + 1);
341 | } else if( !strncasecmp(atCmd, "RD", 2)
342 | || !strncasecmp(atCmd, "RT", 2) ) {
343 | // read time and date
344 | atCmd = doDateTime(atCmd + 2);
345 | } else if( !strncasecmp(atCmd, "V", 1) ) {
346 | // query/set verbose mode
347 | atCmd = doVerbose(atCmd + 1);
348 | } else if( !strncasecmp(atCmd, "X", 1) ) {
349 | // query/set extended result codes
350 | atCmd = doExtended(atCmd + 1);
351 | } else if( !strncasecmp(atCmd, "$W", 2) ) {
352 | // query/set startup wait
353 | atCmd = doStartupWait(atCmd + 2);
354 | } else if( !strncasecmp(atCmd, "NET", 3) ) {
355 | // query/set telnet mode
356 | atCmd = doTelnetMode(atCmd + 3);
357 | } else if( !strncasecmp(atCmd, "$AE", 3) ) {
358 | // do auto execute commands
359 | atCmd = doAutoExecute(atCmd + 3);
360 | } else if( !strncasecmp(atCmd, "$TTY", 4) ) {
361 | // do telnet terminal type
362 | atCmd = doTerminalType(atCmd + 4);
363 | } else if( !strncasecmp(atCmd, "$TTL", 4) ) {
364 | // do telnet location
365 | atCmd = doLocation(atCmd + 4);
366 | } else if( !strncasecmp(atCmd, "$TTS", 4) ) {
367 | // do telnet location
368 | atCmd = doWindowSize(atCmd + 4);
369 | } else if( !strncasecmp(atCmd, "&K", 2) ) {
370 | // do RTS/CTS flow control
371 | atCmd = doFlowControl(atCmd + 2);
372 | } else if( !strncasecmp(atCmd, "$MDNS", 5) ) {
373 | // handle mDNS name
374 | atCmd = doMdnsName(atCmd + 5);
375 | } else {
376 | // unrecognized command
377 | sendResult(R_ERROR);
378 | }
379 | trim(atCmd);
380 | }
381 | }
382 | }
383 | }
384 | }
385 |
386 | int main(void) {
387 | setup();
388 | while( true ) {
389 | loop();
390 | }
391 | return 0;
392 | }
393 |
394 |
--------------------------------------------------------------------------------
/src/wifi_modem.h:
--------------------------------------------------------------------------------
1 | #ifndef _MODEM_H
2 | #define _MODEM_H
3 |
4 | #define DEBUG 0
5 | #define DEFAULT_SPEED 9600
6 |
7 | #define RING_INTERVAL 1500
8 | #define MAX_CMD_LEN 256
9 | #define TX_BUF_SIZE 256
10 | #define ESC_CHAR '+'
11 | #define ESC_COUNT 3
12 | #define GUARD_TIME 1000
13 | #define MAGIC_NUMBER 0x5678
14 | #define MAX_SSID_LEN 32
15 | #define MAX_WIFI_PWD_LEN 64
16 | #define DEFAULT_LISTEN_PORT 6400
17 | #define TELNET_PORT 23
18 | #define HTTP_PORT 80
19 | #define SPEED_DIAL_SLOTS 10
20 | #define MAGIC_ANSWER_RINGS 3
21 | #define MAX_ALIAS_LEN 16
22 | #define MAX_SPEED_DIAL_LEN 50
23 | #define MAGIC_SPEED_LEN 7
24 | #define MAX_MDNSNAME_LEN 80
25 | #define MAX_BUSYMSG_LEN 80
26 | #define MAX_PWD_LEN 80
27 | #define PASSWORD_TIME 60000
28 | #define PASSWORD_TRIES 3
29 | #define MAX_AUTOEXEC_LEN 80
30 | #define MAX_TERMINAL_LEN 80
31 | #define MAX_LOCATION_LEN 80
32 |
33 | #define NUL '\x00'
34 | #define CTLC '\x03'
35 | #define BS '\x08'
36 | #define LF '\x0A'
37 | #define CR '\x0D'
38 | #define DEL '\x7F'
39 |
40 | #define NO_TELNET ((uint8_t)0)
41 | #define REAL_TELNET ((uint8_t)1)
42 | #define FAKE_TELNET ((uint8_t)2)
43 |
44 | // Telnet codes
45 | #define VLSUP ((uint8_t)0)
46 | #define VLREQ ((uint8_t)1)
47 | #define LOC ((uint8_t)23)
48 | #define TTYPE ((uint8_t)24)
49 | #define NAWS ((uint8_t)31)
50 | #define TSPEED ((uint8_t)32)
51 | #define LFLOW ((uint8_t)33)
52 | #define LINEMODE ((uint8_t)34)
53 | #define XDISPLOC ((uint8_t)35)
54 | #define NEW_ENVIRON ((uint8_t)39)
55 | #define BINARY ((uint8_t)0)
56 | #define ECHO ((uint8_t)1)
57 | #define SUP_GA ((uint8_t)3)
58 | #define SE ((uint8_t)240)
59 | #define DM ((uint8_t)242)
60 | #define BRK ((uint8_t)243)
61 | #define AYT ((uint8_t)246)
62 | #define SB ((uint8_t)250)
63 | #define WILL ((uint8_t)251)
64 | #define WONT ((uint8_t)252)
65 | #define DO ((uint8_t)253)
66 | #define DONT ((uint8_t)254)
67 | #define IAC ((uint8_t)255)
68 |
69 | #define NIST_HOST "time.nist.gov"
70 | #define NIST_PORT 13
71 |
72 | #define ACTIVE LOW // RS232 control signals are active low
73 |
74 | #define RTS 2 // (GPIO02) input
75 | #define CTS 3 // (GPIO03) output
76 | #define DCD 4 // (GPIO04) output
77 | #define DSR 5 // (GPIO05) output
78 | #define DTR 6 // (GPIO06) input
79 | #define RI 7 // (GPIO07) output
80 |
81 | #define OUTPUT true
82 | #define INPUT false
83 | #define HIGH true
84 | #define LOW false
85 |
86 | // I2C EEPROM definitions
87 | #define I2C_ADDR 0x50
88 | #define I2C_SDA 16
89 | #define I2C_SCL 17
90 | #define I2C_BAUD 100000
91 |
92 | #define TCP_CLIENT_RX_BUF_SIZE 20000
93 | #define TCP_CLIENT_TX_BUF_SIZE 1100
94 |
95 | #ifndef NDEBUG
96 | #define POLL_STATE_LED 8
97 | #define RXBUFF_OVFL 9
98 | #define TXBUFF_OVFL 10
99 | #endif
100 |
101 | #endif
102 |
--------------------------------------------------------------------------------