1 /* Teensy Serial to OGI Lumen Nixie Driver board rev 0.1
3 * Based on (read as "a quick hack of"):
4 * Simple example for Teensy USB Development Board
5 * http://www.pjrc.com/teensy/
6 * Copyright (c) 2008 PJRC.COM, LLC
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 * Nixie Driver Pin Teensy Pin
38 * Nixie digit order, front to back: 3894057621
42 #include <avr/pgmspace.h>
44 #include <util/delay.h>
45 #include "usb_serial.h"
47 #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
48 #define NIXIE_SER (1 << 4)
49 #define NIXIE_SCK (1 << 5)
50 #define NIXIE_RCK (1 << 6)
52 void send_str(const char *s);
53 uint8_t recv_str(char *buf, uint8_t size);
54 void parse_and_execute_command(const char *buf, uint8_t num);
58 PORTD &= ~(NIXIE_SER);
59 PORTD &= ~(NIXIE_SCK);
60 PORTD &= ~(NIXIE_RCK);
61 DDRD |= (NIXIE_SER | NIXIE_SCK | NIXIE_RCK);
64 void nixie_send_digit(uint8_t digit)
66 for (int i=0; i < 4; i++) {
67 PORTD &= ~(NIXIE_SCK);
68 if ((digit & 0x8) != 0) {
71 PORTD &= ~(NIXIE_SER);
78 PORTD &= ~(NIXIE_SCK);
87 PORTD &= ~(NIXIE_RCK);
96 // set for 16 MHz clock, and turn on the LED
99 // initialize the USB, and then wait for the host
100 // to set configuration. If the Teensy is powered
101 // without a PC connected to the USB port, this
102 // will wait forever.
104 while (!usb_configured()) /* wait */ ;
119 // wait for the user to run their terminal emulator program
120 // which sets DTR to indicate it is ready to receive.
121 while (!(usb_serial_get_control() & USB_SERIAL_DTR)) /* wait */ ;
123 // discard anything that was received prior. Sometimes the
124 // operating system or other software will send a modem
125 // "AT command", which can still be buffered.
126 usb_serial_flush_input();
128 // print a nice welcome message
129 send_str(PSTR("\r\nTeensy USB Serial Example, "
130 "Simple Pin Control Shell\r\n\r\n"
131 "Example Commands\r\n"
132 " B0? Read Port B, pin 0\r\n"
133 " C2=0 Write Port C, pin 1 LOW\r\n"
134 " D6=1 Write Port D, pin 6 HIGH (D6 is LED pin)\r\n\r\n"));
136 // and then listen for commands and process them
138 send_str(PSTR("> "));
139 n = recv_str(buf, sizeof(buf));
141 send_str(PSTR("\r\n"));
142 // parse_and_execute_command(buf, n);
147 // Send a string to the USB serial port. The string must be in
148 // flash memory, using PSTR
150 void send_str(const char *s)
154 c = pgm_read_byte(s++);
156 usb_serial_putchar(c);
160 // Receive a string from the USB serial port. The string is stored
161 // in the buffer and this function will not exceed the buffer size.
162 // A carriage return or newline completes the string, and is not
163 // stored into the buffer.
164 // The return value is the number of characters received, or 255 if
165 // the virtual serial connection was closed while waiting.
167 uint8_t recv_str(char *buf, uint8_t size)
172 while (count < size) {
173 r = usb_serial_getchar();
175 if (r == '\r' || r == '\n') {
179 if (r >= '0' && r <= '9') {
181 usb_serial_putchar(r);
184 } else if (r == ' ') {
185 usb_serial_putchar(r);
186 nixie_send_digit(10);
189 if (!usb_configured() ||
190 !(usb_serial_get_control() & USB_SERIAL_DTR)) {
191 // user no longer connected
194 // just a normal timeout, keep waiting
200 // parse a user command and execute it, or print an error message
202 void parse_and_execute_command(const char *buf, uint8_t num)
204 uint8_t port, pin, val;
207 send_str(PSTR("unrecognized format, 3 chars min req'd\r\n"));
210 // first character is the port letter
211 if (buf[0] >= 'A' && buf[0] <= 'F') {
213 } else if (buf[0] >= 'a' && buf[0] <= 'f') {
216 send_str(PSTR("Unknown port \""));
217 usb_serial_putchar(buf[0]);
218 send_str(PSTR("\", must be A - F\r\n"));
221 // second character is the pin number
222 if (buf[1] >= '0' && buf[1] <= '7') {
225 send_str(PSTR("Unknown pin \""));
226 usb_serial_putchar(buf[0]);
227 send_str(PSTR("\", must be 0 to 7\r\n"));
230 // if the third character is a question mark, read the pin
232 // make the pin an input
233 *(uint8_t *)(0x21 + port * 3) &= ~(1 << pin);
235 val = *(uint8_t *)(0x20 + port * 3) & (1 << pin);
236 usb_serial_putchar(val ? '1' : '0');
237 send_str(PSTR("\r\n"));
240 // if the third character is an equals sign, write the pin
241 if (num >= 4 && buf[2] == '=') {
243 // make the pin an output
244 *(uint8_t *)(0x21 + port * 3) |= (1 << pin);
246 *(uint8_t *)(0x22 + port * 3) &= ~(1 << pin);
248 } else if (buf[3] == '1') {
249 // make the pin an output
250 *(uint8_t *)(0x21 + port * 3) |= (1 << pin);
252 *(uint8_t *)(0x22 + port * 3) |= (1 << pin);
255 send_str(PSTR("Unknown value \""));
256 usb_serial_putchar(buf[3]);
257 send_str(PSTR("\", must be 0 or 1\r\n"));
261 // otherwise, error message
262 send_str(PSTR("Unknown command \""));
263 usb_serial_putchar(buf[0]);
264 send_str(PSTR("\", must be ? or =\r\n"));