This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM3358:如何在 PRU 中使用 I2C

Guru**** 2964790 points

Other Parts Discussed in Thread: AM3358

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/676198/am3358-how-to-use-i2c-in-pru

器件型号:AM3358

您好!

我正在 PRU 内核中初始化 am3358的 i2c-1。

在这里、我可以看到使用 DSO 的 sda 引脚上的从器件地址。

但我无法接收 ACK。 总是带着 NACK 返回

而相同的硬件在不同的设置下工作。

我在这里附加了我的代码。

#include "main.h"
#include "hw_types.h"
#include "error.h"
#include "delay.h"
#include "hsi2c.h"
#include "hw_hsi2c.h"
#include "HW_cm_per.h"

#define I2C0_bus 0
#define I2C1_bus 1

#define DELAY_SEC_MILLEY 1

#define I2C_TIMEOUT 5

#define SUCCESS 1
#define 失败 0


/**
* clockInit
*
** brief
*
*此例程根据总线编号
*
*参数 busNum 初始化 I2C 的时钟部分 [IN]总线实例编号
*
* return
* NA
*
//

void clockInit
(
uint8_t busNum
)
{
#ifdef centarus
HWREG (PINCNTL263)= I2C0_PIN_EN;
HWREG (PINCNTL264)= I2C0_PIN_EN;

/*确保模块已启用,并且其时钟也已启用*/
HWREG (PRCM + CM_PER_I2C0_CLKCTRL)=
CM_PER_I2C0_CLKCTRL_MODULEMODE_ENABLE;

DELAYMilliSeconds (I2C_TIMEOUT);

/*检查状态是否已更改*/
while (HWREG (CM_ALWON_I2C_0_CLKCTRL)和 CM_PER_I2C2_CLKCTRL_IDLEST);

DELAYMilliSeconds (DELAY_Milli_SEC);

*(uint32_t*)(PRCM + CM_PER_I2C1_CLKCTR)=
CM_PER_I2C0_CLKCTRL_MODULEMODE_ENABLE;

DELAYMilliSeconds (I2C_TIMEOUT);

/*检查状态是否已更改*/
while (*(uint32_t*) CM_ALWON_I2C_1_CLKCTRL)& CM_PER_I2C2_CLKCTRL_IDLEST);

DELAYMilliSeconds (DELAY_Milli_SEC);


#else

// switch (busNum)
//{
// 情况 I2C0_BUS:
/*确保模块已启用,并且其时钟也已启用*/
HWREG (SOC_PRCM_regs + CM_PER_I2C1_CLKCTRL)= CM_PER_I2C1_CLKCTRL_MODULEMODE_ENABLE;
// 中断;
// 案例 I2C1_BUS:
/*确保模块已启用,并且其时钟也已启用*/
HWREG (SOC_PRCM_regs + CM_PER_I2C2_CLKCTRL)= CM_PER_I2C2_CLKCTRL_MODULEMODE_ENABLE;
// 中断;
//}

/*等待时钟处于非活动状态*/
while (((HWREG (SOC_PRCM_regs + CM_PER_L4LS_CLKSTCTRL))和 CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_I2C_FCLK)
= CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_I2C_FCLK_INACT);

#endif
}


/**
* int16_t i2cInit()
*用于初始化 I2C 的简短例程
*
*此例程根据给定的总线编号初始化 I2C 实例。在此不使用
*中断,因为代码旨在以
轮询模式执行所有 I/O 操作*。
*
*参数 busNum [in]总线实例编号
*
* return
* 成功返回-说明
* 错误返回失败-说明
*/
int16_t I2CInit
(
uint8_t busNum
)
{
int16_t RetVal =成功;
uint16_t sclValues = 0;
uint32_t baseI2c = 0;
uint8_t flag=0;
uint16_t delayCnt = 1000;

交换机(总线号)
{
情况 I2C0_BUS:
baseI2c = SOC_I2C_0_regs;
中断;
案例 I2C1_BUS:
baseI2c = SOC_I2C_1_regs;
中断;
默认值:
RetVal = E_INVALID_PARARAM;
返回 RetVal;
}

if (成功==RetVal)
{
#ifdef centarus
;#else

/*设置 I2C///所需的 PINMUX
pinmuxSetting (busNum);
#endif
/*根据需要设置时钟以便 I2C 正常工作*/
clockInit (busNum);

/*重置所有寄存器*/
HWREG (baseI2c + I2C_CON)= 0;
HWREG (baseI2c + I2C_PSC)= 0;
HWREG (baseI2c + I2C_SCLL)= 0;
HWREG (baseI2c + I2C_SCLH)= 0;
HWREG (baseI2c + I2C_BUF)= 0;
HWREG (baseI2c + I2C_SYSC)= 0;
HWREG (baseI2c + I2C_WI)= 0;
HWREG (baseI2c + I2C_IRQSTATUS)= 0;

delay_ms (1);
/*对 I2C 控制器进行软复位*/
HWREG (baseI2c + I2C_SYSC)= I2C_SYSC_SRST;

/*需要启用 I2C 才能完成复位*/
HWREG (baseI2c + I2C_CON)= I2C_CON_I2C_EN;

/*等待重置*/
while (I2C_SYSC_SRST_RESET!=标志)
{
FLAG =(HWREG (baseI2c + I2C_SYSC)& I2C_SYSC_SRST_RESET);
delayCnt--;
delay_ms (1);
if (delayCnt <= 0) 中断;
}
如果(delayCnt=0)
{
RetVal =失败;
返回(返回值);
}
delay_ms (I2C_TIMEOUT);


/*唤醒*/
HWREG (baseI2c + I2C_SYSC)= I2C_SYSC_ENAWAKEUP;
// |I2C_SYSC_AUTOIDLE
// /*NO IDLE MODE*//
|(I2C_SYSC_IDLEMODE_SMARTIDLE << I2C_SYSC_IDLEMODE_SHIFT);
// /*功能模式下的时钟活动*//
|(I2C_SYSC_CLKACTIVITY_FUNC << I2C_SYSC_CLKACTIVITY_SHIFT);


/*禁用控制器*/
HWREG (baseI2c + I2C_CON)= 0;

/*计算 PSC 值*//
IF (HSI2C_BUS_CLOCK > I2C_TIMEOUT)
// {
/* I2C 预分频设置。 *
HWREG (baseI2c + I2C_PSC)= 0xb;//HSI2C_PRESALE_DIV1;
// sclValues = HSI2C_INTERNAL_CLOCK1/HSI2C_BUS_CLOCK;
//}
// else
// {
// /* I2C 预分频设置。 */
// HWREG (baseI2c + I2C_PSC)= HSI2C_PRESALE_DIV2;
// sclValues = HSI2C_INTERNAL_CLOCK2 / HSI2C_BUS_CLOCK;
//}

/*禁用并清除所有中断*/
HWREG (baseI2c + I2C_IRQENABLE_CLR)= 0xFFFFFFFF;//HSI2C_IRQDISABLE_ALL;

/*设置 SCL 低电平和高电平时间*/
HWREG (baseI2c + I2C_SCLL)= 0xd;
HWREG (baseI2c + I2C_SCLH)= 0xF;
// HWREG (baseI2c + I2C_SCLL)= sclValues - HI2C_SCLL_VAL;
// HWREG (baseI2c + I2C_SCLH)= sclValues - HI2C_SCLH_VAL;

/*设置自地址*/
HWREG (baseI2c + I2C_OA)= 0;//I2C_OA_OA 和 OIL_ADD;

/*启用 I2C 控制器*/
HWREG (baseI2c + I2C_CON)= I2C_CON_I2C_EN;

/*设置从地址*/
HWREG (baseI2c + I2C_SA)=(int16_t) NULL;

/*设置数据计数*/
HWREG (baseI2c + I2C_CNT)=(int16_t) NULL;

HWREG (baseI2c + I2C_we)= I2C_WE_AL | I2C_WE_NACK | I2C_WE_ARDY | I2C_WE_DRDY;
}
返回(RetVal);
}

void DELAYSeconds (int sec)
{
int k=0;
for (k=0;k<2000;k++){}


typedef 枚举{
I2C_TRANSFERS_SUCCESS=0、
I2C_Arbitration_Lost、
I2C_Nack_received、
I2C_ACCESS_ERROR、
I2C_BUS_BUS_BUSY、
I2C_Receive_overrun、
I2C_TIMEOUT_ERROR、
I2C_INVALID_PARARAM、
I2C_AAS_SLAVE_ADDR、
I2C_INVALID_ERROR
}I2C_ERROR_CODE_Type;

uint32_t I2C_GetBaseAddress (uint8_t busNum)
{
uint32_t baseI2c=0;
交换机(总线号)
{
情况 I2C0_BUS:
baseI2c = SOC_I2C_0_regs;
中断;
案例 I2C1_BUS:
baseI2c = SOC_I2C_1_regs;
中断;
默认值:
返回 I2C_INVALID_PARAM;
}
return baseI2c;
}
I2C_ERROR_CODE_Type I2C_ErrorHandling (uint32_t baseAddress)
{
uint32_t status=0;
状态= HWREG (baseAddress + I2C_IRQSTATUS);

if (I2C_IRQSTATUS_RAW_AL_AL_LOST =(STATUS & I2C_IRQSTATUS_RAW_AL)){
HWREG (baseAddress + I2C_IRQSTATUS)|= I2C_IRQSTATUS_RAW_AL;
返回 I2C_arbitration_lost;
}
if (I2C_IRQSTATUS_RAW_AERR =(STATUS & I2C_IRQSTATUS_RAW_AERR)){
HWREG (baseAddress + I2C_IRQSTATUS)|= I2C_IRQSTATUS_RAW_AERR;
返回 I2C_ACCESS_ERROR;
}
if (I2C_IRQSTATUS_RAW_NACK =(status & I2C_IRQSTATUS_RAW_NACK)){
HWREG (baseAddress + I2C_IRQSTATUS)|= I2C_IRQSTATUS_RAW_NACK;
返回 I2C_Nack_received;
}
if (I2C_IRQSTATUS_RAW_ROVR =(status & I2C_IRQSTATUS_RAW_ROVR)){
HWREG (baseAddress + I2C_IRQSTATUS)|= I2C_IRQSTATUS_RAW_ROVR;
返回 I2C_Receive_overrun;
}
if (I2C_IRQSTATUS_RAW_AAS =(STATUS & I2C_IRQSTATUS_RAW_AAS)){
HWREG (baseAddress + I2C_IRQSTATUS)|= I2C_IRQSTATUS_RAW_AAS;
// 返回 I2C_AAS_SLAVE_ADDR;
}
返回 I2C_TRANSFER_SUCCESS;
}

/**
*\n\brief 例程、用于从 I2C 器件读取数据- 0
*
此例程初始化 I2C 控制
器、以便从连接到总线的从器件*外设读取数据。 此函数将从器件地址
*作为一个参数、同时读取缓冲区指针和缓冲区长度。
*此函数返回读取到输出长度指针的字节数。
*
* busNum [在] I2C 总线编号
* slaveAddr [in] 从
*缓冲区读取的 I2C 从器件地址 [输出] 将数据复制到
* bufLen 的缓冲指针 [在] 输入缓冲区指针的长度
* pDataRead [out] 放置占位符以返回读取的字节数
*
*\return
*\n 成功返回-说明
*\n 错误返回失败-说明
*/
I2C_ERROR_CODE_Type I2CRead
(
uint8_t busNum、
uint16_t slaveAddr、
uint8_t *缓冲区、
uint8_t bufLen、
uint8_t *pDataRead
)
{
I2C_ERROR_CODE_Type RetVal = I2C_TRANSFER_SUCCESS;
uint16_t status = 0;
uint8_t bytesRead = 0;
uint8_t* pDataPtr = NULL;/*用于保存接收数据的指针*/
uint32_t 超时= I2C_TIMEOUT;
uint32_t baseI2c = 0;

/*输入参数验证*/
if ((NULL!= buffer)&&(0!= bufLen)&&(NULL!= pDataRead)){
pDataPtr =缓冲器;
}否则{
返回 I2C_INVALID_PARAM;
}

baseI2c = I2C_GetBaseAddress (busNum);
if (baseI2c =I2C_INVALID_PARARAM)返回 I2C_INVALID_PARARAM;

/*设置从地址*/
HWREG (baseI2c + I2C_SA)= slaveAddr & I2C_SA_SA;

/*设置计数*/
HWREG (baseI2c + I2C_CNT)= bufLen;

/*轮询总线以使其空闲/空闲*/
对于(超时= 0;超时< I2C_TIMEOUT;TIMEOUT++)
{
IF (I2C_IRQSTATUS_RAW_BB_FREE =(HWREG (baseI2c + I2C_IRQSTATUS)& I2C_IRQSTATUS_RAW_BB)) 中断;
}

如果(超时=I2C_TIMEOUT) 返回 I2C_TIMEOUT_ERROR;

/*将 I2C 总线配置为主接收模式*/
HWREG (baseI2c + I2C_CON)= I2C_CON_I2C_EN | I2C_CON_MST | I2C_CON_TRX_RCV | I2C_CON_STP | I2C_CON_STT;

/*直到我们必须读取所有数据或超时为止,
*从 I2C 数据寄存器读取数据并返回
*

对于(超时= 0;超时< I2C_TIMEOUT;TIMEOUT++)
{
状态= HWREG (baseI2c + I2C_IRQSTATUS);

/*检查 NACK */
if (0 =(status & I2C_IRQSTATUS_RAW_NACK))
{
/*收到 ACK。 现在检查数据就绪*/
IF (0 =(STATUS & I2C_IRQSTATUS_RAW_ARDY))
{
/*检查 RRDY 数据可用性*/
IF (I2C_IRQSTATUS_RAW_RRDY ==(status & I2C_IRQSTATUS_RAW_RRDY))
{
/*检查我们是否有可用的缓冲空间*/
if (bytesRead < bufLen)
{
/*数据可用。 立即阅读并 ACK */
*pDataPtR++=(HWREG (baseI2c + I2C_DATA)和 I2C_DATA_DATA;
字节 read++;
}

/*清除 RRDY 位*/
HWREG (baseI2c + I2C_IRQSTATUS)= I2C_IRQSTATUS_RAW_RRDY;
}
}
RetVal = I2C_ErrorHandling (baseI2c);
if (RetVal!= I2C_TRANSFS_SUCCESS) 返回 RetVal;

delay_ms (10);
}
其他
{
/*清除 NACK 位*/
HWREG (baseI2c + I2C_IRQSTATUS)=(I2C_IRQSTATUS_RAW_NACK_CLEAR << I2C_IRQSTATUS_RAW_NACK_SHIFT);
返回 I2C_Nack_received;
}
}

/*返回前,也更新返回计数*/
if (NULL!= pDataRead) *pDataRead = bytesRead;

return I2C_transfer_Success;
}/**


*\n\brief 例程、用于从从器件写入数据 I2C - 0
*
此例程初始化 I2C 控制
器以写入连接到总线的从器件*外设。 此函数将从器件地址
*作为一个参数、同时将写入缓冲器指针和缓冲器长度作为参数。
*此函数返回写入输出长度指针的字节数。
*
* busNum [在] I2C 总线编号
* slaveAddr [in] 从
*缓冲区读取的 I2C 从器件地址 [输出] 将数据复制到
* bufLen 的缓冲指针 [在] 输入缓冲区指针的长度
* pDataRead [out] 放置占位符以返回读取的字节数
*
* return
* 成功返回-说明
* 错误返回失败-说明
*/
I2C_ERROR_CODE_Type I2CWrite
(
uint8_t busNum、
uint16_t slaveAddr、
uint8_t *缓冲区、
uint8_t bufLen、
uint8_t *dataWritten
)
{
I2C_ERROR_CODE_Type RetVal = I2C_TRANSFER_SUCCESS;
uint16_t status = 0;
uint8_t 字节 Written = 0;
uint32_t 超时= I2C_TIMEOUT;
uint32_t baseI2c = 0;

if ((NULL == buffer)||(0 == bufLen)||(NULL == dataWritten)){
返回 I2C_INVALID_PARAM;
}

/*分配 I2C 寄存器基地址*/
baseI2c = I2C_GetBaseAddress (busNum);
if (baseI2c =I2C_INVALID_PARARAM)返回 I2C_INVALID_PARARAM;

/*仅为了确保清除先前的事务标志*/
HWREG (baseI2c + I2C_IRQSTATUS)= I2C_CNT_DCOUNT;
delay_ms (1);

/*设置从地址*/
HWREG (baseI2c + I2C_SA)=(slaveAddr << 1)& I2C_SA_SA;
delay_ms (1);
ConsoleUtilsPrintf ("\n 从地址:0x%x"、HWREG (baseI2c + I2C_SA);

/*设置计数*/
HWREG (baseI2c + I2C_CNT)= bufLen;
delay_ms (1);
ConsoleUtilsPrintf ("\n 缓冲区长度:0x%x"、HWREG (baseI2c + I2C_CNT));

/*轮询总线以使其空闲/空闲*/
对于(超时= 0;超时< I2C_TIMEOUT;TIMEOUT++)
{
IF (I2C_IRQSTATUS_RAW_BB_FREE =(HWREG (baseI2c + I2C_IRQSTATUS)& I2C_IRQSTATUS_RAW_BB)) 中断;
}

/******* /

如果(超时=I2C_TIMEOUT) 返回 I2C_TIMEOUT_ERROR;

/*将 I2C 总线配置为主接收模式*/
HWREG (baseI2c + I2C_CON)= I2C_CON_I2C_EN | I2C_CON_MST | I2C_CON_TRX_TRX | I2C_CON_STP;
// DELAY_ms (1);
//控制台 UtilsPrintf ("\n I2C 控制:0x%x"、HWREG (baseI2c + I2C_CON));

/*循环、直至我们写入所有数据或超时*//
for (timeout = 0;timeout < I2C_timeout;timeout++)
//{
HWREG (baseI2c + I2C_CON)|= I2C_CON_STT;
//__ delay_cycles (5000);
ConsoleUtilsPrintf ("\n con:0x%x"、HWREG (baseI2c + I2C_CON));
//_ delay_cycles (5000);
while (1)
{
超时++;
if (timeout =I2C_TIMEOUT) 返回 I2C_TIMEOUT_ERROR;

/*清除 AL 位*/
// HWREG (baseI2c + I2C_IRQSTATUS)= I2C_IRQSTATUS_RAW_AL_AL_CLEAR;
状态= HWREG (baseI2c + I2C_IRQSTATUS);
// _delay_cycles (5000);
控制台 UtilsPrintf ("\n 原始状态:0x%x"、HWREG (baseI2c + I2C_IRQSTATUS_RAW));
// _delay_cycles (5000);
ConsoleUtilsPrintf ("\n 状态:0x%x",状态);

/*检查 NACK */
if (!(status & I2C_IRQSTATUS_RAW_NACK))
{
/*收到 ACK。 现在检查数据就绪*/
if (!(status & I2C_IRQSTATUS_RAW_ARDY))
{
/*检查 XRDY 以了解数据可用性*/
if (status & I2C_IRQSTATUS_RAW_XRDY)
{
ConsoleUtilsPrintf ("\n 更新数据。");
/*检查我们是否有可用的缓冲空间*/
if (bytesWritten < bufLen)
{
/*写入数据和 ACK */
HWREG (baseI2c + I2C_DATA)=(* buffer++& I2C_DATA_DATA);
delay_ms (1);
字节 Written++;
}
/*检查我们是否有可用的缓冲空间*/

/*清除 XRDY 位*/
HWREG (baseI2c + I2C_IRQSTATUS)=(I2C_IRQSTATUS_RAW_XRDY_CLEAR << I2C_IRQSTATUS_RAW_XRDY_SHIFT);
delay_ms (1);
}
其他
{
/*循环以再次尝试*/
控制台 UtilsPrintf ("\n XRDY 不可用|:0x%x"、status);
// RetVal = I2C_ErrorHandling (baseI2c);
if (RetVal!= I2C_TRANSFS_SUCCESS)
返回 I2C_INVALID_ERROR;
}
}
其他
{
ConsoleUtilsPrintf ("\n 注册访问不可用:0x%x",状态);
}
if (bytesWritten =bufLen) delay_ms (I2C_TIMEOUT);

RetVal = I2C_ErrorHandling (baseI2c);
if (RetVal!= I2C_TRANSFS_SUCCESS) 返回 RetVal;

}
其他
{
// RetVal =失败;
ConsoleUtilsPrintf ("\n 接收到 Nack");
RetVal = I2C_ErrorHandling (baseI2c);
if (RetVal!= I2C_TRANSFS_SUCCESS) 返回 RetVal;
// /*清除 NACK 位*/
// HWREG (baseI2c + I2C_IRQSTATUS)=(I2C_IRQSTATUS_RAW_NACK_CLEAR << I2C_IRQSTATUS_RAW_NACK_SHIFT);
// 返回 I2C_Nack_received;
}
}

/*返回前,也更新返回计数*/
if (NULL!= dataWritten){
*dataWritten =字节 Written;
ConsoleUtilsPrintf ("\n 数据写入:%d、%d、* dataWritten、bytesWritten);
}

返回 I2C_TRANSFER_SUCCESS;
}

#define I2C_READ 0x21
#define I2C_WRITE 0x21

#define REG_BIT_MASK (0x1f)
#define REG_IDX_SHIFT (0x05)
void init_i2c1 (void)
{
//需要启用时钟和 I2C 外设
I2CInit (I2C1_BUS);

HWREG (SOC_I2C_1_regs + I2C_IRQENABLE_SET)= I2C_IRQENABLE_Set_AL_AL_IE | I2C_IRQENABLE_SET_NACK_IE |
I2C_IRQENABLE_SET_ROVR | I2C_IRQENABLE_SET_RRDY_IE | I2C_IRQENABLE_SET_ARDY_IE |
I2C_IRQENABLE_SET_XRDY_IE | I2C_IRQENABLE_SET_XDR_IE | I2C_IRQENABLE_SET_RDR_IE;
_delay_cycles (5000);
IntUtilsPrintf ("\n 中断设置:0x%x"、HWREG (SOC_I2C_1_regs + I2C_IRQENABLE_SET));
}

void READ_ProductID (void)
{
uint8_t PRODUCT_command1[2]={0x36、0x7C};
uint8_t SOFT_RESET_RETURN
= 0xint8_0_t = 0xint8_0_t = 0xint0_t 产品0x2

;错误0xint8_0_t 0_t = 0xint0_t 0_t 0_t 0_int_t = 0xint0_int_int_int0_int_int_int_int_int_int_int_int_int_int_int2;t 0_int_int_int_int_int_int_int_int_int_



memset (return_product_id、0x00、sizeof return_product_id);

错误代码= I2CWrite (I2C1_bus、I2C_WRITE、SOFT_RESET_cmd、2、WRITE_BYTES);
if (errorCode!= I2C_TRANSFERS_SUCCESS) ConsoleUtilsPrintf ("\n 写入数据时出错,字节:%d |错误:%d"、write_bytes、errorCode);
其他
{
控制台 UtilsPrintf ("\n 正在写入命令代码1.");
错误代码= I2CWrite (I2C1_bus、I2C_WRITE、product_command1、2、write_bytes);
if (errorCode!= I2C_TRANSFERS_SUCCESS) ConsoleUtilsPrintf ("\n 写入数据时出错,字节:%d |错误:%d"、write_bytes、errorCode);
否则{
delay_ms (2);
ConsoleUtilsPrintf (""正在写入命令代码2。 、字节:%d "、write_bytes);
错误代码= I2CWrite (I2C1_bus、I2C_WRITE、product_command2、写入字节);
if (errorCode!= I2C_TRANSFERS_SUCCESS) ConsoleUtilsPrintf ("\n 写入数据时出错,字节:%d |错误:%d"、write_bytes、errorCode);
否则{
delay_ms (2);
ConsoleUtilsPrintf (""正在读取产品数据。 、字节:%d "、write_bytes);
错误代码= I2CRead (I2C1_bus、I2C_Read、return_product_id、18、read_Bytes);
if (errorCode!= I2C_TRANSFERS_SUCCESS) ConsoleUtilsPrintf ("\n 读取数据时出错,字节:%d |错误:%d"、read_Bytes、errorCode);
否则{
ConsoleUtilsPrintf (""读取成功。 ,字节:%d”,Read_Bytes);
}
}


if (errorCode = I2C_transfer_Success){
//打印产品 ID
控制台 UtilsPrintf ("\n 产品 ID。");
for (i=0;i<20;i++)
{
控制台 UtilsPrintf ("\nBYTE[%d]:0x%02x"、i、return_product_id[i]);
}
}

}


void read_i2c_register (uint8_t i2cBus)
{
uint32_t i2cAddr=0、clkAddr=0;

if (i2cBus = 0)
{
i2cAddr = SOC_I2C_0_regs;
clkAddr = CM_PER_I2C1_CLKCTRL;
}
其他
{
i2cAddr = SOC_I2C_1_regs;
clkAddr = CM_PER_I2C2_CLKCTRL;
}

控制台 UtilsPrintf ("\n ********* ");
控制台 UtilsPrintf ("\n********* I2C 总线:%d@0x%x ******** "、i2cBus、i2cAddr);
控制台 UtilsPrintf ("\n ********* ");
控制台 UtilsPrintf ("\n CM_PER_I2C_CLKCTRL[0x%x]:0x%x"、clkAddr、HWREG (SOC_PRCM_regs + clkAddr));
控制台 UtilsPrintf ("\n I2C_REVNB_LO:0x%x"、HWREG (i2cAddr + I2C_REVNB_LO));
控制台 UtilsPrintf ("\n I2C_REVNB_HI:0x%x"、HWREG (i2cAddr + I2C_REVNB_HI));
ConsoleUtilsPrintf ("\n I2C_SYSC:0x%x"、HWREG (i2cAddr + I2C_SYSC));
ConsoleUtilsPrintf ("\n I2C_EOI:0x%x"、HWREG (i2cAddr + I2C_EOI));
控制台 UtilsPrintf ("\n I2C_IRQSTATUS_RAW:0x%x"、HWREG (i2cAddr + I2C_IRQSTATUS_RAW));
控制台 UtilsPrintf ("\n I2C_IRQSTATUS:0x%x"、HWREG (i2cAddr + I2C_IRQSTATUS));
控制台 UtilsPrintf ("\n I2C_IRQENABLE_SET:0x%x"、HWREG (i2cAddr + I2C_IRQENABLE_SET));
控制台 UtilsPrintf ("\n I2C_IRQENABLE_CLR:0x%x"、HWREG (i2cAddr + I2C_IRQENABLE_CLR));
ConsoleUtilsPrintf ("\n I2C_WE:0x%x"、HWREG (i2cAddr + I2C_We");
控制台 UtilsPrintf ("\n I2C_DMARXENABLE_SET:0x%x"、HWREG (i2cAddr + I2C_DMARXENABLE_SET));
控制台 UtilsPrintf ("\n I2C_DMATXENABLE_SET:0x%x"、HWREG (i2cAddr + I2C_DMATXENABLE_SET));
控制台 UtilsPrintf ("\n I2C_DMARXENABLE_CLR:0x%x"、HWREG (i2cAddr + I2C_DMARXENABLE_CLR));
控制台 UtilsPrintf ("\n I2C_DMATXENABLE_CLR:0x%x"、HWREG (i2cAddr + I2C_DMATXENABLE_CLR));
控制台 UtilsPrintf ("\n I2C_DMARXWAKE_EN:0x%x"、HWREG (i2cAddr + I2C_DMARXWAKE_EN));
控制台 UtilsPrintf ("\n I2C_DMATXWAKE_EN:0x%x"、HWREG (i2cAddr + I2C_DMATXWAKE_EN));
控制台 UtilsPrintf ("\n I2C_SYSS:0x%x"、HWREG (i2cAddr + I2C_SYSS));
控制台 UtilsPrintf ("\n I2C_BUF:0x%x"、HWREG (i2cAddr + I2C_BUF));
控制台 UtilsPrintf ("\n I2C_CNT:0x%x"、HWREG (i2cAddr + I2C_CNT));
控制台 UtilsPrintf ("\n I2C_DATA:0x%x"、HWREG (i2cAddr + I2C_DATA));
控制台 UtilsPrintf ("\n I2C_CON:0x%x"、HWREG (i2cAddr + I2C_CON));
ConsoleUtilsPrintf ("\n I2C_OA:0x%x"、HWREG (i2cAddr + I2C_OA);
控制台 UtilsPrintf ("\n I2C_SA:0x%x"、HWREG (i2cAddr + I2C_SA));
控制台 UtilsPrintf ("\n I2C_PSC:0x%x"、HWREG (i2cAddr + I2C_PSC));
控制台 UtilsPrintf ("\n I2C_SCLL:0x%x"、HWREG (i2cAddr + I2C_SCLL));
控制台 UtilsPrintf ("\n I2C_SCLH:0x%x"、HWREG (i2cAddr + I2C_SCLH));
ConsoleUtilsPrintf ("\n I2C_SYSTEST:0x%x"、HWREG (i2cAddr + I2C_SYSTEST));
控制台 UtilsPrintf ("\n I2C_BUFSTAT:0x%x"、HWREG (i2cAddr + I2C_BUFSTAT));
控制台 UtilsPrintf ("\n I2C_ACTOA:0x%x"、HWREG (i2cAddr + I2C_ACTOA));
ConsoleUtilsPrintf ("\n I2C_SBLOCK:0x%x"、HWREG (i2cAddr + I2C_SBLOCK));
控制台 UtilsPrintf ("\n ********* ");
} 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您的 I2C 引脚多路复用设置是什么? 您在哪里设置它们?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    它已在 DTS 文件中完成。
    我可以在示波器上看到波形

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是否在 I2C_SCK 上启用了输入?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是我的 i2c dts pinmux。

    上拉电阻器以外部方式连接

    i2c1_PINS_DEFAULT:i2c1_PINS_DEFAULT{
    pinctrl-single、PINS =<
    0x110 (PIN_INPUT | MUX_MODE3)/*(J15) gmii1_rxer.I2C1_SCL *
    / 0x10c (PIN_INPUT | MUX_MODE3)/*(H17_rxer.I2c1_SCL *
    )
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、因此引脚多路复用是正确的。 它必须与 PRU 代码一起使用。 我可以参考 AM335x Starterware I2C 示例、以检查代码是否存在差异:
    processors.wiki.ti.com/.../StarterWare
    processors.wiki.ti.com/.../StarterWare_HSI2C