FPGA, SoC, And CPLD Boards And Kits
FPGA Evaluation and Development Kits
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
5283 Discussions

Problem with reading register of deo nano's accelerometer

Altera_Forum
Honored Contributor II
929 Views

Hello everyone, 

I am using deo nano and am trying to read the register of its accelerometer via I2C. 

I have used the same program to read a value from eeprom register and it works out well. 

But using the same program, I cannot get acknowledge signal at the moment I sent the device address(accelerometer). I have checked my timing diagram and have generated a slower clock that pass with accelerometer. I also use signaltap2 to check out the value of my internal register.  

Here is the syntax: 

 

// ADXL clock= 400kHz or 2.5uS or 125 samples of 50mHz. 

// ADXL address= 0x53/1010011 (alt address pin grounded) 

module ADXL_Read( 

clk_50, //clock 50Mhz// 

key, 

I2C_sclk, 

I2C_sdat, 

); 

 

input clk_50; 

input [1:0] key; 

output I2C_sclk; 

inout I2C_sdat; 

 

wire reset_n; 

reg GO; 

reg sdi; 

reg sclk; 

reg [6:0] count; // Create slower clock with 128 samples of 50Mhz 

reg [6:0] sd_counter;  

reg [6:0] slave_add = 1010011; // DEFINE SLAVE ADDRESS 

reg [7:0] register_add = 00110010; // DEFINE REGISTER ADDRESS 

reg [7:0] data; //Data that is read 

 

assign reset_n= key[0]; 

 

// 50MHz clock is too fast for the our devive(in this case eeprom), 

// therefore slower clk need to be generated 

always@(posedge clk_50) count <= count + 1; 

 

// key[0] is to reset the whole operation 

// key[1] is to give a start signal 

always@(posedge count[6] or negedge reset_n) 

begin  

if (!reset_n) 

GO <= 0; 

else  

if (!key[1]) 

GO <= 1; 

end 

 

always@ (posedge count[6] or negedge reset_n) 

begin  

if(!reset_n) 

sd_counter <= 6'b0; 

else  

begin  

if (!GO) 

sd_counter <= 0; 

else 

if (sd_counter < 52) //sd_counter maximum 

sd_counter <= sd_counter + 1; 

end 

end 

 

always@ (posedge count[6] or negedge reset_n) 

begin 

if (!reset_n) 

begin 

sclk <= 1; 

sdi <= 1; 

end 

else 

case (sd_counter) 

 

6'd0 : begin sdi<=1; sclk<=1;end 

 

//START 

6'd1 : sdi <= 0; 

6'd2 : sclk <= 0; 

 

//SLAVE ADDR+Write(Control Byte) 

6'd3 : sdi <= slave_add[6]; 

6'd4 : sdi <= slave_add[5]; 

6'd5 : sdi <= slave_add[4]; 

6'd6 : sdi <= slave_add[3]; 

6'd7 : sdi <= slave_add[2]; 

6'd8 : sdi <= slave_add[1]; 

6'd9 : sdi <= slave_add[0]; 

6'd10 : sdi <= 0; //Write(0) 

6'd11 : sdi <= 1'bz;//Slave ACK 

 

//SUB ADDR(WORD ADDRESS) 

6'd12 : sdi <= register_add[7]; 

6'd13 : sdi <= register_add[6]; 

6'd14 : sdi <= register_add[5]; 

6'd15 : sdi <= register_add[4]; 

6'd16 : sdi <= register_add[3]; 

6'd17 : sdi <= register_add[2]; 

6'd18 : sdi <= register_add[1]; 

6'd19 : sdi <= register_add[0]; 

6'd20 : sdi <= 1'bz;//Slave ACK 

 

//START 

6'd21 : begin sdi <= 1; sclk<=1; end 

6'd22 : sdi <= 0; 

 

//SLAVE ADDR+Read(CONTROL BYTE) 

6'd23 : sdi <= slave_add[6];  

6'd24 : sdi <= slave_add[5]; 

6'd25 : sdi <= slave_add[4]; 

6'd26 : sdi <= slave_add[3]; 

6'd27 : sdi <= slave_add[2]; 

6'd28 : sdi <= slave_add[1]; 

6'd29 : sdi <= slave_add[0]; 

6'd30 : sdi <= 1; //Read(1) 

6'd31 : sdi <= 1'bz;//Slave ACK 

 

//Data read(DATA) 

//Data byte 1 

6'd32 : data[7]= I2C_sdat; 

6'd33 : data[6]= I2C_sdat; 

6'd34 : data[5]= I2C_sdat; 

6'd35 : data[4]= I2C_sdat; 

6'd36 : data[3]= I2C_sdat; 

6'd37 : data[2]= I2C_sdat; 

6'd38 : data[1]= I2C_sdat; 

6'd39 : data[0]= I2C_sdat; 

6'd40 : sdi <= 1'b1;//Master ACK 

 

//Data byte 2 

6'd41 : data[7]= I2C_sdat; 

6'd42 : data[6]= I2C_sdat; 

6'd43 : data[5]= I2C_sdat; 

6'd44 : data[4]= I2C_sdat; 

6'd45 : data[3]= I2C_sdat; 

6'd46 : data[2]= I2C_sdat; 

6'd47 : data[1]= I2C_sdat; 

6'd48 : data[0]= I2C_sdat; 

//stop 

6'd49 : begin sdi <= 1'b0; sclk <= 1'b1; end  

6'd50 : sdi <= 1'b1;  

endcase 

end 

 

assign I2C_sclk = (((sd_counter >= 4)&(sd_counter <= 20))|((sd_counter >=24)&(sd_counter <=50)))? ~count[6] : sclk; 

assign I2C_sdat = sdi; 

 

endmodule 

 

Here are the pin planner assignment: 

I2C_sclk : F2; I2C_sdat : F1 ; clk_50 : R8 ; key[1] : E1 ; key[0] : J15 ; 

 

Here are the signaltap node(trigger cond): sd_counter(don't care), I2C_sclk(don't care), I2C_sdat(don't care), GO(Rising edge). 

 

Signal configuration for signaltap2: clock(count[5]), sample depth(1k), storage qualifier(continuous), trigger(sequential, pretrigger position, 1) 

Note: make the "bus display format" of node "sd_counter" to be "unsigned decimal" for the ease of viewing. 

 

I realize the problem happen when sdat at 6'd3 until 6'd9. Although I assign slave_add to be 1010011, it appears at the signal tap to be 1011011 

Why does it happen? 

 

I realize it is too much to ask. Please someone help me find out the solution. I have stuck in this problem for the last 3 days and have yet no idea. 

 

Thank you so much for helping me.
0 Kudos
1 Reply
Altera_Forum
Honored Contributor II
171 Views
Reply