PHS module SMA-01 library. see: https://developer.mbed.org/users/phsfan/notebook/abitusbmodem/

Dependencies:   Socket lwip-sys lwip

Dependents:   AbitUSBModem_HTTPTest AbitUSBModem_MQTTTest AbitUSBModem_WebsocketTest AbitUSBModem_SMSTest

Fork of VodafoneUSBModem by mbed official

/media/uploads/phsfan/sma01_003.png

Committer:
phsfan
Date:
Wed Feb 25 14:34:13 2015 +0000
Revision:
99:514e67a69ad6
Parent:
97:7d9cc95e2ea7
supported SMS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
phsfan 97:7d9cc95e2ea7 1 /* USBHostPhs.cpp */
phsfan 97:7d9cc95e2ea7 2 /* Modified by 2015 phsfan
phsfan 97:7d9cc95e2ea7 3 * for ABIT SMA-01
phsfan 97:7d9cc95e2ea7 4 */
phsfan 96:b50f5f795684 5 /* mbed USBHost Library
phsfan 96:b50f5f795684 6 * Copyright (c) 2006-2013 ARM Limited
phsfan 96:b50f5f795684 7 *
phsfan 96:b50f5f795684 8 * Licensed under the Apache License, Version 2.0 (the "License");
phsfan 96:b50f5f795684 9 * you may not use this file except in compliance with the License.
phsfan 96:b50f5f795684 10 * You may obtain a copy of the License at
phsfan 96:b50f5f795684 11 *
phsfan 96:b50f5f795684 12 * http://www.apache.org/licenses/LICENSE-2.0
phsfan 96:b50f5f795684 13 *
phsfan 96:b50f5f795684 14 * Unless required by applicable law or agreed to in writing, software
phsfan 96:b50f5f795684 15 * distributed under the License is distributed on an "AS IS" BASIS,
phsfan 96:b50f5f795684 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
phsfan 96:b50f5f795684 17 * See the License for the specific language governing permissions and
phsfan 96:b50f5f795684 18 * limitations under the License.
phsfan 96:b50f5f795684 19 */
phsfan 96:b50f5f795684 20
phsfan 97:7d9cc95e2ea7 21 /* WANDongle.cpp, WANDongleSerialPort.cpp */
phsfan 97:7d9cc95e2ea7 22 /* Copyright (c) 2010-2012 mbed.org, MIT License
phsfan 97:7d9cc95e2ea7 23 *
phsfan 97:7d9cc95e2ea7 24 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
phsfan 97:7d9cc95e2ea7 25 * and associated documentation files (the "Software"), to deal in the Software without
phsfan 97:7d9cc95e2ea7 26 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
phsfan 97:7d9cc95e2ea7 27 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
phsfan 97:7d9cc95e2ea7 28 * Software is furnished to do so, subject to the following conditions:
phsfan 97:7d9cc95e2ea7 29 *
phsfan 97:7d9cc95e2ea7 30 * The above copyright notice and this permission notice shall be included in all copies or
phsfan 97:7d9cc95e2ea7 31 * substantial portions of the Software.
phsfan 97:7d9cc95e2ea7 32 *
phsfan 97:7d9cc95e2ea7 33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
phsfan 97:7d9cc95e2ea7 34 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
phsfan 97:7d9cc95e2ea7 35 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
phsfan 97:7d9cc95e2ea7 36 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
phsfan 97:7d9cc95e2ea7 37 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
phsfan 97:7d9cc95e2ea7 38 */
phsfan 97:7d9cc95e2ea7 39
phsfan 96:b50f5f795684 40
phsfan 96:b50f5f795684 41 #define __DEBUG__ 0
phsfan 96:b50f5f795684 42 #ifndef __MODULE__
phsfan 96:b50f5f795684 43 #define __MODULE__ "USBHostPhs.cpp"
phsfan 96:b50f5f795684 44 #endif
phsfan 96:b50f5f795684 45
phsfan 96:b50f5f795684 46 #include "core/dbg.h"
phsfan 96:b50f5f795684 47 #include <cstdint>
phsfan 96:b50f5f795684 48 #include "rtos.h"
phsfan 96:b50f5f795684 49
phsfan 96:b50f5f795684 50 #include "USBHostPhs.h"
phsfan 96:b50f5f795684 51
phsfan 96:b50f5f795684 52 #define CHECK_INTERFACE(cls,subcls,proto) \
phsfan 96:b50f5f795684 53 (((cls == 0xFF) && (subcls == 0xFF) && (proto == 0xFF)) /* QUALCOM CDC */ || \
phsfan 96:b50f5f795684 54 ((cls == SERIAL_CLASS) && (subcls == 0x00) && (proto == 0x00)) /* STANDARD CDC */ )
phsfan 96:b50f5f795684 55
phsfan 96:b50f5f795684 56 USBHostPhs::USBHostPhs()
phsfan 96:b50f5f795684 57 {
phsfan 96:b50f5f795684 58 host = USBHost::getHostInst();
phsfan 96:b50f5f795684 59 ports_found = 0;
phsfan 96:b50f5f795684 60 dev_connected = false;
phsfan 96:b50f5f795684 61 }
phsfan 96:b50f5f795684 62
phsfan 96:b50f5f795684 63 bool USBHostPhs::connected()
phsfan 96:b50f5f795684 64 {
phsfan 96:b50f5f795684 65 return dev_connected;
phsfan 96:b50f5f795684 66 }
phsfan 96:b50f5f795684 67
phsfan 96:b50f5f795684 68 void USBHostPhs::disconnect(void)
phsfan 96:b50f5f795684 69 {
phsfan 96:b50f5f795684 70 USBHostPhsPort::reset();
phsfan 96:b50f5f795684 71 ports_found = 0;
phsfan 96:b50f5f795684 72 dev = NULL;
phsfan 96:b50f5f795684 73 }
phsfan 96:b50f5f795684 74
phsfan 96:b50f5f795684 75 bool USBHostPhs::connect() {
phsfan 96:b50f5f795684 76
phsfan 96:b50f5f795684 77 if (dev)
phsfan 96:b50f5f795684 78 {
phsfan 96:b50f5f795684 79 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
phsfan 96:b50f5f795684 80 {
phsfan 96:b50f5f795684 81 USBDeviceConnected* d = host->getDevice(i);
phsfan 96:b50f5f795684 82 if (dev == d)
phsfan 96:b50f5f795684 83 return true;
phsfan 96:b50f5f795684 84 }
phsfan 96:b50f5f795684 85 disconnect();
phsfan 96:b50f5f795684 86 }
phsfan 96:b50f5f795684 87 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
phsfan 96:b50f5f795684 88 {
phsfan 96:b50f5f795684 89 USBDeviceConnected* d = host->getDevice(i);
phsfan 96:b50f5f795684 90 if (d != NULL) {
phsfan 96:b50f5f795684 91
phsfan 96:b50f5f795684 92 USB_DBG("Trying to connect serial device \r\n");
phsfan 96:b50f5f795684 93 if(host->enumerate(d, this))
phsfan 96:b50f5f795684 94 break;
phsfan 96:b50f5f795684 95 DBG("Device has VID:%04x PID:%04x", d->getVid(), d->getPid());
phsfan 96:b50f5f795684 96 if ((d->getVid() != PHS_VID) || (d->getPid() != PHS_PID)) break;
phsfan 96:b50f5f795684 97
phsfan 96:b50f5f795684 98 USBEndpoint* bulk_in = d->getEndpoint(port_intf, BULK_ENDPOINT, IN);
phsfan 96:b50f5f795684 99 USBEndpoint* bulk_out = d->getEndpoint(port_intf, BULK_ENDPOINT, OUT);
phsfan 96:b50f5f795684 100 if (bulk_in && bulk_out)
phsfan 96:b50f5f795684 101 {
phsfan 96:b50f5f795684 102 USBHostPhsPort::connect(host,d,port_intf,bulk_in, bulk_out);
phsfan 96:b50f5f795684 103 dev = d;
phsfan 96:b50f5f795684 104 dev_connected = true;
phsfan 96:b50f5f795684 105 DBG("Device connected");
phsfan 96:b50f5f795684 106 }
phsfan 96:b50f5f795684 107 }
phsfan 96:b50f5f795684 108 }
phsfan 96:b50f5f795684 109 return dev != NULL;
phsfan 96:b50f5f795684 110 }
phsfan 96:b50f5f795684 111
phsfan 96:b50f5f795684 112 /*virtual*/ void USBHostPhs::setVidPid(uint16_t vid, uint16_t pid)
phsfan 96:b50f5f795684 113 {
phsfan 96:b50f5f795684 114 // we don't check VID/PID for MSD driver
phsfan 96:b50f5f795684 115 }
phsfan 96:b50f5f795684 116
phsfan 96:b50f5f795684 117 /*virtual*/ bool USBHostPhs::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
phsfan 96:b50f5f795684 118 {
phsfan 96:b50f5f795684 119 if (!ports_found &&
phsfan 96:b50f5f795684 120 CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
phsfan 96:b50f5f795684 121 port_intf = intf_nb;
phsfan 96:b50f5f795684 122 ports_found = true;
phsfan 96:b50f5f795684 123 return true;
phsfan 96:b50f5f795684 124 }
phsfan 96:b50f5f795684 125 return false;
phsfan 96:b50f5f795684 126 }
phsfan 96:b50f5f795684 127
phsfan 96:b50f5f795684 128 /*virtual*/ bool USBHostPhs::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
phsfan 96:b50f5f795684 129 {
phsfan 96:b50f5f795684 130 if (ports_found && (intf_nb == port_intf)) {
phsfan 96:b50f5f795684 131 if (type == BULK_ENDPOINT)
phsfan 96:b50f5f795684 132 return true;
phsfan 96:b50f5f795684 133 }
phsfan 96:b50f5f795684 134 return false;
phsfan 96:b50f5f795684 135 }
phsfan 96:b50f5f795684 136
phsfan 96:b50f5f795684 137 //------------------------------------------------------------------------------
phsfan 96:b50f5f795684 138
phsfan 96:b50f5f795684 139 #define SET_LINE_CODING 0x20
phsfan 96:b50f5f795684 140
phsfan 96:b50f5f795684 141 USBHostPhsPort::USBHostPhsPort() : cb_tx_en(false), cb_rx_en(false), listener(NULL)
phsfan 96:b50f5f795684 142 {
phsfan 96:b50f5f795684 143 init();
phsfan 96:b50f5f795684 144 reset();
phsfan 96:b50f5f795684 145 }
phsfan 96:b50f5f795684 146
phsfan 96:b50f5f795684 147 void USBHostPhsPort::init(void)
phsfan 96:b50f5f795684 148 {
phsfan 96:b50f5f795684 149 host = NULL;
phsfan 96:b50f5f795684 150 dev = NULL;
phsfan 96:b50f5f795684 151 serial_intf = NULL;
phsfan 96:b50f5f795684 152 size_bulk_in = 0;
phsfan 96:b50f5f795684 153 size_bulk_out = 0;
phsfan 96:b50f5f795684 154 bulk_in = NULL;
phsfan 96:b50f5f795684 155 bulk_out = NULL;
phsfan 96:b50f5f795684 156 line_coding.baudrate = 921600;
phsfan 96:b50f5f795684 157 line_coding.data_bits = 8;
phsfan 96:b50f5f795684 158 line_coding.parity = None;
phsfan 96:b50f5f795684 159 line_coding.stop_bits = 1;
phsfan 96:b50f5f795684 160 }
phsfan 96:b50f5f795684 161
phsfan 96:b50f5f795684 162 void USBHostPhsPort::connect(USBHost* _host, USBDeviceConnected * _dev,
phsfan 96:b50f5f795684 163 uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out)
phsfan 96:b50f5f795684 164 {
phsfan 96:b50f5f795684 165 host = _host;
phsfan 96:b50f5f795684 166 dev = _dev;
phsfan 96:b50f5f795684 167 serial_intf = _serial_intf;
phsfan 96:b50f5f795684 168 bulk_in = _bulk_in;
phsfan 96:b50f5f795684 169 bulk_out = _bulk_out;
phsfan 96:b50f5f795684 170
phsfan 96:b50f5f795684 171 max_out_size = bulk_out->getSize();
phsfan 96:b50f5f795684 172 if( max_out_size > WANDONGLE_MAX_OUTEP_SIZE )
phsfan 96:b50f5f795684 173 {
phsfan 96:b50f5f795684 174 max_out_size = WANDONGLE_MAX_OUTEP_SIZE;
phsfan 96:b50f5f795684 175 }
phsfan 96:b50f5f795684 176
phsfan 96:b50f5f795684 177 USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf);
phsfan 96:b50f5f795684 178 dev->setName("Serial", serial_intf);
phsfan 96:b50f5f795684 179 host->registerDriver(dev, serial_intf, this, &USBHostPhsPort::init);
phsfan 96:b50f5f795684 180 baud(921600);
phsfan 96:b50f5f795684 181 size_bulk_in = bulk_in->getSize();
phsfan 96:b50f5f795684 182 size_bulk_out = bulk_out->getSize();
phsfan 96:b50f5f795684 183 bulk_in->attach(this, &USBHostPhsPort::rxHandler);
phsfan 96:b50f5f795684 184 bulk_out->attach(this, &USBHostPhsPort::txHandler);
phsfan 96:b50f5f795684 185
phsfan 96:b50f5f795684 186 readPacket(); //Start receiving data
phsfan 96:b50f5f795684 187 }
phsfan 96:b50f5f795684 188
phsfan 96:b50f5f795684 189 void USBHostPhsPort::rxHandler() {
phsfan 96:b50f5f795684 190 if (((USBEndpoint *) bulk_in)->getState() == USB_TYPE_IDLE) //Success
phsfan 96:b50f5f795684 191 {
phsfan 96:b50f5f795684 192 buf_in_read_pos = 0;
phsfan 96:b50f5f795684 193 buf_in_len = ((USBEndpoint *) bulk_in)->getLengthTransferred(); //Update length
phsfan 96:b50f5f795684 194 //lock_rx.unlock();
phsfan 96:b50f5f795684 195 rx_mtx.lock();
phsfan 96:b50f5f795684 196 lock_rx = false; //Transmission complete
phsfan 96:b50f5f795684 197 if(cb_rx_en)
phsfan 96:b50f5f795684 198 {
phsfan 96:b50f5f795684 199 rx_mtx.unlock();
phsfan 96:b50f5f795684 200 listener->readable(); //Call handler from the IRQ context
phsfan 96:b50f5f795684 201 //readPacket() should be called by the handler subsequently once the buffer has been emptied
phsfan 96:b50f5f795684 202 }
phsfan 96:b50f5f795684 203 else
phsfan 96:b50f5f795684 204 {
phsfan 96:b50f5f795684 205 cb_rx_pending = true; //Queue the callback
phsfan 96:b50f5f795684 206 rx_mtx.unlock();
phsfan 96:b50f5f795684 207 }
phsfan 96:b50f5f795684 208
phsfan 96:b50f5f795684 209 }
phsfan 96:b50f5f795684 210 else //Error, try reading again
phsfan 96:b50f5f795684 211 {
phsfan 96:b50f5f795684 212 //lock_rx.unlock();
phsfan 96:b50f5f795684 213 DBG("Trying again");
phsfan 96:b50f5f795684 214 readPacket();
phsfan 96:b50f5f795684 215 }
phsfan 96:b50f5f795684 216 }
phsfan 96:b50f5f795684 217
phsfan 96:b50f5f795684 218 void USBHostPhsPort::txHandler() {
phsfan 96:b50f5f795684 219 if (((USBEndpoint *) bulk_out)->getState() == USB_TYPE_IDLE) //Success
phsfan 96:b50f5f795684 220 {
phsfan 96:b50f5f795684 221 tx_mtx.lock();
phsfan 96:b50f5f795684 222 buf_out_len = 0; //Reset length
phsfan 96:b50f5f795684 223 lock_tx = false; //Transmission complete
phsfan 96:b50f5f795684 224 //lock_tx.unlock();
phsfan 96:b50f5f795684 225 if(cb_tx_en)
phsfan 96:b50f5f795684 226 {
phsfan 96:b50f5f795684 227 tx_mtx.unlock();
phsfan 96:b50f5f795684 228 listener->writeable(); //Call handler from the IRQ context
phsfan 96:b50f5f795684 229 //writePacket() should be called by the handler subsequently once the buffer has been filled
phsfan 96:b50f5f795684 230 }
phsfan 96:b50f5f795684 231 else
phsfan 96:b50f5f795684 232 {
phsfan 96:b50f5f795684 233 cb_tx_pending = true; //Queue the callback
phsfan 96:b50f5f795684 234 tx_mtx.unlock();
phsfan 96:b50f5f795684 235 }
phsfan 96:b50f5f795684 236 }
phsfan 96:b50f5f795684 237 else //Error, try reading again
phsfan 96:b50f5f795684 238 {
phsfan 96:b50f5f795684 239 //lock_tx.unlock();
phsfan 96:b50f5f795684 240 writePacket();
phsfan 96:b50f5f795684 241 }
phsfan 96:b50f5f795684 242 }
phsfan 96:b50f5f795684 243
phsfan 96:b50f5f795684 244 void USBHostPhsPort::baud(int baudrate) {
phsfan 96:b50f5f795684 245 line_coding.baudrate = baudrate;
phsfan 96:b50f5f795684 246 format(line_coding.data_bits, (Parity)line_coding.parity, line_coding.stop_bits);
phsfan 96:b50f5f795684 247 }
phsfan 96:b50f5f795684 248
phsfan 96:b50f5f795684 249 void USBHostPhsPort::format(int bits, Parity parity, int stop_bits) {
phsfan 96:b50f5f795684 250 line_coding.data_bits = bits;
phsfan 96:b50f5f795684 251 line_coding.parity = parity;
phsfan 96:b50f5f795684 252 line_coding.stop_bits = (stop_bits == 1) ? 0 : 2;
phsfan 96:b50f5f795684 253
phsfan 96:b50f5f795684 254 // set line coding
phsfan 96:b50f5f795684 255 host->controlWrite( dev,
phsfan 96:b50f5f795684 256 USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
phsfan 96:b50f5f795684 257 SET_LINE_CODING,
phsfan 96:b50f5f795684 258 0, serial_intf, (uint8_t *)&line_coding, 7);
phsfan 96:b50f5f795684 259 }
phsfan 96:b50f5f795684 260
phsfan 96:b50f5f795684 261
phsfan 96:b50f5f795684 262 void USBHostPhsPort::reset()
phsfan 96:b50f5f795684 263 {
phsfan 96:b50f5f795684 264 tx_mtx.lock();
phsfan 96:b50f5f795684 265 rx_mtx.lock();
phsfan 96:b50f5f795684 266
phsfan 96:b50f5f795684 267 buf_out_len = 0;
phsfan 96:b50f5f795684 268 max_out_size = 0;
phsfan 96:b50f5f795684 269 lock_tx = false;
phsfan 96:b50f5f795684 270 cb_tx_pending = false;
phsfan 96:b50f5f795684 271
phsfan 96:b50f5f795684 272 buf_in_len = 0;
phsfan 96:b50f5f795684 273 buf_in_read_pos = 0;
phsfan 96:b50f5f795684 274 lock_rx = false;
phsfan 96:b50f5f795684 275 cb_rx_pending = false;
phsfan 96:b50f5f795684 276
phsfan 96:b50f5f795684 277 tx_mtx.unlock();
phsfan 96:b50f5f795684 278 rx_mtx.unlock();
phsfan 96:b50f5f795684 279 }
phsfan 96:b50f5f795684 280
phsfan 96:b50f5f795684 281 int USBHostPhsPort::readPacket()
phsfan 96:b50f5f795684 282 {
phsfan 96:b50f5f795684 283 DBG("Read packet on %p", this);
phsfan 96:b50f5f795684 284 rx_mtx.lock();
phsfan 96:b50f5f795684 285 if(lock_rx)
phsfan 96:b50f5f795684 286 {
phsfan 96:b50f5f795684 287 ERR("Fail");
phsfan 96:b50f5f795684 288 rx_mtx.unlock();
phsfan 96:b50f5f795684 289 return -1;
phsfan 96:b50f5f795684 290 }
phsfan 96:b50f5f795684 291
phsfan 96:b50f5f795684 292 if( bulk_in == NULL )
phsfan 96:b50f5f795684 293 {
phsfan 96:b50f5f795684 294 WARN("Port is disconnected");
phsfan 96:b50f5f795684 295 rx_mtx.unlock();
phsfan 96:b50f5f795684 296 return -1;
phsfan 96:b50f5f795684 297 }
phsfan 96:b50f5f795684 298
phsfan 96:b50f5f795684 299 lock_rx = true; //Receiving
phsfan 96:b50f5f795684 300 rx_mtx.unlock();
phsfan 96:b50f5f795684 301 // DBG("readPacket");
phsfan 96:b50f5f795684 302 //lock_rx.lock();
phsfan 96:b50f5f795684 303 USB_TYPE res = host->bulkRead(dev, (USBEndpoint *)bulk_in, buf_in, ((USBEndpoint *)bulk_in)->getSize(), false); //Queue transfer
phsfan 96:b50f5f795684 304 #if __DEBUG__ >= 5
phsfan 96:b50f5f795684 305 printf(" - bulkRead:");
phsfan 96:b50f5f795684 306 for (int i = 0; i < buf_in_len; i ++) {
phsfan 96:b50f5f795684 307 if (buf_in[i] >= 0x20 && buf_in[i] < 0x7f) {
phsfan 96:b50f5f795684 308 printf(" %c", buf_in[i]);
phsfan 96:b50f5f795684 309 } else {
phsfan 96:b50f5f795684 310 printf(" %02x", buf_in[i]);
phsfan 96:b50f5f795684 311 }
phsfan 96:b50f5f795684 312 }
phsfan 96:b50f5f795684 313 printf("\r\n");
phsfan 96:b50f5f795684 314 #endif
phsfan 96:b50f5f795684 315 if(res != USB_TYPE_PROCESSING)
phsfan 96:b50f5f795684 316 {
phsfan 96:b50f5f795684 317 //lock_rx.unlock();
phsfan 96:b50f5f795684 318 ERR("host->bulkRead() returned %d", res);
phsfan 96:b50f5f795684 319 Thread::wait(100);
phsfan 96:b50f5f795684 320 return -1;
phsfan 96:b50f5f795684 321 }
phsfan 96:b50f5f795684 322 return 0;
phsfan 96:b50f5f795684 323 }
phsfan 96:b50f5f795684 324
phsfan 96:b50f5f795684 325 int USBHostPhsPort::writePacket()
phsfan 96:b50f5f795684 326 {
phsfan 96:b50f5f795684 327 tx_mtx.lock();
phsfan 96:b50f5f795684 328 if(lock_tx)
phsfan 96:b50f5f795684 329 {
phsfan 96:b50f5f795684 330 ERR("Fail");
phsfan 96:b50f5f795684 331 tx_mtx.unlock();
phsfan 96:b50f5f795684 332 return -1;
phsfan 96:b50f5f795684 333 }
phsfan 96:b50f5f795684 334
phsfan 96:b50f5f795684 335 if( bulk_out == NULL )
phsfan 96:b50f5f795684 336 {
phsfan 96:b50f5f795684 337 WARN("Port is disconnected");
phsfan 96:b50f5f795684 338 tx_mtx.unlock();
phsfan 96:b50f5f795684 339 return -1;
phsfan 96:b50f5f795684 340 }
phsfan 96:b50f5f795684 341
phsfan 96:b50f5f795684 342 lock_tx = true; //Transmitting
phsfan 96:b50f5f795684 343 tx_mtx.unlock();
phsfan 96:b50f5f795684 344 // DBG("writePacket");
phsfan 96:b50f5f795684 345
phsfan 96:b50f5f795684 346 //lock_tx.lock();
phsfan 96:b50f5f795684 347 USB_TYPE res = host->bulkWrite(dev, (USBEndpoint *)bulk_out, buf_out, buf_out_len, false); //Queue transfer
phsfan 96:b50f5f795684 348 #if __DEBUG__ >= 5
phsfan 96:b50f5f795684 349 printf(" - bulkWrite:");
phsfan 96:b50f5f795684 350 for (int i = 0; i < buf_out_len; i ++) {
phsfan 96:b50f5f795684 351 if (buf_out[i] >= 0x20 && buf_out[i] < 0x7f) {
phsfan 96:b50f5f795684 352 printf(" %c", buf_out[i]);
phsfan 96:b50f5f795684 353 } else {
phsfan 96:b50f5f795684 354 printf(" %02x", buf_out[i]);
phsfan 96:b50f5f795684 355 }
phsfan 96:b50f5f795684 356 }
phsfan 96:b50f5f795684 357 printf("\r\n");
phsfan 96:b50f5f795684 358 #endif
phsfan 96:b50f5f795684 359 if(res != USB_TYPE_PROCESSING)
phsfan 96:b50f5f795684 360 {
phsfan 96:b50f5f795684 361 //lock_tx.unlock();
phsfan 96:b50f5f795684 362 ERR("host->bulkWrite() returned %d", res);
phsfan 96:b50f5f795684 363 Thread::wait(100);
phsfan 96:b50f5f795684 364 return -1;
phsfan 96:b50f5f795684 365 }
phsfan 96:b50f5f795684 366 return 0;
phsfan 96:b50f5f795684 367 }
phsfan 96:b50f5f795684 368
phsfan 96:b50f5f795684 369 int USBHostPhsPort::putc(int c)
phsfan 96:b50f5f795684 370 {
phsfan 96:b50f5f795684 371 tx_mtx.lock();
phsfan 96:b50f5f795684 372 if(!lock_tx)
phsfan 96:b50f5f795684 373 {
phsfan 96:b50f5f795684 374 if(buf_out_len < max_out_size)
phsfan 96:b50f5f795684 375 {
phsfan 96:b50f5f795684 376 buf_out[buf_out_len] = (uint8_t)c;
phsfan 96:b50f5f795684 377 buf_out_len++;
phsfan 96:b50f5f795684 378 }
phsfan 96:b50f5f795684 379 }
phsfan 96:b50f5f795684 380 else
phsfan 96:b50f5f795684 381 {
phsfan 96:b50f5f795684 382 ERR("CAN'T WRITE!");
phsfan 96:b50f5f795684 383 }
phsfan 96:b50f5f795684 384 tx_mtx.unlock();
phsfan 96:b50f5f795684 385 return c;
phsfan 96:b50f5f795684 386 }
phsfan 96:b50f5f795684 387
phsfan 96:b50f5f795684 388 int USBHostPhsPort::getc()
phsfan 96:b50f5f795684 389 {
phsfan 96:b50f5f795684 390 rx_mtx.lock();
phsfan 96:b50f5f795684 391 int c = 0;
phsfan 96:b50f5f795684 392 if(!lock_rx)
phsfan 96:b50f5f795684 393 {
phsfan 96:b50f5f795684 394 if(buf_in_read_pos < buf_in_len)
phsfan 96:b50f5f795684 395 {
phsfan 96:b50f5f795684 396 c = (int)buf_in[buf_in_read_pos];
phsfan 96:b50f5f795684 397 buf_in_read_pos++;
phsfan 96:b50f5f795684 398 }
phsfan 96:b50f5f795684 399 }
phsfan 96:b50f5f795684 400 else
phsfan 96:b50f5f795684 401 {
phsfan 96:b50f5f795684 402 ERR("CAN'T READ!");
phsfan 96:b50f5f795684 403 }
phsfan 96:b50f5f795684 404 rx_mtx.unlock();
phsfan 96:b50f5f795684 405 return c;
phsfan 96:b50f5f795684 406 }
phsfan 96:b50f5f795684 407
phsfan 96:b50f5f795684 408 int USBHostPhsPort::readable()
phsfan 96:b50f5f795684 409 {
phsfan 96:b50f5f795684 410 rx_mtx.lock();
phsfan 96:b50f5f795684 411 if (lock_rx)
phsfan 96:b50f5f795684 412 {
phsfan 96:b50f5f795684 413 rx_mtx.unlock();
phsfan 96:b50f5f795684 414 return 0;
phsfan 96:b50f5f795684 415 }
phsfan 96:b50f5f795684 416
phsfan 96:b50f5f795684 417 /* if( !lock_rx.trylock() )
phsfan 96:b50f5f795684 418 {
phsfan 96:b50f5f795684 419 return 0;
phsfan 96:b50f5f795684 420 }*/
phsfan 96:b50f5f795684 421 int res = buf_in_len - buf_in_read_pos;
phsfan 96:b50f5f795684 422 //lock_rx.unlock();
phsfan 96:b50f5f795684 423 rx_mtx.unlock();
phsfan 96:b50f5f795684 424 return res;
phsfan 96:b50f5f795684 425 }
phsfan 96:b50f5f795684 426
phsfan 96:b50f5f795684 427 int USBHostPhsPort::writeable()
phsfan 96:b50f5f795684 428 {
phsfan 96:b50f5f795684 429 tx_mtx.lock();
phsfan 96:b50f5f795684 430 if (lock_tx)
phsfan 96:b50f5f795684 431 {
phsfan 96:b50f5f795684 432 tx_mtx.unlock();
phsfan 96:b50f5f795684 433 return 0;
phsfan 96:b50f5f795684 434 }
phsfan 96:b50f5f795684 435
phsfan 96:b50f5f795684 436 /*if( !lock_tx.trylock() )
phsfan 96:b50f5f795684 437 {
phsfan 96:b50f5f795684 438 return 0;
phsfan 96:b50f5f795684 439 }*/
phsfan 96:b50f5f795684 440 int res = max_out_size - buf_out_len;
phsfan 96:b50f5f795684 441 tx_mtx.unlock();
phsfan 96:b50f5f795684 442 //lock_tx.unlock();
phsfan 96:b50f5f795684 443 return res;
phsfan 96:b50f5f795684 444 }
phsfan 96:b50f5f795684 445
phsfan 96:b50f5f795684 446 void USBHostPhsPort::attach(IUSBHostSerialListener* pListener)
phsfan 96:b50f5f795684 447 {
phsfan 96:b50f5f795684 448 if(pListener == NULL)
phsfan 96:b50f5f795684 449 {
phsfan 96:b50f5f795684 450 setupIrq(false, IUSBHostSerial::RxIrq);
phsfan 96:b50f5f795684 451 setupIrq(false, IUSBHostSerial::TxIrq);
phsfan 96:b50f5f795684 452 }
phsfan 96:b50f5f795684 453 listener = pListener;
phsfan 96:b50f5f795684 454 if(pListener != NULL)
phsfan 96:b50f5f795684 455 {
phsfan 96:b50f5f795684 456 setupIrq(true, IUSBHostSerial::RxIrq);
phsfan 96:b50f5f795684 457 setupIrq(true, IUSBHostSerial::TxIrq);
phsfan 96:b50f5f795684 458 }
phsfan 96:b50f5f795684 459 }
phsfan 96:b50f5f795684 460
phsfan 96:b50f5f795684 461 void USBHostPhsPort::setupIrq(bool en, IUSBHostSerial::IrqType irq /*= RxIrq*/)
phsfan 96:b50f5f795684 462 {
phsfan 96:b50f5f795684 463 switch(irq)
phsfan 96:b50f5f795684 464 {
phsfan 96:b50f5f795684 465 case IUSBHostSerial::RxIrq:
phsfan 96:b50f5f795684 466 rx_mtx.lock();
phsfan 96:b50f5f795684 467 cb_rx_en = en;
phsfan 96:b50f5f795684 468 if(en && cb_rx_pending)
phsfan 96:b50f5f795684 469 {
phsfan 96:b50f5f795684 470 cb_rx_pending = false;
phsfan 96:b50f5f795684 471 rx_mtx.unlock();
phsfan 96:b50f5f795684 472 listener->readable(); //Process the interrupt that was raised
phsfan 96:b50f5f795684 473 }
phsfan 96:b50f5f795684 474 else
phsfan 96:b50f5f795684 475 {
phsfan 96:b50f5f795684 476 rx_mtx.unlock();
phsfan 96:b50f5f795684 477 }
phsfan 96:b50f5f795684 478 break;
phsfan 96:b50f5f795684 479 case IUSBHostSerial::TxIrq:
phsfan 96:b50f5f795684 480 tx_mtx.lock();
phsfan 96:b50f5f795684 481 cb_tx_en = en;
phsfan 96:b50f5f795684 482 if(en && cb_tx_pending)
phsfan 96:b50f5f795684 483 {
phsfan 96:b50f5f795684 484 cb_tx_pending = false;
phsfan 96:b50f5f795684 485 tx_mtx.unlock();
phsfan 96:b50f5f795684 486 listener->writeable(); //Process the interrupt that was raised
phsfan 96:b50f5f795684 487 }
phsfan 96:b50f5f795684 488 else
phsfan 96:b50f5f795684 489 {
phsfan 96:b50f5f795684 490 tx_mtx.unlock();
phsfan 96:b50f5f795684 491 }
phsfan 96:b50f5f795684 492 break;
phsfan 96:b50f5f795684 493 }
phsfan 96:b50f5f795684 494 }