//遍历所有I2C地址(仅限7bit寻址!) 对于(uint8\t i=0x01;i<0x7F;i++) { //Set next slave address i2c_init(i);
send_i2c_command(0x00&0x3ff);//在总线上传输地址 等待_while_i2c_fifo_is_full();//Wait if I2C Tx FIFO is full SEND_I2C_COMMAND(0x0100 & 0x3FF); // Send read register 0x00 wait_until_i2c_fifo_is_empty();//等到TX FIFO是空的 等待_,直到_NO _MASTER _ACTIVITY();//确保MASTER已完成
//Did we receive any data? if(GetWord16(I2C_RXFLR_REG) != 0) { //读取接收到的数据(设备id) uint8\u t device\u id=0xFF&GetWord16(I2C\u DATA\u CMD\u REG); //如果这是扩展扫描,则报告设备ID和地址 if(扩展) //扩展扫描。报告地址和注册0x00(device_id) Sprintf(Temp_str,“0x%02x => 0x%02x,”,i,device_id); else //正常扫描=>报告地址 sprintf(临时字符串,“0x%02X”,i); memcpy(&response_str[response_idx],temp_str,strlen(temp_str)); //Warning: will fail if more than 50 I2C devices available on bus 响应\u idx+=strlen(温度\u str); }
I don't know why don't you add this in the documentation and libraries of the SDK !!, many people in this forum will be happy. There are so many I2C devices on the market, each with own structure and protocol.
你好,好的,这很清楚。 In your code above , 。。。。。。。。。。............ 无效i2c写入字节(uint16地址,uint8 wr数据) { i2c_send_address(地址); 等待_while_i2c_fifo_is_full();//Wait if I2C Tx FIFO is full send_i2c_command(wr_data&0xff);//发送写入数据 wait_until_i2c_fifo_is_empty();//等到TX FIFO是空的 wait_until_no_master_actity();//等到没有主活动 } Tar寄存器包含从站的地址,DATA_CMD寄存器包含要发送的数据。I2C_SEND_ADDRESS(地址)会将地址写入DATA_CMD寄存器,然后send_i2c_command(wr_data ..)会这样做!。
Is this a mistake or I am missing something? 都应该通过data_cmd_reg?即,要发送目标和数据的地址? If yes , what is the scope of TAR_REG bits 0:7?
什么是简单的机制: 1 - 向奴隶发送一个命令? 命令可以读,写,复位。。 2-从从设备读取N.字节? All without interrupts , just to get it easy. Thank you !
The IC_TAR register contains the address of the slave device, in the i2c driver the device will first write the register address of the module, that it wants to read/write to the DATA_CMD, and then, place in the DATA_CMD register the data to be transmitted. The I2C_TAR is the address of the device itself the setting of your device address is set during the i2c initialization.
I2C_tar包含DA14580将写入的I2C设备的地址。 The DATA_CMD_REG contains the data to communicate to the DEVICE.
When I write to the DATA_CMD_REG any data , on the i2c bus you have first the I2C_TAR_REG followed by the I2C_DATA_REG content.
If I write the slave address to the DATA_CMD_REG , you will have the address TWO times on the bus !!
If there is single i2c DEVICE on the bus , one needs to load the TAR_REG once and then writes data to DATA_CMD_REG then I get address-->Data sent to the device,
i2c\错误代码i2c\ eeprom\读取数据(uint8\ t*rd\ u data\ t ptr,uint32\ t address,uint32\ t size,uint32\ t*bytes\ u read) { uint32_t tmp_size;
如果(大小==0) { *读取字节数=0; 返回i2c_no_error; }
//Check for max bytes to be read from a (MAX_SIZE x 8) I2C EEPROM if(size> i2c_eeprom_size - 地址) { tmp\ U size=I2C\ EEPROM\ U size—地址; *bytes\ u read=tmp\ u大小; } else { tmp_size = size; *bytes_read=大小; }
//检查是否收到ACK for (uint32_t i = 0; i < I2C_MAX_RETRIES; i++) { SEND_I2C_COMMAND(0x08); // Make a dummy access wait_until_i2c_fifo_is_empty();//等到TX FIFO是空的 wait_until_no_master_actity();//等到没有主活动 tx_abrt_source = getword16(i2c_tx_abrt_source_reg);//读取i2c_tx_abrt_source_reg寄存器 getword16(i2c_clr_tx_abrt_reg);//清除i2c_tx_abrt_source寄存器 if((tx_abrt_source&abrt_7b_addr_noack)== 0) { 返回i2c_no_error; } } 返回i2c_7b_addr_noack_error; }
note: if i loaded the bond data in sysram, it is working fine. i.e, #undef USER_CFG_APP_BOND_DB_USE_SPI_FLASH #undef user_cfg_app_bond_db_use_i2c_eeprom.
please give a valuable suggesssition to avoid this problem.advance thanks.
你好,sjabir2004,
请查看外围设备示例应用部分(7)中的文档UM-B-050,也可以查看外围设备驱动程序部分(10)中的文档UM-B-051。雷竞技安卓下载
谢谢你的对话
你好,
I have already seen these documents.
没有描述外设的硬件结构以及如何设置这些外设。这些例子不能涵盖所有可能的组合和功能。
请确认此文件丢失。
你好,sjabir2004,
没有关于da外围设备和开发的API的其他文档,有关任何附加功能的更多信息,请参阅da的数据表。另外,您可能需要查看文档UM-B-005和UM-B-004,以检查这些文档是否包含任何附加功能。
谢谢你的对话
示例:我想使用i2c命令传感器。我需要发送命令写入然后最终读取。读取可以是max n字节。
我不知道如何设置I2C寄存器中的位和字节来发送和接收,因为它没有写入任何地方!。
在这种情况下,I2C_EEPROM示例的功能是可用的?
Thank you !
Hi,
我不认为I2C_EEPROM示例的I2C功能是传感器驱动程序的一个很好的起点。我一直在使用下面的例子,更好地解释了如何攻击I2C:
/ ****************************************************************************************
*宏
*****************************************************************************************
// i2c Helper宏
#define SEND_I2C_COMMAND(X) SetWord16(I2C_DATA_CMD_REG, (X))
#定义WAIT\ WHILE\ uI2C\ uFIFO\ u IS\ u FULL()WHILE(!(GetWord16(I2C\u STATUS\u REG)和TFNF)
#定义等待直到\u I2C \u FIFO \u为空()而(!(GetWord16(I2C\u STATUS\u REG)和TFE))
#define WAIT_UNTIL_NO_MASTER_ACTIVITY() while(GetWord16(I2C_STATUS_REG) & MST_ACTIVITY)
#定义WAIT \u FOR \u RECEIVED \u BYTE(),while(!GetWord16(I2C\u RXFLR\u REG)
/*---------------------------------------------------------------------------------------
|@brieie初始化提供从地址的I2C接口
|
|@param[in] slave_address, The I2C slave address to communicate with
|
|@return void
------------------------------------------------------------------------------------------------- * /
void i2c_init(uint8_t slave_address)
{
//使用作为参数提供的地址初始化I2C
//TODO: Support 10bit addressing
SetBits16(CLK_PER_REG, I2C_ENABLE, 1); // Enable clock for I2C
SetWord16(I2C_ENABLE_REG,0x0);//禁用I2C控制器
setword16(i2c_con_reg,i2c_master_mode | i2c_slave_disable | i2c_restart_en);//从站被禁用
SetBits16(I2C_CON_REG, I2C_SPEED, 1); // Set speed. Standard speed = 1, fast = 2
SetBits16(I2C_CON_REG,I2C_10BITADDR_MASTER,0);//设置寻址模式。7位=0,10位=1
SetWord16(I2C_TAR_REG, slave_address & 0xFF); // Set Slave device address
setword16(i2c_enable_reg,0x1);//启用I2C控制器
while(GetWord16(I2C_STATUS_REG) & 0x20); // Wait for I2C master FSM to be IDLE
}
//
/*---------------------------------------------------------------------------------------
|@brief Scans the I2C bus for slave devices
|
|@param[in]扩展,如果为真:响应将包括潜在的I2C从设备ID
|@param [in]远程,扫描命令的始发者
|
|@return void
------------------------------------------------------------------------------------------------- * /
void i2c_scan(bool extended,bool remote)
{
char temp_str[255]={0};
char response_str[255] = {0};
uint8_t response_idx=0;
//遍历所有I2C地址(仅限7bit寻址!)
对于(uint8\t i=0x01;i<0x7F;i++)
{
//Set next slave address
i2c_init(i);
send_i2c_command(0x00&0x3ff);//在总线上传输地址
等待_while_i2c_fifo_is_full();//Wait if I2C Tx FIFO is full
SEND_I2C_COMMAND(0x0100 & 0x3FF); // Send read register 0x00
wait_until_i2c_fifo_is_empty();//等到TX FIFO是空的
等待_,直到_NO _MASTER _ACTIVITY();//确保MASTER已完成
//Did we receive any data?
if(GetWord16(I2C_RXFLR_REG) != 0)
{
//读取接收到的数据(设备id)
uint8\u t device\u id=0xFF&GetWord16(I2C\u DATA\u CMD\u REG);
//如果这是扩展扫描,则报告设备ID和地址
if(扩展)
//扩展扫描。报告地址和注册0x00(device_id)
Sprintf(Temp_str,“0x%02x => 0x%02x,”,i,device_id);
else
//正常扫描=>报告地址
sprintf(临时字符串,“0x%02X”,i);
memcpy(&response_str[response_idx],temp_str,strlen(temp_str));
//Warning: will fail if more than 50 I2C devices available on bus
响应\u idx+=strlen(温度\u str);
}
}
//在响应中附加回车、换行符和“确定”
sprintf(temp_str,"\n\rOK");
memcpy(&response_str [response_idx-1],temp_str,strlen(temp_str));
//显示响应(远程或本地)
响应(response_str,strlen(response_str),远程);
//Disable I2C
SetWord16(I2C_ENABLE_REG,0x0);//禁用I2C控制器
SetBits16(CLK_PER_REG,I2C_ENABLE,0);//禁用I2C的时钟
}
//
/*---------------------------------------------------------------------------------------
|@brief发送i2c从存储器地址
|
|@param [in] I2C从存储器的地址
------------------------------------------------------------------------------------------------- * /
void i2c_send_address(uint8_t address_to_send)
{
SEND_I2C_COMMAND(address_to_send & 0xFF); // Set address LSB, write access
}
//
/*---------------------------------------------------------------------------------------
|@brief从i2c从站读取单个字节。
|
|@param[in]address,读取字节的内存地址。
|
|@返回读取字节。
------------------------------------------------------------------------------------------------- * /
int8\t i2c\u读取字节(uint8\t地址)
{
i2c\发送\地址(address&0x3FF);
等待_while_i2c_fifo_is_full();//等待TX FIFO已满
SEND_I2C_COMMAND(0x0100&0x3FF);//将R/W位设为1(读访问)
WAIT_UNTIL_I2C_FIFO_IS_EMPTY();//等待I2C Tx FIFO EMPTY
wait_until_no_master_actity();//Make sure master has finished
return (0xFF & GetWord16(I2C_DATA_CMD_REG)); // Get received byte
}
//
/*---------------------------------------------------------------------------------------
|@brief Writes single byte to I2C slave.
|
|@param[in]address,写入字节的内存地址。
|@param[in] wr_data, Data to write.
|
|@return void.
------------------------------------------------------------------------------------------------- * /
无效i2c写入字节(uint16地址,uint8 wr数据)
{
i2c_send_address(地址);
等待_while_i2c_fifo_is_full();//Wait if I2C Tx FIFO is full
send_i2c_command(wr_data&0xff);//发送写入数据
wait_until_i2c_fifo_is_empty();//等到TX FIFO是空的
wait_until_no_master_actity();//等到没有主活动
}
//
/*---------------------------------------------------------------------------------------{
|@brief Reads data from an I2C slave
|
|@param [in] hw_address,i2c从设备的HW地址
|@param [in] reg_address,要读取的注册地址
|@param[in] num_bytes, Number of bytes to read
|@param[in] remote, originator of the read command
|
|@return void
------------------------------------------------------------------------------------------------- * /
void i2c_read(uint16_t hw_address,uint16_t reg_address,uint8_t num_bytes,bool远程)
{
char temp_str[255]={0};
i2c\ u init(硬件地址);
for(uint8\t i=0;i
uint8_t data = i2c_read_byte(reg_address+i);
字符str[10];
如果(i==0)
sprintf(str,“0x%02X”,数据);
else
sprintf(str,",0x%02X",data);
sprintf(temp_str,"%s%s",temp_str,str);
}
Sprintf(Temp_str,“%s \ n \ rok”,temp_str);
响应(temp\u str,strlen(temp\u str),远程);
}
//
/*---------------------------------------------------------------------------------------
|@brief将数据写入I2C从站的寄存器地址
|
|@param [in] hw_address,i2c从设备的HW地址
|@param[in]寄存器地址,要写入的寄存器地址
|@param[in] data, Data to write
|@param[in] remote, originator of the read command
|
|@return void
------------------------------------------------------------------------------------------------- * /
无效i2c写入(uint16\u t hw\u地址、uint16\u t reg\u地址、uint16\u t wr\u数据、bool remote)
{
i2c\ u init(硬件地址);
i2c\写入\字节(reg\地址,wr\数据);
响应正常(远程);
}
//
我希望这有帮助。
好吧,看来我就是这样looking for. I will give it a try.
I don't know why don't you add this in the documentation and libraries of the SDK !!, many people in this forum will be happy. There are so many I2C devices on the market, each with own structure and protocol.
谢谢你!
您好,我在哪里找到了这些功能
Sprintf(Temp_str,“%s \ n \ rok”,temp_str);
响应(temp\u str,strlen(temp\u str),远程);
对不起,我的意思是回复()和respond_ok()
Hi,
SprIntf来自STDLIB库(只是#include“stdlib.h”) - 当您想要将数据转储到用户或调试期间,真正有用。
这两个respond函数只是我实现的一组函数,用于将数据转储到串行端口。您可以在代码中使用UART2和arch\u printf来实现这一点。
I agree that this should be added to the documentation - useful material for a quick tutorial.
你好,好的,这很清楚。
In your code above ,
。。。。。。。。。。............
无效i2c写入字节(uint16地址,uint8 wr数据)
{
i2c_send_address(地址);
等待_while_i2c_fifo_is_full();//Wait if I2C Tx FIFO is full
send_i2c_command(wr_data&0xff);//发送写入数据
wait_until_i2c_fifo_is_empty();//等到TX FIFO是空的
wait_until_no_master_actity();//等到没有主活动
}
Tar寄存器包含从站的地址,DATA_CMD寄存器包含要发送的数据。I2C_SEND_ADDRESS(地址)会将地址写入DATA_CMD寄存器,然后send_i2c_command(wr_data ..)会这样做!。
Is this a mistake or I am missing something?
都应该通过data_cmd_reg?即,要发送目标和数据的地址?
If yes , what is the scope of TAR_REG bits 0:7?
什么是简单的机制:
1 - 向奴隶发送一个命令?
命令可以读,写,复位。。
2-从从设备读取N.字节?
All without interrupts , just to get it easy.
Thank you !
你好,sjabir2004,
The IC_TAR register contains the address of the slave device, in the i2c driver the device will first write the register address of the module, that it wants to read/write to the DATA_CMD, and then, place in the DATA_CMD register the data to be transmitted. The I2C_TAR is the address of the device itself the setting of your device address is set during the i2c initialization.
谢谢你的对话
你好
I2C_tar包含DA14580将写入的I2C设备的地址。
The DATA_CMD_REG contains the data to communicate to the DEVICE.
When I write to the DATA_CMD_REG any data , on the i2c bus you have first the I2C_TAR_REG followed by the I2C_DATA_REG content.
If I write the slave address to the DATA_CMD_REG , you will have the address TWO times on the bus !!
If there is single i2c DEVICE on the bus , one needs to load the TAR_REG once and then writes data to DATA_CMD_REG then I get address-->Data sent to the device,
This is what I see on the memory oscilloscope.
我是不是漏了什么?
你好,sjabir2004,
你的意思是 ?如果在data_cmd_reg中编写设备的从站地址,则模块将发送I2C_TAR_REG(这是模块的地址),然后将在DATA_CMD_REG中发送数据,该数据再次成为模块的地址。您只需要使用要通信的设备初始化I2C,然后每次在data_cmd_reg中写入内容时,设备的地址将在总线上遵循操作(读/写),然后是数据在data_cmd_reg中。停止或重新启动条件后,I2C将启动新事务时,设备的地址将再次在总线上。
谢谢你的对话
你好,
我正在使用SDK 5.0.4。在DA14580设备中检查安全功能,我必须在EEPROM中存储绑定数据。在向EEPROM写入字节时,我面临i2c_wait_until_eeprom_ready()函数的问题。它会影响调试。
if ((GetWord16(SYS_STAT_REG) & DBG_IS_UP) == DBG_IS_UP)
__asm("BKPT #0\n");
我的代码如下所示,
************************************************************************************
/ ************************************************************
*Select memory medium for bond data storage:
*
*- SPI FLASH (#define USER_CFG_APP_BOND_DB_USE_SPI_FLASH)
*-I2C EEPROM(#定义用户#CFGŠ应用Š绑定ŠDBŠ使用ŠI2CŠEEPROM)
* - 仅缓存(定义任何内容)
*
*只选择一个选项。
************************************************************
*/
#undef USER_CFG_APP_BOND_DB_USE_SPI_FLASH
#define user_cfg_app_bond_db_use_i2c_eeprom.
static inline void bond_db_load_ext(void)
{
#if defined (USER_CFG_APP_BOND_DB_USE_SPI_FLASH)
bond_db_load_flash();
# elif (USER_CFG_APP_BOND_DB_USE_I2C_EEPROM定义)
bond_db_load_eeprom();
#万一
}
# elif (USER_CFG_APP_BOND_DB_USE_I2C_EEPROM定义)
static void bond_db_load_eeprom(void)
{
读取32字节;
i2c_eeprom_init(I2C_SLAVE_ADDRESS, I2C_SPEED_MODE, I2C_ADDRESS_MODE, I2C_ADDRESS_SIZE);
i2c_eeprom_read_data((uint8_t *)&bdb,app_bond_db_data_offset,sizeof(struct bond_db),&bytes_read);
ASSERT_ERROR(bytes_read==sizeof(struct bond_db));
i2c_eeprom_release();
}
i2c\错误代码i2c\ eeprom\读取数据(uint8\ t*rd\ u data\ t ptr,uint32\ t address,uint32\ t size,uint32\ t*bytes\ u read)
{
uint32_t tmp_size;
如果(大小==0)
{
*读取字节数=0;
返回i2c_no_error;
}
//Check for max bytes to be read from a (MAX_SIZE x 8) I2C EEPROM
if(size> i2c_eeprom_size - 地址)
{
tmp\ U size=I2C\ EEPROM\ U size—地址;
*bytes\ u read=tmp\ u大小;
}
else
{
tmp_size = size;
*bytes_read=大小;
}
如果(i2c),请等待直到eeprom就绪()!=I2C(无错误)
{
返回i2c_7b_addr_noack_error;
}
//Read 32 bytes at a time
while(tmp\u大小>=32)
{
read_data_single(&rd_data_ptr, address, 32);
address+=32;//更新读取的基址
tmp\u size-=32;//为剩余要读取的字节更新tmp\u size
}
if (tmp_size)
{
读取数据单(&R)数据ptr、地址、tmp大小;
}
返回i2c_no_error;
}
i2c错误代码i2c等待eeprom就绪(无效)
{
uint16_t tx_abrt_source;
//检查是否收到ACK
for (uint32_t i = 0; i < I2C_MAX_RETRIES; i++)
{
SEND_I2C_COMMAND(0x08); // Make a dummy access
wait_until_i2c_fifo_is_empty();//等到TX FIFO是空的
wait_until_no_master_actity();//等到没有主活动
tx_abrt_source = getword16(i2c_tx_abrt_source_reg);//读取i2c_tx_abrt_source_reg寄存器
getword16(i2c_clr_tx_abrt_reg);//清除i2c_tx_abrt_source寄存器
if((tx_abrt_source&abrt_7b_addr_noack)== 0)
{
返回i2c_no_error;
}
}
返回i2c_7b_addr_noack_error;
}
note: if i loaded the bond data in sysram, it is working fine. i.e,
#undef USER_CFG_APP_BOND_DB_USE_SPI_FLASH
#undef user_cfg_app_bond_db_use_i2c_eeprom.
please give a valuable suggesssition to avoid this problem.advance thanks.
嗨ajay98,
i2c等待直到eeprom ready()通过发送0x08字节来轮询设备,直到设备以ACK响应。你能在调试模式下运行代码并指出在i2c的哪个点等待代码被卡住吗?另外,您使用的是哪个SDK示例?这是自定义实现吗?是否可以在SDK的ble\u app\u安全示例中复制它?
我还建议你创建一个新的论坛线程与你的问题,因为这是一个非常古老的。
谢谢,下午好