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 18 09:40:07 2015 +0000
Revision:
96:b50f5f795684
Child:
97:7d9cc95e2ea7
1st build.; ABIT SMA-01

Who changed what in which revision?

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