"
module P3008A

title 'P3008A'

"Version 1, [19-APR-07] First version."

"Version 2, [20-SEP-13] Add ready indicator. Turn on RF oscillator all the time so it"
"never gets to cool down."

"Version 3, [22-APR-16] Make sure RF signals are not connected to the return amplifiers"
"during loop-back."


"Pins"
declarations
A pin 3; "LVDS input"
LED1 pin 6; "LED1 Indicator"
LED2 pin 8; "LED2 Indicator"
B pin 19; "LVDS output"
LB pin 16; "Loop Back"
!RESET pin 22;"RESET"			
!CSD pin 70; "Chip Select for DAC"
SCLKD pin 71; "Serial Clock for DAC"
DIND pin 72; "Data In for DAC"
FSD pin 69; "Frame Synch for DAC"
LOEN pin 67; "Local Oscillator Enable"
S0 pin 60; "Select IF0"
S1 pin 58; "Select IF1"
S2 pin 59; "Select IF2:
S3 pin 61; "Select IF3"
ARCK pin 89; "Asynchronous 32-kHz Clock on CLK0"
DCK pin 38; "Data Clock on CLK1"
equations 


"LWDAQ Command and Address Decoding"
"----------------------------------"

"This LWDAQ receiver uses the 40-MHz data clock to generate"
"the DA and DDA signals. We synchronise the incoming serial"
"logic signal, A, with the data clock."

declarations
SA node istype 'reg'; "Synchronized A"
DSA node istype 'reg'; "Delayed SA"
DA node istype 'com,keep'; "Delayed A Rising Edge"
DDA node istype 'com,keep'; "Delayed DA"
AA node istype 'reg'; "Address Active"
DAA node istype 'reg'; "Delayed AA"
CA node istype 'reg'; "Command Active"
DCA node istype 'reg'; "Delayed CA"
ER,Q1..Q16 node istype 'reg'; "Receiver Bits"
LT3..LT0 node istype 'reg'; "LWDAQ Timer"
lt = [LT3..LT0];
AS node istype 'reg'; "Address Strobe"
CS node istype 'reg'; "Command Strobe"
DS node istype 'reg'; "Data Strobe"
DC1..DC16 node istype 'reg';"Device Command Bits"
DA0..DA15 node istype 'reg';"Device Address Bits"
WAKE node istype 'com'; "Wake"
DTX node istype 'com'; "Device Transmit"
ATR node istype 'com'; "Address and Timestamp Reset"
equations

"We synchronize A with DCK, and provide a delayed"
"version of A that allows us to detect edges."
[SA,DSA].clk = DCK;
[SA,DSA].aclr = RESET;
SA := A;
DSA := SA;

"This timer allows us to generate the Delayed A (DA)"
"and Double-Delayed A (DDA) signals for serial reception."
lt.clk = DCK;
lt.aclr = RESET;
when lt==0 then {
  when SA & !DSA then lt:=1
  else lt:=0;
} else {
  when lt==9 then lt:=0
  else lt:=lt+1;
}
DA = (lt==4);
DDA = (lt==9);

"We use DCK to clock the receiver registers, and RESET to"
"clear them."
[ER,Q1..Q16,AA,DAA,AS,CA,DCA,CS,DS,DC1..DC16,DA0..DA15].clk = DCK;
[ER,Q1..Q16,AA,DAA,AS,CA,DCA,CS,DS,DC1..DC16,DA0..DA15].aclr = RESET;

"We move bits along the shift register on DA."
when DA then [ER,Q1..Q16] := [SA,ER,Q1..Q15];
else [ER,Q1..Q16] := [ER,Q1..Q16];

"Address Active provides a pulse that begins with DDA"
"on the start bit of an address transmission, and ends"
"with the stop bit of an address transmission. Delayed"
"AA allows us to create Address Strobe, or AS. Address"
"Strobe provides a pulse at the end of an address"
"reception. We clock the receiver bits into the address"
"register on a rusing edge of AS."
when DDA then AA := (!AA & !CA & !SA & !ER) # (AA & !SA)
else AA := AA;
DAA := AA;
AS := DAA & !AA;
when AS then [DA0..DA15] := [Q1..Q16]
else [DA0..DA15] := [DA0..DA15];

"Command Active provides a pulse that begins with DDA"
"on the start bit of a command transmission, and ends"
"with the stop bit of a command transmission. Delayed"
"CA allows us to create Command Strobe, or CS. Command"
"strobe provides a pulse at the end of each command"
"reception. We clock the receiver bits into the command"
"register on a rusing edge of CS."
when DDA then CA := (!AA & !CA & !SA & ER) # (CA & !SA)
else CA := CA;
DCA := CA;
CS := DCA & !CA;
when CS then [DC1..DC16] := [Q1..Q16]
else [DC1..DC16] := [DC1..DC16];

"Data Strobe identifies a solitary low pulse on A. A"
"solitary low pulse, combined with DTX, indicates that"
"the drivers is expecting this device to upload eight"
"bits of data."
DS := DDA & SA & !AA & !CA;


"Command Bit Allocation"
"----------------------"

"We loop back A to B."
B = A;

"We enable the return LVDS driver when DC7 is set."
LB = DC7;

"WAKE bit."
WAKE = DC8;

"We use DC1..DC3 to select one of S0..S3."
S0 = [DC3..DC1] == 4;
S1 = [DC3..DC1] == 5;
S2 = [DC3..DC1] == 6;
S3 = [DC3..DC1] == 7;

"We always enable the Local Oscillator, so that it will"
"warm up and be ready to use. Older versions of the firmware"
"used DC3 to turn on the Local Oscillator, leading to"
"instability in the Spectrometer's frequency response, as its"
"VCO warmed up and cooled between data samples."
LOEN = 1;

"We always assert Chip Select for the TLV5623 DAC."
CSD = 1;

"We use DC4 as Frame Synch for the TLV5623 DAC. When"
"DC4 is HI, FS goes LO, indicating a new eight-bit"
"data word is about to be transmitted."
FSD = !DC4;

"We use Q5 as DIN for the TLV5623 DAC. We don't use"
"DC5 because we want DIN to be established for over"
"25 ns before the falling edge of SCLK. This falling"
"edge occurs on the falling edge of DCA, which is only"
"a few nanoseconds after the rising edge of CS that"
"clocks DC5."
DIND = Q5;

"SCLK is the fourth and final connection to the DAC. It"
"clocks data bits into the DAC on its falling edges. We"
"produce one falling edge on SCKL at the end of a command"
"reception that sets DC6."
SCLKD = !DC6 # DCA;



"Power-Up Timer"
"--------------"

"The power-up timer makes the power-up LED flash on and"
"off every second for sixty seconds. After that, the"
"spectrometer is warmed up and ready to use."
declarations
T0..T23 node istype 'reg'; "timer"
timer=[T23..T0]; "timer"
tb0=[T7..T0]; "timer byte zero"
tb1=[T15..T8]; "timer byte one"
tb2=[T23..T16]; "timer byte two"
TC0,TC1 node istype 'com,keep'; "timer carry"
WARM node istype 'reg'; "warmed-up"
equations

timer.aclr = RESET;
timer.clk = ARCK;
TC0 = (tb0==^hFF);
TC1 = (tb1==^hFF);
tb0:=tb0+1;
when TC0 then tb1:=tb1+1;
else tb1:=tb1;
when TC0 & TC1 then tb2:=tb2+1;
else tb2:=tb2;

WARM.clk = T23;
WARM.aclr = RESET;
WARM:=1;

"LED1 is the Power Indicator."
LED1 = WARM # !T14;

"LED2 is the WAKE Indicator. So long as the instrument"
"that reads this device sets the WAKE bit during the"
"read-out, LED2 will turn on during the read-out, showing"
"read-out activity."
LED2 = WAKE;


end