Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
SnCommUsb.cpp@3:24c5f0f50bf1, 2012-07-31 (annotated)
- Committer:
- uci1
- Date:
- Tue Jul 31 04:59:16 2012 +0000
- Revision:
- 3:24c5f0f50bf1
- Parent:
- 2:e67f7c158087
- Child:
- 4:a91682e19d6b
Test bench version. Communications not completed. Debugging output present. But will read the local config file and save events that can be used for testing.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| uci1 | 1:e392595b4b76 | 1 | #include "SnCommUsb.h" |
| uci1 | 1:e392595b4b76 | 2 | |
| uci1 | 1:e392595b4b76 | 3 | #include "Timer.h" |
| uci1 | 1:e392595b4b76 | 4 | |
| uci1 | 1:e392595b4b76 | 5 | #include "SnStatusFrame.h" |
| uci1 | 1:e392595b4b76 | 6 | #include "SnConfigFrame.h" |
| uci1 | 1:e392595b4b76 | 7 | #include "SnEventFrame.h" |
| uci1 | 2:e67f7c158087 | 8 | #include "SnHeaderFrame.h" |
| uci1 | 2:e67f7c158087 | 9 | #include "SnSDUtils.h" |
| uci1 | 1:e392595b4b76 | 10 | |
| uci1 | 1:e392595b4b76 | 11 | MODSERIAL* SnCommUsb::fgCpu = 0; |
| uci1 | 1:e392595b4b76 | 12 | |
| uci1 | 1:e392595b4b76 | 13 | void __Recv(MODSERIAL_IRQ_INFO* s) { |
| uci1 | 1:e392595b4b76 | 14 | static DigitalOut led4(LED4); |
| uci1 | 1:e392595b4b76 | 15 | static DigitalOut led3(LED3); |
| uci1 | 1:e392595b4b76 | 16 | for (uint8_t i=0; i<20; i++) { |
| uci1 | 1:e392595b4b76 | 17 | led4=!led4; |
| uci1 | 1:e392595b4b76 | 18 | led3=!led3; |
| uci1 | 1:e392595b4b76 | 19 | wait(0.1); |
| uci1 | 1:e392595b4b76 | 20 | } |
| uci1 | 1:e392595b4b76 | 21 | } |
| uci1 | 1:e392595b4b76 | 22 | |
| uci1 | 1:e392595b4b76 | 23 | SnCommWin::ECommWinResult SnCommUsb::SetupPort(MODSERIAL& cpu) { |
| uci1 | 1:e392595b4b76 | 24 | fgCpu = &cpu; |
| uci1 | 1:e392595b4b76 | 25 | |
| uci1 | 1:e392595b4b76 | 26 | // set up serial-usb port |
| uci1 | 1:e392595b4b76 | 27 | fgCpu->baud( 230400 ); |
| uci1 | 1:e392595b4b76 | 28 | fgCpu->format( 8, Serial::None, 1 ); |
| uci1 | 1:e392595b4b76 | 29 | fgCpu->txBufferFlush(); |
| uci1 | 1:e392595b4b76 | 30 | fgCpu->rxBufferFlush(); |
| uci1 | 1:e392595b4b76 | 31 | //fgCpu->attach(&__Recv, MODSERIAL::RxIrq); |
| uci1 | 1:e392595b4b76 | 32 | return kOkNoMsg; |
| uci1 | 1:e392595b4b76 | 33 | } |
| uci1 | 1:e392595b4b76 | 34 | |
| uci1 | 1:e392595b4b76 | 35 | |
| uci1 | 1:e392595b4b76 | 36 | SnCommWin::ECommWinResult SnCommUsb::OpenWindow(const uint32_t timeout, |
| uci1 | 1:e392595b4b76 | 37 | const bool sendStatus, |
| uci1 | 1:e392595b4b76 | 38 | const SnConfigFrame& conf, |
| uci1 | 1:e392595b4b76 | 39 | const SnEventFrame& evt, |
| uci1 | 2:e67f7c158087 | 40 | char* const genBuf) { |
| uci1 | 1:e392595b4b76 | 41 | // usb port always connected (or never) |
| uci1 | 1:e392595b4b76 | 42 | SnCommWin::ECommWinResult ret = SnCommWin::kConnected; |
| uci1 | 1:e392595b4b76 | 43 | |
| uci1 | 1:e392595b4b76 | 44 | if (sendStatus) { |
| uci1 | 2:e67f7c158087 | 45 | ret = SendStatus(conf, evt, genBuf); |
| uci1 | 1:e392595b4b76 | 46 | } |
| uci1 | 1:e392595b4b76 | 47 | |
| uci1 | 1:e392595b4b76 | 48 | return ret; |
| uci1 | 1:e392595b4b76 | 49 | } |
| uci1 | 1:e392595b4b76 | 50 | |
| uci1 | 3:24c5f0f50bf1 | 51 | SnCommWin::ECommWinResult SnCommUsb::WaitHandshake(const uint32_t timeout, |
| uci1 | 3:24c5f0f50bf1 | 52 | char* const buf, |
| uci1 | 3:24c5f0f50bf1 | 53 | const uint32_t bsize) { |
| uci1 | 3:24c5f0f50bf1 | 54 | printf("WaitHandshake, to=%u\r\n",timeout); |
| uci1 | 3:24c5f0f50bf1 | 55 | |
| uci1 | 3:24c5f0f50bf1 | 56 | bool hasData = fgCpu->readable()==1; |
| uci1 | 3:24c5f0f50bf1 | 57 | |
| uci1 | 3:24c5f0f50bf1 | 58 | while ( (hasData==false) && (time(0) < timeout) ) { |
| uci1 | 3:24c5f0f50bf1 | 59 | wait_ms(10); |
| uci1 | 3:24c5f0f50bf1 | 60 | |
| uci1 | 3:24c5f0f50bf1 | 61 | hasData = fgCpu->readable()==1; |
| uci1 | 3:24c5f0f50bf1 | 62 | } |
| uci1 | 3:24c5f0f50bf1 | 63 | |
| uci1 | 3:24c5f0f50bf1 | 64 | if( hasData ) { |
| uci1 | 3:24c5f0f50bf1 | 65 | uint8_t mcode; |
| uci1 | 3:24c5f0f50bf1 | 66 | uint32_t mlen; |
| uci1 | 3:24c5f0f50bf1 | 67 | SnHeaderFrame::ReadFrom(*fgCpu, mcode, mlen); |
| uci1 | 3:24c5f0f50bf1 | 68 | if (mcode==SnHeaderFrame::kHandshakeCode) { |
| uci1 | 3:24c5f0f50bf1 | 69 | return SnCommWin::kOkWithMsg; |
| uci1 | 3:24c5f0f50bf1 | 70 | } else { |
| uci1 | 3:24c5f0f50bf1 | 71 | // TODO: somehow handle unexpected message? |
| uci1 | 3:24c5f0f50bf1 | 72 | return SnCommWin::kUnexpectedRec; |
| uci1 | 3:24c5f0f50bf1 | 73 | } |
| uci1 | 3:24c5f0f50bf1 | 74 | } else { |
| uci1 | 3:24c5f0f50bf1 | 75 | return SnCommWin::kOkNoMsg; |
| uci1 | 3:24c5f0f50bf1 | 76 | } |
| uci1 | 3:24c5f0f50bf1 | 77 | } |
| uci1 | 3:24c5f0f50bf1 | 78 | |
| uci1 | 1:e392595b4b76 | 79 | SnCommWin::ECommWinResult SnCommUsb::GetConfig(SnConfigFrame& conf, |
| uci1 | 1:e392595b4b76 | 80 | const uint32_t timeOut, |
| uci1 | 3:24c5f0f50bf1 | 81 | char* const confBuf, |
| uci1 | 3:24c5f0f50bf1 | 82 | const uint32_t bsize) { |
| uci1 | 1:e392595b4b76 | 83 | // confBuf not used by usb. bytes read directly from serial port |
| uci1 | 1:e392595b4b76 | 84 | |
| uci1 | 1:e392595b4b76 | 85 | SnCommWin::ECommWinResult res = SnCommWin::kUndefFail; |
| uci1 | 1:e392595b4b76 | 86 | |
| uci1 | 1:e392595b4b76 | 87 | bool hasData = fgCpu->readable()==1; |
| uci1 | 2:e67f7c158087 | 88 | |
| uci1 | 1:e392595b4b76 | 89 | while ( (hasData==false) && (time(0) < timeOut) ) { |
| uci1 | 1:e392595b4b76 | 90 | wait_ms(10); |
| uci1 | 1:e392595b4b76 | 91 | |
| uci1 | 1:e392595b4b76 | 92 | hasData = fgCpu->readable()==1; |
| uci1 | 1:e392595b4b76 | 93 | } |
| uci1 | 1:e392595b4b76 | 94 | |
| uci1 | 1:e392595b4b76 | 95 | if( hasData ) { |
| uci1 | 2:e67f7c158087 | 96 | uint8_t mcode; |
| uci1 | 2:e67f7c158087 | 97 | uint32_t mlen; |
| uci1 | 2:e67f7c158087 | 98 | SnHeaderFrame::ReadFrom(*fgCpu, mcode, mlen); |
| uci1 | 2:e67f7c158087 | 99 | // TODO: do something with the header info? |
| uci1 | 1:e392595b4b76 | 100 | conf.ReadFrom(*fgCpu); |
| uci1 | 1:e392595b4b76 | 101 | res = SnCommWin::kOkWithMsg; |
| uci1 | 1:e392595b4b76 | 102 | } else { |
| uci1 | 1:e392595b4b76 | 103 | res = SnCommWin::kOkNoMsg; |
| uci1 | 1:e392595b4b76 | 104 | } |
| uci1 | 1:e392595b4b76 | 105 | |
| uci1 | 1:e392595b4b76 | 106 | return res; |
| uci1 | 1:e392595b4b76 | 107 | } |
| uci1 | 1:e392595b4b76 | 108 | |
| uci1 | 3:24c5f0f50bf1 | 109 | SnCommWin::ECommWinResult SnCommUsb::SendFilename(const char* fn, char* const genBuf) { |
| uci1 | 3:24c5f0f50bf1 | 110 | const size_t flen = strlen(fn); |
| uci1 | 3:24c5f0f50bf1 | 111 | bool ok = SnHeaderFrame::WriteTo(*fgCpu, |
| uci1 | 3:24c5f0f50bf1 | 112 | SnHeaderFrame::kFilenameCode, |
| uci1 | 3:24c5f0f50bf1 | 113 | SnHeaderFrame::SizeOf()); |
| uci1 | 3:24c5f0f50bf1 | 114 | if (ok) { |
| uci1 | 3:24c5f0f50bf1 | 115 | ok = SendBytes(fn, flen); |
| uci1 | 3:24c5f0f50bf1 | 116 | } |
| uci1 | 3:24c5f0f50bf1 | 117 | return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; |
| uci1 | 3:24c5f0f50bf1 | 118 | } |
| uci1 | 3:24c5f0f50bf1 | 119 | |
| uci1 | 1:e392595b4b76 | 120 | SnCommWin::ECommWinResult SnCommUsb::SendStatus(const SnConfigFrame& conf, |
| uci1 | 1:e392595b4b76 | 121 | const SnEventFrame& evt, |
| uci1 | 2:e67f7c158087 | 122 | char* const genBuf) { |
| uci1 | 2:e67f7c158087 | 123 | const bool ok = SnHeaderFrame::WriteTo(*fgCpu, |
| uci1 | 2:e67f7c158087 | 124 | SnHeaderFrame::kStatusCode, SnStatusFrame::SizeOf(conf)); |
| uci1 | 2:e67f7c158087 | 125 | if (ok) { |
| uci1 | 2:e67f7c158087 | 126 | return SnStatusFrame::WriteTo(*fgCpu, SnConfigFrame::kUSB, conf, evt, genBuf); |
| uci1 | 2:e67f7c158087 | 127 | } else { |
| uci1 | 2:e67f7c158087 | 128 | return SnCommWin::kFailNoneSent; |
| uci1 | 2:e67f7c158087 | 129 | } |
| uci1 | 1:e392595b4b76 | 130 | } |
| uci1 | 1:e392595b4b76 | 131 | |
| uci1 | 1:e392595b4b76 | 132 | SnCommWin::ECommWinResult SnCommUsb::SendData(FILE* inf) { |
| uci1 | 2:e67f7c158087 | 133 | const int foff = ftell(inf); |
| uci1 | 2:e67f7c158087 | 134 | fseek(inf, 0, SEEK_END); |
| uci1 | 2:e67f7c158087 | 135 | const int fsize = ftell(inf) - foff; |
| uci1 | 2:e67f7c158087 | 136 | fseek(inf, foff, SEEK_SET); |
| uci1 | 2:e67f7c158087 | 137 | if (fsize>0) { |
| uci1 | 2:e67f7c158087 | 138 | SnHeaderFrame::WriteTo(*fgCpu, |
| uci1 | 2:e67f7c158087 | 139 | SnHeaderFrame::kFileCode, fsize); |
| uci1 | 2:e67f7c158087 | 140 | SendBytes(inf, fsize); |
| uci1 | 2:e67f7c158087 | 141 | return SnCommWin::kOkMsgSent; |
| uci1 | 2:e67f7c158087 | 142 | } else { |
| uci1 | 2:e67f7c158087 | 143 | return SnCommWin::kFailNoneSent; |
| uci1 | 2:e67f7c158087 | 144 | } |
| uci1 | 2:e67f7c158087 | 145 | } |
| uci1 | 2:e67f7c158087 | 146 | |
| uci1 | 2:e67f7c158087 | 147 | bool SnCommUsb::SendBytes(FILE* f, const uint32_t nbytes) { |
| uci1 | 2:e67f7c158087 | 148 | register uint32_t i=0; |
| uci1 | 2:e67f7c158087 | 149 | for (i=0; (i<nbytes) |
| uci1 | 2:e67f7c158087 | 150 | && (feof(f)==0) |
| uci1 | 2:e67f7c158087 | 151 | && (ferror(f)==0); i++) { |
| uci1 | 2:e67f7c158087 | 152 | fgCpu->putc( getc(f) ); |
| uci1 | 2:e67f7c158087 | 153 | } |
| uci1 | 2:e67f7c158087 | 154 | return (i==nbytes); |
| uci1 | 2:e67f7c158087 | 155 | } |
| uci1 | 2:e67f7c158087 | 156 | |
| uci1 | 2:e67f7c158087 | 157 | bool SnCommUsb::SendBytes(const char* const buf, |
| uci1 | 2:e67f7c158087 | 158 | const uint32_t nbytes) { |
| uci1 | 2:e67f7c158087 | 159 | const char* b = buf; |
| uci1 | 2:e67f7c158087 | 160 | for (uint32_t j=0; j<nbytes; j++, b++) { |
| uci1 | 2:e67f7c158087 | 161 | fgCpu->putc( *b ); |
| uci1 | 2:e67f7c158087 | 162 | } |
| uci1 | 2:e67f7c158087 | 163 | return true; |
| uci1 | 1:e392595b4b76 | 164 | } |
| uci1 | 1:e392595b4b76 | 165 | |
| uci1 | 1:e392595b4b76 | 166 | SnCommWin::ECommWinResult SnCommUsb::SendConfAndEvents(FILE* inf, |
| uci1 | 1:e392595b4b76 | 167 | const SnConfigFrame& curConf, |
| uci1 | 1:e392595b4b76 | 168 | SnEventFrame& evt, |
| uci1 | 2:e67f7c158087 | 169 | char* const genBuf, |
| uci1 | 1:e392595b4b76 | 170 | const uint32_t nevts, |
| uci1 | 1:e392595b4b76 | 171 | const uint32_t firstEvt) { |
| uci1 | 1:e392595b4b76 | 172 | // firstEvt==0 ==> start at beginning |
| uci1 | 1:e392595b4b76 | 173 | // nevts==0 ==> NO events! (see SnCommWin::SendData |
| uci1 | 1:e392595b4b76 | 174 | // for the fcn to send the full file) |
| uci1 | 1:e392595b4b76 | 175 | |
| uci1 | 1:e392595b4b76 | 176 | // TODO: check memory for temporary config/event frames? |
| uci1 | 2:e67f7c158087 | 177 | uint64_t macadr; |
| uci1 | 2:e67f7c158087 | 178 | uint32_t run; |
| uci1 | 2:e67f7c158087 | 179 | uint16_t seq; |
| uci1 | 2:e67f7c158087 | 180 | SnSDUtils::ReadFileHeader(inf, macadr, run, seq); |
| uci1 | 1:e392595b4b76 | 181 | SnConfigFrame conf; |
| uci1 | 1:e392595b4b76 | 182 | conf.ReadFrom(inf); |
| uci1 | 1:e392595b4b76 | 183 | |
| uci1 | 1:e392595b4b76 | 184 | uint8_t sLoseLSB=0, sLoseMSB=0; |
| uci1 | 1:e392595b4b76 | 185 | uint16_t sWvBase=0; |
| uci1 | 2:e67f7c158087 | 186 | curConf.GetPackParsFor(SnConfigFrame::kUSB, sLoseLSB, sLoseMSB, sWvBase); |
| uci1 | 1:e392595b4b76 | 187 | // do we have to unpack & repack events? |
| uci1 | 1:e392595b4b76 | 188 | const bool repack = (sLoseLSB != conf.GetWvLoseLSB()) |
| uci1 | 1:e392595b4b76 | 189 | && (sLoseMSB != conf.GetWvLoseMSB()) |
| uci1 | 1:e392595b4b76 | 190 | && (sWvBase != conf.GetWvBaseline()); |
| uci1 | 1:e392595b4b76 | 191 | |
| uci1 | 1:e392595b4b76 | 192 | // size of event in file |
| uci1 | 1:e392595b4b76 | 193 | const uint32_t esize = SnEventFrame::SizeOf(conf.GetWvLoseLSB(), |
| uci1 | 1:e392595b4b76 | 194 | conf.GetWvLoseMSB()); |
| uci1 | 1:e392595b4b76 | 195 | // move up to first event |
| uci1 | 2:e67f7c158087 | 196 | const uint32_t csize = conf.SizeOf(); |
| uci1 | 2:e67f7c158087 | 197 | fseek(inf, csize + (firstEvt*esize), SEEK_SET); |
| uci1 | 2:e67f7c158087 | 198 | |
| uci1 | 2:e67f7c158087 | 199 | // send the header and conf |
| uci1 | 2:e67f7c158087 | 200 | char* b = genBuf; |
| uci1 | 2:e67f7c158087 | 201 | SnHeaderFrame::WriteTo(b, |
| uci1 | 2:e67f7c158087 | 202 | SnHeaderFrame::kConfAndEvtsCode, csize); |
| uci1 | 2:e67f7c158087 | 203 | conf.WriteTo(b); |
| uci1 | 2:e67f7c158087 | 204 | bool ok = SendBytes(genBuf, csize); |
| uci1 | 2:e67f7c158087 | 205 | |
| uci1 | 2:e67f7c158087 | 206 | // size of event sent over afar |
| uci1 | 2:e67f7c158087 | 207 | const uint32_t ssize = (repack) ? |
| uci1 | 2:e67f7c158087 | 208 | SnEventFrame::SizeOf(sLoseLSB, sLoseMSB) : |
| uci1 | 2:e67f7c158087 | 209 | esize; |
| uci1 | 2:e67f7c158087 | 210 | |
| uci1 | 2:e67f7c158087 | 211 | for (uint32_t i=0; i<nevts; i++) { |
| uci1 | 2:e67f7c158087 | 212 | if (repack) { |
| uci1 | 2:e67f7c158087 | 213 | evt.ReadFrom(inf, genBuf, |
| uci1 | 1:e392595b4b76 | 214 | conf.GetWvLoseLSB(), conf.GetWvLoseMSB(), |
| uci1 | 1:e392595b4b76 | 215 | conf.GetWvBaseline()); |
| uci1 | 2:e67f7c158087 | 216 | evt.WriteTo(genBuf, sLoseLSB, sLoseMSB, sWvBase); |
| uci1 | 2:e67f7c158087 | 217 | |
| uci1 | 2:e67f7c158087 | 218 | ok &= SendBytes(SnHeaderFrame::GetHdBuf(SnHeaderFrame::kEventCode, |
| uci1 | 2:e67f7c158087 | 219 | ssize), |
| uci1 | 2:e67f7c158087 | 220 | SnHeaderFrame::SizeOf()); |
| uci1 | 2:e67f7c158087 | 221 | ok &= SendBytes(genBuf, |
| uci1 | 2:e67f7c158087 | 222 | evt.SizeOf(conf.GetWvLoseLSB(), conf.GetWvLoseMSB())); |
| uci1 | 2:e67f7c158087 | 223 | } else { |
| uci1 | 2:e67f7c158087 | 224 | ok &= SendBytes(SnHeaderFrame::GetHdBuf(SnHeaderFrame::kEventCode, |
| uci1 | 2:e67f7c158087 | 225 | ssize), |
| uci1 | 2:e67f7c158087 | 226 | SnHeaderFrame::SizeOf()); |
| uci1 | 2:e67f7c158087 | 227 | ok &= SendBytes(inf, ssize); |
| uci1 | 1:e392595b4b76 | 228 | } |
| uci1 | 1:e392595b4b76 | 229 | } |
| uci1 | 2:e67f7c158087 | 230 | return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent; |
| uci1 | 1:e392595b4b76 | 231 | } |