Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Fri Aug 31 02:09:09 2012 +0000
Revision:
15:f2569d8e4176
Parent:
12:d472f9811262
Child:
16:744ce85aede2
Removed debug output between trigger and and dFPGA->MB request that corrupted data. Lots of work on SBD, but not quite working yet. Debug output off, but start/stop running notifications are on.

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 0:664899e0b988 194
uci1 0:664899e0b988 195 DIR* d;
uci1 0:664899e0b988 196 struct dirent* dent;
uci1 0:664899e0b988 197
uci1 0:664899e0b988 198 SnCommWin::ECommWinResult rs = SnCommWin::kUndefFail;
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 6:6f002d202f59 218 rs = comm->SendData(f, dent->d_name,
uci1 8:95a325df1f6b 219 curConf, evt, pow, buf, bsize,
uci1 12:d472f9811262 220 0, timeout, handshakeTimeout);
uci1 12:d472f9811262 221 // send data should close or delete the file (if appropriate)
uci1 12:d472f9811262 222 // unless it's the current file
uci1 3:24c5f0f50bf1 223 if (isCurFile) {
uci1 3:24c5f0f50bf1 224 // move (back) to the end of the file
uci1 3:24c5f0f50bf1 225 // altho hopefully no writing will happen after this
uci1 3:24c5f0f50bf1 226 fseek(fgCurFile, 0, SEEK_END);
uci1 0:664899e0b988 227 }
uci1 0:664899e0b988 228 }
uci1 0:664899e0b988 229 }
uci1 0:664899e0b988 230 closedir(d);
uci1 0:664899e0b988 231 }
uci1 0:664899e0b988 232
uci1 0:664899e0b988 233 return rs;
uci1 0:664899e0b988 234 }
uci1 0:664899e0b988 235