14 #include "pulserdriversh.h"
15 #include "charinterface.h"
17 REGISTER_TYPE(
XDriverList, SHPulser,
"NMR pulser handmade-SH2");
23 #define DMA_PERIOD (1.0/(28.64e3/2))
30 #define MIN_MTU_LEN 50e-3
32 #define MTU_PERIOD (1.0/(28.64e3/1))
36 #define PATTERNS_ZIPPED_MAX 40000u
39 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_DMA_END = 0;
43 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_DMA_COPY_HBURST = 1;
46 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_DMA_LSET_LONG = 2;
49 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_DMA_LSET_START = 0x10;
50 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_DMA_LSET_END = 0xffu;
53 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_END = 0;
55 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_WAIT = 1;
58 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_WAIT_LONG = 2;
62 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_WAIT_LONG_LONG = 3;
64 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_AUX1 = 4;
66 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_AUX3 = 5;
69 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_AUX2_DA = 6;
71 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_DO = 7;
72 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_LOOP = 8;
73 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_LOOP_INF = 9;
74 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_BREAKPOINT = 0xa;
75 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_PULSEON = 0xb;
77 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_DMA_SET = 0xc;
80 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_DMA_HBURST = 0xd;
83 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_SET_DA_TUNE_OFFSET = 0xe;
86 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_SET_DA_TUNE_LEVEL = 0xf;
89 const unsigned char XSHPulser::PATTERN_ZIPPED_COMMAND_SET_DA_TUNE_DELAY = 0x10;
91 XSHPulser::XSHPulser(
const char *name,
bool runtime,
92 Transaction &tr_meas,
const shared_ptr<XMeasure> &meas) :
95 interface()->setEOS(
"\n");
96 interface()->setSerialBaudRate(115200);
97 interface()->setSerialStopBits(2);
100 PORTSEL_GATE, PORTSEL_PREGATE, PORTSEL_TRIG1, PORTSEL_TRIG2,
101 PORTSEL_GATE3, PORTSEL_COMB, PORTSEL_QSW, PORTSEL_ASW,
102 PORTSEL_PULSE1, PORTSEL_PULSE2, PORTSEL_COMB_FM, PORTSEL_COMB
105 for(
unsigned int i = 0; i <
sizeof(ports)/
sizeof(
int); i++) {
106 tr[ *portSel(i)] = ports[i];
115 tr[ *
this].m_dmaTerm = 0;
116 tr[ *
this].m_lastPattern = 0;
118 insertPreamble(tr, (uint16_t)pat);
119 for(Payload::RelPatList::const_iterator it = shot[ *
this].relPatList().begin();
120 it != shot[ *
this].relPatList().end(); it++) {
121 pulseAdd(tr, it->toappear, it->pattern, (it == shot[ *
this].relPatList().begin() ),
true );
125 insertPreamble(tr, (uint16_t)pat);
127 for(
unsigned int i = 0; i < PAT_QAM_PULSE_IDX_MASK/PAT_QAM_PULSE_IDX; i++) {
128 const uint16_t word = shot[ *
this].qamWaveForm(i).size();
130 tr[ *
this].m_waveformPos[i] = shot[ *
this].m_zippedPatterns.size();
131 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_DMA_HBURST);
132 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(word / 0x100) );
133 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(word % 0x100) );
134 for(std::vector<std::complex<double> >::const_iterator it =
135 shot[ *
this].qamWaveForm(i).begin(); it != shot[ *
this].qamWaveForm(i).end(); it++) {
136 double x = max(min(it->real() * 125.0, 124.0), -124.0);
137 double y = max(min(it->imag() * 125.0, 124.0), -124.0);
138 tr[ *
this].m_zippedPatterns.push_back( (
unsigned char)(
char)x );
139 tr[ *
this].m_zippedPatterns.push_back( (
unsigned char)(
char)y );
143 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_DO);
144 tr[ *
this].m_zippedPatterns.push_back(0);
145 tr[ *
this].m_zippedPatterns.push_back(0);
146 for(Payload::RelPatList::const_iterator it = shot[ *
this].relPatList().begin();
147 it != shot[ *
this].relPatList().end(); it++) {
148 pulseAdd(tr, it->toappear, it->pattern, (it == shot[ *
this].relPatList().begin() ),
false );
153 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_END);
157 XSHPulser::setAUX2DA(
Transaction &tr,
double volt,
int addr) {
158 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_AUX2_DA);
159 tr[ *
this].m_zippedPatterns.push_back((
unsigned char) addr);
160 volt = max(volt, 0.0);
161 uint16_t word = (uint16_t)rint(4096u * volt / 2 / 2.5);
162 word = min(word, (uint16_t)4095u);
163 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(word / 0x100) );
164 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(word % 0x100) );
168 XSHPulser::insertPreamble(
Transaction &tr, uint16_t startpattern) {
170 const double masterlevel = pow(10.0, shot[ *
this].
masterLevel() / 20.0);
171 const double qamlevel1 = shot[ *qamLevel1()];
172 const double qamlevel2 = shot[ *
qamLevel2()];
173 tr[ *
this].m_zippedPatterns.clear();
175 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_SET_DA_TUNE_OFFSET);
176 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(
signed char)rint(
177 127.5 * shot[ *qamOffset1()] *1e-2 / masterlevel ) );
178 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(
signed char)rint(
179 127.5 * shot[ *
qamOffset2()] *1e-2 / masterlevel ) );
180 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_SET_DA_TUNE_LEVEL);
181 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(
signed char)rint(qamlevel1 * 0x100) );
182 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(
signed char)rint(qamlevel2 * 0x100) );
183 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_SET_DA_TUNE_DELAY);
187 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(
signed char)rint(0) );
188 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(
signed char)rint(0) );
192 len = lrint(1.0 / MTU_PERIOD);
193 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_WAIT_LONG);
194 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)((len % 0x10000) / 0x100) );
195 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)((len % 0x10000) % 0x100) );
196 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)((len / 0x10000) / 0x100) );
197 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)((len / 0x10000) % 0x100) );
198 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_DMA_SET);
199 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(startpattern / 0x100) );
200 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(startpattern % 0x100) );
201 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_DMA_LSET_START + 2);
202 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(startpattern / 0x100) );
203 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(startpattern % 0x100) );
204 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_DMA_END);
206 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_PULSEON);
209 len = lrint(10.0 / MTU_PERIOD);
210 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_WAIT_LONG);
211 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)((len % 0x10000) / 0x100) );
212 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)((len % 0x10000) % 0x100) );
213 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)((len / 0x10000) / 0x100) );
214 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)((len / 0x10000) % 0x100) );
222 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_AUX1);
223 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)3);
231 setAUX2DA(tr, 0.0, 1);
232 setAUX2DA(tr, 0.0, 2);
233 setAUX2DA(tr, 0.0, 3);
234 setAUX2DA(tr, 0.0, 4);
235 setAUX2DA(tr, 0.0, 5);
236 setAUX2DA(tr, 0.0, 6);
237 setAUX2DA(tr, 0.0, 7);
238 setAUX2DA(tr, 1.6 * masterlevel, 0);
244 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_DMA_END);
245 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_LOOP_INF);
252 int64_t mtu_term = term * llrint(
resolution() / MTU_PERIOD);
253 if( (msec > MIN_MTU_LEN) &&
254 ((shot[ *
this].m_lastPattern & PAT_QAM_PULSE_IDX_MASK)/PAT_QAM_PULSE_IDX == 0) ) {
257 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_DMA_END);
259 mtu_term += shot[ *
this].m_dmaTerm;
260 uint32_t ulen = (uint32_t)(mtu_term / 0x10000uLL);
261 uint16_t ulenh = (uint16_t)(ulen / 0x10000uL);
262 uint16_t ulenl = (uint16_t)(ulen % 0x10000uL);
263 uint16_t dlen = (uint32_t)(mtu_term % 0x10000uLL);
265 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_WAIT_LONG_LONG);
266 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(dlen / 0x100) );
267 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(dlen % 0x100) );
268 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(ulenh / 0x100) );
269 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(ulenh % 0x100) );
270 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(ulenl / 0x100) );
271 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(ulenl % 0x100) );
274 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_WAIT_LONG);
275 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(dlen / 0x100) );
276 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(dlen % 0x100) );
277 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(ulenl / 0x100) );
278 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(ulenl % 0x100) );
281 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_WAIT);
282 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(dlen / 0x100) );
283 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(dlen % 0x100) );
286 mtu_term -= ulen*0x10000uL + dlen;
287 mtu_term = max(0LL, mtu_term);
288 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_DMA_SET);
289 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(shot[ *
this].m_lastPattern / 0x100) );
290 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(shot[ *
this].m_lastPattern % 0x100) );
291 tr[ *
this].m_dmaTerm = 0;
293 tr[ *
this].m_dmaTerm += mtu_term;
294 unsigned long pos_l = shot[ *
this].m_dmaTerm / llrint(
resolution() / MTU_PERIOD);
297 uint16_t pos = (uint16_t)pos_l;
298 uint16_t len = mtu_term / llrint(
resolution() / MTU_PERIOD);
299 if( ((shot[ *
this].m_lastPattern & PAT_QAM_PULSE_IDX_MASK)/PAT_QAM_PULSE_IDX == 0) &&
300 ((pattern & PAT_QAM_PULSE_IDX_MASK)/PAT_QAM_PULSE_IDX > 0) ) {
301 uint16_t qam_pos = shot[ *
this].m_waveformPos[(pattern & PAT_QAM_PULSE_IDX_MASK)/PAT_QAM_PULSE_IDX - 1];
303 if(!qam_pos || (shot[ *
this].m_zippedPatterns[qam_pos] != PATTERN_ZIPPED_COMMAND_DMA_HBURST))
305 uint16_t word = shot[ *
this].m_zippedPatterns.size() - qam_pos;
306 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_DMA_COPY_HBURST);
307 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)((pattern & PAT_QAM_PHASE_MASK)/PAT_QAM_PHASE));
308 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(pos / 0x100) );
309 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(pos % 0x100) );
310 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(word / 0x100) );
311 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(word % 0x100) );
314 if(len > PATTERN_ZIPPED_COMMAND_DMA_LSET_END - PATTERN_ZIPPED_COMMAND_DMA_LSET_START) {
315 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_DMA_LSET_LONG);
316 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(len / 0x100) );
317 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(len % 0x100) );
318 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(pattern / 0x100) );
319 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(pattern % 0x100) );
322 tr[ *
this].m_zippedPatterns.push_back(PATTERN_ZIPPED_COMMAND_DMA_LSET_START + (
unsigned char)len);
323 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(pattern / 0x100) );
324 tr[ *
this].m_zippedPatterns.push_back((
unsigned char)(pattern % 0x100) );
326 tr[ *
this].m_lastPattern = pattern;
333 if( !interface()->isOpened())
337 if(shot[ *
this].m_zippedPatterns.empty())
339 for(
unsigned int retry = 0; ; retry++) {
341 interface()->write(
"!", 1);
342 interface()->receive();
344 if((interface()->scanf(
"Pulse %3s", buf) != 1) || strncmp(buf,
"Off", 3))
346 unsigned int size = shot[ *
this].m_zippedPatterns.size();
347 interface()->sendf(
"$pload %x", size );
348 interface()->receive();
349 interface()->write(
">", 1);
351 for(
unsigned int i = 0; i < shot[ *
this].m_zippedPatterns.size(); i++) {
352 sum += shot[ *
this].m_zippedPatterns[i];
355 interface()->write((
char*) &shot[ *
this].m_zippedPatterns[0], size);
357 interface()->receive();
359 if(interface()->scanf(
"%x", &ret) != 1)
363 interface()->send(
"$pon");
364 interface()->receive();
365 if((interface()->scanf(
"Pulse %2s", buf) != 1) || strncmp(buf,
"On", 2))
369 if(retry > 1)
throw e;
370 e.print(
getLabel() +
": " + i18n(
"try to continue") +
", ");
378 interface()->write(
"!", 1);
379 interface()->receive();