I thought I had a solution and this code seems to work but the channel 1 bleeds into channel 2 if channel 2 is set to 3.3 V. I can't figure out if it is a wire /antenna problem or code problem. This is especially prevalent when switchcounter is very small. I'd like switch counter to be 0 so I can sample fast, but I can't tell if it is working or not.
Note for this to work I have to change the if (cont == 1) to 1 from 2. it appeared that the ADC chip was off by 1 bit if using all channels. possibly I have other problems.
module ADC_CTRL2 (
iCLK,
iCLK_n,
oCH0,
oCH1,
oCH2,
oCH3,
oCH4,
oDIN,
oCS_n,
oSCLK,
oCH,
iDOUT
);
input iCLK;
input iCLK_n;
output [11:0] oCH0;
output [11:0] oCH1;
output [11:0] oCH2;
output [11:0] oCH3;
output [11:0] oCH4;
output [1:0] oCH;
output oDIN;
output oCS_n;
output oSCLK;
input iDOUT;
reg data =0; // serial address data out
reg go_en=1; // always enabled after power up
reg [1:0] ch_sel = 2'b00; // Start at channel 0
reg [1:0] chOUT = 2'b00; // Register to store channnel output
reg sclk;
reg [3:0] cont;
reg [3:0] m_cont;
reg [11:0] adc_data;
reg [11:0] ch0;
reg [11:0] ch1;
reg [11:0] ch2;
reg [11:0] ch3;
reg [11:0] ch4;
reg [8:0] switchcount; // Slow enough to see at 21 bits. ~ 1 change per sec at 15 very fast
assign oCS_n = ~go_en;
assign oSCLK = (go_en)? iCLK:1'b1;
assign oDIN = data;
assign oCH0 = ch0;
assign oCH1 = ch1;
assign oCH2 = ch2;
assign oCH3 = ch3;
assign oCH4 = ch4;
assign oCH = chOUT;
always@(posedge iCLK )
// always running
begin
cont <= cont + 4'b001;
end
always@(posedge iCLK_n)
begin
if(iCLK_n)
begin // on some clock check to see if timer expired
m_cont <= cont;
switchcount <= switchcount + 1;
if (switchcount == 0) //if last bit is set the increment to next sample addresss
begin
ch_sel <= ch_sel + 1; // increment the address
end
end
end
always@(posedge iCLK_n )
// always running
begin
if(iCLK_n)
begin
if (cont == 1) //MSB add in MSB if using all 8 ADC inputs
data <= 0;
else if (cont == 2) // Middle Bit
data <= ch_sel[1];
else if (cont == 3) // LSB
data <= ch_sel[0];
else data <= 0; // if not sending out address send out 0 to DOUT
end
end
always@(posedge iCLK)
begin
begin
if(iCLK)
begin
if (m_cont == 4)
adc_data[11] <= iDOUT;
else if (m_cont == 5)
adc_data[10] <= iDOUT;
else if (m_cont == 6)
adc_data[9] <= iDOUT;
else if (m_cont == 7)
adc_data[8] <= iDOUT;
else if (m_cont == 8)
adc_data[7] <= iDOUT;
else if (m_cont == 9)
adc_data[6] <= iDOUT;
else if (m_cont == 10)
adc_data[5] <= iDOUT;
else if (m_cont == 11)
adc_data[4] <= iDOUT;
else if (m_cont == 12)
adc_data[3] <= iDOUT;
else if (m_cont == 13)
adc_data[2] <= iDOUT;
else if (m_cont == 14)
adc_data[1] <= iDOUT;
else if (m_cont == 15)
adc_data[0] <= iDOUT;
else if (m_cont == 1) // on first clock store data to output port
begin
ch4 <= adc_data;
case (ch_sel) // Select last channel data store to corresponding output port
3'b00 : ch0 <= adc_data;
3'b01 : ch1 <= adc_data;
3'b10 : ch2 <= adc_data;
3'b11 : ch3 <= adc_data;
default : ch4 <= adc_data;
endcase
chOUT <= ch_sel;
end
end
end
end
endmodule