AD5791 data and clock bits now settable via methods (like latch enable)
This commit is contained in:
parent
921d0b8ead
commit
3da3b70ddd
@ -27,21 +27,35 @@ using std::vector;
|
|||||||
#define DAC_DATA_BITS 20
|
#define DAC_DATA_BITS 20
|
||||||
#define DAC_CONTROL_BITS 4
|
#define DAC_CONTROL_BITS 4
|
||||||
|
|
||||||
// The channel configuration
|
// The default channel configuration
|
||||||
#define DATA_BIT 18//18
|
#define LE_BIT 17
|
||||||
#define CLK_BIT 16//16
|
#define DATA_BIT 18
|
||||||
|
#define CLK_BIT 16
|
||||||
|
|
||||||
|
// Input shift register addresses
|
||||||
|
|
||||||
|
// Write to DAC register 0001
|
||||||
|
#define WRITE_DAC 1
|
||||||
|
// Write to the control register 0010
|
||||||
|
#define WRITE_CONTROL_REGISTER 2
|
||||||
|
// Write to the clearcode register 0011
|
||||||
|
#define WRITE_CLEARCODE_REGISTER 3
|
||||||
|
// Write to the software control register 0100
|
||||||
|
#define WRITE_SOFTWARE_CONTROL_REGISTER 4
|
||||||
|
|
||||||
|
|
||||||
// this bit needs to be set to write the DAC register
|
|
||||||
#define WRITE_DAC 1<<20
|
|
||||||
|
|
||||||
|
|
||||||
// software control register
|
// software control register settings
|
||||||
|
// Setting this bit to a 1 returns the AD5791 to its power-on state.
|
||||||
#define RESET 1
|
#define RESET 1
|
||||||
|
// Setting this bit to a 1 sets the DAC register to a user defined value (see Table 13) and updates the DAC output. The output
|
||||||
|
// value depends on the DAC register coding that is being used, either binary or twos complement.
|
||||||
#define CLR 2
|
#define CLR 2
|
||||||
|
// Setting this bit to a 1 updates the DAC register and consequently the DAC output.
|
||||||
#define LDAC 4
|
#define LDAC 4
|
||||||
|
|
||||||
// control register
|
// control register settings
|
||||||
// Linearity error compensation for varying reference input spans.
|
// Linearity error compensation for varying reference input spans.
|
||||||
#define LINCOMP_10V 0*1<<9 + 0*1<<8 + 0*1<<7 + 0*1<<6
|
#define LINCOMP_10V 0*1<<9 + 0*1<<8 + 0*1<<7 + 0*1<<6
|
||||||
#define LINCOMP_12V 1*1<<9 + 0*1<<8 + 0*1<<7 + 1*1<<6
|
#define LINCOMP_12V 1*1<<9 + 0*1<<8 + 0*1<<7 + 1*1<<6
|
||||||
@ -63,7 +77,9 @@ using std::vector;
|
|||||||
|
|
||||||
AD5791::AD5791(int myid) : id(myid) {
|
AD5791::AD5791(int myid) : id(myid) {
|
||||||
dac_value = 0;
|
dac_value = 0;
|
||||||
set_latch_bit(17);
|
set_latch_bit(LE_BIT);
|
||||||
|
set_data_bit(DATA_BIT);
|
||||||
|
set_clock_bit(CLK_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
AD5791::~AD5791() {}
|
AD5791::~AD5791() {}
|
||||||
@ -72,10 +88,20 @@ void AD5791::set_dac(signed dw) {
|
|||||||
dac_value = dw;
|
dac_value = dw;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AD5791::set_latch_bit(int le_bit)
|
void AD5791::set_latch_bit(int bit)
|
||||||
{
|
{
|
||||||
latch_bit = le_bit;
|
latch_bit = bit;
|
||||||
}
|
}
|
||||||
|
void AD5791::set_data_bit(int bit)
|
||||||
|
{
|
||||||
|
data_bit = bit;
|
||||||
|
}
|
||||||
|
void AD5791::set_clock_bit(int bit)
|
||||||
|
{
|
||||||
|
clock_bit = bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This sets the DAC
|
// This sets the DAC
|
||||||
void AD5791::set_dac(state &experiment) {
|
void AD5791::set_dac(state &experiment) {
|
||||||
state_sequent *exp_sequence = dynamic_cast<state_sequent *>(&experiment);
|
state_sequent *exp_sequence = dynamic_cast<state_sequent *>(&experiment);
|
||||||
@ -98,111 +124,67 @@ void AD5791::set_dac(state &experiment) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* push one bit to the DAC, this function returns a state_sequent one can add
|
||||||
|
*
|
||||||
|
* @param bit
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
state_sequent* AD5791::tx_bit(unsigned int bit) {
|
state_sequent* AD5791::tx_bit(unsigned int bit) {
|
||||||
state_sequent* tx = new state_sequent();
|
state_sequent* tx = new state_sequent();
|
||||||
ttlout* ttl_state = new ttlout();
|
ttlout* ttl_state = new ttlout();
|
||||||
state s(TIMING);
|
state s(TIMING);
|
||||||
s.push_back(ttl_state);
|
s.push_back(ttl_state);
|
||||||
|
|
||||||
ttl_state->ttls = bit*(1<<DATA_BIT) + (1 << CLK_BIT);
|
ttl_state->ttls = bit*(1<<data_bit) + (1 << clock_bit);
|
||||||
tx->push_back(s.copy_new());
|
tx->push_back(s.copy_new());
|
||||||
ttl_state->ttls = (1<<DATA_BIT);
|
ttl_state->ttls = (1<<data_bit);
|
||||||
tx->push_back(s.copy_new());
|
tx->push_back(s.copy_new());
|
||||||
return tx;
|
return tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
state_sequent* AD5791::select_input_shift_register(unsigned int register_address){
|
||||||
|
state_sequent* tx = new state_sequent();
|
||||||
|
int count = DAC_CONTROL_BITS;
|
||||||
|
while (register_address != 0 and count !=0 ) {
|
||||||
|
tx->push_back(tx_bit(register_address & 1));
|
||||||
|
register_address >>= 1;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
return tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
state_sequent* AD5791::write_serial_register(unsigned int register_value){
|
||||||
|
state_sequent* tx = new state_sequent();
|
||||||
|
vector<int> dac_word;
|
||||||
|
// generate the bit pattern, this is MSB last
|
||||||
|
for (int j = 0; j < DAC_DATA_BITS; j++) {
|
||||||
|
int bit = register_value & 1;
|
||||||
|
dac_word.push_back(bit);
|
||||||
|
register_value >>= 1;
|
||||||
|
}
|
||||||
|
// iterate over the dac_word from end to beginning, this is MSB first
|
||||||
|
// TODO: Run Length Encoding (maybe better on higher level, i.e. full state sequence?)
|
||||||
|
for (vector<int>::reverse_iterator current_bit = dac_word.rbegin();
|
||||||
|
current_bit != dac_word.rend();
|
||||||
|
++current_bit){
|
||||||
|
tx->push_back(tx_bit(*current_bit));
|
||||||
|
}
|
||||||
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AD5791::set_dac_to_zero(state_sequent* exp_sequence, state::iterator where) {
|
void AD5791::set_dac_to_zero(state_sequent* exp_sequence, state::iterator where) {
|
||||||
// 0001 0000 0000 0000 0000 0000
|
// 0001 0000 0000 0000 0000 0000
|
||||||
state s(TIMING);
|
exp_sequence->insert(where, select_input_shift_register(WRITE_DAC));
|
||||||
ttlout* ttl_state = new ttlout();
|
exp_sequence->insert(where, write_serial_register(0));
|
||||||
ttl_state->id = 0;
|
|
||||||
s.push_front(ttl_state);
|
|
||||||
|
|
||||||
// test exp_sequence->insert(where, tx_bit(1));
|
|
||||||
exp_sequence->insert(where, tx_bit(1));
|
|
||||||
// 0
|
|
||||||
ttl_state->ttls = 0 + (1 << CLK_BIT);
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
ttl_state->ttls = 0;
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
// 0
|
|
||||||
ttl_state->ttls = 0 + (1 << CLK_BIT);
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
ttl_state->ttls = 0;
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
// 0
|
|
||||||
ttl_state->ttls = 0 + (1 << CLK_BIT);
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
ttl_state->ttls = 0;
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
// 1
|
|
||||||
ttl_state->ttls = (1<<DATA_BIT) + (1 << CLK_BIT);
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
ttl_state->ttls = (1<<DATA_BIT);
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
|
|
||||||
// the rest
|
|
||||||
state_sequent *rep_sequence = new state_sequent();
|
|
||||||
rep_sequence->repeat = DAC_DATA_BITS;
|
|
||||||
ttl_state->ttls = 0 + (1 << CLK_BIT);
|
|
||||||
rep_sequence->push_back(s.copy_new());
|
|
||||||
ttl_state->ttls = 0;
|
|
||||||
rep_sequence->push_back(s.copy_new());
|
|
||||||
exp_sequence->insert(where, rep_sequence);
|
|
||||||
//read in the word
|
|
||||||
ttl_state->ttls = 0;
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
ttl_state->ttls = (1 << latch_bit);
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AD5791::init_dac(state_sequent *exp_sequence, state::iterator where) {
|
void AD5791::init_dac(state_sequent *exp_sequence, state::iterator where) {
|
||||||
state s(TIMING);
|
exp_sequence->insert(where, select_input_shift_register(WRITE_CONTROL_REGISTER));
|
||||||
ttlout *ttl_state = new ttlout();
|
exp_sequence->insert(where, write_serial_register(0));
|
||||||
ttl_state->id = 0;
|
|
||||||
s.push_front(ttl_state);
|
|
||||||
// 0010 0000 0000 0000 0000 0000
|
|
||||||
// 0
|
|
||||||
ttl_state->ttls = 0 + (1 << CLK_BIT);
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
ttl_state->ttls = 0;
|
|
||||||
exp_sequence->insert(where,s.copy_new());
|
|
||||||
// 0
|
|
||||||
ttl_state->ttls = 0 + (1 << CLK_BIT);
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
ttl_state->ttls = 0;
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
// 1
|
|
||||||
ttl_state->ttls = (1<<DATA_BIT) + (1 << CLK_BIT);
|
|
||||||
exp_sequence->insert(where,s.copy_new());
|
|
||||||
ttl_state->ttls = (1<<DATA_BIT);
|
|
||||||
exp_sequence->insert(where,s.copy_new());
|
|
||||||
// 0
|
|
||||||
ttl_state->ttls = 0 + (1 << CLK_BIT);
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
ttl_state->ttls = 0;
|
|
||||||
exp_sequence->insert(where,s.copy_new());
|
|
||||||
|
|
||||||
// the rest
|
|
||||||
state_sequent *rep_sequence = new state_sequent();
|
|
||||||
rep_sequence->repeat = DAC_DATA_BITS;
|
|
||||||
ttl_state->ttls = 0 + (1 << CLK_BIT);
|
|
||||||
rep_sequence->push_back(s.copy_new());
|
|
||||||
ttl_state->ttls = 0;
|
|
||||||
rep_sequence->push_back(s.copy_new());
|
|
||||||
exp_sequence->insert(where, rep_sequence);
|
|
||||||
|
|
||||||
//read in the word
|
|
||||||
ttl_state->ttls = 0;
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
ttl_state->ttls = (1 << latch_bit) + (1<<CLK_BIT);
|
|
||||||
s.length = 180e-9;
|
|
||||||
exp_sequence->insert(where, s.copy_new());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This loops recursive through the state tree
|
// This loops recursive through the state tree
|
||||||
void AD5791::set_dac_recursive(state_sequent &the_sequence, state::iterator &the_state) {
|
void AD5791::set_dac_recursive(state_sequent &the_sequence, state::iterator &the_state) {
|
||||||
|
|
||||||
@ -232,8 +214,9 @@ void AD5791::set_dac_recursive(state_sequent &the_sequence, state::iterator &the
|
|||||||
}
|
}
|
||||||
// there is no place for me here
|
// there is no place for me here
|
||||||
else {
|
else {
|
||||||
throw pfg_exception("found another DAC section, ignoring");
|
|
||||||
delete aout;
|
delete aout;
|
||||||
|
throw pfg_exception("found another DAC section, ignoring");
|
||||||
|
|
||||||
}
|
}
|
||||||
// remove the analog out section
|
// remove the analog out section
|
||||||
this_state->erase(pos++);
|
this_state->erase(pos++);
|
||||||
@ -261,67 +244,23 @@ void AD5791::set_dac_recursive(state_sequent &the_sequence, state::iterator &the
|
|||||||
if (abs(dac_analog_out->dac_value) > pow(2.0, int(DAC_DATA_BITS - 1)))
|
if (abs(dac_analog_out->dac_value) > pow(2.0, int(DAC_DATA_BITS - 1)))
|
||||||
throw pfg_exception("dac_value too low");
|
throw pfg_exception("dac_value too low");
|
||||||
|
|
||||||
// set dac write register 1<<20
|
state_sequent *input = new state_sequent();
|
||||||
dac_analog_out->dac_value += WRITE_DAC;
|
state_sequent *dacword = new state_sequent();
|
||||||
vector<int> dac_word;
|
input = select_input_shift_register(WRITE_DAC);
|
||||||
// generate the bit pattern, this is MSB last
|
dacword = write_serial_register(dac_analog_out->dac_value);
|
||||||
for (int j = 0; j < (DAC_DATA_BITS + DAC_CONTROL_BITS); j++) {
|
register_state->push_back(input);
|
||||||
int bit = dac_analog_out->dac_value & 1;
|
register_state->push_back(dacword);
|
||||||
dac_word.push_back(bit);
|
|
||||||
dac_analog_out->dac_value >>= 1;
|
|
||||||
std::cout << bit;
|
|
||||||
}
|
|
||||||
// reverse the bit pattern (MSB first)
|
|
||||||
reverse(dac_word.begin(), dac_word.end());
|
|
||||||
|
|
||||||
// need one clock cycle to read in bit
|
|
||||||
// latch enable (LE) should always be high while doing so
|
|
||||||
// except for the last bit
|
|
||||||
|
|
||||||
// do run length encoding, grouping same bit values in loops
|
|
||||||
int last_seen_bit = dac_word[0];
|
|
||||||
int last_seen_bit_count = 1;
|
|
||||||
for (int i = 1; i < (DAC_DATA_BITS + DAC_CONTROL_BITS) + 1; i++) {
|
|
||||||
if (i == (DAC_DATA_BITS + DAC_CONTROL_BITS) || last_seen_bit != dac_word[i]) {
|
|
||||||
// so we have to write the bits
|
|
||||||
// either because the previous were different or we are finished
|
|
||||||
if (last_seen_bit_count > 1) {
|
|
||||||
// insert a loop
|
|
||||||
state_sequent *rep_sequence = new state_sequent();
|
|
||||||
rep_sequence->repeat = last_seen_bit_count;
|
|
||||||
register_ttls->ttls = (1 << DATA_BIT) * last_seen_bit + (1 << CLK_BIT) + (1 << latch_bit);
|
|
||||||
rep_sequence->push_back(register_state->copy_new());
|
|
||||||
register_ttls->ttls = (1 << DATA_BIT) * last_seen_bit + (1 << latch_bit);
|
|
||||||
rep_sequence->push_back(register_state->copy_new());
|
|
||||||
the_sequence.insert(the_state, rep_sequence);
|
|
||||||
} else {
|
|
||||||
// no loop necessary, insert two states
|
|
||||||
register_ttls->ttls = (1 << DATA_BIT) * last_seen_bit + (1 << CLK_BIT) + (1 << latch_bit);
|
|
||||||
the_sequence.insert(the_state, register_state->copy_new());
|
|
||||||
register_ttls->ttls = (1 << DATA_BIT) * last_seen_bit + (1 << latch_bit);
|
|
||||||
the_sequence.insert(the_state, register_state->copy_new());
|
|
||||||
}
|
|
||||||
// reset counter and bits if we are not finished
|
|
||||||
if (i < (DAC_DATA_BITS + DAC_CONTROL_BITS)) {
|
|
||||||
last_seen_bit = dac_word[i];
|
|
||||||
last_seen_bit_count = 1;
|
|
||||||
}
|
|
||||||
} // finished writing
|
|
||||||
else
|
|
||||||
last_seen_bit_count += 1; // same bit value, so continue
|
|
||||||
} // end of bit loop
|
|
||||||
register_ttls->ttls = 0;
|
|
||||||
the_sequence.insert(the_state, register_state->copy_new());
|
|
||||||
|
|
||||||
// shorten the remaining state
|
// shorten the remaining state
|
||||||
|
this_state->length -= input->length + dacword->length;
|
||||||
// and add LE high to this state
|
// and add LE high to this state
|
||||||
ttlout *ttls = new ttlout();
|
ttlout *ttls = new ttlout();
|
||||||
// 2 clocks per bit + 1 for sync
|
|
||||||
this_state->length -= TIMING * 2 * (DAC_DATA_BITS + DAC_CONTROL_BITS) + 1;
|
|
||||||
ttls->ttls = 1 << latch_bit;
|
ttls->ttls = 1 << latch_bit;
|
||||||
this_state->push_front(ttls);
|
this_state->push_front(ttls);
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
|
delete input;
|
||||||
|
delete dacword;
|
||||||
delete register_state;
|
delete register_state;
|
||||||
delete dac_analog_out;
|
delete dac_analog_out;
|
||||||
} // state was long enough to work on
|
} // state was long enough to work on
|
||||||
|
Loading…
Reference in New Issue
Block a user