Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
Diff: main.cpp
- Revision:
- 119:b3d7699d0eb0
- Parent:
- 116:8099b754fbb4
- Child:
- 122:c1b5023eac69
--- a/main.cpp Mon Oct 24 19:10:43 2016 +0000 +++ b/main.cpp Thu Sep 21 17:53:35 2017 +0000 @@ -50,8 +50,8 @@ #include "SDFileSystem.h" #ifdef USE_MODSERIAL -#define MODSERIAL_RX_BUF_SIZE 512 -#define MODSERIAL_TX_BUF_SIZE 512 +#define MODSERIAL_RX_BUF_SIZE 512//Geoffs512 +#define MODSERIAL_TX_BUF_SIZE 512//Geoffs512 #include "MODSERIAL.h" #endif // USE_MODSERIAL #include "FATDirHandle.h" @@ -262,6 +262,13 @@ void procTempCheck(void const *) { return procTempCheck(); } #endif // USE_RTOS +#if CHIPBOARD==ATWD4CH +void SetAtwdPlas(); +void SetAtwdDACs(); +#else +void SetSstDACs(); +#endif + // // globals // @@ -335,7 +342,7 @@ static const uint32_t gBufSize=SnStatusFrame::kMaxSizeOf + (2u*SnHeaderFrame::kMaxSizeOf) + SnPowerFrame::kMaxSizeOf + SnEventFrame::kMaxSizeOf // this is too big, because max status frame already includes an ATWD 4*128samp event (as of status i/o v9) //- SnEventFrame::kMaxSizeOfV1 // so we should be able to do this.. but requires long term testing as of 2016-04-26 - + 256; // some breathing room + + 256;//Geoffs+ 256; // some breathing room static char gGenBuf[gBufSize]; // must be big enough for event or status or config! static SnCommWin* gComms[kNcomms] = { 0 }; // order => priority. afar uses RTOS, and must be made inside main #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) @@ -1950,6 +1957,161 @@ } // +// trigger board setup +// +#if CHIPBOARD==ATWD4CH +void SetAtwdPlas() { + uint16_t hi, lo; + PIN_PLA_cs=1; +#ifdef USE_RTOS + Thread::wait(4000); +#else + wait(4); +#endif + for (uint8_t pi=0; pi<kNplas; ++pi) { + if (pi < gConf.GetNumPlas()) { + SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo); + PIN_spi.write(hi); + PIN_spi.write(lo); +#ifdef DEBUG + printf("pla hi %hu, lo %hu\r\n",hi,lo); +#endif + } else { + PIN_spi.write(kNoTrigPla); // hi + PIN_spi.write(kNoTrigPla); // lo +#ifdef DEBUG + printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla); +#endif + } + Watchdog::kick(); + } +#ifdef USE_RTOS + Thread::wait(3000); +#else + wait(3); +#endif + PIN_PLA_cs=0; +#ifdef USE_RTOS + Thread::wait(3000); +#else + wait(3); +#endif +} + +void SetAtwdDACs() { + // DAC values + // + // first 12 bits = DAC value + // next 2 bits = DAC ID + // last 2 bits = dFPGA ID + // + // But FPGA uses "gray encoding" which means only 1 bit + // can change at a time (of the last 4 bits). So even tho + // the card/dac# is encoded, the order is also important + // 0000 (dac0,card0), 0001 (dac0,card1), 0011 (dac0,card3), 0010 (dac0,card2), + // 0110 (dac1,card2), 0111 (dac1,card3), 0101 (dac1,card1), etc. +#ifdef DEBUG + printf("setting dacs\r\n"); +#endif + uint16_t dv=0; + for (uint8_t i=0, gri=0; i<kTotDacs; ++i) { + // get the gray-codes for this iteration + gri = SnBitUtils::binToGray(i); + + // build bit word + dv = static_cast<int>(gConf.GetDac(gri & 0x0003u, gri >> 2u)); + dv <<= 4u; + dv |= gri; + +#ifdef DEBUG + printf("dac %04x\r\n",dv); +#endif + + // send to FPGA + PIN_start_fpga=1; + PIN_spi.write(dv); + PIN_start_fpga=0; + + Watchdog::kick(); + + } +} +#endif // ATWD4CH + +#if CHIPBOARD!=ATWD4CH +void SetSstDACs() { + // set and/or & differential pins + // set DACs via I2C + + uint16_t dv=0; + uint8_t dn=0; + uint8_t cmdAndDac[3]; + uint8_t dadr=0; + for (uint8_t ch=0; ch<kNchans; ++ch) { + dadr = kLTC2657Adrs[ ch / kChansPerLTC2657 ]; + for (uint8_t dc=0; dc<kNchanDacs; ++dc) { + bool dok = false; + for (uint8_t tries = 0; (tries<kMaxDacSetTries) && (dok==false); ++tries) { +#ifdef DEBUG + printf("start i2c for dc=%hhu, ch=%hhu, try=%hhu, dok=%s\r\n", + dc, ch, tries, (dok ? "true" : "false")); + printf("address 0x%hhx (%hhd) ", dadr, dadr); + SnBitUtils::printBits(dadr, true); +#endif + // build data to send + // blame the engineers for this bizzare mapping from + // chan, threshold -> DAC number + dn = ((kChansPerLTC2657*kNchanDacs)-1)-(dc*kChansPerLTC2657)-(ch % kChansPerLTC2657); + if (dn>7) { // invalid code for LTC2657 dac chip + printf("kTotDacs=%hu, dc=%hhu, ch=%hhu, kChansPerLTC2657=%hhu, dn=%hhu\n", + kTotDacs, dc, ch, kChansPerLTC2657, dn); + error("chan/dac combination too big for 3 bits!"); + } + dn |= (kUpdateDacCmd<<4); // prefix with update DAC value command +#ifdef DEBUG + printf("dn=%hhu ", dn); + SnBitUtils::printBits(dn, true); +#endif + +#ifdef DEBUG + printf("%d bit dacs\n", static_cast<int>(DAC_BITS)); +#endif + dv = (gConf.GetDac(ch, dc)); +#if DAC_BITS==12 + dv = dv << 4; // put 0's at the end (12 bits of num then 4 zero bits) +#elif DAC_BITS==16 + // no shift required for 16 bit dacs +#else +#error DAC_BITS has invalid value! Must be either 12 or 16. +#endif // DAC_BITS + +#ifdef DEBUG + printf("dv=%hu\r\n",dv); + printf("ch=%hhu, dc=%hhu, dac=%hu\r\n",ch,dc,gConf.GetDac(ch,dc)); +#endif + // mbed i2c.write seems to send it "backwards" from a (low endian) bit + // point of view.. i guess it's forwards from an intuitive pov? + cmdAndDac[0] = dn; + cmdAndDac[1] = (dv & 0xFF00u) >> 8; // 8 MSBs of dac first + cmdAndDac[2] = (dv & 0x00FFu); // 8 LSBs of dac second + +#ifdef DEBUG + printf("cmdAndDac[0]="); SnBitUtils::printBits(cmdAndDac[2],true); + printf("cmdAndDac[1]="); SnBitUtils::printBits(cmdAndDac[1],true); + printf("cmdAndDac[2]="); SnBitUtils::printBits(cmdAndDac[0],true); +#endif + // try to send it + // TODO: if no ACK, is just re-trying the whole thing good enough? + dok = PIN_i2c.write(dadr, + reinterpret_cast<char*>(cmdAndDac), + 3*sizeof(uint8_t))==0; + } // end try loop + } + } +} +#endif + +// // set configuration // void SetConfigAndMakeOutputFile() { @@ -1988,140 +2150,13 @@ PIN_MajLogHiBit=1; PIN_MajLogLoBit=1; PIN_enableThermTrig=0; - + + // set DACs (and PLAs if needed) #if CHIPBOARD==ATWD4CH - uint16_t hi, lo; - PIN_PLA_cs=1; -#ifdef USE_RTOS - Thread::wait(4000); -#else - wait(4); -#endif - for (uint8_t pi=0; pi<kNplas; ++pi) { - if (pi < gConf.GetNumPlas()) { - SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo); - PIN_spi.write(hi); - PIN_spi.write(lo); -#ifdef DEBUG - printf("pla hi %hu, lo %hu\r\n",hi,lo); -#endif - } else { - PIN_spi.write(kNoTrigPla); // hi - PIN_spi.write(kNoTrigPla); // lo -#ifdef DEBUG - printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla); -#endif - } - Watchdog::kick(); - } -#ifdef USE_RTOS - Thread::wait(3000); -#else - wait(3); -#endif - PIN_PLA_cs=0; -#ifdef USE_RTOS - Thread::wait(3000); -#else - wait(3); -#endif - - - // DAC values - // - // first 12 bits = DAC value - // next 2 bits = DAC ID - // last 2 bits = dFPGA ID - // - // But FPGA uses "gray encoding" which means only 1 bit - // can change at a time (of the last 4 bits). So even tho - // the card/dac# is encoded, the order is also important - // 0000 (dac0,card0), 0001 (dac0,card1), 0011 (dac0,card3), 0010 (dac0,card2), - // 0110 (dac1,card2), 0111 (dac1,card3), 0101 (dac1,card1), etc. -#ifdef DEBUG - printf("setting dacs\r\n"); -#endif - uint16_t dv=0; - for (uint8_t i=0, gri=0; i<kTotDacs; ++i) { - // get the gray-codes for this iteration - gri = SnBitUtils::binToGray(i); - - // build bit word - dv = static_cast<int>(gConf.GetDac(gri & 0x0003u, gri >> 2u)); - dv <<= 4u; - dv |= gri; - -#ifdef DEBUG - printf("dac %04x\r\n",dv); -#endif - - // send to FPGA - PIN_start_fpga=1; - PIN_spi.write(dv); - PIN_start_fpga=0; - - Watchdog::kick(); - - } + SetAtwdPlas(); + SetAtwdDACs(); #else // SST - - // set and/or & differential pins - - // set DACs via I2C - - uint16_t dv=0; - uint8_t dn=0; - uint8_t cmdAndDac[3]; - for (uint8_t ch=0; ch<kNchans; ++ch) { - for (uint8_t dc=0; dc<kNchanDacs; ++dc) { -// for (uint16_t dc=kNchanDacs-1; dc>=0; --dc) { // first all the highs, then the lows -// for (int16_t ch=kNchans-1; ch>=0; --ch) { // chans in reverse order - bool dok = false; - for (uint8_t tries = 0; (tries<kMaxDacSetTries) && (dok==false); ++tries) { -#ifdef DEBUG - printf("start i2c for dc=%hhu, ch=%hhu, try=%hhu, dok=%s\r\n", - dc, ch, tries, (dok ? "true" : "false")); - printf("address 0x%hhx (%hhd) ", kAllLTC2657, kAllLTC2657); - SnBitUtils::printBits(kAllLTC2657, true); -#endif - // build data to send - // blame the engineers for this bizzare mapping from - // chan, threshold -> DAC number - dn = (kTotDacs-1)-(dc*kNchans)-ch; - if (dn>7) { // invalid code for LTC2657 dac chip - error("chan/dac combination too big for 3 bits!"); - } - dn |= (kUpdateDacCmd<<4); // prefix with update DAC value command -#ifdef DEBUG - printf("dn=%hhu ", dn); - SnBitUtils::printBits(dn, true); -#endif - dv = (gConf.GetDac(ch, dc)) << 4; // put 0's at the end (12 bits of num then 4 zero bits) -#ifdef DEBUG - printf("dv=%hu\r\n",dv); - printf("ch=%hhu, dc=%hhu, dac=%hu\r\n",ch,dc,gConf.GetDac(ch,dc)); -#endif - // mbed i2c.write seems to send it "backwards" from a (low endian) bit - // point of view.. i guess it's forwards from an intuitive pov? - cmdAndDac[0] = dn; - cmdAndDac[1] = (dv & 0xFF00u) >> 8; // 8 MSBs of 12 bit num first - cmdAndDac[2] = (dv & 0x00FFu); // 4 LSBs of 12 bit num followed by 4 zeros - -#ifdef DEBUG - printf("cmdAndDac[0]="); SnBitUtils::printBits(cmdAndDac[2],true); - printf("cmdAndDac[1]="); SnBitUtils::printBits(cmdAndDac[1],true); - printf("cmdAndDac[2]="); SnBitUtils::printBits(cmdAndDac[0],true); -#endif - // try to send it - // TODO: if no ACK, is just re-trying the whole thing good enough? - // TODO: assign correct slave address for the DAC chip (this is a global address) - dok = PIN_i2c.write(kAllLTC2657, - reinterpret_cast<char*>(cmdAndDac), - 3*sizeof(uint8_t))==0; - } // end try loop - } - } - + SetSstDACs(); #endif // CHIPBOARD #ifdef DEBUG