本帖最后由 feihufuture 于 2020-8-26 13:00 编辑
[payamount]1.00[/payamount]
[pay]
- //------------------------------------------------------------------------------
-
- //------------------------------------------------------------------------------
- module adc1118
- #
- (
- parameter SPI_SCK_CYCLE = 50,
- parameter SPI_BIT_NUM = 16
- )
- (
- input i_clk,
- input i_rsto_power_on,
- //
- input [1 : 0] i_fpga_spi_cs_0_s,
- output o_fpga_spi_sck,
- output o_fpga_spi_cs,
- input i_fpga_spi_miso,
- output o_fpga_spi_mosi,
- //
- output [15 : 0] o_adc_c1_data,
- output [15 : 0] o_adc_c2_data
- );
-
-
- reg [7 : 0] cs_cnt;
- reg [5 : 0] ws;//work state
- reg fpga_spi_miso_d;
-
-
- reg [6:0] basic_clk_cnt ;
- reg [4:0] fpga_spi_clk_cnt;
- reg [3:0] spi_byte_cnt ;
- wire [2:0] spi_bit_index;
- reg fpga_spi_sck = 0;
- reg fpga_spi_cs = 1;
- reg fpga_spi_mosi = 0;
-
- wire sample_point;
- reg sample_point_d;
- reg [15 : 0] adc_c1_data;
- reg [15 : 0] adc_c2_data;
- reg [15 : 0] adc_c1_data_r;
- reg [15 : 0] adc_c2_data_r;
-
-
- wire clk = i_clk;
- wire rsto_power_on = i_rsto_power_on;
- wire [1 : 0] fpga_spi_cs_0_s = i_fpga_spi_cs_0_s;
- wire fpga_spi_miso = i_fpga_spi_miso;
- //------------------------------------------------------------------------------
- //datasheet: "The next time CS is taken low, data transmission starts with the currently buffered conversion result
- //on the first SCLK rising edge. If DOUT/DRDY is low when data retrieval starts, the conversion buffer is
- //already updated with a new result. Otherwise, if DOUT/DRDY is high, the same result from the previous data
- //transmission cycle is read."
- //
- parameter S_IDLE = 6'b00_0001;
- parameter S_IN_RD = 6'b00_0010;
- parameter S_ADC_WR_FRONT = 6'b00_0100;
- parameter S_ADC_WR_WAIT = 6'b00_1000;
- parameter S_ADC_WR = 6'b01_0000;
- parameter S_ADC_WR_BACK = 6'b10_0000;
- //
- //
- //8ms is 128sps of ADC.
- //"fpga_spi_cs_0_s_cnt" is used to count the number of 0.6ms.
- reg [9:0] fpga_spi_cs_0_s_cnt;
- //
- always @(posedge clk)
- begin
- if (~rsto_power_on) fpga_spi_cs_0_s_cnt <= 10'd0;
- else if(fpga_spi_cs_0_s == 2'b01) fpga_spi_cs_0_s_cnt <= fpga_spi_cs_0_s_cnt + 1;
- else fpga_spi_cs_0_s_cnt <= fpga_spi_cs_0_s_cnt;
- end
- //
- //channel_change_flag "0": send AN2-3 command; "1" send AN0-1 command.
- //
- reg channel_change_flag;
- always @(posedge clk)
- begin
- if (~rsto_power_on) channel_change_flag <= 1'b0;
- else if(fpga_spi_cs_0_s == 2'b01)
- begin
- if(&fpga_spi_cs_0_s_cnt) channel_change_flag <= ~channel_change_flag;
- end
- end
- //
- //
- always @(posedge clk)
- begin
- if (~rsto_power_on) ws <= S_IDLE;
- else
- case(ws)
- S_IDLE : ws <= S_IN_RD;
- //
- S_IN_RD : if(fpga_spi_cs_0_s == 2'b01)
- begin
- if(&fpga_spi_cs_0_s_cnt[3:0]) ws <= S_ADC_WR_FRONT;
- end
- //
- S_ADC_WR_FRONT : if(&cs_cnt) ws <= S_ADC_WR;
- //S_ADC_WR_WAIT : if(~fpga_spi_miso) ws <= S_ADC_WR;
- S_ADC_WR : if((basic_clk_cnt == SPI_SCK_CYCLE - 1)&(fpga_spi_clk_cnt == SPI_BIT_NUM - 1)) ws <= S_ADC_WR_BACK;
- S_ADC_WR_BACK : if(&cs_cnt) ws <= S_IDLE;
- default: ;
- endcase
- end
- //cs of spi changes in the midle of cs_cnt, that is 256/2 * 10ns, about 1.28us keeping high or low.
- always @(posedge clk)
- begin
- if (~rsto_power_on) cs_cnt <= 8'b0;
- else
- case(ws)
- S_ADC_WR_FRONT,S_ADC_WR_BACK: cs_cnt <= cs_cnt + 1;
- default: cs_cnt <= 8'b0;
- endcase
- end
- //
- always @(posedge clk)
- begin
- if (~rsto_power_on) fpga_spi_miso_d <= 1'b1;
- else fpga_spi_miso_d <= fpga_spi_miso;
- end
- //------------------------------------------------------------------------------
-
-
-
-
- //------------------------------------------------------------------------------
- //The datasheet of ADS1118 says: " When CS is taken high, the serial interface is reset, SCLK is ignored, and DOUT/DRDY
- //enters a high-impedance state; as such, DOUT/DRDY cannot provide indication of data ready. "
- //
- parameter CS_FALL_LIMIT_CNT = 128;
- parameter CS_RISE_LIMIT_CNT = 128;
- //
- assign o_fpga_spi_cs = fpga_spi_cs;
- always @(posedge clk)
- begin
- if (~rsto_power_on) fpga_spi_cs <= 1'b1;
- else
- case(ws)
- S_ADC_WR_BACK : if( cs_cnt == CS_FALL_LIMIT_CNT ) fpga_spi_cs <= 1'b1;
- S_ADC_WR_FRONT : if( cs_cnt == CS_RISE_LIMIT_CNT ) fpga_spi_cs <= 1'b0;
- default: ;
- endcase
- end
- //
- //------------------------------------------------------------------------------
-
-
-
-
- //------------------------------------------------------------------------------
- //basic_clk_cnt: count the number of system clock within one spi clock.
- //fpga_spi_clk_cnt: count the number of the spi clock; every spi clock is consisted of "fpga_spi_sck_cycle" cycles of the system clock "clk".
- always @(posedge clk)
- begin
- if (~rsto_power_on)
- begin
- basic_clk_cnt <= 7'd0;
- fpga_spi_clk_cnt <= 5'd0;
- end
- else
- case(ws)
- S_ADC_WR:
- begin
- if (basic_clk_cnt == SPI_SCK_CYCLE - 1)
- begin
- basic_clk_cnt <= 7'd0;
- fpga_spi_clk_cnt <= fpga_spi_clk_cnt + 1;
- end
- else basic_clk_cnt <= basic_clk_cnt + 1;
- end
- default:
- begin
- basic_clk_cnt <= 7'd0;
- fpga_spi_clk_cnt <= 5'd0;
- end
- endcase
- end
- //
- assign spi_bit_index = fpga_spi_clk_cnt[2:0];
- //
- //spi_byte_cnt counts the byte number of spi data sending, while fpga_spi_clk_cnt counts the bit number.
- always @(posedge clk)
- begin
- if (~rsto_power_on) spi_byte_cnt <= 4'd0;
- else
- case(ws)
- S_ADC_WR:
- begin
- if ((basic_clk_cnt == SPI_SCK_CYCLE - 1)&(fpga_spi_clk_cnt[2:0] == 3'd7)) spi_byte_cnt <= spi_byte_cnt + 1;
- end
- default: spi_byte_cnt <= 4'd0;
- endcase
- end
- //
- //------------------------------------------------------------------------------
-
-
-
- //------------------------------------------------------------------------------
- assign o_fpga_spi_sck = fpga_spi_sck;
- //
- always @(posedge clk)
- begin
- if (~rsto_power_on) fpga_spi_sck <= 1'b0;
- else
- case(ws)
- S_ADC_WR:
- //From the datasheet of ADC1118, says : " The device latches data on DIN on the falling edge of SCLK."
- begin
- if (basic_clk_cnt == 6'd1) fpga_spi_sck <= 1'b1;
- else if (basic_clk_cnt == SPI_SCK_CYCLE/2) fpga_spi_sck <= 1'b0;
- end
- default: fpga_spi_sck <= 1'b0;
- endcase
- end
- //------------------------------------------------------------------------------
-
-
-
- //------------------------------------------------------------------------------
- //AN0 acquire voltage.
- //Bits[14:12] : 100 : AINP = AIN0 and AINN = GND
- //Bits[11:9] : 001 : FS = ±4.096V , (if Vin ≥ FS (2^15 – 1)/2^15 output code is 7FFFh )
- //Bits[7:5] : 111 : 860SPS
- //Bit 4 : 0 : ADC mode
- //Bit 3 : 1 : Pull-up resistor enabled on DOUT pin
- //Bits[2:1] : 01 : Valid data, update the Config Register
- //
- parameter C1_CONFIG_BYTE0 = 8'b0011_0000;
- parameter C1_CONFIG_BYTE1 = 8'b1000_1011;
- //
- parameter C2_CONFIG_BYTE0 = 8'b0000_0000;
- parameter C2_CONFIG_BYTE1 = 8'b1000_1011;
- //
- assign o_fpga_spi_mosi = fpga_spi_mosi;
- //
- //
- //
- always @(posedge clk)
- begin
- if (~rsto_power_on) fpga_spi_mosi <= 1'b0 ;
- else if(~channel_change_flag)//send AN2-3 command, and get AN2-3 data.
- case(ws)
- S_ADC_WR:
- begin
- if ((basic_clk_cnt == 6'd1)&(spi_byte_cnt == 4'd0))
- begin
- case (spi_bit_index)
- 3'd0 : fpga_spi_mosi <= C1_CONFIG_BYTE0[7];
- 3'd1 : fpga_spi_mosi <= C1_CONFIG_BYTE0[6];
- 3'd2 : fpga_spi_mosi <= C1_CONFIG_BYTE0[5];
- 3'd3 : fpga_spi_mosi <= C1_CONFIG_BYTE0[4];
- 3'd4 : fpga_spi_mosi <= C1_CONFIG_BYTE0[3];
- 3'd5 : fpga_spi_mosi <= C1_CONFIG_BYTE0[2];
- 3'd6 : fpga_spi_mosi <= C1_CONFIG_BYTE0[1];
- 3'd7 : fpga_spi_mosi <= C1_CONFIG_BYTE0[0];
- default :;
- endcase
- end
- else if ((basic_clk_cnt == 6'd1)&(spi_byte_cnt == 4'd1))
- begin
- case (spi_bit_index)
- 3'd0 : fpga_spi_mosi <= C1_CONFIG_BYTE1[7];
- 3'd1 : fpga_spi_mosi <= C1_CONFIG_BYTE1[6];
- 3'd2 : fpga_spi_mosi <= C1_CONFIG_BYTE1[5];
- 3'd3 : fpga_spi_mosi <= C1_CONFIG_BYTE1[4];
- 3'd4 : fpga_spi_mosi <= C1_CONFIG_BYTE1[3];
- 3'd5 : fpga_spi_mosi <= C1_CONFIG_BYTE1[2];
- 3'd6 : fpga_spi_mosi <= C1_CONFIG_BYTE1[1];
- 3'd7 : fpga_spi_mosi <= C1_CONFIG_BYTE1[0];
- default :;
- endcase
- end
- end
- endcase
- else
- case(ws)
- S_ADC_WR:
- begin
- if ((basic_clk_cnt == 6'd1)&(spi_byte_cnt == 4'd0))
- begin
- case (spi_bit_index)
- 3'd0 : fpga_spi_mosi <= C2_CONFIG_BYTE0[7];
- 3'd1 : fpga_spi_mosi <= C2_CONFIG_BYTE0[6];
- 3'd2 : fpga_spi_mosi <= C2_CONFIG_BYTE0[5];
- 3'd3 : fpga_spi_mosi <= C2_CONFIG_BYTE0[4];
- 3'd4 : fpga_spi_mosi <= C2_CONFIG_BYTE0[3];
- 3'd5 : fpga_spi_mosi <= C2_CONFIG_BYTE0[2];
- 3'd6 : fpga_spi_mosi <= C2_CONFIG_BYTE0[1];
- 3'd7 : fpga_spi_mosi <= C2_CONFIG_BYTE0[0];
- default :;
- endcase
- end
- else if ((basic_clk_cnt == 6'd1)&(spi_byte_cnt == 4'd1))
- begin
- case (spi_bit_index)
- 3'd0 : fpga_spi_mosi <= C2_CONFIG_BYTE1[7];
- 3'd1 : fpga_spi_mosi <= C2_CONFIG_BYTE1[6];
- 3'd2 : fpga_spi_mosi <= C2_CONFIG_BYTE1[5];
- 3'd3 : fpga_spi_mosi <= C2_CONFIG_BYTE1[4];
- 3'd4 : fpga_spi_mosi <= C2_CONFIG_BYTE1[3];
- 3'd5 : fpga_spi_mosi <= C2_CONFIG_BYTE1[2];
- 3'd6 : fpga_spi_mosi <= C2_CONFIG_BYTE1[1];
- 3'd7 : fpga_spi_mosi <= C2_CONFIG_BYTE1[0];
- default :;
- endcase
- end
- end
- endcase
- end
- //------------------------------------------------------------------------------
-
-
-
- //------------------------------------------------------------------------------
- assign sample_point = (basic_clk_cnt == (SPI_SCK_CYCLE - 2)) ;
- //
- always @(posedge clk)
- begin
- sample_point_d <= sample_point ;
- end
- //
- assign o_adc_c1_data = adc_c1_data_r;
- assign o_adc_c2_data = adc_c2_data_r;
- //
- //"adc_c1_data_r" is avoid of sending the changing data to the upper application layer.
- always @(posedge clk)
- begin
- if (~rsto_power_on)
- begin
- adc_c1_data_r <= 16'b0;
- adc_c2_data_r <= 16'b0;
- end
- else if(ws == S_ADC_WR_BACK)
- begin
- if(fpga_spi_cs_0_s_cnt > 10'd32)//128sps, the data will be ok after about 32 0.6s's period.
- begin
- adc_c1_data_r <= adc_c1_data;
- adc_c2_data_r <= adc_c2_data;
- end
- end
- end
- //
- //From the datasheet of ADC1118, says : " Data on DOUT/DRDY are shifted out on the rising edge of SCLK.
- //The MSB of the data (bit 15) on DOUT/DRDY is clocked out on the first rising edge of SCLK."
- //
- //the FPGA should acquire data using the falling edge of SCK.
- //
- //Below, FPGA acquire data a little time before the rising edge of SCK, that is a large time after the falling edge of SCK.
- //
- //Must pay attention: when configure channel 1, and read data of channel 2; configure channel 2, read channel 1.(this chip feature
- //is data is valid in next cycle.)
- //
- //
- always @(posedge clk)
- begin
- if (~rsto_power_on)
- begin
- adc_c1_data <= 16'b0;
- adc_c2_data <= 16'b0;
- end
- else if(~channel_change_flag)
- case(ws)
- S_ADC_WR:
- begin
- case(spi_byte_cnt)
- 4'd0:
- begin
- if (sample_point)
- case (spi_bit_index)
- 3'd0 : adc_c1_data[15] <= fpga_spi_miso_d;
- 3'd1 : adc_c1_data[14] <= fpga_spi_miso_d;
- 3'd2 : adc_c1_data[13] <= fpga_spi_miso_d;
- 3'd3 : adc_c1_data[12] <= fpga_spi_miso_d;
- 3'd4 : adc_c1_data[11] <= fpga_spi_miso_d;
- 3'd5 : adc_c1_data[10] <= fpga_spi_miso_d;
- 3'd6 : adc_c1_data[9] <= fpga_spi_miso_d;
- 3'd7 : adc_c1_data[8] <= fpga_spi_miso_d;
- endcase
- end
- 4'd1:
- begin
- if (sample_point)
- case (spi_bit_index)
- 3'd0 : adc_c1_data[7] <= fpga_spi_miso_d;
- 3'd1 : adc_c1_data[6] <= fpga_spi_miso_d;
- 3'd2 : adc_c1_data[5] <= fpga_spi_miso_d;
- 3'd3 : adc_c1_data[4] <= fpga_spi_miso_d;
- 3'd4 : adc_c1_data[3] <= fpga_spi_miso_d;
- 3'd5 : adc_c1_data[2] <= fpga_spi_miso_d;
- 3'd6 : adc_c1_data[1] <= fpga_spi_miso_d;
- 3'd7 : adc_c1_data[0] <= fpga_spi_miso_d;
- endcase
- end
- default: ;
- endcase
- end
- endcase
- else
- case(ws)
- S_ADC_WR:
- begin
- case(spi_byte_cnt)
- 4'd0:
- begin
- if (sample_point)
- case (spi_bit_index)
- 3'd0 : adc_c2_data[15] <= fpga_spi_miso_d;
- 3'd1 : adc_c2_data[14] <= fpga_spi_miso_d;
- 3'd2 : adc_c2_data[13] <= fpga_spi_miso_d;
- 3'd3 : adc_c2_data[12] <= fpga_spi_miso_d;
- 3'd4 : adc_c2_data[11] <= fpga_spi_miso_d;
- 3'd5 : adc_c2_data[10] <= fpga_spi_miso_d;
- 3'd6 : adc_c2_data[9] <= fpga_spi_miso_d;
- 3'd7 : adc_c2_data[8] <= fpga_spi_miso_d;
- endcase
- end
- 4'd1:
- begin
- if (sample_point)
- case (spi_bit_index)
- 3'd0 : adc_c2_data[7] <= fpga_spi_miso_d;
- 3'd1 : adc_c2_data[6] <= fpga_spi_miso_d;
- 3'd2 : adc_c2_data[5] <= fpga_spi_miso_d;
- 3'd3 : adc_c2_data[4] <= fpga_spi_miso_d;
- 3'd4 : adc_c2_data[3] <= fpga_spi_miso_d;
- 3'd5 : adc_c2_data[2] <= fpga_spi_miso_d;
- 3'd6 : adc_c2_data[1] <= fpga_spi_miso_d;
- 3'd7 : adc_c2_data[0] <= fpga_spi_miso_d;
- endcase
- end
- default: ;
- endcase
- end
- default: ;
- endcase
- end
- //------------------------------------------------------------------------------
-
-
-
- endmodule
-
-
-
-
-
-
-
-
-
-
[/pay]
|