S K UCI / Mbed 2 deprecated AutonomousDAQ

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

SnCommUsb.cpp

Committer:
uci1
Date:
2012-08-02
Revision:
4:a91682e19d6b
Parent:
3:24c5f0f50bf1
Child:
6:6f002d202f59

File content as of revision 4:a91682e19d6b:

#include "SnCommUsb.h"

#include "Timer.h"

#include "SnStatusFrame.h"
#include "SnConfigFrame.h"
#include "SnEventFrame.h"
#include "SnHeaderFrame.h"
#include "SnSDUtils.h"

MODSERIAL* SnCommUsb::fgCpu     =  0;

void __Recv(MODSERIAL_IRQ_INFO* s) {
    static DigitalOut led4(LED4);
    static DigitalOut led3(LED3);
    for (uint8_t i=0; i<20; i++) {
        led4=!led4;
        led3=!led3;
        wait(0.1);
    }
}

SnCommWin::ECommWinResult SnCommUsb::SetupPort(MODSERIAL& cpu) {
    fgCpu = &cpu;
    
    // set up serial-usb port
    fgCpu->baud( 230400 );
    fgCpu->format( 8, Serial::None, 1 );
    fgCpu->txBufferFlush();
    fgCpu->rxBufferFlush();
    //fgCpu->attach(&__Recv, MODSERIAL::RxIrq);
    return kOkNoMsg;
}


SnCommWin::ECommWinResult SnCommUsb::OpenWindow(const uint32_t timeout,
                                                const bool sendStatus,
                                                const SnConfigFrame& conf,
                                                const SnEventFrame& evt,
                                                char* const genBuf) {
    // usb port always connected (or never)
    SnCommWin::ECommWinResult ret = SnCommWin::kConnected;
    
    if (sendStatus) {
        ret = SendStatus(conf, evt, genBuf);
    }
    
    return ret;
}

SnCommWin::ECommWinResult SnCommUsb::WaitHandshake(const uint32_t timeout,
                                                   char* const buf,
                                                   const uint32_t bsize) {
    printf("WaitHandshake, to=%u\r\n",timeout);
    
    bool hasData = fgCpu->readable()==1;
        
    while ( (hasData==false) && (time(0) < timeout) ) {        
        wait_ms(10);
        
        hasData = fgCpu->readable()==1;
    }
    
    if( hasData ) {
        uint8_t  mcode;
        uint32_t mlen;
        SnHeaderFrame::ReadFrom(*fgCpu, mcode, mlen);
        if (mcode==SnHeaderFrame::kHandshakeCode) {
            return SnCommWin::kOkWithMsg;
        } else {
            // TODO: somehow handle unexpected message?
            return SnCommWin::kUnexpectedRec;
        }
    } else {
        return SnCommWin::kOkNoMsg;
    }
}

SnCommWin::ECommWinResult SnCommUsb::GetConfig(SnConfigFrame& conf,
                                               const uint32_t timeOut,
                                               char* const confBuf,
                                               const uint32_t bsize) {
    // confBuf not used by usb. bytes read directly from serial port
    
    SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
    
    bool hasData = fgCpu->readable()==1;
        
    while ( (hasData==false) && (time(0) < timeOut) ) {        
        wait_ms(10);
        
        hasData = fgCpu->readable()==1;
    }
    
    if( hasData ) {
        uint8_t  mcode;
        uint32_t mlen;
        SnHeaderFrame::ReadFrom(*fgCpu, mcode, mlen);
        // TODO: do something with the header info?
        conf.ReadFrom(*fgCpu);
        res = SnCommWin::kOkWithMsg;
    } else {
        res = SnCommWin::kOkNoMsg;
    }
    
    return res;
}

SnCommWin::ECommWinResult SnCommUsb::SendFilename(const char* fn, char* const genBuf) {
    const size_t flen = strlen(fn);
    bool ok = SnHeaderFrame::WriteTo(*fgCpu,
        SnHeaderFrame::kFilenameCode,
        SnHeaderFrame::SizeOf());
    if (ok) {
        ok = SendBytes(fn, flen);
    }
    return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
}

SnCommWin::ECommWinResult SnCommUsb::SendStatus(const SnConfigFrame& conf,
                                                const SnEventFrame& evt,
                                                char* const genBuf) {
    const bool ok = SnHeaderFrame::WriteTo(*fgCpu,
        SnHeaderFrame::kStatusCode, SnStatusFrame::SizeOf(conf));
    if (ok) {
        return SnStatusFrame::WriteTo(*fgCpu, SnConfigFrame::kUSB, conf, evt, genBuf);
    } else {
        return SnCommWin::kFailNoneSent;
    }
}

SnCommWin::ECommWinResult SnCommUsb::SendData(FILE* inf) {
    const int foff = ftell(inf);
    fseek(inf, 0, SEEK_END);
    const int fsize = ftell(inf) - foff;
    fseek(inf, foff, SEEK_SET);
    if (fsize>0) {
        SnHeaderFrame::WriteTo(*fgCpu,
            SnHeaderFrame::kFileCode, fsize);
        SendBytes(inf, fsize);
        return SnCommWin::kOkMsgSent;
    } else {
        return SnCommWin::kFailNoneSent;
    }
}

bool SnCommUsb::SendBytes(FILE* f, const uint32_t nbytes) {
    register uint32_t i=0;
    for (i=0; (i<nbytes) 
           && (feof(f)==0) 
           && (ferror(f)==0); i++) {
        fgCpu->putc( getc(f) );
    }
    return (i==nbytes);
}

bool SnCommUsb::SendBytes(const char* const buf,
                          const uint32_t nbytes) {
    const char* b = buf;
    for (uint32_t j=0; j<nbytes; j++, b++) {
        fgCpu->putc( *b );
    }
    return true;
}

SnCommWin::ECommWinResult SnCommUsb::SendConfAndEvents(FILE* inf,
                                                    const SnConfigFrame& curConf,
                                                    SnEventFrame& evt,
                                                    char* const genBuf,
                                                    const uint32_t nevts,
                                                    const uint32_t firstEvt) {
    // firstEvt==0 ==> start at beginning
    // nevts==0 ==> NO events! (see SnCommWin::SendData
    //    for the fcn to send the full file)
    
    // TODO: check memory for temporary config/event frames?
    uint64_t macadr;
    uint32_t run;
    uint16_t seq, v1, v2;
    SnSDUtils::ReadFileHeader(inf, macadr, run, seq, v1, v2);
    SnConfigFrame conf;
    conf.ReadFrom(inf);

    uint8_t sLoseLSB=0, sLoseMSB=0;
    uint16_t sWvBase=0;
    curConf.GetPackParsFor(SnConfigFrame::kUSB, sLoseLSB, sLoseMSB, sWvBase);
    // do we have to unpack & repack events?
    const bool repack =    (sLoseLSB != conf.GetWvLoseLSB())
                        && (sLoseMSB != conf.GetWvLoseMSB())
                        && (sWvBase  != conf.GetWvBaseline());
    
    // size of event in file
    const uint32_t esize = SnEventFrame::SizeOf(conf.GetWvLoseLSB(),
                                                conf.GetWvLoseMSB());
    // move up to first event
    const uint32_t csize = conf.SizeOf();
    fseek(inf, csize + (firstEvt*esize), SEEK_SET);

    // send the header and conf
    char* b = genBuf;
    SnHeaderFrame::WriteTo(b,
        SnHeaderFrame::kConfAndEvtsCode, csize);
    conf.WriteTo(b);
    bool ok = SendBytes(genBuf, csize);

    // size of event sent over afar
    const uint32_t ssize = (repack) ?
        SnEventFrame::SizeOf(sLoseLSB, sLoseMSB) :
        esize;
    
    for (uint32_t i=0; i<nevts; i++) {
        if (repack) {
            evt.ReadFrom(inf, genBuf,
                conf.GetWvLoseLSB(), conf.GetWvLoseMSB(),
                conf.GetWvBaseline());
            evt.WriteTo(genBuf, sLoseLSB, sLoseMSB, sWvBase);
            
            ok &= SendBytes(SnHeaderFrame::GetHdBuf(SnHeaderFrame::kEventCode,
                                              ssize),
                            SnHeaderFrame::SizeOf());
            ok &= SendBytes(genBuf, 
                    evt.SizeOf(conf.GetWvLoseLSB(), conf.GetWvLoseMSB()));
        } else {
            ok &= SendBytes(SnHeaderFrame::GetHdBuf(SnHeaderFrame::kEventCode,
                                              ssize),
                            SnHeaderFrame::SizeOf());
            ok &= SendBytes(inf, ssize);
        }
    }
    return ok ? SnCommWin::kOkMsgSent : SnCommWin::kFailPartSent;
}