Use --tty/-T on command line to specify target device
[fw/altos] / ao-tools / lib / ccdbg-io.c
1 /*
2  * Copyright © 2008 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include "ccdbg.h"
20 #include <time.h>
21 #include "cc-usb.h"
22 #include "cc-bitbang.h"
23
24 struct ccdbg *
25 ccdbg_open(char *tty)
26 {
27         struct ccdbg *dbg;
28
29         dbg = calloc(sizeof (struct ccdbg), 1);
30         if (!dbg) {
31                 perror("calloc");
32                 return NULL;
33         }
34         if (!tty)
35                 tty = getenv("ALTOS_TTY");
36         if (!tty)
37                 tty="/dev/ttyACM0";
38
39         if (!strcmp(tty, "BITBANG")) {
40                 dbg->bb = cc_bitbang_open();
41                 if (!dbg->bb) {
42                         free(dbg);
43                         return NULL;
44                 }
45         } else {
46                 dbg->usb = cc_usb_open(tty);
47                 if (!dbg->usb) {
48                         free(dbg);
49                         return NULL;
50                 }
51         }
52         return dbg;
53 }
54
55 void
56 ccdbg_close(struct ccdbg *dbg)
57 {
58         if (dbg->usb)
59                 cc_usb_close(dbg->usb);
60         if (dbg->bb)
61                 cc_bitbang_close(dbg->bb);
62         free (dbg);
63 }
64
65 void
66 ccdbg_debug_mode(struct ccdbg *dbg)
67 {
68         if (dbg->usb)
69                 cc_usb_debug_mode(dbg->usb);
70         else if (dbg->bb)
71                 cc_bitbang_debug_mode(dbg->bb);
72 }
73
74 void
75 ccdbg_reset(struct ccdbg *dbg)
76 {
77         if (dbg->usb)
78                 cc_usb_reset(dbg->usb);
79         else if (dbg->bb)
80                 cc_bitbang_reset(dbg->bb);
81 }
82
83 void
84 ccdbg_send_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes)
85 {
86         if (dbg->usb)
87                 cc_usb_send_bytes(dbg->usb, bytes, nbytes);
88         else if (dbg->bb)
89                 cc_bitbang_send_bytes(dbg->bb, bytes, nbytes);
90 }
91
92 void
93 ccdbg_recv_bytes(struct ccdbg *dbg, uint8_t *bytes, int nbytes)
94 {
95         if (dbg->usb)
96                 cc_usb_recv_bytes(dbg->usb, bytes, nbytes);
97         else if (dbg->bb)
98                 cc_bitbang_recv_bytes(dbg->bb, bytes, nbytes);
99 }
100
101 void
102 ccdbg_sync(struct ccdbg *dbg)
103 {
104         if (dbg->usb)
105                 cc_usb_sync(dbg->usb);
106         else if (dbg->bb)
107                 cc_bitbang_sync(dbg->bb);
108 }
109
110 void
111 ccdbg_cmd_write(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
112 {
113         ccdbg_send_bytes(dbg, &cmd, 1);
114         ccdbg_send_bytes(dbg, data, len);
115 }
116
117 uint8_t
118 ccdbg_cmd_write_read8(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
119 {
120         uint8_t byte[1];
121         ccdbg_cmd_write(dbg, cmd, data, len);
122         ccdbg_recv_bytes(dbg, byte, 1);
123         ccdbg_sync(dbg);
124         return byte[0];
125 }
126
127 uint16_t
128 ccdbg_cmd_write_read16(struct ccdbg *dbg, uint8_t cmd, uint8_t *data, int len)
129 {
130         uint8_t byte[2];
131         ccdbg_cmd_write(dbg, cmd, data, len);
132         ccdbg_recv_bytes(dbg, byte, 2);
133         ccdbg_sync(dbg);
134         return (byte[0] << 8) | byte[1];
135 }
136
137 void
138 ccdbg_cmd_write_queue8(struct ccdbg *dbg, uint8_t cmd,
139                        uint8_t *data, int len,
140                        uint8_t *reply)
141 {
142         ccdbg_cmd_write(dbg, cmd, data, len);
143         ccdbg_recv_bytes(dbg, reply, 1);
144 }