view main.cc @ 5:1a405bda2ffe

rewrite gpib using state machine instead of procedural code, add proper timeout, command queueing, several new commands, improve hardcopy utility
author Frank Kingswood <frank@kingswood-consulting.co.uk>
date Sat, 29 Mar 2014 23:23:58 +0000
parents a70e0a8ac73e
children acbd0ddd002b
line wrap: on
line source
1 /* #------------------------------------------------------------------------#
2 | |
3 | main.cc |
4 | |
5 | USB-GPIB startup and main loop. |
6 | |
7 | Based in part on Simple example for Teensy USB Development Board. |
8 | http://www.pjrc.com/teensy/ Copyright (c) 2008 PJRC.COM, LLC |
9 | |
10 | Copyright 2014, Frank A. Kingswood, www.kingswood-consulting.co.uk |
11 | |
12 #------------------------------------------------------------------------# */
14 #include <avr/io.h>
15 #include <avr/pgmspace.h>
16 #include <stdint.h>
17 #include <util/delay.h>
18 #include "usb_serial.h"
19 #include "serial.h"
20 #include "gpib.h"
22 #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
24 uint8_t recv_str(char *buf, uint8_t size);
25 const UsbSerial __attribute__((__progmem__)) USB;
28 /* -------------------------------------------------------------------------- */
30 void Version();
31 int16_t Command(char *);
33 int main(void)
34 {
35 uint8_t n;
36 static char buf[100];
38 // set for 16 MHz clock, and turn on the LED
39 CPU_PRESCALE(0);
41 GPIB.Initialize();
42 GPIB.LED(true);
43 Serial.Initialize();
45 // initialize the USB, and then wait for the host
46 // to set configuration. If the Teensy is powered
47 // without a PC connected to the USB port, this
48 // will wait forever.
49 USB.Initialize();
50 while (!usb_configured())
51 { }
52 _delay_ms(1000);
54 while (1)
55 {
56 // wait for the user to run their terminal emulator program
57 // which sets DTR to indicate it is ready to receive.
58 while (!(usb_serial_get_control() & USB_SERIAL_DTR))
59 { }
61 // discard anything that was received prior. Sometimes the
62 // operating system or other software will send a modem
63 // "AT command", which can still be buffered.
64 usb_serial_flush_input();
66 // print a nice welcome message
67 Version();
69 // state
70 bool DirectMode=false;
72 // and then listen for commands and process them
73 while(1)
74 {
75 //GPIB.Report();
76 USB<<ROMS("++");
78 GPIB.LED(false);
80 n = recv_str(buf, sizeof(buf));
81 if(n == 255)
82 break;
83 buf[n]=0;
85 GPIB.LED(true);
87 if(n>3 && buf[0]=='+' && buf[1]=='+')
88 {
89 USB<<endl;
90 Command(buf+2);
91 }
92 else if(!DirectMode)
93 {
94 USB<<endl;
95 Command(buf);
96 }
97 else
98 {
99 // send GPIB
100 }
101 }
102 }
103 }
105 // Receive a string from the USB serial port. The string is stored
106 // in the buffer and this function will not exceed the buffer size.
107 // A carriage return or newline completes the string, and is not
108 // stored into the buffer.
109 // The return value is the number of characters received, or 255 if
110 // the virtual serial connection was closed while waiting.
111 //
112 uint8_t recv_str(char *buf, uint8_t size)
113 {
114 int16_t r;
115 uint8_t count=0;
117 while(count < size)
118 {
119 // TODO: move to main
120 r=GPIB.Poll();
121 if(r)
122 USB<<ROMS("++error ")<<r<<endl;
124 r=GPIB.Read();
125 if(r)
126 {
127 r&=0xff;
128 if(r==10)
129 USB<<ROMS("\\012\r\n");
130 else if(r=='\\')
131 USB<<ROMS("\\134");
132 else
133 USB.SendSafeChar(r);
134 }
136 r = usb_serial_getchar();
137 if(r==-1)
138 {
139 if(!usb_configured() || !(usb_serial_get_control() & USB_SERIAL_DTR))
140 {
141 // user no longer connected
142 return 255;
143 }
144 // just a normal timeout, keep waiting
145 }
146 else
147 {
148 if(r=='\r' || r=='\n')
149 return count;
150 if(r=='\b' && count>0)
151 { --buf;
152 --count;
153 usb_serial_putchar(r);
154 usb_serial_putchar(' ');
155 usb_serial_putchar(r);
156 }
157 else if(r >= ' ' && r <= '~')
158 {
159 *buf++ = r;
160 usb_serial_putchar(r);
161 count++;
162 }
163 }
164 }
165 return count;
166 }
168 /* ----- EOF main.cc ----- */