Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Sep 12 04:47:22 2012 +0000
Revision:
16:744ce85aede2
Parent:
15:f2569d8e4176
Child:
19:74155d652c37
SBD comm seems to be working. USB comm seems to be working (at 115200 baud). AFAR comm seems to be working. This version is set for USB communication and has zero text output.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uci1 0:664899e0b988 1 #include "SnSDUtils.h"
uci1 0:664899e0b988 2
uci1 0:664899e0b988 3 #include "mbed.h"
uci1 0:664899e0b988 4 #include "SDFileSystem.h"
uci1 0:664899e0b988 5 #include <string.h>
uci1 12:d472f9811262 6 #include <string>
uci1 0:664899e0b988 7
uci1 0:664899e0b988 8 #include "SnConfigFrame.h"
uci1 0:664899e0b988 9 #include "SnEventFrame.h"
uci1 0:664899e0b988 10
uci1 15:f2569d8e4176 11 //#define DEBUG
uci1 0:664899e0b988 12
uci1 1:e392595b4b76 13 const char* const SnSDUtils::kSDsubDir = "/sd";
uci1 2:e67f7c158087 14 char SnSDUtils::fgCurFileName[kFNBufSize]={0};
uci1 1:e392595b4b76 15 FILE* SnSDUtils::fgCurFile = 0;
uci1 12:d472f9811262 16 uint16_t SnSDUtils::fgCurSeq = 0;
uci1 8:95a325df1f6b 17 const uint8_t SnSDUtils::kIOvers = 3;
uci1 5:9cea89700c66 18 const uint32_t SnSDUtils::kMaxSizeOfFileHdr =
uci1 5:9cea89700c66 19 sizeof(uint8_t)+sizeof(uint64_t)+sizeof(uint32_t)+sizeof(uint16_t)
uci1 8:95a325df1f6b 20 +(sizeof(uint8_t)+(2u*sizeof(uint16_t))); // power frame v1
uci1 4:a91682e19d6b 21
uci1 4:a91682e19d6b 22 static const uint16_t __kMaxUShort = ~0;
uci1 0:664899e0b988 23
uci1 0:664899e0b988 24 const char* SnSDUtils::GetOutFileName(const uint64_t macadr,
uci1 0:664899e0b988 25 const uint32_t run,
uci1 0:664899e0b988 26 const uint16_t seq) {
uci1 0:664899e0b988 27 // returns the formatted file name, or NULL if the directory is too long
uci1 0:664899e0b988 28 // and the full name cannot fit in the buffer
uci1 0:664899e0b988 29 // NOTE: this fcn uses a static buffer, and so should not be called
uci1 0:664899e0b988 30 // multiple times in the same line (that includes the calling of functions
uci1 0:664899e0b988 31 // that call this function!)
uci1 0:664899e0b988 32 //
uci1 0:664899e0b988 33 // filename = SnEvtsM[6-byte hex mac adr]r[6-digit run num]s[5-digit seq num].dat
uci1 0:664899e0b988 34 // 35 chars 7 + 12 +1+ 5 +1+ 5 + 4
uci1 0:664899e0b988 35
uci1 0:664899e0b988 36 if (strlen(kSDsubDir)<(kFNBufSize-37)) {
uci1 0:664899e0b988 37 static char tbuf[kFNBufSize];
uci1 0:664899e0b988 38 memset(tbuf, 0, sizeof(char)*kFNBufSize);
uci1 0:664899e0b988 39 // if file name format changes, GetSeqNum must be changed too
uci1 0:664899e0b988 40 sprintf(tbuf, "%s/SnEvtsM%012llXr%05ds%05d.dat",
uci1 0:664899e0b988 41 kSDsubDir,
uci1 0:664899e0b988 42 macadr>>16, // 64 -> 48 bits
uci1 0:664899e0b988 43 run, seq);
uci1 0:664899e0b988 44 return tbuf;
uci1 0:664899e0b988 45 } else {
uci1 0:664899e0b988 46 return NULL;
uci1 0:664899e0b988 47 }
uci1 0:664899e0b988 48 }
uci1 12:d472f9811262 49 /*
uci1 10:3c93db1cfb12 50 uint16_t SnSDUtils::GetCurSeqNum() {
uci1 10:3c93db1cfb12 51 return GetSeqNumFromFileName(fgCurFileName);
uci1 10:3c93db1cfb12 52 }
uci1 12:d472f9811262 53 */
uci1 10:3c93db1cfb12 54 uint16_t SnSDUtils::GetSeqNumFromFileName(const char* fn) {
uci1 10:3c93db1cfb12 55 uint16_t seq=0;
uci1 10:3c93db1cfb12 56 const uint32_t ncomp = strrchr(fn, 's') - fn;
uci1 10:3c93db1cfb12 57 if (ncomp<strlen(fn)) {
uci1 10:3c93db1cfb12 58 sscanf(fn+ncomp,"s%hu.dat",&seq);
uci1 10:3c93db1cfb12 59 }
uci1 10:3c93db1cfb12 60 return seq;
uci1 10:3c93db1cfb12 61 }
uci1 10:3c93db1cfb12 62
uci1 0:664899e0b988 63 uint16_t SnSDUtils::GetSeqNum(const uint64_t macadr,
uci1 0:664899e0b988 64 const uint32_t run) {
uci1 0:664899e0b988 65 // count the files having expected filename format
uci1 0:664899e0b988 66
uci1 0:664899e0b988 67 const char* fn = GetOutFileName(macadr, run, 0)
uci1 0:664899e0b988 68 + strlen(kSDsubDir) + 1; // take out dir and '/'s
uci1 0:664899e0b988 69
uci1 0:664899e0b988 70 DIR* d;
uci1 0:664899e0b988 71 struct dirent* dent;
uci1 0:664899e0b988 72
uci1 6:6f002d202f59 73 uint16_t seq=0, newseq=0;
uci1 0:664899e0b988 74 if ( (d = opendir( kSDsubDir ))!=NULL ) {
uci1 0:664899e0b988 75 // don't compare seq#. don't use num of chars in case seq is >999
uci1 0:664899e0b988 76 const uint32_t ncomp = strrchr(fn, 's') - fn;
uci1 0:664899e0b988 77 while ( (dent = readdir(d))!=NULL ) {
uci1 0:664899e0b988 78 if (strncmp(dent->d_name, fn, ncomp)==0) {
uci1 6:6f002d202f59 79 // allow for deleted files to make gaps.
uci1 6:6f002d202f59 80 // search for highest seq number and increase that
uci1 7:079617408fec 81 sscanf((dent->d_name)+ncomp,"s%hu.dat",&seq);
uci1 12:d472f9811262 82 #ifdef DEBUG
uci1 7:079617408fec 83 /*
uci1 7:079617408fec 84 printf("dn=%s, seq=%hu, __kMaxUShort=%hu\r\n",
uci1 7:079617408fec 85 dent->d_name, seq, __kMaxUShort);
uci1 7:079617408fec 86 */
uci1 12:d472f9811262 87 #endif
uci1 4:a91682e19d6b 88 if (seq==__kMaxUShort) {
uci1 6:6f002d202f59 89 newseq = seq;
uci1 6:6f002d202f59 90 break;
uci1 6:6f002d202f59 91 }
uci1 6:6f002d202f59 92 if (seq>=newseq) {
uci1 6:6f002d202f59 93 newseq=seq+1;
uci1 6:6f002d202f59 94 }
uci1 6:6f002d202f59 95 if (newseq==__kMaxUShort) {
uci1 4:a91682e19d6b 96 break;
uci1 4:a91682e19d6b 97 }
uci1 0:664899e0b988 98 }
uci1 0:664899e0b988 99 }
uci1 0:664899e0b988 100 closedir(d);
uci1 0:664899e0b988 101 }
uci1 7:079617408fec 102
uci1 6:6f002d202f59 103 return newseq;
uci1 0:664899e0b988 104 }
uci1 0:664899e0b988 105
uci1 3:24c5f0f50bf1 106 FILE* SnSDUtils::OpenExistingFile(const char* name, const bool setcurrent) {
uci1 0:664899e0b988 107 FILE* f = 0;
uci1 0:664899e0b988 108 if (name!=NULL) {
uci1 3:24c5f0f50bf1 109 f = OpenSDFile(name, "rb");
uci1 12:d472f9811262 110 /*
uci1 3:24c5f0f50bf1 111 if (setcurrent) {
uci1 3:24c5f0f50bf1 112 fgCurFile = f;
uci1 12:d472f9811262 113 strncpy(fgCurFileName, name, kFNBufSize-1);
uci1 12:d472f9811262 114 fgCurSeq = GetSeqNumFromFileName(fgCurFileName);
uci1 3:24c5f0f50bf1 115 }
uci1 12:d472f9811262 116 */
uci1 0:664899e0b988 117 }
uci1 0:664899e0b988 118 return f;
uci1 0:664899e0b988 119 }
uci1 0:664899e0b988 120
uci1 3:24c5f0f50bf1 121 FILE* SnSDUtils::OpenSDFile(const char* name, const char* mode) {
uci1 12:d472f9811262 122 // TODO: check if we have memory?
uci1 12:d472f9811262 123 std::string fn(name);
uci1 12:d472f9811262 124 if (strncmp(name, kSDsubDir, strlen(kSDsubDir))!=0) {
uci1 12:d472f9811262 125 // filename lacks directory
uci1 12:d472f9811262 126 fn = kSDsubDir;
uci1 12:d472f9811262 127 fn += "/";
uci1 12:d472f9811262 128 fn += name;
uci1 12:d472f9811262 129 }
uci1 12:d472f9811262 130 #ifdef DEBUG
uci1 12:d472f9811262 131 printf("OpenSDFile: %s, mode %s\r\n",fn.c_str(),mode);
uci1 12:d472f9811262 132 #endif
uci1 12:d472f9811262 133 FILE* f = fopen(fn.c_str(), mode);
uci1 1:e392595b4b76 134 //setvbuf(f, 0, _IONBF, 0); // no buffering
uci1 1:e392595b4b76 135 return f;
uci1 1:e392595b4b76 136 }
uci1 1:e392595b4b76 137
uci1 0:664899e0b988 138 FILE* SnSDUtils::OpenNewOutputFile(const uint64_t macadr,
uci1 8:95a325df1f6b 139 const uint32_t run) {
uci1 0:664899e0b988 140 // opens a new file in the specified directory and writes this
uci1 0:664899e0b988 141 // this mbed's mac address as the first sizeof(uint64_t) bytes (i.e. 4 bytes)
uci1 0:664899e0b988 142 //
uci1 12:d472f9811262 143 fgCurSeq = GetSeqNum(macadr, run);
uci1 0:664899e0b988 144 memset(fgCurFileName, 0, sizeof(char)*kFNBufSize);
uci1 12:d472f9811262 145 strncpy(fgCurFileName,GetOutFileName(macadr, run, fgCurSeq),kFNBufSize-1);
uci1 12:d472f9811262 146 //fprintf(stderr,"cur file = %s (%hu)\n\r",fgCurFileName,fgCurSeq);
uci1 1:e392595b4b76 147 fgCurFile = 0;
uci1 0:664899e0b988 148 if (fgCurFileName!=NULL) {
uci1 3:24c5f0f50bf1 149 fgCurFile = OpenSDFile(fgCurFileName, "wb");
uci1 2:e67f7c158087 150 if (fgCurFile!=NULL && ferror(fgCurFile)==0) {
uci1 12:d472f9811262 151 WriteFileHeader(fgCurFile, macadr, run, fgCurSeq);
uci1 2:e67f7c158087 152 }
uci1 0:664899e0b988 153 }
uci1 1:e392595b4b76 154 return fgCurFile;
uci1 0:664899e0b988 155 }
uci1 0:664899e0b988 156
uci1 0:664899e0b988 157 bool SnSDUtils::WriteEventTo(FILE* efile, char* const evtBuf,
uci1 0:664899e0b988 158 const SnEventFrame& evt,
uci1 0:664899e0b988 159 const SnConfigFrame& conf) {
uci1 0:664899e0b988 160 // write event to SD card
uci1 0:664899e0b988 161
uci1 0:664899e0b988 162 uint8_t sLoseLSB=0, sLoseMSB=0;
uci1 0:664899e0b988 163 uint16_t sWvBase=0;
uci1 0:664899e0b988 164 conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase);
uci1 8:95a325df1f6b 165 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kEventCode,
uci1 8:95a325df1f6b 166 evt.SizeOf(SnEventFrame::kIOVers, sLoseLSB, sLoseMSB));
uci1 0:664899e0b988 167 const bool ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase);
uci1 0:664899e0b988 168 fflush(efile);
uci1 0:664899e0b988 169 return ret;
uci1 0:664899e0b988 170 }
uci1 0:664899e0b988 171
uci1 0:664899e0b988 172 bool SnSDUtils::WriteConfig(FILE* efile,
uci1 0:664899e0b988 173 const SnConfigFrame& conf) {
uci1 8:95a325df1f6b 174 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kConfigCode,
uci1 8:95a325df1f6b 175 conf.SizeOf(SnConfigFrame::kIOVers));
uci1 0:664899e0b988 176 conf.WriteTo(efile);
uci1 0:664899e0b988 177 return true;
uci1 0:664899e0b988 178 }
uci1 0:664899e0b988 179
uci1 0:664899e0b988 180 void SnSDUtils::DeleteFile(FILE*& f, const char* fname) {
uci1 0:664899e0b988 181 fclose(f);
uci1 0:664899e0b988 182 f=0;
uci1 0:664899e0b988 183 remove(fname);
uci1 0:664899e0b988 184 }
uci1 0:664899e0b988 185
uci1 0:664899e0b988 186 SnCommWin::ECommWinResult SnSDUtils::SendAllFiles(SnCommWin* comm,
uci1 3:24c5f0f50bf1 187 const uint32_t timeout,
uci1 3:24c5f0f50bf1 188 char* const buf,
uci1 6:6f002d202f59 189 const uint32_t bsize,
uci1 6:6f002d202f59 190 const SnConfigFrame& curConf,
uci1 8:95a325df1f6b 191 SnEventFrame& evt,
uci1 12:d472f9811262 192 SnPowerFrame& pow,
uci1 12:d472f9811262 193 const uint32_t handshakeTimeout) {
uci1 16:744ce85aede2 194
uci1 0:664899e0b988 195 DIR* d;
uci1 0:664899e0b988 196 struct dirent* dent;
uci1 0:664899e0b988 197
uci1 16:744ce85aede2 198 SnCommWin::ECommWinResult rs = SnCommWin::kOkMsgSent;
uci1 0:664899e0b988 199
uci1 12:d472f9811262 200 const bool doDelete = curConf.IsDeletingFiles();
uci1 12:d472f9811262 201
uci1 0:664899e0b988 202 if ( (d = opendir( kSDsubDir ))!=NULL ) {
uci1 0:664899e0b988 203 FILE* f;
uci1 0:664899e0b988 204 while ( (dent = readdir(d))!=NULL ) {
uci1 0:664899e0b988 205 if (strncmp(dent->d_name, "SnEvts", 6)==0) {
uci1 1:e392595b4b76 206 const bool isCurFile =
uci1 1:e392595b4b76 207 (strcmp(dent->d_name, GetCurFileName())==0);
uci1 1:e392595b4b76 208 if (isCurFile) {
uci1 3:24c5f0f50bf1 209 // file must already be written out!
uci1 1:e392595b4b76 210 f = GetCurFile();
uci1 1:e392595b4b76 211 } else {
uci1 3:24c5f0f50bf1 212 f = OpenExistingFile(dent->d_name, false);
uci1 1:e392595b4b76 213 }
uci1 12:d472f9811262 214 #ifdef DEBUG
uci1 12:d472f9811262 215 printf("calling senddata: f=%p (cur %p), fn=%s\r\n",
uci1 12:d472f9811262 216 f, GetCurFile(), dent->d_name);
uci1 12:d472f9811262 217 #endif
uci1 16:744ce85aede2 218 const SnCommWin::ECommWinResult res =
uci1 16:744ce85aede2 219 comm->SendData(f, dent->d_name,
uci1 16:744ce85aede2 220 curConf, evt, pow, buf, bsize,
uci1 16:744ce85aede2 221 0, timeout, handshakeTimeout);
uci1 16:744ce85aede2 222 if (res<rs) {
uci1 16:744ce85aede2 223 rs = res;
uci1 16:744ce85aede2 224 }
uci1 16:744ce85aede2 225 // don't stop if res is bad. don't want one bad file to
uci1 16:744ce85aede2 226 // prevent sending the others
uci1 16:744ce85aede2 227
uci1 12:d472f9811262 228 // send data should close or delete the file (if appropriate)
uci1 12:d472f9811262 229 // unless it's the current file
uci1 3:24c5f0f50bf1 230 if (isCurFile) {
uci1 3:24c5f0f50bf1 231 // move (back) to the end of the file
uci1 3:24c5f0f50bf1 232 // altho hopefully no writing will happen after this
uci1 3:24c5f0f50bf1 233 fseek(fgCurFile, 0, SEEK_END);
uci1 0:664899e0b988 234 }
uci1 0:664899e0b988 235 }
uci1 0:664899e0b988 236 }
uci1 0:664899e0b988 237 closedir(d);
uci1 0:664899e0b988 238 }
uci1 0:664899e0b988 239
uci1 0:664899e0b988 240 return rs;
uci1 0:664899e0b988 241 }
uci1 0:664899e0b988 242