14 #include "thamwaypulser.h"
15 #include "charinterface.h"
18 REGISTER_TYPE(
XDriverList, ThamwayUSBPulser,
"NMR pulser Thamway N210-1026 PG32U40(USB)");
20 REGISTER_TYPE(
XDriverList, ThamwayCharPulser,
"NMR pulser Thamway N210-1026S/T (GPIB/TCP)");
22 #define MAX_PATTERN_SIZE 256*1024u
24 #define TIMER_PERIOD (1.0/(40.0e3))
26 #define MIN_PULSE_WIDTH 0.0001 //100ns, perhaps 50ns is enough?
29 #define ADDR_REG_ADDR_L 0x00
30 #define ADDR_REG_ADDR_H 0x02
31 #define ADDR_REG_STS 0x03
32 #define ADDR_REG_TIME_LSW 0x04
33 #define ADDR_REG_TIME_MSW 0x06
34 #define ADDR_REG_DATA_LSW 0x08
35 #define ADDR_REG_REP_N 0x0a
36 #define ADDR_REG_MODE 0x0c
37 #define ADDR_REG_CTRL 0x0d
38 #define ADDR_REG_DATA_MSW 0x0e
39 #define CMD_TRG 0xff80uL
40 #define CMD_STOP 0xff40uL
41 #define CMD_JP 0xff20uL
42 #define CMD_INT 0xff10uL
50 return MIN_PULSE_WIDTH;
54 XThamwayPulser::XThamwayPulser(
const char *name,
bool runtime,
55 Transaction &tr_meas,
const shared_ptr<XMeasure> &meas) :
56 XPulser(name, runtime, ref(tr_meas), meas) {
59 XPulser::PORTSEL_GATE, XPulser::PORTSEL_PREGATE, XPulser::PORTSEL_TRIG1, XPulser::PORTSEL_QPSK_OLD_PSGATE,
60 XPulser::PORTSEL_QPSK_OLD_INV, XPulser::PORTSEL_GATE, XPulser::PORTSEL_TRIG2, XPulser::PORTSEL_TRIG1,
61 XPulser::PORTSEL_PULSE1, XPulser::PORTSEL_ASW, XPulser::PORTSEL_UNSEL, XPulser::PORTSEL_UNSEL,
62 XPulser::PORTSEL_UNSEL, XPulser::PORTSEL_UNSEL, XPulser::PORTSEL_UNSEL, XPulser::PORTSEL_UNSEL
65 for(
unsigned int i = 0; i <
sizeof(ports)/
sizeof(
int); i++) {
66 tr[ *XPulser::portSel(i)] = ports[i];
75 tr[ *
this].m_patterns.clear();
76 uint16_t pat = (uint16_t)(shot[ *
this].relPatList().back().pattern & XPulser::PAT_DO_MASK);
79 uint32_t startaddr = 2;
80 for(
auto it = shot[ *
this].relPatList().begin();
81 it != shot[ *
this].relPatList().end(); it++) {
83 pat = (uint16_t)(it->pattern & XPulser::PAT_DO_MASK);
89 p.term_n_cmd = CMD_JP * 0x10000uL + startaddr;
91 tr[ *
this].m_patterns.push_back(p);
92 p.term_n_cmd = CMD_STOP * 0x10000uL;
94 tr[ *
this].m_patterns.push_back(p);
99 term = std::max(term, (uint64_t)lrint(MIN_PULSE_WIDTH / TIMER_PERIOD));
101 uint64_t t = std::min((uint64_t)term, (uint64_t)0xfe000000uL);
106 tr[ *
this].m_patterns.push_back(p);
114 if( !this->interface()->isOpened())
117 this->interface()->send(
"STOP");
118 this->interface()->send(
"SAVER 0");
119 this->interface()->send(
"SETMODE 1");
120 this->interface()->send(
"MEMCLR 0");
122 if(shot[ *
this].m_patterns.size() >= MAX_PATTERN_SIZE) {
126 unsigned int addr = 0;
127 for(
auto it = shot[ *
this].m_patterns.begin(); it != shot[ *
this].m_patterns.end(); ++it) {
128 this->interface()->sendf(
"POKE 0x%x,0x%x,0x%x", addr, it->term_n_cmd, it->data);
131 this->interface()->send(
"START 0");
136 XThamwayCharPulser::getStatus(
bool *running,
bool *extclk_det) {
138 this->interface()->query(
"ISRUN?");
139 *running = (this->interface()->toStrSimplified() ==
"RUN");
147 this->interface()->setEOS(
"\r\n");
151 #if defined USE_EZUSB
156 if( !this->interface()->isOpened())
159 this->interface()->resetBulkWrite();
160 this->interface()->writeToRegister8(ADDR_REG_CTRL, 0);
161 this->interface()->writeToRegister8(ADDR_REG_MODE, 2);
162 this->interface()->writeToRegister16(ADDR_REG_DATA_LSW, blankpattern % 0x10000uL);
163 this->interface()->writeToRegister16(ADDR_REG_DATA_MSW, blankpattern / 0x10000uL);
164 this->interface()->writeToRegister8(ADDR_REG_MODE, 0);
165 this->interface()->writeToRegister16(ADDR_REG_ADDR_L, 0);
166 this->interface()->writeToRegister8(ADDR_REG_ADDR_H, 0);
168 if(shot[ *
this].m_patterns.size() >= MAX_PATTERN_SIZE) {
171 this->interface()->deferWritings();
172 for(
auto it = shot[ *
this].m_patterns.begin(); it != shot[ *
this].m_patterns.end(); ++it) {
173 this->interface()->writeToRegister16(ADDR_REG_TIME_LSW, it->term_n_cmd % 0x10000uL);
174 this->interface()->writeToRegister16(ADDR_REG_TIME_MSW, it->term_n_cmd / 0x10000uL);
175 this->interface()->writeToRegister16(ADDR_REG_DATA_LSW, it->data % 0x10000uL);
176 this->interface()->writeToRegister16(ADDR_REG_DATA_MSW, it->data / 0x10000uL);
177 this->interface()->writeToRegister8(ADDR_REG_CTRL, 2);
179 this->interface()->bulkWriteStored();
181 this->interface()->writeToRegister8(ADDR_REG_STS, 0);
182 this->interface()->writeToRegister16(ADDR_REG_REP_N, 0);
183 this->interface()->writeToRegister16(ADDR_REG_ADDR_L, 0);
184 this->interface()->writeToRegister8(ADDR_REG_ADDR_H, 0);
185 bool ext_clock =
false;
187 this->interface()->writeToRegister8(ADDR_REG_MODE, 8 | (ext_clock ? 4 : 0));
188 this->interface()->writeToRegister8(ADDR_REG_CTRL, 1);
194 XThamwayUSBPulser::getStatus(
bool *running,
bool *extclk_det) {
195 uint8_t sta = this->interface()->singleRead(ADDR_REG_STS);
197 *running = sta & 0x2;
199 *extclk_det = !(sta & 0x20);
200 this->interface()->writeToRegister8(ADDR_REG_STS, 0);
205 XString idn = this->interface()->getIDN();
206 fprintf(stderr,
"PG IDN=%s\n", idn.c_str());