Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Aug 08 23:27:37 2012 +0000
Revision:
8:95a325df1f6b
Parent:
7:079617408fec
Child:
10:3c93db1cfb12
Check power for low pow running. Average power over 500 readings. Use RTOS timers instead of tickers. Allow data taking of events, power readings or both, even if cards are off. Bug in EthernetInterface prevents IPs being reset. Lots of debug 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 0:664899e0b988 6
uci1 0:664899e0b988 7 #include "SnConfigFrame.h"
uci1 0:664899e0b988 8 #include "SnEventFrame.h"
uci1 0:664899e0b988 9
uci1 0:664899e0b988 10
uci1 1:e392595b4b76 11 const char* const SnSDUtils::kSDsubDir = "/sd";
uci1 2:e67f7c158087 12 char SnSDUtils::fgCurFileName[kFNBufSize]={0};
uci1 1:e392595b4b76 13 FILE* SnSDUtils::fgCurFile = 0;
uci1 8:95a325df1f6b 14 const uint8_t SnSDUtils::kIOvers = 3;
uci1 5:9cea89700c66 15 const uint32_t SnSDUtils::kMaxSizeOfFileHdr =
uci1 5:9cea89700c66 16 sizeof(uint8_t)+sizeof(uint64_t)+sizeof(uint32_t)+sizeof(uint16_t)
uci1 8:95a325df1f6b 17 +(sizeof(uint8_t)+(2u*sizeof(uint16_t))); // power frame v1
uci1 4:a91682e19d6b 18
uci1 4:a91682e19d6b 19 static const uint16_t __kMaxUShort = ~0;
uci1 0:664899e0b988 20
uci1 0:664899e0b988 21 const char* SnSDUtils::GetOutFileName(const uint64_t macadr,
uci1 0:664899e0b988 22 const uint32_t run,
uci1 0:664899e0b988 23 const uint16_t seq) {
uci1 0:664899e0b988 24 // returns the formatted file name, or NULL if the directory is too long
uci1 0:664899e0b988 25 // and the full name cannot fit in the buffer
uci1 0:664899e0b988 26 // NOTE: this fcn uses a static buffer, and so should not be called
uci1 0:664899e0b988 27 // multiple times in the same line (that includes the calling of functions
uci1 0:664899e0b988 28 // that call this function!)
uci1 0:664899e0b988 29 //
uci1 0:664899e0b988 30 // filename = SnEvtsM[6-byte hex mac adr]r[6-digit run num]s[5-digit seq num].dat
uci1 0:664899e0b988 31 // 35 chars 7 + 12 +1+ 5 +1+ 5 + 4
uci1 0:664899e0b988 32
uci1 0:664899e0b988 33 if (strlen(kSDsubDir)<(kFNBufSize-37)) {
uci1 0:664899e0b988 34 static char tbuf[kFNBufSize];
uci1 0:664899e0b988 35 memset(tbuf, 0, sizeof(char)*kFNBufSize);
uci1 0:664899e0b988 36 // if file name format changes, GetSeqNum must be changed too
uci1 0:664899e0b988 37 sprintf(tbuf, "%s/SnEvtsM%012llXr%05ds%05d.dat",
uci1 0:664899e0b988 38 kSDsubDir,
uci1 0:664899e0b988 39 macadr>>16, // 64 -> 48 bits
uci1 0:664899e0b988 40 run, seq);
uci1 0:664899e0b988 41 return tbuf;
uci1 0:664899e0b988 42 } else {
uci1 0:664899e0b988 43 return NULL;
uci1 0:664899e0b988 44 }
uci1 0:664899e0b988 45 }
uci1 0:664899e0b988 46
uci1 0:664899e0b988 47 uint16_t SnSDUtils::GetSeqNum(const uint64_t macadr,
uci1 0:664899e0b988 48 const uint32_t run) {
uci1 0:664899e0b988 49 // count the files having expected filename format
uci1 0:664899e0b988 50
uci1 0:664899e0b988 51 const char* fn = GetOutFileName(macadr, run, 0)
uci1 0:664899e0b988 52 + strlen(kSDsubDir) + 1; // take out dir and '/'s
uci1 0:664899e0b988 53
uci1 0:664899e0b988 54 DIR* d;
uci1 0:664899e0b988 55 struct dirent* dent;
uci1 0:664899e0b988 56
uci1 6:6f002d202f59 57 uint16_t seq=0, newseq=0;
uci1 0:664899e0b988 58 if ( (d = opendir( kSDsubDir ))!=NULL ) {
uci1 0:664899e0b988 59 // don't compare seq#. don't use num of chars in case seq is >999
uci1 0:664899e0b988 60 const uint32_t ncomp = strrchr(fn, 's') - fn;
uci1 0:664899e0b988 61 while ( (dent = readdir(d))!=NULL ) {
uci1 0:664899e0b988 62 if (strncmp(dent->d_name, fn, ncomp)==0) {
uci1 6:6f002d202f59 63 // allow for deleted files to make gaps.
uci1 6:6f002d202f59 64 // search for highest seq number and increase that
uci1 7:079617408fec 65 sscanf((dent->d_name)+ncomp,"s%hu.dat",&seq);
uci1 7:079617408fec 66 /*
uci1 7:079617408fec 67 printf("dn=%s, seq=%hu, __kMaxUShort=%hu\r\n",
uci1 7:079617408fec 68 dent->d_name, seq, __kMaxUShort);
uci1 7:079617408fec 69 */
uci1 4:a91682e19d6b 70 if (seq==__kMaxUShort) {
uci1 6:6f002d202f59 71 newseq = seq;
uci1 6:6f002d202f59 72 break;
uci1 6:6f002d202f59 73 }
uci1 6:6f002d202f59 74 if (seq>=newseq) {
uci1 6:6f002d202f59 75 newseq=seq+1;
uci1 6:6f002d202f59 76 }
uci1 6:6f002d202f59 77 if (newseq==__kMaxUShort) {
uci1 4:a91682e19d6b 78 break;
uci1 4:a91682e19d6b 79 }
uci1 0:664899e0b988 80 }
uci1 0:664899e0b988 81 }
uci1 0:664899e0b988 82 closedir(d);
uci1 0:664899e0b988 83 }
uci1 7:079617408fec 84
uci1 6:6f002d202f59 85 return newseq;
uci1 0:664899e0b988 86 }
uci1 0:664899e0b988 87
uci1 3:24c5f0f50bf1 88 FILE* SnSDUtils::OpenExistingFile(const char* name, const bool setcurrent) {
uci1 0:664899e0b988 89 FILE* f = 0;
uci1 0:664899e0b988 90 if (name!=NULL) {
uci1 3:24c5f0f50bf1 91 f = OpenSDFile(name, "rb");
uci1 3:24c5f0f50bf1 92 if (setcurrent) {
uci1 3:24c5f0f50bf1 93 fgCurFile = f;
uci1 3:24c5f0f50bf1 94 }
uci1 0:664899e0b988 95 }
uci1 0:664899e0b988 96 return f;
uci1 0:664899e0b988 97 }
uci1 0:664899e0b988 98
uci1 3:24c5f0f50bf1 99 FILE* SnSDUtils::OpenSDFile(const char* name, const char* mode) {
uci1 3:24c5f0f50bf1 100 FILE* f = fopen(name, mode);
uci1 1:e392595b4b76 101 //setvbuf(f, 0, _IONBF, 0); // no buffering
uci1 1:e392595b4b76 102 return f;
uci1 1:e392595b4b76 103 }
uci1 1:e392595b4b76 104
uci1 0:664899e0b988 105 FILE* SnSDUtils::OpenNewOutputFile(const uint64_t macadr,
uci1 8:95a325df1f6b 106 const uint32_t run) {
uci1 0:664899e0b988 107 // opens a new file in the specified directory and writes this
uci1 0:664899e0b988 108 // this mbed's mac address as the first sizeof(uint64_t) bytes (i.e. 4 bytes)
uci1 0:664899e0b988 109 //
uci1 0:664899e0b988 110 const uint16_t seq = GetSeqNum(macadr, run);
uci1 0:664899e0b988 111 memset(fgCurFileName, 0, sizeof(char)*kFNBufSize);
uci1 2:e67f7c158087 112 strncpy(fgCurFileName,GetOutFileName(macadr, run, seq),kFNBufSize-1);
uci1 0:664899e0b988 113 //fprintf(stderr,"cur file = %s (%hu)\n\r",fgCurFileName,seq);
uci1 1:e392595b4b76 114 fgCurFile = 0;
uci1 0:664899e0b988 115 if (fgCurFileName!=NULL) {
uci1 3:24c5f0f50bf1 116 fgCurFile = OpenSDFile(fgCurFileName, "wb");
uci1 2:e67f7c158087 117 if (fgCurFile!=NULL && ferror(fgCurFile)==0) {
uci1 8:95a325df1f6b 118 WriteFileHeader(fgCurFile, macadr, run, seq);
uci1 2:e67f7c158087 119 }
uci1 0:664899e0b988 120 }
uci1 1:e392595b4b76 121 return fgCurFile;
uci1 0:664899e0b988 122 }
uci1 0:664899e0b988 123
uci1 0:664899e0b988 124 bool SnSDUtils::WriteEventTo(FILE* efile, char* const evtBuf,
uci1 0:664899e0b988 125 const SnEventFrame& evt,
uci1 0:664899e0b988 126 const SnConfigFrame& conf) {
uci1 0:664899e0b988 127 // write event to SD card
uci1 0:664899e0b988 128
uci1 0:664899e0b988 129 uint8_t sLoseLSB=0, sLoseMSB=0;
uci1 0:664899e0b988 130 uint16_t sWvBase=0;
uci1 0:664899e0b988 131 conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase);
uci1 8:95a325df1f6b 132 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kEventCode,
uci1 8:95a325df1f6b 133 evt.SizeOf(SnEventFrame::kIOVers, sLoseLSB, sLoseMSB));
uci1 0:664899e0b988 134 const bool ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase);
uci1 0:664899e0b988 135 fflush(efile);
uci1 0:664899e0b988 136 return ret;
uci1 0:664899e0b988 137 }
uci1 0:664899e0b988 138
uci1 0:664899e0b988 139 bool SnSDUtils::WriteConfig(FILE* efile,
uci1 0:664899e0b988 140 const SnConfigFrame& conf) {
uci1 8:95a325df1f6b 141 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kConfigCode,
uci1 8:95a325df1f6b 142 conf.SizeOf(SnConfigFrame::kIOVers));
uci1 0:664899e0b988 143 conf.WriteTo(efile);
uci1 0:664899e0b988 144 return true;
uci1 0:664899e0b988 145 }
uci1 0:664899e0b988 146
uci1 0:664899e0b988 147 void SnSDUtils::DeleteFile(FILE*& f, const char* fname) {
uci1 0:664899e0b988 148 fclose(f);
uci1 0:664899e0b988 149 f=0;
uci1 0:664899e0b988 150 remove(fname);
uci1 0:664899e0b988 151 }
uci1 0:664899e0b988 152
uci1 0:664899e0b988 153 SnCommWin::ECommWinResult SnSDUtils::SendAllFiles(SnCommWin* comm,
uci1 3:24c5f0f50bf1 154 const bool doDelete,
uci1 3:24c5f0f50bf1 155 const uint32_t timeout,
uci1 3:24c5f0f50bf1 156 char* const buf,
uci1 6:6f002d202f59 157 const uint32_t bsize,
uci1 6:6f002d202f59 158 const SnConfigFrame& curConf,
uci1 8:95a325df1f6b 159 SnEventFrame& evt,
uci1 8:95a325df1f6b 160 SnPowerFrame& pow) {
uci1 0:664899e0b988 161
uci1 0:664899e0b988 162 DIR* d;
uci1 0:664899e0b988 163 struct dirent* dent;
uci1 0:664899e0b988 164
uci1 0:664899e0b988 165 SnCommWin::ECommWinResult rs = SnCommWin::kUndefFail;
uci1 0:664899e0b988 166
uci1 0:664899e0b988 167 if ( (d = opendir( kSDsubDir ))!=NULL ) {
uci1 0:664899e0b988 168 FILE* f;
uci1 0:664899e0b988 169 while ( (dent = readdir(d))!=NULL ) {
uci1 0:664899e0b988 170 if (strncmp(dent->d_name, "SnEvts", 6)==0) {
uci1 1:e392595b4b76 171 const bool isCurFile =
uci1 1:e392595b4b76 172 (strcmp(dent->d_name, GetCurFileName())==0);
uci1 1:e392595b4b76 173 if (isCurFile) {
uci1 3:24c5f0f50bf1 174 // file must already be written out!
uci1 1:e392595b4b76 175 f = GetCurFile();
uci1 1:e392595b4b76 176 } else {
uci1 3:24c5f0f50bf1 177 f = OpenExistingFile(dent->d_name, false);
uci1 1:e392595b4b76 178 }
uci1 6:6f002d202f59 179 rs = comm->SendData(f, dent->d_name,
uci1 8:95a325df1f6b 180 curConf, evt, pow, buf, bsize,
uci1 6:6f002d202f59 181 0, timeout, 0);
uci1 3:24c5f0f50bf1 182 if (isCurFile) {
uci1 3:24c5f0f50bf1 183 // move (back) to the end of the file
uci1 3:24c5f0f50bf1 184 // altho hopefully no writing will happen after this
uci1 3:24c5f0f50bf1 185 fseek(fgCurFile, 0, SEEK_END);
uci1 0:664899e0b988 186 }
uci1 0:664899e0b988 187 }
uci1 0:664899e0b988 188 }
uci1 0:664899e0b988 189 closedir(d);
uci1 0:664899e0b988 190 }
uci1 0:664899e0b988 191
uci1 0:664899e0b988 192 return rs;
uci1 0:664899e0b988 193 }
uci1 0:664899e0b988 194