source: azure_iot_hub_f767zi/trunk/asp_baseplatform/usb/host/BLUETOOTH/tusbh_bluetooth.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 16.0 KB
Line 
1/*
2 * TOPPERS BASE PLATFORM MIDDLEWARE
3 *
4 * Copyright (C) 2017-2018 by TOPPERS PROJECT
5 * Educational Working Group.
6 *
7 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12 * スコード中に含まれていること.
13 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16 * の無保証規定を掲載すること.
17 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19 * と.
20 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
22 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23 * 報告すること.
24 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28 * 免責すること.
29 *
30 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34 * の責任を負わない.
35 *
36 * @(#) $Id$
37 */
38/*
39 * USB Host Middleware BLUETOOTH CLASS部
40 */
41
42#include "tusbh_bluetooth.h"
43
44#define BLUETOOTH_SENDDATA(d, b, l) tusbhControlRequest((d), (b), BLUETOOTH_DATA_TYPE, 0, 0, 0, (l))
45#define ORDER_MASK (BT_INTERRUPT_ORDER | BT_CTLWRITE_ORDER | BT_BLKREAD_ORDER | BT_BLKWRITE_ORDER)
46
47static TUSBH_ERCODE tusbhBLUETOOTHInit(TUSBH_Device_t *pdevice);
48static TUSBH_ERCODE tusbhBLUETOOTHeInit(TUSBH_Device_t *pdevice);
49static TUSBH_ERCODE tusbhBLUETOOTHProcess(TUSBH_Device_t *pdevice, uint8_t *mes);
50
51static TUSBH_Class_t BLUETOOTH_Class = {
52 NULL,
53 "BLUETOOTH",
54 BLUETOOTH_CLASS,
55 tusbhBLUETOOTHInit,
56 tusbhBLUETOOTHeInit,
57 tusbhBLUETOOTHProcess,
58 NULL
59};
60
61/*
62 * SERIALクラスセットアップ関数
63 */
64void tusbhLinkBLUETOOTH(TUSBH_Handle_t *phost)
65{
66 tusbhLinkClass(phost, &BLUETOOTH_Class);
67}
68
69/*
70 * BLUETOOTHクラス初期設定
71 * parameter1 pdevice: デバイスハンドラ
72 * return TUSBH_ERCODE
73 */
74static TUSBH_ERCODE
75tusbhBLUETOOTHInit(TUSBH_Device_t *pdevice)
76{
77 uint8_t interface = 0;
78 BLUETOOTH_Handle_t *hblue;
79 TUSBH_Handle_t *phost = pdevice->pHost;
80 uint8_t max_ep, i;
81
82 interface = tusbhFindInterface(pdevice, pdevice->pClass->classCode, 0x01, 0x01);
83
84 if(interface == NO_INTERFACE){
85 syslog_1(LOG_ERROR, "[BLUETOOTH] Cannot Find the interface for %s class.", pdevice->pClass->Name);
86 return TUSBH_E_ERR;
87 }
88 tusbhSelectInterface(pdevice, interface);
89
90 hblue = (BLUETOOTH_Handle_t *)tusbmalloc(sizeof(BLUETOOTH_Handle_t));
91 pdevice->pData = hblue;
92 memset(hblue, 0, sizeof(BLUETOOTH_Handle_t));
93 max_ep = pdevice->ItfDesc[interface].bNumEndpoints;
94 if(max_ep < 3 || (pdevice->EpDesc[interface][0].bEndpointAddress & 0x80) == 0)
95 return TUSBH_E_ERR;
96
97 hblue->CommInEp = pdevice->EpDesc[interface][0].bEndpointAddress;
98 hblue->CommInEpSize = pdevice->EpDesc[interface][0].wMaxPacketSize;
99 hblue->CommInPipe = tusbhAllocPipe(phost, hblue->CommInEp);
100 hblue->poll = pdevice->EpDesc[interface][0].bInterval;
101
102 if(hblue->poll < BT_MIN_POLL)
103 hblue->poll = BT_MIN_POLL;
104
105 for(i = 1 ; i < max_ep; i++){
106 if(pdevice->EpDesc[interface][i].bEndpointAddress & 0x80){
107 hblue->InEp = (pdevice->EpDesc[interface][i].bEndpointAddress);
108 hblue->InEpSize = pdevice->EpDesc[interface][i].wMaxPacketSize;
109 hblue->InPipe = tusbhAllocPipe(phost, hblue->InEp);
110 }
111 else{
112 hblue->OutEp = (pdevice->EpDesc[interface][i].bEndpointAddress);
113 hblue->OutEpSize = pdevice->EpDesc[interface][i].wMaxPacketSize;
114 hblue->OutPipe = tusbhAllocPipe(phost, hblue->OutEp);
115 }
116 }
117
118 if(hblue->OutPipe == 0 || hblue->InPipe == 0)
119 return TUSBH_E_ERR;
120
121 hblue->state = BLUETOOTH_PROCESS_INIT;
122 hblue->timer = 0;
123 hblue->pDev = pdevice;
124
125 /*
126 * NSCチャネルオープン
127 */
128 tusbhOpenPipe(pdevice, hblue->CommInPipe, hblue->CommInEp, USB_EP_TYPE_INTR, 64);
129 tusbhHDSetToggle(phost, hblue->CommInPipe, 0);
130 tusbhOpenPipe(pdevice, hblue->OutPipe, hblue->OutEp, USB_EP_TYPE_BULK, hblue->OutEpSize);
131 tusbhHDSetToggle(phost, hblue->OutPipe, 0);
132 tusbhOpenPipe(pdevice, hblue->InPipe, hblue->InEp, USB_EP_TYPE_BULK, hblue->InEpSize);
133 tusbhHDSetToggle(phost, hblue->InPipe, 0);
134
135 /* タイマースタート */
136 pdevice->timeid = pdevice->timecount = hblue->poll;
137 return TUSBH_E_OK;
138}
139
140/*
141 * BLUETOOTHクラス終了設定
142 * parameter1 pdevice: デバイスハンドラ
143 * return TUSBH_ERCODE
144 */
145static TUSBH_ERCODE
146tusbhBLUETOOTHeInit(TUSBH_Device_t *pdevice)
147{
148 BLUETOOTH_Handle_t *hblue;
149 TUSBH_Handle_t *phost = pdevice->pHost;
150
151 hblue = (BLUETOOTH_Handle_t *)pdevice->pData;
152 hblue->ifstate &= ~ORDER_MASK;
153 if(hblue->CommInPipe != 0){
154 tusbhClosePipe(pdevice, hblue->CommInPipe);
155 tusbFreePipe(phost, hblue->CommInPipe);
156 hblue->CommInPipe = 0;
157 }
158
159 if(hblue->OutPipe != 0){
160 tusbhClosePipe(pdevice, hblue->OutPipe);
161 tusbFreePipe(phost, hblue->OutPipe);
162 hblue->OutPipe = 0;
163 }
164
165 if(hblue->InPipe != 0){
166 tusbhClosePipe(pdevice, hblue->InPipe);
167 tusbFreePipe(phost, hblue->InPipe);
168 hblue->InPipe = 0;
169 }
170
171 if(pdevice->pData != NULL){
172 tusbfree(pdevice->pData);
173 pdevice->pData = NULL;
174 }
175 return TUSBH_E_OK;
176}
177
178/*
179 * BLUETOOTHクラスプロセス実行
180 * parameter1 pdevice: デバイスハンドラ
181 * parameter2 mes: 通信メッセージへのポインタ
182 * return TUSBH_ERCODE
183 */
184static TUSBH_ERCODE
185tusbhBLUETOOTHProcess(TUSBH_Device_t *pdevice, uint8_t *mes)
186{
187 BLUETOOTH_Handle_t *hblue = (BLUETOOTH_Handle_t *)pdevice->pData;
188 TUSBH_Handle_t *phost = pdevice->pHost;
189 void (*func)(TUSBH_Device_t *, uint8_t, int16_t, uint8_t *) = pdevice->pClass->subfunc;
190 TUSBH_URBState_t URB_Status = mes[3];
191 TUSBH_ERCODE ercd = TUSBH_E_BUSY;
192 uint8_t mesreq = 0;
193 bool_t timereq = false;
194
195 if(mes[0] == TUSBH_TIME_EVENT){
196 hblue->timer += mes[3];
197 pdevice->timeid = pdevice->timecount = hblue->poll;
198 timereq = true;
199 }
200 else if(mes[0] == TUSBH_CLASS_EVENT && mes[2] != 0)
201 hblue->state = mes[2];
202 switch (hblue->state){
203 case BLUETOOTH_PROCESS_INIT:
204 if(phost->usrcallback != NULL)
205 phost->usrcallback(phost, pdevice, HOST_USER_CLASS_ACTIVE);
206 hblue->state = BLUETOOTH_PROCESS_IDLE;
207 case BLUETOOTH_PROCESS_IDLE:
208 if(timereq && (hblue->ifstate & (BT_INTERRUPT_ORDER | BT_INTERRUPT_REQUEST)) == BT_INTERRUPT_ORDER){
209 tusbhInterruptRead(pdevice, &hblue->CommInBuf[0], hblue->CommInEpSize, hblue->CommInPipe);
210 hblue->ifstate |= BT_INTERRUPT_REQUEST;
211 }
212 if(mes[0] != TUSBH_URB_EVENT)
213 break;
214 if(mes[2] == hblue->CommInPipe){ /* interrupt */
215 if(URB_Status == TUSBH_URB_DONE){
216 if(func != NULL)
217 func(pdevice, HCI_EVENT_PACKET, hblue->CommInEpSize, &hblue->CommInBuf[0]);
218 hblue->ifstate &= ~BT_INTERRUPT_REQUEST;
219 }
220 else if(URB_Status == TUSBH_URB_STALL)
221 hblue->state = BLUETOOTH_PROCESS_ERROR;
222 else
223 hblue->ifstate &= ~BT_INTERRUPT_REQUEST;
224 }
225 else if(mes[2] == hblue->InPipe){ /* blk read */
226 if(URB_Status == TUSBH_URB_DONE){
227 if(func != NULL)
228 func(pdevice, HCI_ACL_DATA_PACKET, tusbhHDTrasLength(phost, hblue->InPipe), hblue->pBRecvBuff);
229 }
230 else if(URB_Status == TUSBH_URB_NOTREADY){
231 hblue->ifstate |= BT_BLKREAD_ORDER;
232 mesreq = BLUETOOTH_PROCESS_RECEIVE;
233 }
234 else if(URB_Status == TUSBH_URB_STALL)
235 hblue->state = BLUETOOTH_PROCESS_ERROR;
236 else{
237 if(func != NULL)
238 func(pdevice, HCI_ACL_DATA_PACKET, -1, hblue->pBRecvBuff);
239 }
240 hblue->ifstate &= ~BT_BLKREAD_REQUEST;
241 }
242 else if(mes[2] == hblue->OutPipe){ /* blk write */
243 if(URB_Status == TUSBH_URB_DONE){
244 hblue->BTrnLen += hblue->BTrnCLen;
245 if(hblue->BTrnLen >= hblue->BTrnSize){
246 if(func != NULL)
247 func(pdevice, HCI_SCO_DATA_PACKET, hblue->BTrnSize, NULL);
248 if((hblue->ifstate & (BT_CTLWRITE_ORDER | BT_CTLWRITE_REQUEST)) == BT_CTLWRITE_ORDER)
249 mesreq = BLUETOOTH_PROCESS_SEND;
250 }
251 else{
252 hblue->ifstate |= BT_BLKWRITE_ORDER;
253 mesreq = BLUETOOTH_PROCESS_SEND;
254 }
255 }
256 else if(URB_Status == TUSBH_URB_NOTREADY){
257 hblue->ifstate |= BT_BLKWRITE_ORDER;
258 mesreq = BLUETOOTH_PROCESS_SEND;
259 }
260 else if(URB_Status == TUSBH_URB_STALL)
261 hblue->state = BLUETOOTH_PROCESS_ERROR;
262 else{
263 if(func != NULL)
264 func(pdevice, HCI_SCO_DATA_PACKET, 0, NULL);
265 if((hblue->ifstate & (BT_CTLWRITE_ORDER | BT_CTLWRITE_REQUEST)) == BT_CTLWRITE_ORDER)
266 mesreq = BLUETOOTH_PROCESS_SEND;
267 }
268 hblue->ifstate &= ~BT_BLKWRITE_REQUEST;
269 }
270 else{ /* control write */
271 TUSBH_ERCODE status = tusbhControlWait(pdevice, mes);
272 if(status == TUSBH_E_OK){
273 hblue->ifstate &= ~BT_CTLWRITE_REQUEST;
274 if(func != NULL)
275 func(pdevice, HCI_COMMAND_DATA_PACKET, hblue->CTrnSize, hblue->pCTrnBuff);
276 if((hblue->ifstate & BT_INTERRUPT_STOP) == 0)
277 hblue->ifstate |= BT_INTERRUPT_ORDER;
278 if((hblue->ifstate & (BT_BLKWRITE_ORDER | BT_BLKWRITE_REQUEST)) == BT_BLKWRITE_ORDER)
279 mesreq = BLUETOOTH_PROCESS_SEND;
280 }
281 else if(status != TUSBH_E_BUSY && status != TUSBH_E_BUSY_URB){
282 hblue->state = BLUETOOTH_PROCESS_ERROR;
283 hblue->ifstate &= ~BT_CTLWRITE_REQUEST;
284 }
285 }
286 tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, mesreq, 0);
287 break;
288 case BLUETOOTH_PROCESS_SEND:
289 if((hblue->ifstate & (BT_CTLWRITE_ORDER | BT_CTLWRITE_REQUEST | BT_BLKWRITE_REQUEST)) == BT_CTLWRITE_ORDER){
290 BLUETOOTH_SENDDATA(pdevice, hblue->pCTrnBuff, hblue->CTrnSize);
291 hblue->ifstate |= BT_CTLWRITE_REQUEST;
292 hblue->ifstate &= ~BT_CTLWRITE_ORDER;
293 }
294 if((hblue->ifstate & (BT_BLKWRITE_ORDER | BT_BLKWRITE_REQUEST | BT_CTLWRITE_REQUEST)) == BT_BLKWRITE_ORDER){
295 hblue->BTrnCLen = hblue->BTrnSize - hblue->BTrnLen;
296 if(hblue->BTrnCLen > hblue->OutEpSize)
297 hblue->BTrnCLen = hblue->OutEpSize;
298 tusbhBulkWrite(pdevice, &hblue->pBTrnBuff[hblue->BTrnLen], hblue->BTrnCLen, hblue->OutPipe);
299 hblue->ifstate |= BT_BLKWRITE_REQUEST;
300 hblue->ifstate &= ~BT_BLKWRITE_ORDER;
301 }
302 hblue->state = BLUETOOTH_PROCESS_IDLE;
303 break;
304 case BLUETOOTH_PROCESS_RECEIVE:
305 if((hblue->ifstate & (BT_BLKREAD_ORDER | BT_BLKREAD_REQUEST)) == BT_BLKREAD_ORDER){
306 tusbhBulkRead(pdevice, hblue->pBRecvBuff, hblue->BRecvSize, hblue->InPipe);
307 hblue->ifstate &= ~BT_BLKREAD_ORDER;
308 hblue->ifstate |= BT_BLKREAD_REQUEST;
309 }
310 hblue->state = BLUETOOTH_PROCESS_IDLE;
311 break;
312 case BLUETOOTH_PROCESS_ERROR:
313 break;
314 default:
315 break;
316 }
317 return ercd;
318}
319
320
321/*
322 * BLUETOOTH TRANSFAR READY
323 * parameter1 phost: ホストハンドラ
324 * parameter2 unit: UNIT#
325 * parameter3 mode: 確認モード
326 * return bool
327 */
328bool_t
329tusbhBluetoothTransfarReady(TUSBH_Handle_t *phost, uint8_t unit, uint8_t mode)
330{
331 TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, BLUETOOTH_Class.classCode, &unit);
332 BLUETOOTH_Handle_t *hblue;
333 bool_t result = false;
334
335 if(pdevice != NULL){
336 hblue = pdevice->pData;
337 if(pdevice->dstate != DEVICE_CLASS)
338 return false;
339 if(hblue->state == BLUETOOTH_PROCESS_ERROR)
340 return false;
341 }
342 else
343 return false;
344 switch(mode){
345 case HCI_COMMAND_DATA_PACKET:
346 result = (hblue->ifstate & (BT_CTLWRITE_ORDER | BT_CTLWRITE_REQUEST)) == 0;
347 break;
348 case HCI_ACL_DATA_PACKET:
349 result = (hblue->ifstate & (BT_BLKREAD_ORDER | BT_BLKREAD_REQUEST)) == 0;
350 break;
351 case HCI_SCO_DATA_PACKET:
352 result = (hblue->ifstate & (BT_BLKWRITE_ORDER | BT_BLKWRITE_REQUEST)) == 0;
353 break;
354 case HCI_EVENT_PACKET:
355 result = (hblue->ifstate & BT_INTERRUPT_REQUEST) == 0;
356 break;
357 default:
358 break;
359 }
360 return result;
361}
362
363/*
364 * BLUETOOTH INTERRUPT POLL TIMING
365 * parameter1 phost: ホストハンドラ
366 * parameter2 unit: UNIT#
367 * parameter3 mode: 確認モード
368 * return bool
369 */
370TUSBH_ERCODE
371tusbhBluetoothInterruptPollTiming(TUSBH_Handle_t *phost, uint8_t unit, uint32_t timing)
372{
373 TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, BLUETOOTH_Class.classCode, &unit);
374 BLUETOOTH_Handle_t *hblue;
375
376 if(pdevice != NULL){
377 hblue = pdevice->pData;
378 if(pdevice->dstate != DEVICE_CLASS)
379 return TUSBH_E_OBJ;
380 if(hblue->state == BLUETOOTH_PROCESS_ERROR)
381 return TUSBH_E_ERR;
382 }
383 else
384 return TUSBH_E_OBJ;
385 if(timing == 0){
386 hblue->ifstate |= BT_INTERRUPT_STOP;
387 hblue->ifstate &= ~BT_INTERRUPT_ORDER;
388 }
389 else{
390 if(timing < BT_MIN_POLL)
391 hblue->poll = BT_MIN_POLL;
392 else
393 hblue->poll = timing;
394 hblue->ifstate &= ~BT_INTERRUPT_STOP;
395 hblue->ifstate |= BT_INTERRUPT_ORDER;
396 }
397 return TUSBH_E_OK;
398}
399
400/*
401 * BLUETOOTH DATA SEND
402 * parameter1 phost: ホストハンドラ
403 * parameter2 unit: UNIT#
404 * parameter3 mode: パケットタイプ
405 * parameter4 pbuf: 送信データ領域へのポインタ(cache aline)
406 * parameter5 length: 送信データ長
407 * return TUSBH_ERCODE
408 */
409TUSBH_ERCODE
410tusbhBluetoothSend(TUSBH_Handle_t *phost, uint8_t unit, uint8_t mode, uint8_t *pbuf, uint16_t length)
411{
412 TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, BLUETOOTH_Class.classCode, &unit);
413 BLUETOOTH_Handle_t *hblue;
414
415 if(pdevice != NULL){
416 hblue = pdevice->pData;
417 if(pdevice->dstate != DEVICE_CLASS)
418 return TUSBH_E_OBJ;
419 if(hblue->state == BLUETOOTH_PROCESS_ERROR)
420 return TUSBH_E_ERR;
421 }
422 else
423 return TUSBH_E_OBJ;
424
425 /*
426 * 送信データ設定
427 */
428 if(mode == HCI_COMMAND_DATA_PACKET){
429 if(length > BT_CONTROL_SIZE)
430 return TUSBH_E_PAR;
431 if((hblue->ifstate & BT_CTLWRITE_ORDER) != 0)
432 return TUSBH_E_OBJ;
433 hblue->CTrnSize = length;
434 hblue->pCTrnBuff = pbuf;
435 hblue->ifstate |= BT_CTLWRITE_ORDER;
436 }
437 else if(mode == HCI_SCO_DATA_PACKET){
438 if((hblue->ifstate & BT_BLKWRITE_ORDER) != 0)
439 return TUSBH_E_OBJ;
440 hblue->BTrnSize = length;
441 hblue->BTrnLen = 0;
442 hblue->BTrnCLen = 0;
443 hblue->pBTrnBuff = pbuf;
444 hblue->ifstate |= BT_BLKWRITE_ORDER;
445 }
446 else
447 return TUSBH_E_PAR;
448 tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, BLUETOOTH_PROCESS_SEND, 0);
449 return TUSBH_E_OK;
450}
451
452/*
453 * BLUETOOTH RECEIVE BULK IN
454 * parameter1 phost: ホストハンドラ
455 * parameter2 unit: UNIT#
456 * parameter3 pbuf: 受信データ領域へのポインタ(cache aline)
457 * parameter4 length: 受信データ長
458 * return TUSBH_ERCODE
459 */
460TUSBH_ERCODE
461tusbhBluetoothReceiveBulk(TUSBH_Handle_t *phost, uint8_t unit, uint8_t *pbuf, uint16_t length)
462{
463 TUSBH_Device_t *pdevice = tusbhSearchDevice(phost, BLUETOOTH_Class.classCode, &unit);
464 BLUETOOTH_Handle_t *hblue;
465
466 if(pdevice != NULL){
467 hblue = pdevice->pData;
468 if(pdevice->dstate != DEVICE_CLASS)
469 return TUSBH_E_OBJ;
470 }
471 else
472 return TUSBH_E_OBJ;
473 if(length < hblue->InEpSize)
474 return TUSBH_E_PAR;
475 hblue->BRecvSize = length;
476 hblue->pBRecvBuff = pbuf;
477 hblue->ifstate |= BT_BLKREAD_ORDER;
478 tusbSendData(phost->process_event, TUSBH_CLASS_EVENT, pdevice->idx, BLUETOOTH_PROCESS_RECEIVE, 0);
479 return TUSBH_E_OK;
480}
481
482/*
483 * BLUETOOTHコールバック関数
484 * parameter1 phost: ホストハンドラ
485 * parameter2 func: 関数ポインタ
486 */
487void
488tusbhSetBluetoothCallBack(TUSBH_Handle_t *phost, void (*func)(TUSBH_Device_t *p, uint8_t, int16_t, uint8_t *))
489{
490 BLUETOOTH_Class.subfunc = func;
491}
492
493
Note: See TracBrowser for help on using the repository browser.