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@4:a91682e19d6b, 2012-08-02 (annotated)
- Committer:
- uci1
- Date:
- Thu Aug 02 05:42:47 2012 +0000
- Revision:
- 4:a91682e19d6b
- Parent:
- 3:24c5f0f50bf1
- Child:
- 6:6f002d202f59
Add power reading, once per file. Prevent seq number from wrapping around. Still many debugging messages. Communications not finished.
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 | 4:a91682e19d6b | 179 | uint16_t seq, v1, v2; |
| uci1 | 4:a91682e19d6b | 180 | SnSDUtils::ReadFileHeader(inf, macadr, run, seq, v1, v2); |
| 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 | } |