~ubuntu-branches/ubuntu/wily/bluez/wily

« back to all changes in this revision

Viewing changes to tools/csr_bcsp.c

  • Committer: Bazaar Package Importer
  • Author(s): Mario Limonciello
  • Date: 2008-10-07 12:10:29 UTC
  • Revision ID: james.westby@ubuntu.com-20081007121029-4gup4fmmh2vfo5nh
Tags: upstream-4.12
ImportĀ upstreamĀ versionĀ 4.12

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 *  BlueZ - Bluetooth protocol stack for Linux
 
4
 *
 
5
 *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org>
 
6
 *
 
7
 *
 
8
 *  This program is free software; you can redistribute it and/or modify
 
9
 *  it under the terms of the GNU General Public License as published by
 
10
 *  the Free Software Foundation; either version 2 of the License, or
 
11
 *  (at your option) any later version.
 
12
 *
 
13
 *  This program is distributed in the hope that it will be useful,
 
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 *  GNU General Public License for more details.
 
17
 *
 
18
 *  You should have received a copy of the GNU General Public License
 
19
 *  along with this program; if not, write to the Free Software
 
20
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
21
 *
 
22
 */
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
#include <config.h>
 
26
#endif
 
27
 
 
28
#include <stdio.h>
 
29
#include <errno.h>
 
30
#include <fcntl.h>
 
31
#include <unistd.h>
 
32
#include <string.h>
 
33
#include <stdint.h>
 
34
#include <termios.h>
 
35
 
 
36
#include "csr.h"
 
37
#include "ubcsp.h"
 
38
 
 
39
static uint16_t seqnum = 0x0000;
 
40
 
 
41
static int fd = -1;
 
42
 
 
43
static struct ubcsp_packet send_packet;
 
44
static uint8_t send_buffer[512];
 
45
 
 
46
static struct ubcsp_packet receive_packet;
 
47
static uint8_t receive_buffer[512];
 
48
 
 
49
int csr_open_bcsp(char *device)
 
50
{
 
51
        struct termios ti;
 
52
        uint8_t delay, activity = 0x00;
 
53
        int timeout = 0;
 
54
 
 
55
        if (!device)
 
56
                device = "/dev/ttyS0";
 
57
 
 
58
        fd = open(device, O_RDWR | O_NOCTTY);
 
59
        if (fd < 0) {
 
60
                fprintf(stderr, "Can't open serial port: %s (%d)\n",
 
61
                                                strerror(errno), errno);
 
62
                return -1;
 
63
        }
 
64
 
 
65
        tcflush(fd, TCIOFLUSH);
 
66
 
 
67
        if (tcgetattr(fd, &ti) < 0) {
 
68
                fprintf(stderr, "Can't get port settings: %s (%d)\n",
 
69
                                                strerror(errno), errno);
 
70
                close(fd);
 
71
                return -1;
 
72
        }
 
73
 
 
74
        cfmakeraw(&ti);
 
75
 
 
76
        ti.c_cflag |=  CLOCAL;
 
77
        ti.c_cflag &= ~CRTSCTS;
 
78
        ti.c_cflag |=  PARENB;
 
79
        ti.c_cflag &= ~PARODD;
 
80
        ti.c_cflag &= ~CSIZE;
 
81
        ti.c_cflag |=  CS8;
 
82
        ti.c_cflag &= ~CSTOPB;
 
83
 
 
84
        ti.c_cc[VMIN] = 1;
 
85
        ti.c_cc[VTIME] = 0;
 
86
 
 
87
        cfsetospeed(&ti, B38400);
 
88
 
 
89
        if (tcsetattr(fd, TCSANOW, &ti) < 0) {
 
90
                fprintf(stderr, "Can't change port settings: %s (%d)\n",
 
91
                                                strerror(errno), errno);
 
92
                close(fd);
 
93
                return -1;
 
94
        }
 
95
 
 
96
        tcflush(fd, TCIOFLUSH);
 
97
 
 
98
        if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) < 0) {
 
99
                fprintf(stderr, "Can't set non blocking mode: %s (%d)\n",
 
100
                                                strerror(errno), errno);
 
101
                close(fd);
 
102
                return -1;
 
103
        }
 
104
 
 
105
        memset(&send_packet, 0, sizeof(send_packet));
 
106
        memset(&receive_packet, 0, sizeof(receive_packet));
 
107
 
 
108
        ubcsp_initialize();
 
109
 
 
110
        send_packet.length = 512;
 
111
        send_packet.payload = send_buffer;
 
112
 
 
113
        receive_packet.length = 512;
 
114
        receive_packet.payload = receive_buffer;
 
115
 
 
116
        ubcsp_receive_packet(&receive_packet);
 
117
 
 
118
        while (1) {
 
119
                delay = ubcsp_poll(&activity);
 
120
 
 
121
                if (activity & UBCSP_PACKET_RECEIVED)
 
122
                        break;
 
123
 
 
124
                if (delay) {
 
125
                        usleep(delay * 100);
 
126
 
 
127
                        if (timeout++ > 100) {
 
128
                                fprintf(stderr, "Initialization timed out\n");
 
129
                                return -1;
 
130
                        }
 
131
                }
 
132
        }
 
133
 
 
134
        return 0;
 
135
}
 
136
 
 
137
void put_uart(uint8_t ch)
 
138
{
 
139
        if (write(fd, &ch, 1) < 0)
 
140
                fprintf(stderr, "UART write error\n");
 
141
}
 
142
 
 
143
uint8_t get_uart(uint8_t *ch)
 
144
{
 
145
        int res = read(fd, ch, 1);
 
146
        return res > 0 ? res : 0;
 
147
}
 
148
 
 
149
static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length)
 
150
{
 
151
        unsigned char cp[254], rp[254];
 
152
        uint8_t cmd[10];
 
153
        uint16_t size;
 
154
        uint8_t delay, activity = 0x00;
 
155
        int timeout = 0, sent = 0;
 
156
 
 
157
        size = (length < 8) ? 9 : ((length + 1) / 2) + 5;
 
158
 
 
159
        cmd[0] = command & 0xff;
 
160
        cmd[1] = command >> 8;
 
161
        cmd[2] = size & 0xff;
 
162
        cmd[3] = size >> 8;
 
163
        cmd[4] = seqnum & 0xff;
 
164
        cmd[5] = seqnum >> 8;
 
165
        cmd[6] = varid & 0xff;
 
166
        cmd[7] = varid >> 8;
 
167
        cmd[8] = 0x00;
 
168
        cmd[9] = 0x00;
 
169
 
 
170
        memset(cp, 0, sizeof(cp));
 
171
        cp[0] = 0x00;
 
172
        cp[1] = 0xfc;
 
173
        cp[2] = (size * 2) + 1;
 
174
        cp[3] = 0xc2;
 
175
        memcpy(cp + 4, cmd, sizeof(cmd));
 
176
        memcpy(cp + 14, value, length);
 
177
 
 
178
        receive_packet.length = 512;
 
179
        ubcsp_receive_packet(&receive_packet);
 
180
 
 
181
        send_packet.channel  = 5;
 
182
        send_packet.reliable = 1;
 
183
        send_packet.length   = (size * 2) + 4;
 
184
        memcpy(send_packet.payload, cp, (size * 2) + 4);
 
185
 
 
186
        ubcsp_send_packet(&send_packet);
 
187
 
 
188
        while (1) {
 
189
                delay = ubcsp_poll(&activity);
 
190
 
 
191
                if (activity & UBCSP_PACKET_SENT) {
 
192
                        switch (varid) {
 
193
                        case CSR_VARID_COLD_RESET:
 
194
                        case CSR_VARID_WARM_RESET:
 
195
                        case CSR_VARID_COLD_HALT:
 
196
                        case CSR_VARID_WARM_HALT:
 
197
                                return 0;
 
198
                        }
 
199
 
 
200
                        sent = 1;
 
201
                        timeout = 0;
 
202
                }
 
203
 
 
204
                if (activity & UBCSP_PACKET_RECEIVED) {
 
205
                        if (sent && receive_packet.channel == 5 &&
 
206
                                        receive_packet.payload[0] == 0xff) {
 
207
                                memcpy(rp, receive_packet.payload,
 
208
                                                        receive_packet.length);
 
209
                                break;
 
210
                        }
 
211
 
 
212
                        receive_packet.length = 512;
 
213
                        ubcsp_receive_packet(&receive_packet);
 
214
                        timeout = 0;
 
215
                }
 
216
 
 
217
                if (delay) {
 
218
                        usleep(delay * 100);
 
219
 
 
220
                        if (timeout++ > 100) {
 
221
                                fprintf(stderr, "Operation timed out\n");
 
222
                                return -1;
 
223
                        }
 
224
                }
 
225
        }
 
226
 
 
227
        if (rp[0] != 0xff || rp[2] != 0xc2) {
 
228
                errno = EIO;
 
229
                return -1;
 
230
        }
 
231
 
 
232
        if ((rp[11] + (rp[12] << 8)) != 0) {
 
233
                errno = ENXIO;
 
234
                return -1;
 
235
        }
 
236
 
 
237
        memcpy(value, rp + 13, length);
 
238
 
 
239
        return 0;
 
240
}
 
241
 
 
242
int csr_read_bcsp(uint16_t varid, uint8_t *value, uint16_t length)
 
243
{
 
244
        return do_command(0x0000, seqnum++, varid, value, length);
 
245
}
 
246
 
 
247
int csr_write_bcsp(uint16_t varid, uint8_t *value, uint16_t length)
 
248
{
 
249
        return do_command(0x0002, seqnum++, varid, value, length);
 
250
}
 
251
 
 
252
void csr_close_bcsp(void)
 
253
{
 
254
        close(fd);
 
255
}