Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Fri Aug 10 18:35:43 2012 +0000
Revision:
10:3c93db1cfb12
Parent:
8:95a325df1f6b
Child:
12:d472f9811262
Ensure that lockRegisters (p20) is 0 before accessing the SD card, for example when closing the file. This fixes an issue seen when running in power count mode. Communications still under dev. Many debug outputs.

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 10:3c93db1cfb12 47 uint16_t SnSDUtils::GetCurSeqNum() {
uci1 10:3c93db1cfb12 48 return GetSeqNumFromFileName(fgCurFileName);
uci1 10:3c93db1cfb12 49 }
uci1 10:3c93db1cfb12 50
uci1 10:3c93db1cfb12 51 uint16_t SnSDUtils::GetSeqNumFromFileName(const char* fn) {
uci1 10:3c93db1cfb12 52 uint16_t seq=0;
uci1 10:3c93db1cfb12 53 const uint32_t ncomp = strrchr(fn, 's') - fn;
uci1 10:3c93db1cfb12 54 if (ncomp<strlen(fn)) {
uci1 10:3c93db1cfb12 55 sscanf(fn+ncomp,"s%hu.dat",&seq);
uci1 10:3c93db1cfb12 56 }
uci1 10:3c93db1cfb12 57 return seq;
uci1 10:3c93db1cfb12 58 }
uci1 10:3c93db1cfb12 59
uci1 0:664899e0b988 60 uint16_t SnSDUtils::GetSeqNum(const uint64_t macadr,
uci1 0:664899e0b988 61 const uint32_t run) {
uci1 0:664899e0b988 62 // count the files having expected filename format
uci1 0:664899e0b988 63
uci1 0:664899e0b988 64 const char* fn = GetOutFileName(macadr, run, 0)
uci1 0:664899e0b988 65 + strlen(kSDsubDir) + 1; // take out dir and '/'s
uci1 0:664899e0b988 66
uci1 0:664899e0b988 67 DIR* d;
uci1 0:664899e0b988 68 struct dirent* dent;
uci1 0:664899e0b988 69
uci1 6:6f002d202f59 70 uint16_t seq=0, newseq=0;
uci1 0:664899e0b988 71 if ( (d = opendir( kSDsubDir ))!=NULL ) {
uci1 0:664899e0b988 72 // don't compare seq#. don't use num of chars in case seq is >999
uci1 0:664899e0b988 73 const uint32_t ncomp = strrchr(fn, 's') - fn;
uci1 0:664899e0b988 74 while ( (dent = readdir(d))!=NULL ) {
uci1 0:664899e0b988 75 if (strncmp(dent->d_name, fn, ncomp)==0) {
uci1 6:6f002d202f59 76 // allow for deleted files to make gaps.
uci1 6:6f002d202f59 77 // search for highest seq number and increase that
uci1 7:079617408fec 78 sscanf((dent->d_name)+ncomp,"s%hu.dat",&seq);
uci1 7:079617408fec 79 /*
uci1 7:079617408fec 80 printf("dn=%s, seq=%hu, __kMaxUShort=%hu\r\n",
uci1 7:079617408fec 81 dent->d_name, seq, __kMaxUShort);
uci1 7:079617408fec 82 */
uci1 4:a91682e19d6b 83 if (seq==__kMaxUShort) {
uci1 6:6f002d202f59 84 newseq = seq;
uci1 6:6f002d202f59 85 break;
uci1 6:6f002d202f59 86 }
uci1 6:6f002d202f59 87 if (seq>=newseq) {
uci1 6:6f002d202f59 88 newseq=seq+1;
uci1 6:6f002d202f59 89 }
uci1 6:6f002d202f59 90 if (newseq==__kMaxUShort) {
uci1 4:a91682e19d6b 91 break;
uci1 4:a91682e19d6b 92 }
uci1 0:664899e0b988 93 }
uci1 0:664899e0b988 94 }
uci1 0:664899e0b988 95 closedir(d);
uci1 0:664899e0b988 96 }
uci1 7:079617408fec 97
uci1 6:6f002d202f59 98 return newseq;
uci1 0:664899e0b988 99 }
uci1 0:664899e0b988 100
uci1 3:24c5f0f50bf1 101 FILE* SnSDUtils::OpenExistingFile(const char* name, const bool setcurrent) {
uci1 0:664899e0b988 102 FILE* f = 0;
uci1 0:664899e0b988 103 if (name!=NULL) {
uci1 3:24c5f0f50bf1 104 f = OpenSDFile(name, "rb");
uci1 3:24c5f0f50bf1 105 if (setcurrent) {
uci1 3:24c5f0f50bf1 106 fgCurFile = f;
uci1 3:24c5f0f50bf1 107 }
uci1 0:664899e0b988 108 }
uci1 0:664899e0b988 109 return f;
uci1 0:664899e0b988 110 }
uci1 0:664899e0b988 111
uci1 3:24c5f0f50bf1 112 FILE* SnSDUtils::OpenSDFile(const char* name, const char* mode) {
uci1 3:24c5f0f50bf1 113 FILE* f = fopen(name, mode);
uci1 1:e392595b4b76 114 //setvbuf(f, 0, _IONBF, 0); // no buffering
uci1 1:e392595b4b76 115 return f;
uci1 1:e392595b4b76 116 }
uci1 1:e392595b4b76 117
uci1 0:664899e0b988 118 FILE* SnSDUtils::OpenNewOutputFile(const uint64_t macadr,
uci1 8:95a325df1f6b 119 const uint32_t run) {
uci1 0:664899e0b988 120 // opens a new file in the specified directory and writes this
uci1 0:664899e0b988 121 // this mbed's mac address as the first sizeof(uint64_t) bytes (i.e. 4 bytes)
uci1 0:664899e0b988 122 //
uci1 0:664899e0b988 123 const uint16_t seq = GetSeqNum(macadr, run);
uci1 0:664899e0b988 124 memset(fgCurFileName, 0, sizeof(char)*kFNBufSize);
uci1 2:e67f7c158087 125 strncpy(fgCurFileName,GetOutFileName(macadr, run, seq),kFNBufSize-1);
uci1 0:664899e0b988 126 //fprintf(stderr,"cur file = %s (%hu)\n\r",fgCurFileName,seq);
uci1 1:e392595b4b76 127 fgCurFile = 0;
uci1 0:664899e0b988 128 if (fgCurFileName!=NULL) {
uci1 3:24c5f0f50bf1 129 fgCurFile = OpenSDFile(fgCurFileName, "wb");
uci1 2:e67f7c158087 130 if (fgCurFile!=NULL && ferror(fgCurFile)==0) {
uci1 8:95a325df1f6b 131 WriteFileHeader(fgCurFile, macadr, run, seq);
uci1 2:e67f7c158087 132 }
uci1 0:664899e0b988 133 }
uci1 1:e392595b4b76 134 return fgCurFile;
uci1 0:664899e0b988 135 }
uci1 0:664899e0b988 136
uci1 0:664899e0b988 137 bool SnSDUtils::WriteEventTo(FILE* efile, char* const evtBuf,
uci1 0:664899e0b988 138 const SnEventFrame& evt,
uci1 0:664899e0b988 139 const SnConfigFrame& conf) {
uci1 0:664899e0b988 140 // write event to SD card
uci1 0:664899e0b988 141
uci1 0:664899e0b988 142 uint8_t sLoseLSB=0, sLoseMSB=0;
uci1 0:664899e0b988 143 uint16_t sWvBase=0;
uci1 0:664899e0b988 144 conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase);
uci1 8:95a325df1f6b 145 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kEventCode,
uci1 8:95a325df1f6b 146 evt.SizeOf(SnEventFrame::kIOVers, sLoseLSB, sLoseMSB));
uci1 0:664899e0b988 147 const bool ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase);
uci1 0:664899e0b988 148 fflush(efile);
uci1 0:664899e0b988 149 return ret;
uci1 0:664899e0b988 150 }
uci1 0:664899e0b988 151
uci1 0:664899e0b988 152 bool SnSDUtils::WriteConfig(FILE* efile,
uci1 0:664899e0b988 153 const SnConfigFrame& conf) {
uci1 8:95a325df1f6b 154 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kConfigCode,
uci1 8:95a325df1f6b 155 conf.SizeOf(SnConfigFrame::kIOVers));
uci1 0:664899e0b988 156 conf.WriteTo(efile);
uci1 0:664899e0b988 157 return true;
uci1 0:664899e0b988 158 }
uci1 0:664899e0b988 159
uci1 0:664899e0b988 160 void SnSDUtils::DeleteFile(FILE*& f, const char* fname) {
uci1 0:664899e0b988 161 fclose(f);
uci1 0:664899e0b988 162 f=0;
uci1 0:664899e0b988 163 remove(fname);
uci1 0:664899e0b988 164 }
uci1 0:664899e0b988 165
uci1 0:664899e0b988 166 SnCommWin::ECommWinResult SnSDUtils::SendAllFiles(SnCommWin* comm,
uci1 3:24c5f0f50bf1 167 const bool doDelete,
uci1 3:24c5f0f50bf1 168 const uint32_t timeout,
uci1 3:24c5f0f50bf1 169 char* const buf,
uci1 6:6f002d202f59 170 const uint32_t bsize,
uci1 6:6f002d202f59 171 const SnConfigFrame& curConf,
uci1 8:95a325df1f6b 172 SnEventFrame& evt,
uci1 8:95a325df1f6b 173 SnPowerFrame& pow) {
uci1 0:664899e0b988 174
uci1 0:664899e0b988 175 DIR* d;
uci1 0:664899e0b988 176 struct dirent* dent;
uci1 0:664899e0b988 177
uci1 0:664899e0b988 178 SnCommWin::ECommWinResult rs = SnCommWin::kUndefFail;
uci1 0:664899e0b988 179
uci1 0:664899e0b988 180 if ( (d = opendir( kSDsubDir ))!=NULL ) {
uci1 0:664899e0b988 181 FILE* f;
uci1 0:664899e0b988 182 while ( (dent = readdir(d))!=NULL ) {
uci1 0:664899e0b988 183 if (strncmp(dent->d_name, "SnEvts", 6)==0) {
uci1 1:e392595b4b76 184 const bool isCurFile =
uci1 1:e392595b4b76 185 (strcmp(dent->d_name, GetCurFileName())==0);
uci1 1:e392595b4b76 186 if (isCurFile) {
uci1 3:24c5f0f50bf1 187 // file must already be written out!
uci1 1:e392595b4b76 188 f = GetCurFile();
uci1 1:e392595b4b76 189 } else {
uci1 3:24c5f0f50bf1 190 f = OpenExistingFile(dent->d_name, false);
uci1 1:e392595b4b76 191 }
uci1 6:6f002d202f59 192 rs = comm->SendData(f, dent->d_name,
uci1 8:95a325df1f6b 193 curConf, evt, pow, buf, bsize,
uci1 6:6f002d202f59 194 0, timeout, 0);
uci1 3:24c5f0f50bf1 195 if (isCurFile) {
uci1 3:24c5f0f50bf1 196 // move (back) to the end of the file
uci1 3:24c5f0f50bf1 197 // altho hopefully no writing will happen after this
uci1 3:24c5f0f50bf1 198 fseek(fgCurFile, 0, SEEK_END);
uci1 0:664899e0b988 199 }
uci1 0:664899e0b988 200 }
uci1 0:664899e0b988 201 }
uci1 0:664899e0b988 202 closedir(d);
uci1 0:664899e0b988 203 }
uci1 0:664899e0b988 204
uci1 0:664899e0b988 205 return rs;
uci1 0:664899e0b988 206 }
uci1 0:664899e0b988 207