xref: /openbsd-src/gnu/usr.bin/binutils/gdb/rdi-share/serdrv.c (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
1b725ae77Skettenis /*
2b725ae77Skettenis  * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3b725ae77Skettenis  *
4b725ae77Skettenis  * This software may be freely used, copied, modified, and distributed
5b725ae77Skettenis  * provided that the above copyright notice is preserved in all copies of the
6b725ae77Skettenis  * software.
7b725ae77Skettenis  */
8b725ae77Skettenis 
9b725ae77Skettenis /* -*-C-*-
10b725ae77Skettenis  *
11*63addd46Skettenis  * $Revision: 1.3 $
12*63addd46Skettenis  *     $Date: 2004/12/27 14:00:54 $
13b725ae77Skettenis  *
14b725ae77Skettenis  *
15b725ae77Skettenis  * serdrv.c - Synchronous Serial Driver for Angel.
16b725ae77Skettenis  *            This is nice and simple just to get something going.
17b725ae77Skettenis  */
18b725ae77Skettenis 
19b725ae77Skettenis #ifdef __hpux
20b725ae77Skettenis #  define _POSIX_SOURCE 1
21b725ae77Skettenis #endif
22b725ae77Skettenis 
23b725ae77Skettenis #include <stdio.h>
24b725ae77Skettenis #include <stdlib.h>
25b725ae77Skettenis #include <string.h>
26b725ae77Skettenis 
27b725ae77Skettenis #include "crc.h"
28b725ae77Skettenis #include "devices.h"
29b725ae77Skettenis #include "buffers.h"
30b725ae77Skettenis #include "rxtx.h"
31b725ae77Skettenis #include "hostchan.h"
32b725ae77Skettenis #include "params.h"
33b725ae77Skettenis #include "logging.h"
34b725ae77Skettenis 
35b725ae77Skettenis extern int baud_rate;   /* From gdb/top.c */
36b725ae77Skettenis 
37b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
38b725ae77Skettenis #  undef   ERROR
39b725ae77Skettenis #  undef   IGNORE
40b725ae77Skettenis #  include <windows.h>
41b725ae77Skettenis #  include "angeldll.h"
42b725ae77Skettenis #  include "comb_api.h"
43b725ae77Skettenis #else
44b725ae77Skettenis #  ifdef __hpux
45b725ae77Skettenis #    define _TERMIOS_INCLUDED
46b725ae77Skettenis #    include <sys/termio.h>
47b725ae77Skettenis #    undef _TERMIOS_INCLUDED
48b725ae77Skettenis #  else
49b725ae77Skettenis #    include <termios.h>
50b725ae77Skettenis #  endif
51b725ae77Skettenis #  include "unixcomm.h"
52b725ae77Skettenis #endif
53b725ae77Skettenis 
54b725ae77Skettenis #ifndef UNUSED
55b725ae77Skettenis #  define UNUSED(x) (x = x)      /* Silence compiler warnings */
56b725ae77Skettenis #endif
57b725ae77Skettenis 
58b725ae77Skettenis #define MAXREADSIZE 512
59b725ae77Skettenis #define MAXWRITESIZE 512
60b725ae77Skettenis 
61b725ae77Skettenis #define SERIAL_FC_SET  ((1<<serial_XON)|(1<<serial_XOFF))
62b725ae77Skettenis #define SERIAL_CTL_SET ((1<<serial_STX)|(1<<serial_ETX)|(1<<serial_ESC))
63b725ae77Skettenis #define SERIAL_ESC_SET (SERIAL_FC_SET|SERIAL_CTL_SET)
64b725ae77Skettenis 
65b725ae77Skettenis static const struct re_config config = {
66b725ae77Skettenis     serial_STX, serial_ETX, serial_ESC, /* self-explanatory?               */
67b725ae77Skettenis     SERIAL_FC_SET,                      /* set of flow-control characters  */
68b725ae77Skettenis     SERIAL_ESC_SET,                     /* set of characters to be escaped */
69b725ae77Skettenis     NULL /* serial_flow_control */, NULL  ,    /* what to do with FC chars */
70b725ae77Skettenis     angel_DD_RxEng_BufferAlloc, NULL                /* how to get a buffer */
71b725ae77Skettenis };
72b725ae77Skettenis 
73b725ae77Skettenis static struct re_state rxstate;
74b725ae77Skettenis 
75b725ae77Skettenis typedef struct writestate {
76b725ae77Skettenis   unsigned int wbindex;
77b725ae77Skettenis   /*  static te_status testatus;*/
78b725ae77Skettenis   unsigned char writebuf[MAXWRITESIZE];
79b725ae77Skettenis   struct te_state txstate;
80b725ae77Skettenis } writestate;
81b725ae77Skettenis 
82b725ae77Skettenis static struct writestate wstate;
83b725ae77Skettenis 
84b725ae77Skettenis /*
85b725ae77Skettenis  * The set of parameter options supported by the device
86b725ae77Skettenis  */
87b725ae77Skettenis static unsigned int baud_options[] = {
88b725ae77Skettenis #if defined(B115200) || defined(__hpux)
89b725ae77Skettenis     115200,
90b725ae77Skettenis #endif
91b725ae77Skettenis #if defined(B57600) || defined(__hpux)
92b725ae77Skettenis     57600,
93b725ae77Skettenis #endif
94b725ae77Skettenis     38400, 19200, 9600
95b725ae77Skettenis };
96b725ae77Skettenis 
97b725ae77Skettenis static ParameterList param_list[] = {
98b725ae77Skettenis     { AP_BAUD_RATE,
99b725ae77Skettenis       sizeof(baud_options)/sizeof(unsigned int),
100b725ae77Skettenis       baud_options }
101b725ae77Skettenis };
102b725ae77Skettenis 
103b725ae77Skettenis static const ParameterOptions serial_options = {
104b725ae77Skettenis     sizeof(param_list)/sizeof(ParameterList), param_list };
105b725ae77Skettenis 
106b725ae77Skettenis /*
107b725ae77Skettenis  * The default parameter config for the device
108b725ae77Skettenis  */
109b725ae77Skettenis static Parameter param_default[] = {
110b725ae77Skettenis     { AP_BAUD_RATE, 9600 }
111b725ae77Skettenis };
112b725ae77Skettenis 
113b725ae77Skettenis static ParameterConfig serial_defaults = {
114b725ae77Skettenis     sizeof(param_default)/sizeof(Parameter), param_default };
115b725ae77Skettenis 
116b725ae77Skettenis /*
117b725ae77Skettenis  * The user-modified options for the device
118b725ae77Skettenis  */
119b725ae77Skettenis static unsigned int user_baud_options[sizeof(baud_options)/sizeof(unsigned)];
120b725ae77Skettenis 
121b725ae77Skettenis static ParameterList param_user_list[] = {
122b725ae77Skettenis     { AP_BAUD_RATE,
123b725ae77Skettenis       sizeof(user_baud_options)/sizeof(unsigned),
124b725ae77Skettenis       user_baud_options }
125b725ae77Skettenis };
126b725ae77Skettenis 
127b725ae77Skettenis static ParameterOptions user_options = {
128b725ae77Skettenis     sizeof(param_user_list)/sizeof(ParameterList), param_user_list };
129b725ae77Skettenis 
130b725ae77Skettenis static bool user_options_set;
131b725ae77Skettenis 
132b725ae77Skettenis /* forward declarations */
133b725ae77Skettenis static int serial_reset( void );
134b725ae77Skettenis static int serial_set_params( const ParameterConfig *config );
135b725ae77Skettenis static int SerialMatch(const char *name, const char *arg);
136b725ae77Skettenis 
process_baud_rate(unsigned int target_baud_rate)137b725ae77Skettenis static void process_baud_rate( unsigned int target_baud_rate )
138b725ae77Skettenis {
139b725ae77Skettenis     const ParameterList *full_list;
140b725ae77Skettenis     ParameterList       *user_list;
141b725ae77Skettenis 
142b725ae77Skettenis     /* create subset of full options */
143b725ae77Skettenis     full_list = Angel_FindParamList( &serial_options, AP_BAUD_RATE );
144b725ae77Skettenis     user_list = Angel_FindParamList( &user_options,   AP_BAUD_RATE );
145b725ae77Skettenis 
146b725ae77Skettenis     if ( full_list != NULL && user_list != NULL )
147b725ae77Skettenis     {
148b725ae77Skettenis         unsigned int i, j;
149b725ae77Skettenis         unsigned int def_baud = 0;
150b725ae77Skettenis 
151b725ae77Skettenis         /* find lower or equal to */
152b725ae77Skettenis         for ( i = 0; i < full_list->num_options; ++i )
153b725ae77Skettenis            if ( target_baud_rate >= full_list->option[i] )
154b725ae77Skettenis            {
155b725ae77Skettenis                /* copy remaining */
156b725ae77Skettenis                for ( j = 0; j < (full_list->num_options - i); ++j )
157b725ae77Skettenis                   user_list->option[j] = full_list->option[i+j];
158b725ae77Skettenis                user_list->num_options = j;
159b725ae77Skettenis 
160b725ae77Skettenis                /* check this is not the default */
161b725ae77Skettenis                Angel_FindParam( AP_BAUD_RATE, &serial_defaults, &def_baud );
162b725ae77Skettenis                if ( (j == 1) && (user_list->option[0] == def_baud) )
163b725ae77Skettenis                {
164b725ae77Skettenis #ifdef DEBUG
165b725ae77Skettenis                    printf( "user selected default\n" );
166b725ae77Skettenis #endif
167b725ae77Skettenis                }
168b725ae77Skettenis                else
169b725ae77Skettenis                {
170b725ae77Skettenis                    user_options_set = TRUE;
171b725ae77Skettenis #ifdef DEBUG
172b725ae77Skettenis                    printf( "user options are: " );
173b725ae77Skettenis                    for ( j = 0; j < user_list->num_options; ++j )
174b725ae77Skettenis                       printf( "%u ", user_list->option[j] );
175b725ae77Skettenis                    printf( "\n" );
176b725ae77Skettenis #endif
177b725ae77Skettenis                }
178b725ae77Skettenis 
179b725ae77Skettenis                break;   /* out of i loop */
180b725ae77Skettenis            }
181b725ae77Skettenis 
182b725ae77Skettenis #ifdef DEBUG
183b725ae77Skettenis         if ( i >= full_list->num_options )
184b725ae77Skettenis            printf( "couldn't match baud rate %u\n", target_baud_rate );
185b725ae77Skettenis #endif
186b725ae77Skettenis     }
187b725ae77Skettenis #ifdef DEBUG
188b725ae77Skettenis     else
189b725ae77Skettenis        printf( "failed to find lists\n" );
190b725ae77Skettenis #endif
191b725ae77Skettenis }
192b725ae77Skettenis 
SerialOpen(const char * name,const char * arg)193b725ae77Skettenis static int SerialOpen(const char *name, const char *arg)
194b725ae77Skettenis {
195b725ae77Skettenis     const char *port_name = name;
196b725ae77Skettenis 
197b725ae77Skettenis #ifdef DEBUG
198b725ae77Skettenis     printf("SerialOpen: name %s arg %s\n", name, arg ? arg : "<NULL>");
199b725ae77Skettenis #endif
200b725ae77Skettenis 
201b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
202b725ae77Skettenis     if (IsOpenSerial()) return -1;
203b725ae77Skettenis #else
204b725ae77Skettenis     if (Unix_IsSerialInUse()) return -1;
205b725ae77Skettenis #endif
206b725ae77Skettenis 
207b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
208b725ae77Skettenis     if (SerialMatch(name, arg) != adp_ok)
209b725ae77Skettenis         return adp_failed;
210b725ae77Skettenis #else
211b725ae77Skettenis     port_name = Unix_MatchValidSerialDevice(port_name);
212b725ae77Skettenis # ifdef DEBUG
213b725ae77Skettenis     printf("translated port to %s\n", port_name == 0 ? "NULL" : port_name);
214b725ae77Skettenis # endif
215b725ae77Skettenis     if (port_name == 0) return adp_failed;
216b725ae77Skettenis #endif
217b725ae77Skettenis 
218b725ae77Skettenis     user_options_set = FALSE;
219b725ae77Skettenis 
220b725ae77Skettenis     /* interpret and store the arguments */
221b725ae77Skettenis     if ( arg != NULL )
222b725ae77Skettenis     {
223b725ae77Skettenis         unsigned int target_baud_rate;
224b725ae77Skettenis         target_baud_rate = (unsigned int)strtoul(arg, NULL, 10);
225b725ae77Skettenis         if (target_baud_rate > 0)
226b725ae77Skettenis         {
227b725ae77Skettenis #ifdef DEBUG
228b725ae77Skettenis             printf( "user selected baud rate %u\n", target_baud_rate );
229b725ae77Skettenis #endif
230b725ae77Skettenis             process_baud_rate( target_baud_rate );
231b725ae77Skettenis         }
232b725ae77Skettenis #ifdef DEBUG
233b725ae77Skettenis         else
234b725ae77Skettenis            printf( "could not understand baud rate %s\n", arg );
235b725ae77Skettenis #endif
236b725ae77Skettenis     }
237b725ae77Skettenis     else if (baud_rate > 0)
238b725ae77Skettenis     {
239b725ae77Skettenis       /* If the user specified a baud rate on the command line "-b" or via
240b725ae77Skettenis          the "set remotebaud" command then try to use that one */
241b725ae77Skettenis       process_baud_rate( baud_rate );
242b725ae77Skettenis     }
243b725ae77Skettenis 
244b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
245b725ae77Skettenis     {
246b725ae77Skettenis         int port = IsValidDevice(name);
247b725ae77Skettenis         if (OpenSerial(port, FALSE) != COM_OK)
248b725ae77Skettenis             return -1;
249b725ae77Skettenis     }
250b725ae77Skettenis #else
251b725ae77Skettenis     if (Unix_OpenSerial(port_name) < 0)
252b725ae77Skettenis       return -1;
253b725ae77Skettenis #endif
254b725ae77Skettenis 
255b725ae77Skettenis     serial_reset();
256b725ae77Skettenis 
257b725ae77Skettenis #if defined(__unix) || defined(__CYGWIN__)
258b725ae77Skettenis     Unix_ioctlNonBlocking();
259b725ae77Skettenis #endif
260b725ae77Skettenis 
261b725ae77Skettenis     Angel_RxEngineInit(&config, &rxstate);
262b725ae77Skettenis     /*
263b725ae77Skettenis      * DANGER!: passing in NULL as the packet is ok for now as it is just
264b725ae77Skettenis      * IGNOREd but this may well change
265b725ae77Skettenis      */
266b725ae77Skettenis     Angel_TxEngineInit(&config, NULL, &wstate.txstate);
267b725ae77Skettenis     return 0;
268b725ae77Skettenis }
269b725ae77Skettenis 
SerialMatch(const char * name,const char * arg)270b725ae77Skettenis static int SerialMatch(const char *name, const char *arg)
271b725ae77Skettenis {
272b725ae77Skettenis     UNUSED(arg);
273b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
274b725ae77Skettenis     if (IsValidDevice(name) == COM_DEVICENOTVALID)
275b725ae77Skettenis         return -1;
276b725ae77Skettenis     else
277b725ae77Skettenis         return 0;
278b725ae77Skettenis #else
279b725ae77Skettenis     return Unix_MatchValidSerialDevice(name) == 0 ? -1 : 0;
280b725ae77Skettenis #endif
281b725ae77Skettenis }
282b725ae77Skettenis 
SerialClose(void)283b725ae77Skettenis static void SerialClose(void)
284b725ae77Skettenis {
285b725ae77Skettenis #ifdef DO_TRACE
286b725ae77Skettenis     printf("SerialClose()\n");
287b725ae77Skettenis #endif
288b725ae77Skettenis 
289b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
290b725ae77Skettenis     CloseSerial();
291b725ae77Skettenis #else
292b725ae77Skettenis     Unix_CloseSerial();
293b725ae77Skettenis #endif
294b725ae77Skettenis }
295b725ae77Skettenis 
SerialRead(DriverCall * dc,bool block)296b725ae77Skettenis static int SerialRead(DriverCall *dc, bool block) {
297b725ae77Skettenis   static unsigned char readbuf[MAXREADSIZE];
298b725ae77Skettenis   static int rbindex=0;
299b725ae77Skettenis 
300b725ae77Skettenis   int nread;
301b725ae77Skettenis   int read_errno;
302b725ae77Skettenis   int c=0;
303b725ae77Skettenis   re_status restatus;
304b725ae77Skettenis   int ret_code = -1;            /* assume bad packet or error */
305b725ae77Skettenis 
306b725ae77Skettenis   /* must not overflow buffer and must start after the existing data */
307b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
308b725ae77Skettenis   {
309b725ae77Skettenis     BOOL dummy = FALSE;
310b725ae77Skettenis     nread = BytesInRXBufferSerial();
311b725ae77Skettenis 
312b725ae77Skettenis     if (nread > MAXREADSIZE - rbindex)
313b725ae77Skettenis       nread = MAXREADSIZE - rbindex;
314b725ae77Skettenis 
315b725ae77Skettenis     if ((read_errno = ReadSerial(readbuf+rbindex, nread, &dummy)) == COM_READFAIL)
316b725ae77Skettenis     {
317b725ae77Skettenis         MessageBox(GetFocus(), "Read error\n", "Angel", MB_OK | MB_ICONSTOP);
318b725ae77Skettenis         return -1;   /* SJ - This really needs to return a value, which is picked up in */
319b725ae77Skettenis                      /*      DevSW_Read as meaning stop debugger but don't kill. */
320b725ae77Skettenis     }
321b725ae77Skettenis     else if (pfnProgressCallback != NULL && read_errno == COM_OK)
322b725ae77Skettenis     {
323b725ae77Skettenis       progressInfo.nRead += nread;
324b725ae77Skettenis       (*pfnProgressCallback)(&progressInfo);
325b725ae77Skettenis     }
326b725ae77Skettenis   }
327b725ae77Skettenis #else
328b725ae77Skettenis   nread = Unix_ReadSerial(readbuf+rbindex, MAXREADSIZE-rbindex, block);
329b725ae77Skettenis   read_errno = errno;
330b725ae77Skettenis #endif
331b725ae77Skettenis 
332b725ae77Skettenis   if ((nread > 0) || (rbindex > 0)) {
333b725ae77Skettenis 
334b725ae77Skettenis #ifdef DO_TRACE
335b725ae77Skettenis     printf("[%d@%d] ", nread, rbindex);
336b725ae77Skettenis #endif
337b725ae77Skettenis 
338b725ae77Skettenis     if (nread>0)
339b725ae77Skettenis        rbindex = rbindex+nread;
340b725ae77Skettenis 
341b725ae77Skettenis     do {
342b725ae77Skettenis       restatus = Angel_RxEngine(readbuf[c], &(dc->dc_packet), &rxstate);
343b725ae77Skettenis #ifdef DO_TRACE
344b725ae77Skettenis       printf("<%02X ",readbuf[c]);
345b725ae77Skettenis       if (!(++c % 16))
346b725ae77Skettenis           printf("\n");
347b725ae77Skettenis #else
348b725ae77Skettenis       c++;
349b725ae77Skettenis #endif
350b725ae77Skettenis     } while (c<rbindex &&
351b725ae77Skettenis              ((restatus == RS_IN_PKT) || (restatus == RS_WAIT_PKT)));
352b725ae77Skettenis 
353b725ae77Skettenis #ifdef DO_TRACE
354b725ae77Skettenis    if (c % 16)
355b725ae77Skettenis         printf("\n");
356b725ae77Skettenis #endif
357b725ae77Skettenis 
358b725ae77Skettenis     switch(restatus) {
359b725ae77Skettenis 
360b725ae77Skettenis       case RS_GOOD_PKT:
361b725ae77Skettenis         ret_code = 1;
362b725ae77Skettenis         /* fall through to: */
363b725ae77Skettenis 
364b725ae77Skettenis       case RS_BAD_PKT:
365b725ae77Skettenis         /*
366b725ae77Skettenis          * We now need to shuffle any left over data down to the
367b725ae77Skettenis          * beginning of our private buffer ready to be used
368b725ae77Skettenis          *for the next packet
369b725ae77Skettenis          */
370b725ae77Skettenis #ifdef DO_TRACE
371b725ae77Skettenis         printf("SerialRead() processed %d, moving down %d\n", c, rbindex-c);
372b725ae77Skettenis #endif
373b725ae77Skettenis         if (c != rbindex) memmove((char *) readbuf, (char *) (readbuf+c),
374b725ae77Skettenis                                   rbindex-c);
375b725ae77Skettenis         rbindex -= c;
376b725ae77Skettenis         break;
377b725ae77Skettenis 
378b725ae77Skettenis       case RS_IN_PKT:
379b725ae77Skettenis       case RS_WAIT_PKT:
380b725ae77Skettenis         rbindex = 0;            /* will have processed all we had */
381b725ae77Skettenis         ret_code = 0;
382b725ae77Skettenis         break;
383b725ae77Skettenis 
384b725ae77Skettenis       default:
385b725ae77Skettenis #ifdef DEBUG
386b725ae77Skettenis         printf("Bad re_status in serialRead()\n");
387b725ae77Skettenis #endif
388b725ae77Skettenis         break;
389b725ae77Skettenis     }
390b725ae77Skettenis   } else if (nread == 0)
391b725ae77Skettenis     ret_code = 0;               /* nothing to read */
392b725ae77Skettenis   else if (read_errno == ERRNO_FOR_BLOCKED_IO) /* nread < 0 */
393b725ae77Skettenis     ret_code = 0;
394b725ae77Skettenis 
395b725ae77Skettenis #ifdef DEBUG
396b725ae77Skettenis   if ((nread<0) && (read_errno!=ERRNO_FOR_BLOCKED_IO))
397b725ae77Skettenis     perror("read() error in serialRead()");
398b725ae77Skettenis #endif
399b725ae77Skettenis 
400b725ae77Skettenis   return ret_code;
401b725ae77Skettenis }
402b725ae77Skettenis 
403b725ae77Skettenis 
SerialWrite(DriverCall * dc)404b725ae77Skettenis static int SerialWrite(DriverCall *dc) {
405b725ae77Skettenis   int nwritten = 0;
406b725ae77Skettenis   te_status testatus = TS_IN_PKT;
407b725ae77Skettenis 
408b725ae77Skettenis   if (dc->dc_context == NULL) {
409b725ae77Skettenis     Angel_TxEngineInit(&config, &(dc->dc_packet), &(wstate.txstate));
410b725ae77Skettenis     wstate.wbindex = 0;
411b725ae77Skettenis     dc->dc_context = &wstate;
412b725ae77Skettenis   }
413b725ae77Skettenis 
414b725ae77Skettenis   while ((testatus == TS_IN_PKT) && (wstate.wbindex < MAXWRITESIZE))
415b725ae77Skettenis   {
416b725ae77Skettenis     /* send the raw data through the tx engine to escape and encapsulate */
417b725ae77Skettenis     testatus = Angel_TxEngine(&(dc->dc_packet), &(wstate.txstate),
418b725ae77Skettenis                               &(wstate.writebuf)[wstate.wbindex]);
419b725ae77Skettenis     if (testatus != TS_IDLE) wstate.wbindex++;
420b725ae77Skettenis   }
421b725ae77Skettenis 
422b725ae77Skettenis   if (testatus == TS_IDLE) {
423b725ae77Skettenis #ifdef DEBUG
424b725ae77Skettenis     printf("SerialWrite: testatus is TS_IDLE during preprocessing\n");
425b725ae77Skettenis #endif
426b725ae77Skettenis   }
427b725ae77Skettenis 
428b725ae77Skettenis #ifdef DO_TRACE
429b725ae77Skettenis   {
430b725ae77Skettenis     int i = 0;
431b725ae77Skettenis 
432b725ae77Skettenis     while (i<wstate.wbindex)
433b725ae77Skettenis     {
434b725ae77Skettenis         printf(">%02X ",wstate.writebuf[i]);
435b725ae77Skettenis 
436b725ae77Skettenis         if (!(++i % 16))
437b725ae77Skettenis             printf("\n");
438b725ae77Skettenis     }
439b725ae77Skettenis     if (i % 16)
440b725ae77Skettenis         printf("\n");
441b725ae77Skettenis   }
442b725ae77Skettenis #endif
443b725ae77Skettenis 
444b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
445b725ae77Skettenis   if (WriteSerial(wstate.writebuf, wstate.wbindex) == COM_OK)
446b725ae77Skettenis   {
447b725ae77Skettenis     nwritten = wstate.wbindex;
448b725ae77Skettenis     if (pfnProgressCallback != NULL)
449b725ae77Skettenis     {
450b725ae77Skettenis       progressInfo.nWritten += nwritten;
451b725ae77Skettenis       (*pfnProgressCallback)(&progressInfo);
452b725ae77Skettenis     }
453b725ae77Skettenis   }
454b725ae77Skettenis   else
455b725ae77Skettenis   {
456b725ae77Skettenis       MessageBox(GetFocus(), "Write error\n", "Angel", MB_OK | MB_ICONSTOP);
457b725ae77Skettenis       return -1;   /* SJ - This really needs to return a value, which is picked up in */
458b725ae77Skettenis                    /*      DevSW_Read as meaning stop debugger but don't kill. */
459b725ae77Skettenis   }
460b725ae77Skettenis #else
461b725ae77Skettenis   nwritten = Unix_WriteSerial(wstate.writebuf, wstate.wbindex);
462b725ae77Skettenis 
463b725ae77Skettenis   if (nwritten < 0) {
464b725ae77Skettenis     nwritten=0;
465b725ae77Skettenis   }
466b725ae77Skettenis #endif
467b725ae77Skettenis 
468b725ae77Skettenis #ifdef DEBUG
469b725ae77Skettenis   if (nwritten > 0)
470b725ae77Skettenis     printf("Wrote %#04x bytes\n", nwritten);
471b725ae77Skettenis #endif
472b725ae77Skettenis 
473b725ae77Skettenis   if ((unsigned) nwritten == wstate.wbindex &&
474b725ae77Skettenis       (testatus == TS_DONE_PKT || testatus == TS_IDLE)) {
475b725ae77Skettenis 
476b725ae77Skettenis     /* finished sending the packet */
477b725ae77Skettenis 
478b725ae77Skettenis #ifdef DEBUG
479b725ae77Skettenis     printf("SerialWrite: calling Angel_TxEngineInit after sending packet (len=%i)\n",wstate.wbindex);
480b725ae77Skettenis #endif
481b725ae77Skettenis     testatus = TS_IN_PKT;
482b725ae77Skettenis     wstate.wbindex = 0;
483b725ae77Skettenis     return 1;
484b725ae77Skettenis   }
485b725ae77Skettenis   else {
486b725ae77Skettenis #ifdef DEBUG
487b725ae77Skettenis     printf("SerialWrite: Wrote part of packet wbindex=%i, nwritten=%i\n",
488b725ae77Skettenis            wstate.wbindex, nwritten);
489b725ae77Skettenis #endif
490b725ae77Skettenis 
491b725ae77Skettenis     /*
492b725ae77Skettenis      *  still some data left to send shuffle whats left down and reset
493b725ae77Skettenis      * the ptr
494b725ae77Skettenis      */
495b725ae77Skettenis     memmove((char *) wstate.writebuf, (char *) (wstate.writebuf+nwritten),
496b725ae77Skettenis             wstate.wbindex-nwritten);
497b725ae77Skettenis     wstate.wbindex -= nwritten;
498b725ae77Skettenis     return 0;
499b725ae77Skettenis   }
500b725ae77Skettenis   return -1;
501b725ae77Skettenis }
502b725ae77Skettenis 
503b725ae77Skettenis 
serial_reset(void)504b725ae77Skettenis static int serial_reset( void )
505b725ae77Skettenis {
506b725ae77Skettenis #ifdef DEBUG
507b725ae77Skettenis     printf( "serial_reset\n" );
508b725ae77Skettenis #endif
509b725ae77Skettenis 
510b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
511b725ae77Skettenis     FlushSerial();
512b725ae77Skettenis #else
513b725ae77Skettenis     Unix_ResetSerial();
514b725ae77Skettenis #endif
515b725ae77Skettenis 
516b725ae77Skettenis     return serial_set_params( &serial_defaults );
517b725ae77Skettenis }
518b725ae77Skettenis 
519b725ae77Skettenis 
find_baud_rate(unsigned int * speed)520b725ae77Skettenis static int find_baud_rate( unsigned int *speed )
521b725ae77Skettenis {
522b725ae77Skettenis     static struct {
523b725ae77Skettenis           unsigned int baud;
524b725ae77Skettenis           int termiosValue;
525b725ae77Skettenis     } possibleBaudRates[] = {
526b725ae77Skettenis #if defined(__hpux)
527b725ae77Skettenis         {115200,_B115200}, {57600,_B57600},
528b725ae77Skettenis #else
529b725ae77Skettenis #ifdef B115200
530b725ae77Skettenis         {115200,B115200},
531b725ae77Skettenis #endif
532b725ae77Skettenis #ifdef B57600
533b725ae77Skettenis 	{57600,B57600},
534b725ae77Skettenis #endif
535b725ae77Skettenis #endif
536b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
537b725ae77Skettenis         {38400,CBR_38400}, {19200,CBR_19200}, {9600, CBR_9600}, {0,0}
538b725ae77Skettenis #else
539b725ae77Skettenis         {38400,B38400}, {19200,B19200}, {9600, B9600}, {0,0}
540b725ae77Skettenis #endif
541b725ae77Skettenis     };
542b725ae77Skettenis     unsigned int i;
543b725ae77Skettenis 
544b725ae77Skettenis     /* look for lower or matching -- will always terminate at 0 end marker */
545b725ae77Skettenis     for ( i = 0; possibleBaudRates[i].baud > *speed; ++i )
546b725ae77Skettenis        /* do nothing */ ;
547b725ae77Skettenis 
548b725ae77Skettenis     if ( possibleBaudRates[i].baud > 0 )
549b725ae77Skettenis        *speed = possibleBaudRates[i].baud;
550b725ae77Skettenis 
551b725ae77Skettenis     return possibleBaudRates[i].termiosValue;
552b725ae77Skettenis }
553b725ae77Skettenis 
554b725ae77Skettenis 
serial_set_params(const ParameterConfig * config)555b725ae77Skettenis static int serial_set_params( const ParameterConfig *config )
556b725ae77Skettenis {
557b725ae77Skettenis     unsigned int speed;
558b725ae77Skettenis     int termios_value;
559b725ae77Skettenis 
560b725ae77Skettenis #ifdef DEBUG
561b725ae77Skettenis     printf( "serial_set_params\n" );
562b725ae77Skettenis #endif
563b725ae77Skettenis 
564b725ae77Skettenis     if ( ! Angel_FindParam( AP_BAUD_RATE, config, &speed ) )
565b725ae77Skettenis     {
566b725ae77Skettenis #ifdef DEBUG
567b725ae77Skettenis         printf( "speed not found in config\n" );
568b725ae77Skettenis #endif
569b725ae77Skettenis         return DE_OKAY;
570b725ae77Skettenis     }
571b725ae77Skettenis 
572b725ae77Skettenis     termios_value = find_baud_rate( &speed );
573b725ae77Skettenis     if ( termios_value == 0 )
574b725ae77Skettenis     {
575b725ae77Skettenis #ifdef DEBUG
576b725ae77Skettenis         printf( "speed not valid: %u\n", speed );
577b725ae77Skettenis #endif
578b725ae77Skettenis         return DE_OKAY;
579b725ae77Skettenis     }
580b725ae77Skettenis 
581b725ae77Skettenis #ifdef DEBUG
582b725ae77Skettenis     printf( "setting speed to %u\n", speed );
583b725ae77Skettenis #endif
584b725ae77Skettenis 
585b725ae77Skettenis #ifdef COMPILING_ON_WINDOWS
586b725ae77Skettenis     SetBaudRate((WORD)termios_value);
587b725ae77Skettenis #else
588b725ae77Skettenis     Unix_SetSerialBaudRate(termios_value);
589b725ae77Skettenis #endif
590b725ae77Skettenis 
591b725ae77Skettenis     return DE_OKAY;
592b725ae77Skettenis }
593b725ae77Skettenis 
594b725ae77Skettenis 
serial_get_user_params(ParameterOptions ** p_options)595b725ae77Skettenis static int serial_get_user_params( ParameterOptions **p_options )
596b725ae77Skettenis {
597b725ae77Skettenis #ifdef DEBUG
598b725ae77Skettenis     printf( "serial_get_user_params\n" );
599b725ae77Skettenis #endif
600b725ae77Skettenis 
601b725ae77Skettenis     if ( user_options_set )
602b725ae77Skettenis     {
603b725ae77Skettenis         *p_options = &user_options;
604b725ae77Skettenis     }
605b725ae77Skettenis     else
606b725ae77Skettenis     {
607b725ae77Skettenis         *p_options = NULL;
608b725ae77Skettenis     }
609b725ae77Skettenis 
610b725ae77Skettenis     return DE_OKAY;
611b725ae77Skettenis }
612b725ae77Skettenis 
613b725ae77Skettenis 
serial_get_default_params(ParameterConfig ** p_config)614b725ae77Skettenis static int serial_get_default_params( ParameterConfig **p_config )
615b725ae77Skettenis {
616b725ae77Skettenis #ifdef DEBUG
617b725ae77Skettenis     printf( "serial_get_default_params\n" );
618b725ae77Skettenis #endif
619b725ae77Skettenis 
620b725ae77Skettenis     *p_config = (ParameterConfig *) &serial_defaults;
621b725ae77Skettenis     return DE_OKAY;
622b725ae77Skettenis }
623b725ae77Skettenis 
624b725ae77Skettenis 
SerialIoctl(const int opcode,void * args)625b725ae77Skettenis static int SerialIoctl(const int opcode, void *args) {
626b725ae77Skettenis 
627b725ae77Skettenis     int ret_code;
628b725ae77Skettenis 
629b725ae77Skettenis #ifdef DEBUG
630b725ae77Skettenis     printf( "SerialIoctl: op %d arg %p\n", opcode, args ? args : "<NULL>");
631b725ae77Skettenis #endif
632b725ae77Skettenis 
633b725ae77Skettenis     switch (opcode)
634b725ae77Skettenis     {
635b725ae77Skettenis        case DC_RESET:
636b725ae77Skettenis            ret_code = serial_reset();
637b725ae77Skettenis            break;
638b725ae77Skettenis 
639b725ae77Skettenis        case DC_SET_PARAMS:
640b725ae77Skettenis            ret_code = serial_set_params((const ParameterConfig *)args);
641b725ae77Skettenis            break;
642b725ae77Skettenis 
643b725ae77Skettenis        case DC_GET_USER_PARAMS:
644b725ae77Skettenis            ret_code = serial_get_user_params((ParameterOptions **)args);
645b725ae77Skettenis            break;
646b725ae77Skettenis 
647b725ae77Skettenis        case DC_GET_DEFAULT_PARAMS:
648b725ae77Skettenis            ret_code = serial_get_default_params((ParameterConfig **)args);
649b725ae77Skettenis            break;
650b725ae77Skettenis 
651b725ae77Skettenis        default:
652b725ae77Skettenis            ret_code = DE_BAD_OP;
653b725ae77Skettenis            break;
654b725ae77Skettenis     }
655b725ae77Skettenis 
656b725ae77Skettenis   return ret_code;
657b725ae77Skettenis }
658b725ae77Skettenis 
659b725ae77Skettenis DeviceDescr angel_SerialDevice = {
660b725ae77Skettenis     "SERIAL",
661b725ae77Skettenis     SerialOpen,
662b725ae77Skettenis     SerialMatch,
663b725ae77Skettenis     SerialClose,
664b725ae77Skettenis     SerialRead,
665b725ae77Skettenis     SerialWrite,
666b725ae77Skettenis     SerialIoctl
667b725ae77Skettenis };
668