Used in Live Traffic Update Nokia LCD Display Project

Fork of NetServices by Segundo Equipo

Committer:
rrajan8
Date:
Wed Mar 06 19:07:23 2013 +0000
Revision:
8:92b57208ab99
Parent:
0:ac1725ba162c
This project utilizes mbed's networking features to display live traffic updates on the Nokia LCD using the MapQuest API's Traffic Web Service.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
segundo 0:ac1725ba162c 1
segundo 0:ac1725ba162c 2 /*
segundo 0:ac1725ba162c 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
segundo 0:ac1725ba162c 4
segundo 0:ac1725ba162c 5 Permission is hereby granted, free of charge, to any person obtaining a copy
segundo 0:ac1725ba162c 6 of this software and associated documentation files (the "Software"), to deal
segundo 0:ac1725ba162c 7 in the Software without restriction, including without limitation the rights
segundo 0:ac1725ba162c 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
segundo 0:ac1725ba162c 9 copies of the Software, and to permit persons to whom the Software is
segundo 0:ac1725ba162c 10 furnished to do so, subject to the following conditions:
segundo 0:ac1725ba162c 11
segundo 0:ac1725ba162c 12 The above copyright notice and this permission notice shall be included in
segundo 0:ac1725ba162c 13 all copies or substantial portions of the Software.
segundo 0:ac1725ba162c 14
segundo 0:ac1725ba162c 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
segundo 0:ac1725ba162c 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
segundo 0:ac1725ba162c 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
segundo 0:ac1725ba162c 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
segundo 0:ac1725ba162c 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
segundo 0:ac1725ba162c 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
segundo 0:ac1725ba162c 21 THE SOFTWARE.
segundo 0:ac1725ba162c 22 */
segundo 0:ac1725ba162c 23
segundo 0:ac1725ba162c 24 #include "rpc.h"
segundo 0:ac1725ba162c 25
segundo 0:ac1725ba162c 26 #include "UsbSerial.h"
segundo 0:ac1725ba162c 27
segundo 0:ac1725ba162c 28 //#define __DEBUG
segundo 0:ac1725ba162c 29 #include "dbg/dbg.h"
segundo 0:ac1725ba162c 30
segundo 0:ac1725ba162c 31 #include "netCfg.h"
segundo 0:ac1725ba162c 32 #if NET_USB_SERIAL
segundo 0:ac1725ba162c 33
segundo 0:ac1725ba162c 34 namespace mbed {
segundo 0:ac1725ba162c 35
segundo 0:ac1725ba162c 36 #define BUF_LEN 64
segundo 0:ac1725ba162c 37 #define FLUSH_TMOUT 100000 //US
segundo 0:ac1725ba162c 38
segundo 0:ac1725ba162c 39 UsbSerial::UsbSerial(UsbDevice* pDevice, int epIn, int epOut, const char* name /*= NULL*/) : Stream(name), m_epIn(pDevice, epIn, true, USB_BULK, BUF_LEN), m_epOut(pDevice, epOut, false, USB_BULK, BUF_LEN),
segundo 0:ac1725ba162c 40 m_pInCbItem(NULL), m_pInCbMeth(NULL), m_pOutCbItem(NULL), m_pOutCbMeth(NULL)
segundo 0:ac1725ba162c 41 {
segundo 0:ac1725ba162c 42 m_inBufEven = new char[BUF_LEN];
segundo 0:ac1725ba162c 43 m_inBufOdd = new char[BUF_LEN];
segundo 0:ac1725ba162c 44 m_pInBufPos = m_inBufUsr = m_inBufEven;
segundo 0:ac1725ba162c 45 m_inBufTrmt = m_inBufOdd;
segundo 0:ac1725ba162c 46
segundo 0:ac1725ba162c 47 m_outBufEven = new char[BUF_LEN];
segundo 0:ac1725ba162c 48 m_outBufOdd = new char[BUF_LEN];
segundo 0:ac1725ba162c 49 m_pOutBufPos = m_outBufUsr = m_outBufEven;
segundo 0:ac1725ba162c 50 m_outBufTrmt = m_outBufOdd;
segundo 0:ac1725ba162c 51
segundo 0:ac1725ba162c 52 m_inBufLen = m_outBufLen = 0;
segundo 0:ac1725ba162c 53
segundo 0:ac1725ba162c 54 DBG("Starting RX'ing on in ep\n");
segundo 0:ac1725ba162c 55
segundo 0:ac1725ba162c 56 m_timeout = false;
segundo 0:ac1725ba162c 57
segundo 0:ac1725ba162c 58 m_epIn.setOnCompletion(this, &UsbSerial::onEpInTransfer);
segundo 0:ac1725ba162c 59 m_epOut.setOnCompletion(this, &UsbSerial::onEpOutTransfer);
segundo 0:ac1725ba162c 60
segundo 0:ac1725ba162c 61 startRx();
segundo 0:ac1725ba162c 62 }
segundo 0:ac1725ba162c 63
segundo 0:ac1725ba162c 64 UsbSerial::~UsbSerial()
segundo 0:ac1725ba162c 65 {
segundo 0:ac1725ba162c 66 delete[] m_inBufEven;
segundo 0:ac1725ba162c 67 delete[] m_inBufOdd;
segundo 0:ac1725ba162c 68 delete[] m_outBufEven;
segundo 0:ac1725ba162c 69 delete[] m_outBufOdd;
segundo 0:ac1725ba162c 70 }
segundo 0:ac1725ba162c 71
segundo 0:ac1725ba162c 72 void UsbSerial::baud(int baudrate) {
segundo 0:ac1725ba162c 73 //
segundo 0:ac1725ba162c 74 }
segundo 0:ac1725ba162c 75
segundo 0:ac1725ba162c 76 void UsbSerial::format(int bits, int parity, int stop) {
segundo 0:ac1725ba162c 77 //
segundo 0:ac1725ba162c 78 }
segundo 0:ac1725ba162c 79
segundo 0:ac1725ba162c 80 #if 0 //For doc only
segundo 0:ac1725ba162c 81 template <class T>
segundo 0:ac1725ba162c 82 void attach(T* pCbItem, void (T::*pCbMeth)())
segundo 0:ac1725ba162c 83 {
segundo 0:ac1725ba162c 84 m_pCbItem = (CDummy*) pCbItem;
segundo 0:ac1725ba162c 85 m_pCbMeth = (void (CDummy::*)()) pCbMeth;
segundo 0:ac1725ba162c 86 }
segundo 0:ac1725ba162c 87 #endif
segundo 0:ac1725ba162c 88
segundo 0:ac1725ba162c 89 int UsbSerial::_getc() {
segundo 0:ac1725ba162c 90 NVIC_DisableIRQ(US_TICKER_TIMER_IRQn);
segundo 0:ac1725ba162c 91 NVIC_DisableIRQ(USB_IRQn);
segundo 0:ac1725ba162c 92 char c;
segundo 0:ac1725ba162c 93 c = *m_pInBufPos;
segundo 0:ac1725ba162c 94 m_pInBufPos++;
segundo 0:ac1725ba162c 95 NVIC_EnableIRQ(USB_IRQn);
segundo 0:ac1725ba162c 96 NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
segundo 0:ac1725ba162c 97 return c;
segundo 0:ac1725ba162c 98 }
segundo 0:ac1725ba162c 99
segundo 0:ac1725ba162c 100 int UsbSerial::_putc(int c) {
segundo 0:ac1725ba162c 101 NVIC_DisableIRQ(US_TICKER_TIMER_IRQn);
segundo 0:ac1725ba162c 102 NVIC_DisableIRQ(USB_IRQn);
segundo 0:ac1725ba162c 103 if( (m_pOutBufPos - m_outBufUsr) < BUF_LEN )
segundo 0:ac1725ba162c 104 {
segundo 0:ac1725ba162c 105 *m_pOutBufPos = (char) c;
segundo 0:ac1725ba162c 106 m_pOutBufPos++;
segundo 0:ac1725ba162c 107 }
segundo 0:ac1725ba162c 108 else
segundo 0:ac1725ba162c 109 {
segundo 0:ac1725ba162c 110 DBG("NO WAY!!!\n");
segundo 0:ac1725ba162c 111 }
segundo 0:ac1725ba162c 112 #if 1
segundo 0:ac1725ba162c 113 if( (m_pOutBufPos - m_outBufUsr) >= BUF_LEN ) //Must flush
segundo 0:ac1725ba162c 114 {
segundo 0:ac1725ba162c 115 if(m_timeout)
segundo 0:ac1725ba162c 116 m_txTimeout.detach();
segundo 0:ac1725ba162c 117 startTx();
segundo 0:ac1725ba162c 118 }
segundo 0:ac1725ba162c 119 else
segundo 0:ac1725ba162c 120 {
segundo 0:ac1725ba162c 121 /*if(m_timeout)
segundo 0:ac1725ba162c 122 m_txTimeout.detach();
segundo 0:ac1725ba162c 123 m_timeout = true;
segundo 0:ac1725ba162c 124 m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT);*/
segundo 0:ac1725ba162c 125 if(!m_timeout)
segundo 0:ac1725ba162c 126 {
segundo 0:ac1725ba162c 127 m_timeout = true;
segundo 0:ac1725ba162c 128 m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT);
segundo 0:ac1725ba162c 129 }
segundo 0:ac1725ba162c 130 }
segundo 0:ac1725ba162c 131 #endif
segundo 0:ac1725ba162c 132 //startTx();
segundo 0:ac1725ba162c 133 NVIC_EnableIRQ(USB_IRQn);
segundo 0:ac1725ba162c 134 NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
segundo 0:ac1725ba162c 135 return c;
segundo 0:ac1725ba162c 136 }
segundo 0:ac1725ba162c 137
segundo 0:ac1725ba162c 138 int UsbSerial::readable() {
segundo 0:ac1725ba162c 139 NVIC_DisableIRQ(US_TICKER_TIMER_IRQn);
segundo 0:ac1725ba162c 140 NVIC_DisableIRQ(USB_IRQn);
segundo 0:ac1725ba162c 141 int res;
segundo 0:ac1725ba162c 142 if( (m_pInBufPos - m_inBufUsr) < m_inBufLen )
segundo 0:ac1725ba162c 143 {
segundo 0:ac1725ba162c 144 //DBG("\r\nREADABLE\r\n");
segundo 0:ac1725ba162c 145 res = true;
segundo 0:ac1725ba162c 146 }
segundo 0:ac1725ba162c 147 else
segundo 0:ac1725ba162c 148 {
segundo 0:ac1725ba162c 149 //DBG("\r\nNOT READABLE\r\n");
segundo 0:ac1725ba162c 150 startRx(); //Try to swap packets & start another transmission
segundo 0:ac1725ba162c 151 res = ((m_pInBufPos - m_inBufUsr) < m_inBufLen )?true:false;
segundo 0:ac1725ba162c 152 }
segundo 0:ac1725ba162c 153 NVIC_EnableIRQ(USB_IRQn);
segundo 0:ac1725ba162c 154 NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
segundo 0:ac1725ba162c 155 return (bool)res;
segundo 0:ac1725ba162c 156 }
segundo 0:ac1725ba162c 157
segundo 0:ac1725ba162c 158 int UsbSerial::writeable() {
segundo 0:ac1725ba162c 159 NVIC_DisableIRQ(US_TICKER_TIMER_IRQn);
segundo 0:ac1725ba162c 160 NVIC_DisableIRQ(USB_IRQn);
segundo 0:ac1725ba162c 161 // DBG("\r\nWRITEABLE???\r\n");
segundo 0:ac1725ba162c 162 int res = (bool)( (m_pOutBufPos - m_outBufUsr) < BUF_LEN);
segundo 0:ac1725ba162c 163 NVIC_EnableIRQ(USB_IRQn);
segundo 0:ac1725ba162c 164 NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
segundo 0:ac1725ba162c 165 return res;
segundo 0:ac1725ba162c 166 }
segundo 0:ac1725ba162c 167
segundo 0:ac1725ba162c 168 void UsbSerial::onReadable()
segundo 0:ac1725ba162c 169 {
segundo 0:ac1725ba162c 170 if(m_pInCbItem && m_pInCbMeth)
segundo 0:ac1725ba162c 171 (m_pInCbItem->*m_pInCbMeth)();
segundo 0:ac1725ba162c 172 }
segundo 0:ac1725ba162c 173
segundo 0:ac1725ba162c 174 void UsbSerial::onWriteable()
segundo 0:ac1725ba162c 175 {
segundo 0:ac1725ba162c 176 if(m_pOutCbItem && m_pOutCbMeth)
segundo 0:ac1725ba162c 177 (m_pOutCbItem->*m_pOutCbMeth)();
segundo 0:ac1725ba162c 178 }
segundo 0:ac1725ba162c 179
segundo 0:ac1725ba162c 180 void UsbSerial::onEpInTransfer()
segundo 0:ac1725ba162c 181 {
segundo 0:ac1725ba162c 182 int len = m_epIn.status();
segundo 0:ac1725ba162c 183 DBG("RX transfer completed w len=%d\n",len);
segundo 0:ac1725ba162c 184 startRx();
segundo 0:ac1725ba162c 185 if(len > 0)
segundo 0:ac1725ba162c 186 onReadable();
segundo 0:ac1725ba162c 187 }
segundo 0:ac1725ba162c 188
segundo 0:ac1725ba162c 189 void UsbSerial::onEpOutTransfer()
segundo 0:ac1725ba162c 190 {
segundo 0:ac1725ba162c 191 int len = m_epOut.status();
segundo 0:ac1725ba162c 192 DBG("TX transfer completed w len=%d\n",len);
segundo 0:ac1725ba162c 193 if(m_timeout)
segundo 0:ac1725ba162c 194 m_txTimeout.detach();
segundo 0:ac1725ba162c 195 startTx();
segundo 0:ac1725ba162c 196 if(len > 0)
segundo 0:ac1725ba162c 197 onWriteable();
segundo 0:ac1725ba162c 198 }
segundo 0:ac1725ba162c 199
segundo 0:ac1725ba162c 200 void UsbSerial::startTx()
segundo 0:ac1725ba162c 201 {
segundo 0:ac1725ba162c 202
segundo 0:ac1725ba162c 203 DBG("Transfer>\n");
segundo 0:ac1725ba162c 204
segundo 0:ac1725ba162c 205 m_timeout = false;
segundo 0:ac1725ba162c 206
segundo 0:ac1725ba162c 207 // m_txTimeout.detach();
segundo 0:ac1725ba162c 208
segundo 0:ac1725ba162c 209 if(!(m_pOutBufPos - m_outBufUsr))
segundo 0:ac1725ba162c 210 {
segundo 0:ac1725ba162c 211 DBG("?!?!?\n");
segundo 0:ac1725ba162c 212 return;
segundo 0:ac1725ba162c 213 }
segundo 0:ac1725ba162c 214
segundo 0:ac1725ba162c 215 if( m_epOut.status() == USBERR_PROCESSING )
segundo 0:ac1725ba162c 216 {
segundo 0:ac1725ba162c 217 //Wait & retry
segundo 0:ac1725ba162c 218 //m_timeout = true;
segundo 0:ac1725ba162c 219 //m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT);
segundo 0:ac1725ba162c 220 DBG("Ep is busy...\n");
segundo 0:ac1725ba162c 221 return;
segundo 0:ac1725ba162c 222 }
segundo 0:ac1725ba162c 223
segundo 0:ac1725ba162c 224 if( m_epOut.status() < 0 )
segundo 0:ac1725ba162c 225 {
segundo 0:ac1725ba162c 226 DBG("Tx trying again...\n");
segundo 0:ac1725ba162c 227 m_epOut.transfer((volatile uint8_t*)m_outBufTrmt, m_outBufLen);
segundo 0:ac1725ba162c 228 return;
segundo 0:ac1725ba162c 229 }
segundo 0:ac1725ba162c 230
segundo 0:ac1725ba162c 231 m_outBufLen = m_pOutBufPos - m_outBufUsr;
segundo 0:ac1725ba162c 232
segundo 0:ac1725ba162c 233 //Swap buffers
segundo 0:ac1725ba162c 234 volatile char* swapBuf = m_outBufUsr;
segundo 0:ac1725ba162c 235 m_outBufUsr = m_outBufTrmt;
segundo 0:ac1725ba162c 236 m_outBufTrmt = swapBuf;
segundo 0:ac1725ba162c 237
segundo 0:ac1725ba162c 238 m_epOut.transfer((volatile uint8_t*)m_outBufTrmt, m_outBufLen);
segundo 0:ac1725ba162c 239
segundo 0:ac1725ba162c 240 m_pOutBufPos = m_outBufUsr;
segundo 0:ac1725ba162c 241
segundo 0:ac1725ba162c 242 }
segundo 0:ac1725ba162c 243
segundo 0:ac1725ba162c 244 void UsbSerial::startRx()
segundo 0:ac1725ba162c 245 {
segundo 0:ac1725ba162c 246 if( (m_pInBufPos - m_inBufUsr) < m_inBufLen )
segundo 0:ac1725ba162c 247 {
segundo 0:ac1725ba162c 248 //User buf is not empty, cannot swap now...
segundo 0:ac1725ba162c 249 return;
segundo 0:ac1725ba162c 250 }
segundo 0:ac1725ba162c 251 int len = m_epIn.status();
segundo 0:ac1725ba162c 252 if( len == USBERR_PROCESSING )
segundo 0:ac1725ba162c 253 {
segundo 0:ac1725ba162c 254 //Previous transmission not completed
segundo 0:ac1725ba162c 255 return;
segundo 0:ac1725ba162c 256 }
segundo 0:ac1725ba162c 257 if( len < 0 )
segundo 0:ac1725ba162c 258 {
segundo 0:ac1725ba162c 259 DBG("Rx trying again...\n");
segundo 0:ac1725ba162c 260 m_epIn.transfer((volatile uint8_t*)m_inBufTrmt, BUF_LEN); //Start another transmission
segundo 0:ac1725ba162c 261 return;
segundo 0:ac1725ba162c 262 }
segundo 0:ac1725ba162c 263
segundo 0:ac1725ba162c 264 m_inBufLen = len;
segundo 0:ac1725ba162c 265
segundo 0:ac1725ba162c 266 //Swap buffers
segundo 0:ac1725ba162c 267 volatile char* swapBuf = m_inBufUsr;
segundo 0:ac1725ba162c 268 m_inBufUsr = m_inBufTrmt;
segundo 0:ac1725ba162c 269 m_inBufTrmt = swapBuf;
segundo 0:ac1725ba162c 270 m_pInBufPos = m_inBufUsr;
segundo 0:ac1725ba162c 271
segundo 0:ac1725ba162c 272 DBG("Starting new transfer\n");
segundo 0:ac1725ba162c 273 m_epIn.transfer((volatile uint8_t*)m_inBufTrmt, BUF_LEN); //Start another transmission
segundo 0:ac1725ba162c 274
segundo 0:ac1725ba162c 275 }
segundo 0:ac1725ba162c 276
segundo 0:ac1725ba162c 277 #ifdef MBED_RPC
segundo 0:ac1725ba162c 278 const struct rpc_method *UsbSerial::get_rpc_methods() {
segundo 0:ac1725ba162c 279 static const rpc_method methods[] = {
segundo 0:ac1725ba162c 280 { "readable", rpc_method_caller<int, UsbSerial, &UsbSerial::readable> },
segundo 0:ac1725ba162c 281 { "writeable", rpc_method_caller<int, UsbSerial, &UsbSerial::writeable> },
segundo 0:ac1725ba162c 282 RPC_METHOD_SUPER(Stream)
segundo 0:ac1725ba162c 283 };
segundo 0:ac1725ba162c 284 return methods;
segundo 0:ac1725ba162c 285 }
segundo 0:ac1725ba162c 286
segundo 0:ac1725ba162c 287 struct rpc_class *UsbSerial::get_rpc_class() {
segundo 0:ac1725ba162c 288 static const rpc_function funcs[] = {
segundo 0:ac1725ba162c 289 /*{ "new", rpc_function_caller<const char*, UsbDevice*, int, int, const char*, Base::construct<UsbSerial,UsbDevice*,int,int,const char*> > },*/ //RPC is buggy
segundo 0:ac1725ba162c 290 RPC_METHOD_END
segundo 0:ac1725ba162c 291 };
segundo 0:ac1725ba162c 292 static rpc_class c = { "UsbSerial", funcs, NULL };
segundo 0:ac1725ba162c 293 return &c;
segundo 0:ac1725ba162c 294 }
segundo 0:ac1725ba162c 295 #endif
segundo 0:ac1725ba162c 296
segundo 0:ac1725ba162c 297 } // namespace mbed
segundo 0:ac1725ba162c 298
segundo 0:ac1725ba162c 299 #endif
segundo 0:ac1725ba162c 300