Fork to support Mouse boot protocol and steam controllers.

Fork of USBHOST by ST

Committer:
frq08711@LMECWL0871.LME.ST.COM
Date:
Wed Apr 26 18:11:37 2017 +0200
Revision:
5:fc157e6bd5a5
Parent:
3:1c76b46ad779
update for hub support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 1 /* mbed USBHost Library
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 2 * Copyright (c) 2006-2013 ARM Limited
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 3 *
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 4 * Licensed under the Apache License, Version 2.0 (the "License");
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 5 * you may not use this file except in compliance with the License.
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 6 * You may obtain a copy of the License at
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 7 *
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 8 * http://www.apache.org/licenses/LICENSE-2.0
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 9 *
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 10 * Unless required by applicable law or agreed to in writing, software
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 11 * distributed under the License is distributed on an "AS IS" BASIS,
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 13 * See the License for the specific language governing permissions and
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 14 * limitations under the License.
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 15 */
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 16 #if defined(TARGET_STM) && defined(USBHOST_OTHER)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 17
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 18 #include "dbg.h"
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 19 #include "USBEndpoint.h"
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 20 extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 21 extern uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 22 extern void HAL_HCD_DisableInt(HCD_HandleTypeDef* hhcd, uint8_t chn_num);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 23 extern void HAL_HCD_EnableInt(HCD_HandleTypeDef* hhcd, uint8_t chn_num);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 24
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 25
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 26
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 27
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 28 void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir_, uint32_t size, uint8_t ep_number, HCTD* td_list_[2])
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 29 {
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 30 HCD_HandleTypeDef *hhcd;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 31 uint32_t *addr;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 32
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 33 hced = hced_;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 34 type = type_;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 35 dir = dir_;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 36 setup = (type == CONTROL_ENDPOINT) ? true : false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 37
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 38 //TDs have been allocated by the host
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 39 memcpy((HCTD**)td_list, td_list_, sizeof(HCTD*)*2); //TODO: Maybe should add a param for td_list size... at least a define
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 40 memset(td_list_[0], 0, sizeof(HCTD));
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 41 memset(td_list_[1], 0, sizeof(HCTD));
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 42
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 43 td_list[0]->ep = this;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 44 td_list[1]->ep = this;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 45
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 46 address = (ep_number & 0x7F) | ((dir - 1) << 7);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 47 this->size = size;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 48 this->ep_number = ep_number;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 49 transfer_len = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 50 transferred = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 51 buf_start = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 52 nextEp = NULL;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 53
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 54 td_current = td_list[0];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 55 td_next = td_list[1];
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 56 /* remove potential post pending from previous endpoint */
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 57 ep_queue.get(0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 58 intf_nb = 0;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 59 hhcd = (HCD_HandleTypeDef*)hced->hhcd;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 60 addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 61 *addr = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 62 state = USB_TYPE_IDLE;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 63 speed =false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 64 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 65 void USBEndpoint::setSize(uint32_t size)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 66 {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 67 this->size = size;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 68 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 69
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 70
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 71 void USBEndpoint::setDeviceAddress(uint8_t addr)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 72 {
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 73 HCD_HandleTypeDef *hhcd;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 74 uint8_t hcd_speed = HCD_SPEED_FULL;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 75 /* fix me : small speed device with hub not supported
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 76 if (this->speed) hcd_speed = HCD_SPEED_LOW; */
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 77 if (this->speed) USB_WARN("small speed device on hub not supported");
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 78 MBED_ASSERT(HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, addr, hcd_speed, type, size)!=HAL_BUSY);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 79 this->device_address = addr;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 80
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 81 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 82
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 83 void USBEndpoint::setSpeed(uint8_t speed)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 84 {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 85 this->speed = speed;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 86 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 87
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 88
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 89
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 90 void USBEndpoint::setState(USB_TYPE st)
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 91 {
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 92 /* modify this state is possible only with a plug */
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 93 if ((state == USB_TYPE_FREE)) return;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 94
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 95 state = st;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 96 if (st == USB_TYPE_FREE) {
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 97 HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef*)hced->hhcd;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 98 uint32_t *addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 99 if ((*addr)&& (type!=INTERRUPT_ENDPOINT)) {
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 100 this->ep_queue.put((uint8_t*)1);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 101 }
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 102 MBED_ASSERT(HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num)!=HAL_BUSY);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 103 HAL_HCD_DisableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 104 *addr = 0;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 105
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 106 }
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 107 if ((st == USB_TYPE_ERROR) ) {
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 108 MBED_ASSERT(HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num)!=HAL_BUSY);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 109 HAL_HCD_DisableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 110
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 111 }
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 112 if ((st == USB_TYPE_ERROR) ) {
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 113 uint8_t hcd_speed = HCD_SPEED_FULL;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 114 /* small speed device with hub not supported
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 115 if (this->speed) hcd_speed = HCD_SPEED_LOW;*/
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 116 MBED_ASSERT(HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, 0, hcd_speed, type, size)!=HAL_BUSY);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 117 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 118 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 119
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 120
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 121 extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 122 extern uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 123
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 124
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 125 USB_TYPE USBEndpoint::queueTransfer()
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 126 {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 127 HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef*)hced->hhcd;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 128 uint32_t *addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 129 uint32_t type = HAL_HCD_HC_GetType(hhcd, hced->ch_num);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 130 uint32_t max_size = HAL_HCD_HC_GetMaxPacket(hhcd, hced->ch_num);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 131 /* if a packet is queue on disconnected ; no solution for now */
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 132 if ((state == USB_TYPE_FREE) ) {
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 133 td_current->state = USB_TYPE_FREE;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 134 return USB_TYPE_FREE;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 135 }
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 136 ep_queue.get(0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 137 MBED_ASSERT(*addr ==0);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 138 transfer_len = td_current->size <= max_size ? td_current->size : max_size;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 139 buf_start = (uint8_t *)td_current->currBufPtr;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 140
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 141 //Now add this free TD at this end of the queue
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 142 state = USB_TYPE_PROCESSING;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 143 /* one request */
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 144 td_current->nextTD = (hcTd*)0;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 145 #if defined(MAX_NYET_RETRY)
frq08711@LMECWL0871.LME.ST.COM 3:1c76b46ad779 146 td_current->retry = 0;
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 147 #endif
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 148 td_current->setup = setup;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 149 *addr = (uint32_t)td_current;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 150 /* dir /setup is inverted for ST */
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 151 /* token is useful only ctrl endpoint */
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 152 /* last parameter is ping ? */
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 153 MBED_ASSERT(HAL_HCD_HC_SubmitRequest((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num, dir-1, type,!setup,(uint8_t*) td_current->currBufPtr, transfer_len, 0)==HAL_OK);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 154 HAL_HCD_EnableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 155
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 156 return USB_TYPE_PROCESSING;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 157 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 158
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 159 void USBEndpoint::unqueueTransfer(volatile HCTD * td)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 160 {
frq08711@LMECWL0871.LME.ST.COM 5:fc157e6bd5a5 161 if (state==USB_TYPE_FREE) return;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 162 uint32_t *addr = &((uint32_t *)((HCD_HandleTypeDef*)hced->hhcd)->pData)[hced->ch_num];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 163 td->state=0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 164 td->currBufPtr=0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 165 td->size=0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 166 td->nextTD=0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 167 *addr = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 168 td_current = td_next;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 169 td_next = td;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 170 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 171
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 172 void USBEndpoint::queueEndpoint(USBEndpoint * ed)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 173 {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 174 nextEp = ed;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 175 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 176 #endif