LISXDX传感器的I2C驱动程序

8个帖子/ 0新
Last post
Horace Hsieh
Offline
Last seen:2 years 7 months ago
Joined:2016-05-05 16:34
LISXDX传感器的I2C驱动程序

Dear Dialog Support Team,

Recently, we are porting LIS2DS/LIS3DH driver on DA14580 platform, but get stuck in I2C operation.

LISX传感器具有来自其他参考I2C传感器的不同读取序列(如MC3410)/ I2C EEPROM。

这是从奴隶读取一个字节的序列
--------------
Master | ST | SAD + W | ... ... | SUB | ... ... | SR | SAD + R | ... ... | ... ... ... | NMAK | SP
Slave | ... ... | ... ... ... ... | SAK | ... ... | SAK | ... ... | ... ... ... ... | SAK | DATA | .... ... | ...

ST: Start Condition
SR: Repeated Start Condition
SP:停止条件
SAK: Slave Acknowledge
子:从属子地址,LISXDX中的寄存器地址
SAD:从地址,0x3A,0011 1010
SAD + W: Slave Address + W, 0x3a, 0011 1010
SAD + R: Slave Address + R, 0x3b, 0011 1011
NMAK: No Master Acknowledge
----
My question is how to implement SR + (SAD +R), and I tried to use
// Send repeated SR & set SAD + R
setword16(i2c_tar_reg,((i2c_dev_address + 1)&ic_tar)|特殊| gc_or_start);
as below:

void i2c_master_init(uint16_t dev_address,uint8_t速度,uint8_t地址_mode,uint8_t地址_size)
{
mem_address_size = address_size;
SetBits16(CLK_PER_REG, I2C_ENABLE, 1); // enable clock for I2C
SetWord16(I2C_ENABLE_REG, 0x0); // Disable the I2C controller
SetWord16(I2C_CON_REG, I2C_MASTER_MODE | I2C_SLAVE_DISABLE | I2C_RESTART_EN); // Slave is disabled
SetBits16(I2C_CON_REG, I2C_SPEED, speed); // Set speed
SetBits16(I2C_CON_REG, I2C_10BITADDR_MASTER, address_mode); // Set addressing mode
SetWord16(I2C_TAR_REG, (dev_address & IC_TAR)); // Set Slave device address
setword16(i2c_enable_reg,0x1);//启用I2C控制器
而((getword16(i2c_status_reg)&0x20)!= 0);//等待I2C主FSM闲置
i2c_dev_address = dev_address;
}
uint8_t i2c_read_byte(uint32_t address)
{
SEND_I2C_COMMAND(地址& 0 xff); // Set address LSB, write access
// Send repeated SR & set SAD + R
setword16(i2c_tar_reg,((i2c_dev_address + 1)&ic_tar)|特殊| gc_or_start);

等待_while_i2c_fifo_is_full();//等待TX FIFO已满
send_i2c_command(0x0100);//将R / W位设置为1(读取访问)
wait_until_i2c_fifo_is_empty();//等到I2C TX FIFO空
wait_for_received_byte();//等待收到的数据
return (0xFF & GetWord16(I2C_DATA_CMD_REG)); // Get received byte
}
但是,它不起作用,并且程序在“wait_for_received_byte()”中被阻止。
我还审查了关于I2C操作的以前的讨论,但似乎没有人可以谈论重复的SR。

请帮助提前谢谢您!

设备:
MT_dialog
Offline
Last seen:2个月6天前
Staff
Joined:2015-06-08 11:34
嗨霍勒斯,

嗨霍勒斯,

You dont have to do anything explictly in order to issue a restart condition on the 580's i2c module. The I2C module will issue a restart command (a start command) when you switch from Read to Write command or the opposite (Write to Read command). Please check the attachment, is the interaction of the 580 with an I2C eeprom flash.

Thanks MT_dialog

Attachment:
Horace Hsieh
Offline
Last seen:2 years 7 months ago
Joined:2016-05-05 16:34
Dear MT,

Dear MT,

Thanks a lot for reply.

>> The I2C module will issue a restart command (a start command) when you switch from Read to Write command or the opposite (Write to Read command

OK, so I simply changed the code like below:
- // Send repeated Start Condition & Set Slave device address
-// SetWord16(I2C_TAR_REG, ((i2c_dev_address + 1) & IC_TAR)|SPECIAL|GC_OR_START);
+ //设置从设备地址
+ setword16(i2c_tar_reg,((i2c_dev_address + 1)和ic_tar));

但它仍然变得止血
wait_for_received_byte();//等待收到的数据

传感器所需的序列与附带的图片有点不同,
and there is only 1 data written after setup write cmd in LISxDx sensor, rather than 2 in eeprom flash.

我不知道为什么以下代码不起作用:(
...
setword16(i2c_tar_reg,(i2c_dev_address和ic_tar));//设置从设备地址
setword16(i2c_enable_reg,0x1);//启用I2C控制器
而((getword16(i2c_status_reg)&0x20)!= 0);//等待I2C主FSM闲置
send_i2c_command(register&0xff);//设置地址LSB,写访问
//设置悲伤+ r
setword16(i2c_tar_reg,((i2c_dev_address + 1)和ic_tar));

等待_while_i2c_fifo_is_full();//等待TX FIFO已满
send_i2c_command(0x0100);//将R / W位设置为1(读取访问)
wait_until_i2c_fifo_is_empty();//等到I2C TX FIFO空
wait_for_received_byte();//等待收到的数据

Please help to indicate where the issue is, thanks again!

MT_dialog
Offline
Last seen:2个月6天前
Staff
Joined:2015-06-08 11:34
嗨霍勒斯,

嗨霍勒斯,

In order to produce the sequence that you ve indicated above i ve used the following code:

i2c_eeprom_init(I2C_SLAVE_ADDRESS, I2C_SPEED_MODE, I2C_ADDRESS_MODE, I2C_ADDRESS_SIZE); //initialize the i2c, in I2C address size place the address size of your device
send_i2c_command(0x03&0xff);//设备具有的地址大小为两个字节长度,如果您的设备需要一个字节长度,则可以使用此指令从0x03地址或所需的任何地址读取。
等待_while_i2c_fifo_is_full();//等待TX FIFO已满
send_i2c_command(0x0100);//设置 times的读取访问

The above snippet produces the waveform that i ve attached below, of course the data responded from the memory is wrong but i suppose this is what you are looking for.

Thanks MT_dialog

Attachment:
Horace Hsieh
Offline
Last seen:2 years 7 months ago
Joined:2016-05-05 16:34
Dear MT,

Dear MT,

非常感谢您的帮助。
However, the case is more complicated than the scenario that you wrote

在您的情况下,从地址保持在0x50不变。
But as the attached spec, the LIS sensor has following requirements.
1)
The Slave Address (SAD) associated to the LIS2DS12 is 00111xxb where the xx bits are
modified by the SA0/SDO pin in order to modify the device address.
如果SA0 / SDO引脚连接到电源电压,则地址为0011101B
2)
The slave address is completed with a Read/Write bit. If the bit is ‘1’ (Read), a repeated
开始(SR)条件必须在两个子地址字节后发出。如果该位是'0'(写)
the master will transmit to the slave with direction unchanged

因此,SAD + R = 0x3B,而SAD + W = 0x3A(如果SA0连接到VCC)
it means I have to change the value in I2C_TAR_REG twice to generate the sequence in Table 20 (please check the attached file or my first comment)

我尝试了多种组合,但所有尝试都失败了,如:

i2c_eeprom_init(0x3a,i2c_fast,i2c_7bit_addr,i2c_1byte_addr);//初始化i2c,sad + w,fast_mode,7bit,1byte
send_i2c_command(0x0f);// who_am_i_reg地址 - 0xF
等待_while_i2c_fifo_is_full();//等待TX FIFO已满

1)setword16(i2c_tar_reg,(0x3a + 1));//重复SR +(SAD + R)
2) SetWord16(I2C_ENABLE_REG, 0);
setword16(i2c_tar_reg,(0x3a + 1));//重复SR +(SAD + R)
SetWord16(I2C_ENABLE_REG, 1);

等待_while_i2c_fifo_is_full();//等待TX FIFO已满
send_i2c_command(0x0100);
...

Any suggestions?

MT_dialog
Offline
Last seen:2个月6天前
Staff
Joined:2015-06-08 11:34
嗨霍勒斯,

嗨霍勒斯,

我没有在那个特定的传感器上看到任何不同的东西,就我所能理解,一个定义传感器地址的一个引脚应该连接到VCC或GND,以便定义传感器7bit地址0x1d或0x1e,这是什么您应该在I2C_TAR_REG中设置,之后您不必在要执行读取或写操作时更改I2C_TAR_REG的值,I2C模块将自动添加“0”或“1”,就像捕捉我送你了。在捕获I VE附上仪器的仪器解码地址和读写操作,如果检查时钟和SDA上的脉冲和SCL上的脉冲,您将看到写入写入[0x50]是0x50加上的8位序列额外的0表示写入(如果将其读取为8位数,则在0xA0中导致的8位数),并且在读取操作中读取[0x50]是0x50的8位序列加上额外的1才能声明读取(如果您读取)它是am 8位的数字,这将导致0xA1的结果。请尝试用作目标Addres而不是0x3a但0x1d,它是设备的实际地址,当您执行读取或写入时,将放置附加位(“1”或“0”)通过i2c_data_cmd_reg。如果将从i2c_data_cmd_reg写入从站的子地址的值(仅写入寄存器的0:7位),则模块将发送设备的地址,后跟写命令(因此1d(11101)+0 - > 0x3A)后跟您在I2C_DATA_CMD_REG中写入的数据。 After that when you want to read, by writting the value 0x100 the module will understand that you want to perform a read (since you have set the 9th bit of theI2C_DATA_CMD_REG) and will provide the address of the device it wants to read, followed by a read command (hence 1D(11101)+1 -> 0x3B) and clock on the SCL line in order to clock data from the slave from the address previously written on the bus, as long as there ins't a stop condition on the bus and you keep feeding the I2C_DATA_CMD_REG with 0x100 the module will keep on providing clock (without exposing the Slave address).

Thanks MT_dialog

Horace Hsieh
Offline
Last seen:2 years 7 months ago
Joined:2016-05-05 16:34
Hi MT,

Hi MT,

Tons of thanks for your patience & kind guiding, although it still doesn't work.
我猜剩下的问题可能与时序相关,并将稍后捕获SDA&SCL的信号。

Horace Hsieh
Offline
Last seen:2 years 7 months ago
Joined:2016-05-05 16:34
Hi MT,

Hi MT,

The driver works now, after the hardware guy replaced with a new board.
请关闭机票,再次谢谢您拯救我们的时间!

Topic locked