pulserdriverh8.cpp
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #include "pulserdriverh8.h"
15 #include "charinterface.h"
16 
17 REGISTER_TYPE(XDriverList, H8Pulser, "NMR pulser handmade-H8");
18 
19 #define MAX_PATTERN_SIZE 2048u
20 //[ms]
21 #define TIMER_PERIOD (1.0/(25.0e3))
22 //[ms]
23 #define MIN_PULSE_WIDTH 0.001
24 
25 double XH8Pulser::resolution() const {
26  return TIMER_PERIOD;
27 }
28 double XH8Pulser::minPulseWidth() const {
29  return MIN_PULSE_WIDTH;
30 }
31 
32 XH8Pulser::XH8Pulser(const char *name, bool runtime,
33  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
34  XCharDeviceDriver<XPulser>(name, runtime, ref(tr_meas), meas) {
35 
36  interface()->setEOS("\r\n");
37  interface()->setSerialBaudRate(115200);
38  interface()->setSerialStopBits(2);
39 
40  const int ports[] = {
41  PORTSEL_GATE, PORTSEL_PREGATE, PORTSEL_TRIG1, PORTSEL_TRIG2,
42  PORTSEL_QPSK_A, PORTSEL_QPSK_B, PORTSEL_ASW, PORTSEL_UNSEL,
43  PORTSEL_PULSE1, PORTSEL_PULSE2, PORTSEL_COMB, PORTSEL_UNSEL,
44  PORTSEL_QPSK_OLD_PSGATE, PORTSEL_QPSK_OLD_NONINV, PORTSEL_QPSK_OLD_INV, PORTSEL_COMB_FM
45  };
46  iterate_commit([=](Transaction &tr){
47  for(unsigned int i = 0; i < sizeof(ports)/sizeof(int); i++) {
48  tr[ *portSel(i)] = ports[i];
49  }
50  });
51 }
52 void
54  start();
55 }
56 
57 void
59  const Snapshot &shot(tr);
60  tr[ *this].m_zippedPatterns.clear();
61  for(Payload::RelPatList::const_iterator it = shot[ *this].relPatList().begin();
62  it != shot[ *this].relPatList().end(); it++) {
63  pulseAdd(tr, it->toappear, (uint16_t)(it->pattern & PAT_DO_MASK));
64  }
65 }
66 int
67 XH8Pulser::pulseAdd(Transaction &tr, uint64_t term, uint16_t pattern) {
68  static_assert(sizeof(long long) == 8, "");
69 
70  term = std::max(term, (uint64_t)lrint(MIN_PULSE_WIDTH / TIMER_PERIOD));
71 
72  uint32_t ulen = (uint32_t)((term - 1) / 0x8000uLL);
73  uint32_t llen = (uint32_t)((term - 1) % 0x8000uLL);
74 
75  switch(ulen) {
77  case 0:
78  x.msb = llen / 0x100;
79  x.lsb = llen % 0x100;
80  tr[ *this].m_zippedPatterns.push_back(x);
81  x.msb = pattern / 0x100;
82  x.lsb = pattern % 0x100;
83  tr[ *this].m_zippedPatterns.push_back(x);
84  break;
85  default:
86  x.msb = (ulen % 0x8000u + 0x8000u) / 0x100;
87  x.lsb = (ulen % 0x8000u + 0x8000u) % 0x100;
88  tr[ *this].m_zippedPatterns.push_back(x);
89  x.msb = (ulen / 0x8000u) / 0x100;
90  x.lsb = (ulen / 0x8000u) % 0x100;
91  tr[ *this].m_zippedPatterns.push_back(x);
92  x.msb = (llen + 0x8000u) / 0x100;
93  x.lsb = (llen + 0x8000u) % 0x100;
94  tr[ *this].m_zippedPatterns.push_back(x);
95  x.msb = pattern / 0x100;
96  x.lsb = pattern % 0x100;
97  tr[ *this].m_zippedPatterns.push_back(x);
98  break;
99  }
100  return 0;
101 }
102 static uint16_t makesum(unsigned char *start, uint32_t bytes) {
103  uint16_t sum = 0;
104 
105  for(; bytes > 0; bytes--)
106  sum += *start++;
107  return sum;
108 }
109 void
110 XH8Pulser::changeOutput(const Snapshot &shot, bool output, unsigned int blankpattern) {
111  XScopedLock<XInterface> lock( *interface());
112  if( !interface()->isOpened())
113  return;
114 
115  if(output) {
116  if(shot[ *this].m_zippedPatterns.empty() |
117  (shot[ *this].m_zippedPatterns.size() >= MAX_PATTERN_SIZE ))
118  throw XInterface::XInterfaceError(i18n("Pulser Invalid pattern"), __FILE__, __LINE__);
119  for(unsigned int retry = 0; ; retry++) {
120  try {
121  interface()->sendf("$poff %x", blankpattern);
122  interface()->send("$pclear");
123  unsigned int size = shot[ *this].m_zippedPatterns.size();
124  unsigned int pincr = size;
125  interface()->sendf("$pload %x %x", size, pincr);
126  interface()->receive();
127  interface()->write(">", 1);
128  msecsleep(1);
129  for(unsigned int j=0; j < size; j += pincr) {
130  interface()->write(
131  (char *) &shot[ *this].m_zippedPatterns[j], pincr * 2);
132  uint16_t sum =
133  makesum((unsigned char *) &shot[ *this].m_zippedPatterns[j], pincr * 2);
134  Payload::h8ushort nsum;
135  nsum.lsb = sum % 0x100; nsum.msb = sum / 0x100;
136  interface()->write((char *)&nsum, 2);
137  }
138  interface()->write(" \n", 5);
139  interface()->receive();
140  unsigned int ret;
141  if(interface()->scanf("%x", &ret) != 1)
142  throw XInterface::XConvError(__FILE__, __LINE__);
143  if(ret != size)
144  throw XInterface::XInterfaceError(i18n("Pulser Check Sum Error"), __FILE__, __LINE__);
145  }
146  catch (XKameError &e) {
147  if(retry > 0) throw e;
148  e.print(getLabel() + ": " + i18n("try to continue") + ", ");
149  continue;
150  }
151  break;
152  }
153  }
154  else {
155  interface()->sendf("$poff %x", blankpattern); //Pulser turned off.
156  }
157 }

Generated for KAME4 by  doxygen 1.8.3