12 #include "remote_bitbang.h"
20 /////////// Circular buffer
23 unsigned int circular_buffer_t
<T
>::size() const
28 return end
+ capacity
- start
;
32 void circular_buffer_t
<T
>::consume(unsigned int bytes
)
34 start
= (start
+ bytes
) % capacity
;
38 unsigned int circular_buffer_t
<T
>::contiguous_empty_size() const
42 return capacity
- end
- 1;
44 return capacity
- end
;
46 return start
- end
- 1;
50 unsigned int circular_buffer_t
<T
>::contiguous_data_size() const
55 return capacity
- start
;
59 void circular_buffer_t
<T
>::data_added(unsigned int bytes
)
62 assert(end
<= capacity
);
68 void circular_buffer_t
<T
>::reset()
75 void circular_buffer_t
<T
>::append(const T
*src
, unsigned int count
)
77 unsigned int copy
= std::min(count
, contiguous_empty_size());
78 memcpy(contiguous_empty(), src
, copy
* sizeof(T
));
82 assert(count
< contiguous_empty_size());
83 memcpy(contiguous_empty(), src
+copy
, count
* sizeof(T
));
89 void circular_buffer_t
<T
>::append(T value
)
94 /////////// remote_bitbang_t
96 remote_bitbang_t::remote_bitbang_t(uint16_t port
, jtag_dtm_t
*tap
) :
103 socket_fd
= socket(AF_INET
, SOCK_STREAM
, 0);
104 if (socket_fd
== -1) {
105 fprintf(stderr
, "remote_bitbang failed to make socket: %s (%d)\n",
106 strerror(errno
), errno
);
110 fcntl(socket_fd
, F_SETFL
, O_NONBLOCK
);
112 if (setsockopt(socket_fd
, SOL_SOCKET
, SO_REUSEADDR
, &reuseaddr
,
113 sizeof(int)) == -1) {
114 fprintf(stderr
, "remote_bitbang failed setsockopt: %s (%d)\n",
115 strerror(errno
), errno
);
119 struct sockaddr_in addr
;
120 memset(&addr
, 0, sizeof(addr
));
121 addr
.sin_family
= AF_INET
;
122 addr
.sin_addr
.s_addr
= INADDR_ANY
;
123 addr
.sin_port
= htons(port
);
125 if (bind(socket_fd
, (struct sockaddr
*) &addr
, sizeof(addr
)) == -1) {
126 fprintf(stderr
, "remote_bitbang failed to bind socket: %s (%d)\n",
127 strerror(errno
), errno
);
131 if (listen(socket_fd
, 1) == -1) {
132 fprintf(stderr
, "remote_bitbang failed to listen on socket: %s (%d)\n",
133 strerror(errno
), errno
);
138 void remote_bitbang_t::accept()
140 client_fd
= ::accept(socket_fd
, NULL
, NULL
);
141 if (client_fd
== -1) {
142 if (errno
== EAGAIN
) {
143 // No client waiting to connect right now.
145 fprintf(stderr
, "failed to accept on socket: %s (%d)\n", strerror(errno
),
150 fcntl(client_fd
, F_SETFL
, O_NONBLOCK
);
154 void remote_bitbang_t::read()
156 // Reading from a non-blocking socket still blocks if there is no data
159 size_t count
= recv_buf
.contiguous_empty_size();
160 ssize_t bytes
= ::read(client_fd
, recv_buf
.contiguous_empty(), count
);
162 if (errno
== EAGAIN
) {
163 // We'll try again the next call.
165 fprintf(stderr
, "failed to read on socket: %s (%d)\n", strerror(errno
), errno
);
168 } else if (bytes
== 0) {
169 // The remote disconnected.
174 recv_buf
.data_added(bytes
);
175 D(fprintf(stderr
, "receive buffer: "));
176 for (unsigned i
= 0; i
< recv_buf
.size(); i
++) {
177 D(fprintf(stderr
, "%c", recv_buf
[i
]));
179 D(fprintf(stderr
, "\n"));
183 void remote_bitbang_t::write()
185 if (send_buf
.empty())
188 while (!send_buf
.empty()) {
189 unsigned int count
= send_buf
.contiguous_data_size();
191 ssize_t bytes
= ::write(client_fd
, send_buf
.contiguous_data(), count
);
193 fprintf(stderr
, "failed to write to socket: %s (%d)\n", strerror(errno
), errno
);
195 } else if (bytes
== 0) {
196 // Client can't take any more data right now.
199 D(fprintf(stderr
, "wrote %zd bytes: ", bytes
));
200 for (int i
= 0; i
< bytes
; i
++) {
201 D(fprintf(stderr
, "%c", send_buf
[i
]));
203 D(fprintf(stderr
, "\n"));
204 send_buf
.consume(bytes
);
209 void remote_bitbang_t::tick()
220 void remote_bitbang_t::process_input()
222 // TODO: get rid of the circular buffers, and just read/write here with
223 // simple local buffers.
224 // Each message is a single character, so there's never any need to keep a
225 // partially transmitted message around.
227 for (unsigned i
= 0; i
< recv_buf
.size(); i
++) {
228 uint8_t command
= recv_buf
[i
];
231 case 'B': fprintf(stderr
, "*BLINK*\n"); break;
232 case 'b': fprintf(stderr
, "_______\n"); break;
233 case 'r': tap
->reset(); break;
234 case '0': tap
->set_pins(0, 0, 0); break;
235 case '1': tap
->set_pins(0, 0, 1); break;
236 case '2': tap
->set_pins(0, 1, 0); break;
237 case '3': tap
->set_pins(0, 1, 1); break;
238 case '4': tap
->set_pins(1, 0, 0); break;
239 case '5': tap
->set_pins(1, 0, 1); break;
240 case '6': tap
->set_pins(1, 1, 0); break;
241 case '7': tap
->set_pins(1, 1, 1); break;
242 case 'R': send_buf
.append(tap
->tdo() ? '1' : '0'); break;
244 fprintf(stderr
, "remote_bitbang got unsupported command '%c'\n", command
);