你好,
我找不到任何谈论14580(或其他)的外围设备功能的文件以及如何为不同的选项设置它们。
I2C,SPI,A / D,PWM,....等。
有人能指出我这样的文件吗?
嗨sjabir2004,
请查看外围示例应用程序部分(7)的文档UM-B-050,也可以查看外围驱动程序部分(10)中的Doc UM-B-051,以获取外围设备的驱动程序雷竞技安卓下载。
谢谢mt_dialog.
我已经看到了这些文件。没有描述外围设备的硬件结构以及如何设置。这些示例无法涵盖所有可能的组合和功能。
请确认缺少此文档。
没有关于DA外围设备和开发的API的其他文档,有关任何其他功能的更多信息,可以在DA的数据表中找到。此外,您可能希望查看文档UM-B-005和UM-B-004以检查这些文档是否涵盖了任何其他功能。
示例:我想使用i2c命令传感器。我需要发送命令写入然后最终读取。读取可以是max n字节。
我不知道如何在I2C寄存器中设置位和字节以发送和接收,因为它不是写在任何地方!。
在这种情况下,I2C_EEPROM示例的功能是可用的?
谢谢 !
我不认为I2C_EEPROM示例的I2C功能是传感器驱动程序的一个很好的起点。我一直在使用下面的例子,更好地解释了如何攻击I2C:
/ *****************************************************************************************宏*****************************************************************************************// i2c Helper宏#define send_i2c_command(x)setword16(i2c_data_cmd_reg,(x))#define wait_whille_i2c_fifo_is_full()while(!(getword16(i2c_status_reg)&tfnf))#define wait_until_i2c_fifo_is_empty(!(getword16(i2c_status_reg)&tfe))#define wait_until_no_master_actity()(getword16(i2c_status_reg)&mst_actity)#define wait_for_received_byte()while(!getword16(i2c_rxflr_reg))
/ * ---------------------------------------------------------------------------|@brieie初始化提供从地址的I2C接口||@param [in] slave_address,i2c从地址与之通信||@return void.------------------------------------------------------------------------------------------------- * /void i2c_init(uint8_t slave_address){//使用作为参数提供的地址初始化I2C// todo:支持10bit寻址setbits16(clk_per_reg,i2c_enable,1);//为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);//设置速度。标准速度= 1,快速= 2setbits16(i2c_con_reg,i2c_10bitaddr_master,0);//设置寻址模式。7bit = 0,10bit = 1setword16(i2c_tar_reg,slave_address&0xff);//设置从设备地址setword16(i2c_enable_reg,0x1);//启用I2C控制器而(getword16(i2c_status_reg)&0x20);//等待I2C主FSM闲置}//
/ * ---------------------------------------------------------------------------|@brief扫描从设备的I2C总线进行奴隶设备||@param [in]扩展,如果为true:响应将包括潜在的i2c从设备ID|@param [in]远程,扫描命令的始发者||@return void.------------------------------------------------------------------------------------------------- * /void i2c_scan(bool扩展,bool remote){char temp_str [255] = {0};char response_str [255] = {0};uint8_t response_idx = 0;//遍历所有I2C地址(仅限7bit寻址!)for(Uint8_t i = 0x01; i <0x7f; i ++){//设置下一个从地址i2c_init(i);send_i2c_command(0x00&0x3ff);//在总线上传输地址等待_while_i2c_fifo_is_full();//等待i2c tx fifo已满send_i2c_command(0x0100&0x3ff);//发送读取寄存器0x00wait_until_i2c_fifo_is_empty();//等到TX FIFO是空的wait_until_no_master_actity();//确保大师已完成//我们是否收到了任何数据?if(getword16(i2c_rxflr_reg)!= 0){//读取收到的数据(device_id)uint8_t device_id = 0xff&getword16(i2c_data_cmd_reg);//如果这是扩展扫描,则报告设备ID以及地址如果(扩展)//扩展扫描。报告地址和注册0x00(device_id)Sprintf(Temp_str,“0x%02x => 0x%02x,”,i,device_id);别的//正常扫描=>报告地址Sprintf(Temp_str,“0x%02x,”i);memcpy(&response_str [response_idx],temp_str,strlen(temp_str));//警告:如果在总线上提供超过50个I2C设备,则会失败response_idx + = strlen(temp_str);}}//附加回车返回,LineFeed和“确定”回复Sprintf(Temp_str,“\ n \ rok”);memcpy(&response_str [response_idx-1],temp_str,strlen(temp_str));//显示响应(远程或本地)响应(response_str,strlen(response_str),远程);
//禁用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地址_to_send){send_i2c_command(地址_to_send&0xff);//设置地址LSB,写访问}//
/ * ---------------------------------------------------------------------------|@brief从i2c从站读取单个字节。||@param [in]地址,存储地址读取字节。||@return读字节。------------------------------------------------------------------------------------------------- * /INT8_T I2C_READ_BYTE(UINT8_T地址){i2c_send_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空wait_until_no_master_actity();//确保大师已完成返回(0xff&getword16(i2c_data_cmd_reg));//获得收到的字节}//
/ * ---------------------------------------------------------------------------|@brief将单个字节写入i2c从属。||@param [in]地址,存储字节写入的内存地址。|@param [in] wr_data,编写的数据。||@return void。------------------------------------------------------------------------------------------------- * /void i2c_write_byte(uint16_t地址,uint8_t wr_data){i2c_send_address(地址);等待_while_i2c_fifo_is_full();//等待i2c tx fifo已满send_i2c_command(wr_data&0xff);//发送写入数据wait_until_i2c_fifo_is_empty();//等到TX FIFO是空的wait_until_no_master_actity();//等到没有主活动}//
/ * ---------------------------------------------------------------------------|@brief从i2c从站读取数据||@param [in] hw_address,i2c从设备的HW地址|@param [in] reg_address,要读取的注册地址|@param [in] num_bytes,要读取的字节数|@param [in]远程,read命令的始发者||@return void.------------------------------------------------------------------------------------------------- * /void i2c_read(uint16_t hw_address,uint16_t reg_address,uint8_t num_bytes,bool远程){char temp_str [255] = {0};i2c_init(hw_address);for(Uint8_t i = 0; i {UINT8_T DATA = I2C_READ_BYTE(REG_ADDRESS + I);char str [10];如果(i == 0)Sprintf(str,“0x%02x”,数据);别的Sprintf(str,“,0x%02x”,数据);Sprintf(Temp_str,“%s%s”,temp_str,str);}Sprintf(Temp_str,“%s \ n \ rok”,temp_str);响应(temp_str,strlen(temp_str),远程);}//
/ * ---------------------------------------------------------------------------|@brief将数据写入I2C从站的寄存器地址||@param [in] hw_address,i2c从设备的HW地址|@param [in] reg_address,注册地址写入|@param [in]数据,数据写入|@param [in]远程,read命令的始发者||@return void.------------------------------------------------------------------------------------------------- * /void i2c_write(uint16_t hw_address,uint16_t reg_address,uint16_t wr_data,bool远程){i2c_init(hw_address);I2C_WRITE_BYTE(REG_ADDRESS,WR_DATA);respons_ok(远程);}//
我希望这有帮助。
好的,这似乎正在寻找什么。我会试一试。
我不知道为什么你没有在SDK的文档和库中添加这个!!,这个论坛的许多人都会很开心。市场上有这么多的I2C设备,每个I2C设备都有自己的结构和协议。
谢谢你!
您好,我在哪里找到了这些功能Sprintf(Temp_str,“%s \ n \ rok”,temp_str);响应(temp_str,strlen(temp_str),远程);
对不起,我的意思是回复()和respond_ok()
SprIntf来自STDLIB库(只是#include“stdlib.h”) - 当您想要将数据转储到用户或调试期间,真正有用。
这两个响应函数只是我已经实现的一组函数,以将数据转储到串行端口。您可以使用UART2和ARCH_PRINTF在代码中执行此操作。
我同意这应该将其添加到文档中 - 用于快速教程的有用材料。
你好,好的,这很清楚。在上面的代码中,......................void i2c_write_byte(uint16_t地址,uint8_t wr_data){i2c_send_address(地址);等待_while_i2c_fifo_is_full();//等待i2c tx fifo已满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 ..)会这样做!。
这是一个错误还是我错过了什么?都应该通过data_cmd_reg?即,要发送目标和数据的地址?如果是,则tar_reg位0:7的范围是多少?
什么是以下机制:1 - 向奴隶发送一个命令?可以读取,写入,重置命令。2-从从设备读取N.字节?所有没有中断,只是为了让它变得简单。谢谢 !
IC_TAR寄存器包含从设备的地址,在I2C驱动程序中,设备将首先写入模块的寄存器地址,即它想要读取/写入data_cmd,然后,在data_cmd中放置数据传输。I2C_tar是设备本身的地址,在I2C初始化期间设置了设备地址的设置。
你好
I2C_tar包含DA14580将写入的I2C设备的地址。data_cmd_reg中包含要与设备进行通信的数据。
当我写入data_cmd_reg任何数据时,在I2C总线上,您首先拥有I2C_TAR_REG,然后是I2C_DATA_REG内容。
如果我将从地址写入data_cmd_reg,你将在公共汽车上有两次的地址!!
如果总线上有单个I2C设备,则需要一次加载tar_reg一次,然后将数据写入data_cmd_reg然后我获取地址 - >发送到设备的数据,
这就是我在内存示波器上看到的。
我在这里错过了什么?
你什么意思 ?如果在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”);
我的代码如下所示,************************************************************************************/ *************************************************************为键数据存储选择内存介质:** - spi flash(#define user_cfg_app_bond_db_use_spi_flash)* - I2C EEPROM(#define user_cfg_app_bond_db_use_i2c_eeprom)* - 仅缓存(定义任何内容)**仅选择一个选项。************************************************************* /#undef user_cfg_app_bond_db_use_spi_flash.#define user_cfg_app_bond_db_use_i2c_eeprom.
静态内联void bond_db_load_ext(void){#f定义(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)
静态void bond_db_load_eeprom(void){uint32_t bytes_read;
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_ERROR_CODE I2C_EEPROM_READ_DATA(UINT8_T * RD_DATA_PTR,UINT32_T地址,UINT32_T大小,UINT32_T * BYTES_READ){uint32_t tmp_size;
if(size == 0){* bytes_read = 0;返回i2c_no_error;}
//检查要从a(max_size x 8)I2C EEPROM的读取的最大字节if(size> i2c_eeprom_size - 地址){tmp_size = i2c_eeprom_size - 地址;* bytes_read = tmp_size;}别的{tmp_size = size;* bytes_read = size;}
if(i2c_wait_until_eeprom_ready()!= i2c_no_error){返回i2c_7b_addr_noack_error;}
//一次读取32个字节而(tmp_size> = 32){read_data_single(&rd_data_ptr,地址,32);
地址+ = 32;//更新读取的基本地址tmp_size - = 32;//更新TMP_SIZE以进行剩余的字节读取}
if(tmp_size){read_data_single(&rd_data_ptr,地址,tmp_size);}
返回i2c_no_error;}
i2c_error_code i2c_wait_until_eeprom_ready(void){uint16_t tx_abrt_source;
//检查是否已收到ACKfor(Uint32_t i = 0; i {send_i2c_command(0x08);//制作假人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;}
注意:如果我在Sysram中加载了键数据,则它正常工作。IE,#undef user_cfg_app_bond_db_use_spi_flash.#undef user_cfg_app_bond_db_use_i2c_eeprom.
请给出一个有价值的建议,以避免这个问题。谢谢。
嗨ajay98,
i2c_wait_until_eeprom_ready()通过发送0x08字节来轮询设备,直到设备用ACK响应。你能在调试模式下运行代码,并指示在哪个点I2c_wait_until_eeprom_ready()代码被困?此外,您使用的是SDK的哪个示例?这是一个定制的实施吗?是否可以在SDK的BLE_APP_SECURY示例中复制它?
我还建议您使用问题创建一个新的论坛线程,因为这是非常旧的。
谢谢,PM_DIALOG.
嗨sjabir2004,
请查看外围示例应用程序部分(7)的文档UM-B-050,也可以查看外围驱动程序部分(10)中的Doc UM-B-051,以获取外围设备的驱动程序雷竞技安卓下载。
谢谢mt_dialog.
你好,
我已经看到了这些文件。
没有描述外围设备的硬件结构以及如何设置。这些示例无法涵盖所有可能的组合和功能。
请确认缺少此文档。
嗨sjabir2004,
没有关于DA外围设备和开发的API的其他文档,有关任何其他功能的更多信息,可以在DA的数据表中找到。此外,您可能希望查看文档UM-B-005和UM-B-004以检查这些文档是否涵盖了任何其他功能。
谢谢mt_dialog.
示例:我想使用i2c命令传感器。我需要发送命令写入然后最终读取。读取可以是max n字节。
我不知道如何在I2C寄存器中设置位和字节以发送和接收,因为它不是写在任何地方!。
在这种情况下,I2C_EEPROM示例的功能是可用的?
谢谢 !
你好,
我不认为I2C_EEPROM示例的I2C功能是传感器驱动程序的一个很好的起点。我一直在使用下面的例子,更好地解释了如何攻击I2C:
/ ****************************************************************************************
*宏
*****************************************************************************************
// i2c Helper宏
#define send_i2c_command(x)setword16(i2c_data_cmd_reg,(x))
#define wait_whille_i2c_fifo_is_full()while(!(getword16(i2c_status_reg)&tfnf))
#define wait_until_i2c_fifo_is_empty(!(getword16(i2c_status_reg)&tfe))
#define wait_until_no_master_actity()(getword16(i2c_status_reg)&mst_actity)
#define wait_for_received_byte()while(!getword16(i2c_rxflr_reg))
/ * ---------------------------------------------------------------------------
|@brieie初始化提供从地址的I2C接口
|
|@param [in] slave_address,i2c从地址与之通信
|
|@return void.
------------------------------------------------------------------------------------------------- * /
void i2c_init(uint8_t slave_address)
{
//使用作为参数提供的地址初始化I2C
// todo:支持10bit寻址
setbits16(clk_per_reg,i2c_enable,1);//为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);//设置速度。标准速度= 1,快速= 2
setbits16(i2c_con_reg,i2c_10bitaddr_master,0);//设置寻址模式。7bit = 0,10bit = 1
setword16(i2c_tar_reg,slave_address&0xff);//设置从设备地址
setword16(i2c_enable_reg,0x1);//启用I2C控制器
而(getword16(i2c_status_reg)&0x20);//等待I2C主FSM闲置
}
//
/ * ---------------------------------------------------------------------------
|@brief扫描从设备的I2C总线进行奴隶设备
|
|@param [in]扩展,如果为true:响应将包括潜在的i2c从设备ID
|@param [in]远程,扫描命令的始发者
|
|@return void.
------------------------------------------------------------------------------------------------- * /
void i2c_scan(bool扩展,bool remote)
{
char temp_str [255] = {0};
char response_str [255] = {0};
uint8_t response_idx = 0;
//遍历所有I2C地址(仅限7bit寻址!)
for(Uint8_t i = 0x01; i <0x7f; i ++)
{
//设置下一个从地址
i2c_init(i);
send_i2c_command(0x00&0x3ff);//在总线上传输地址
等待_while_i2c_fifo_is_full();//等待i2c tx fifo已满
send_i2c_command(0x0100&0x3ff);//发送读取寄存器0x00
wait_until_i2c_fifo_is_empty();//等到TX FIFO是空的
wait_until_no_master_actity();//确保大师已完成
//我们是否收到了任何数据?
if(getword16(i2c_rxflr_reg)!= 0)
{
//读取收到的数据(device_id)
uint8_t device_id = 0xff&getword16(i2c_data_cmd_reg);
//如果这是扩展扫描,则报告设备ID以及地址
如果(扩展)
//扩展扫描。报告地址和注册0x00(device_id)
Sprintf(Temp_str,“0x%02x => 0x%02x,”,i,device_id);
别的
//正常扫描=>报告地址
Sprintf(Temp_str,“0x%02x,”i);
memcpy(&response_str [response_idx],temp_str,strlen(temp_str));
//警告:如果在总线上提供超过50个I2C设备,则会失败
response_idx + = strlen(temp_str);
}
}
//附加回车返回,LineFeed和“确定”回复
Sprintf(Temp_str,“\ n \ rok”);
memcpy(&response_str [response_idx-1],temp_str,strlen(temp_str));
//显示响应(远程或本地)
响应(response_str,strlen(response_str),远程);
//禁用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地址_to_send)
{
send_i2c_command(地址_to_send&0xff);//设置地址LSB,写访问
}
//
/ * ---------------------------------------------------------------------------
|@brief从i2c从站读取单个字节。
|
|@param [in]地址,存储地址读取字节。
|
|@return读字节。
------------------------------------------------------------------------------------------------- * /
INT8_T I2C_READ_BYTE(UINT8_T地址)
{
i2c_send_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空
wait_until_no_master_actity();//确保大师已完成
返回(0xff&getword16(i2c_data_cmd_reg));//获得收到的字节
}
//
/ * ---------------------------------------------------------------------------
|@brief将单个字节写入i2c从属。
|
|@param [in]地址,存储字节写入的内存地址。
|@param [in] wr_data,编写的数据。
|
|@return void。
------------------------------------------------------------------------------------------------- * /
void i2c_write_byte(uint16_t地址,uint8_t wr_data)
{
i2c_send_address(地址);
等待_while_i2c_fifo_is_full();//等待i2c tx fifo已满
send_i2c_command(wr_data&0xff);//发送写入数据
wait_until_i2c_fifo_is_empty();//等到TX FIFO是空的
wait_until_no_master_actity();//等到没有主活动
}
//
/ * ---------------------------------------------------------------------------{
|@brief从i2c从站读取数据
|
|@param [in] hw_address,i2c从设备的HW地址
|@param [in] reg_address,要读取的注册地址
|@param [in] num_bytes,要读取的字节数
|@param [in]远程,read命令的始发者
|
|@return void.
------------------------------------------------------------------------------------------------- * /
void i2c_read(uint16_t hw_address,uint16_t reg_address,uint8_t num_bytes,bool远程)
{
char temp_str [255] = {0};
i2c_init(hw_address);
for(Uint8_t i = 0; i
UINT8_T DATA = I2C_READ_BYTE(REG_ADDRESS + I);
char str [10];
如果(i == 0)
Sprintf(str,“0x%02x”,数据);
别的
Sprintf(str,“,0x%02x”,数据);
Sprintf(Temp_str,“%s%s”,temp_str,str);
}
Sprintf(Temp_str,“%s \ n \ rok”,temp_str);
响应(temp_str,strlen(temp_str),远程);
}
//
/ * ---------------------------------------------------------------------------
|@brief将数据写入I2C从站的寄存器地址
|
|@param [in] hw_address,i2c从设备的HW地址
|@param [in] reg_address,注册地址写入
|@param [in]数据,数据写入
|@param [in]远程,read命令的始发者
|
|@return void.
------------------------------------------------------------------------------------------------- * /
void i2c_write(uint16_t hw_address,uint16_t reg_address,uint16_t wr_data,bool远程)
{
i2c_init(hw_address);
I2C_WRITE_BYTE(REG_ADDRESS,WR_DATA);
respons_ok(远程);
}
//
我希望这有帮助。
好的,这似乎正在寻找什么。我会试一试。
我不知道为什么你没有在SDK的文档和库中添加这个!!,这个论坛的许多人都会很开心。市场上有这么多的I2C设备,每个I2C设备都有自己的结构和协议。
谢谢你!
您好,我在哪里找到了这些功能
Sprintf(Temp_str,“%s \ n \ rok”,temp_str);
响应(temp_str,strlen(temp_str),远程);
对不起,我的意思是回复()和respond_ok()
你好,
SprIntf来自STDLIB库(只是#include“stdlib.h”) - 当您想要将数据转储到用户或调试期间,真正有用。
这两个响应函数只是我已经实现的一组函数,以将数据转储到串行端口。您可以使用UART2和ARCH_PRINTF在代码中执行此操作。
我同意这应该将其添加到文档中 - 用于快速教程的有用材料。
你好,好的,这很清楚。
在上面的代码中,
......................
void i2c_write_byte(uint16_t地址,uint8_t wr_data)
{
i2c_send_address(地址);
等待_while_i2c_fifo_is_full();//等待i2c tx fifo已满
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 ..)会这样做!。
这是一个错误还是我错过了什么?
都应该通过data_cmd_reg?即,要发送目标和数据的地址?
如果是,则tar_reg位0:7的范围是多少?
什么是以下机制:
1 - 向奴隶发送一个命令?
可以读取,写入,重置命令。
2-从从设备读取N.字节?
所有没有中断,只是为了让它变得简单。
谢谢 !
嗨sjabir2004,
IC_TAR寄存器包含从设备的地址,在I2C驱动程序中,设备将首先写入模块的寄存器地址,即它想要读取/写入data_cmd,然后,在data_cmd中放置数据传输。I2C_tar是设备本身的地址,在I2C初始化期间设置了设备地址的设置。
谢谢mt_dialog.
你好
I2C_tar包含DA14580将写入的I2C设备的地址。
data_cmd_reg中包含要与设备进行通信的数据。
当我写入data_cmd_reg任何数据时,在I2C总线上,您首先拥有I2C_TAR_REG,然后是I2C_DATA_REG内容。
如果我将从地址写入data_cmd_reg,你将在公共汽车上有两次的地址!!
如果总线上有单个I2C设备,则需要一次加载tar_reg一次,然后将数据写入data_cmd_reg然后我获取地址 - >发送到设备的数据,
这就是我在内存示波器上看到的。
我在这里错过了什么?
嗨sjabir2004,
你什么意思 ?如果在data_cmd_reg中编写设备的从站地址,则模块将发送I2C_TAR_REG(这是模块的地址),然后将在DATA_CMD_REG中发送数据,该数据再次成为模块的地址。您只需要使用要通信的设备初始化I2C,然后每次在data_cmd_reg中写入内容时,设备的地址将在总线上遵循操作(读/写),然后是数据在data_cmd_reg中。停止或重新启动条件后,I2C将启动新事务时,设备的地址将再次在总线上。
谢谢mt_dialog.
你好,
我正在使用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”);
我的代码如下所示,
************************************************************************************
/ ************************************************************
*为键数据存储选择内存介质:
*
* - spi flash(#define user_cfg_app_bond_db_use_spi_flash)
* - I2C EEPROM(#define user_cfg_app_bond_db_use_i2c_eeprom)
* - 仅缓存(定义任何内容)
*
*仅选择一个选项。
************************************************************
* /
#undef user_cfg_app_bond_db_use_spi_flash.
#define user_cfg_app_bond_db_use_i2c_eeprom.
静态内联void bond_db_load_ext(void)
{
#f定义(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)
静态void bond_db_load_eeprom(void)
{
uint32_t bytes_read;
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_ERROR_CODE I2C_EEPROM_READ_DATA(UINT8_T * RD_DATA_PTR,UINT32_T地址,UINT32_T大小,UINT32_T * BYTES_READ)
{
uint32_t tmp_size;
if(size == 0)
{
* bytes_read = 0;
返回i2c_no_error;
}
//检查要从a(max_size x 8)I2C EEPROM的读取的最大字节
if(size> i2c_eeprom_size - 地址)
{
tmp_size = i2c_eeprom_size - 地址;
* bytes_read = tmp_size;
}
别的
{
tmp_size = size;
* bytes_read = size;
}
if(i2c_wait_until_eeprom_ready()!= i2c_no_error)
{
返回i2c_7b_addr_noack_error;
}
//一次读取32个字节
而(tmp_size> = 32)
{
read_data_single(&rd_data_ptr,地址,32);
地址+ = 32;//更新读取的基本地址
tmp_size - = 32;//更新TMP_SIZE以进行剩余的字节读取
}
if(tmp_size)
{
read_data_single(&rd_data_ptr,地址,tmp_size);
}
返回i2c_no_error;
}
i2c_error_code i2c_wait_until_eeprom_ready(void)
{
uint16_t tx_abrt_source;
//检查是否已收到ACK{
for(Uint32_t i = 0; i
send_i2c_command(0x08);//制作假人
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;
}
注意:如果我在Sysram中加载了键数据,则它正常工作。IE,
#undef user_cfg_app_bond_db_use_spi_flash.
#undef user_cfg_app_bond_db_use_i2c_eeprom.
请给出一个有价值的建议,以避免这个问题。谢谢。
嗨ajay98,
i2c_wait_until_eeprom_ready()通过发送0x08字节来轮询设备,直到设备用ACK响应。你能在调试模式下运行代码,并指示在哪个点I2c_wait_until_eeprom_ready()代码被困?此外,您使用的是SDK的哪个示例?这是一个定制的实施吗?是否可以在SDK的BLE_APP_SECURY示例中复制它?
我还建议您使用问题创建一个新的论坛线程,因为这是非常旧的。
谢谢,PM_DIALOG.