e2e.ti.com/.../Texas_5F00_i2c.c
你(们)好
我不理解管理黑客事件的正确方式。 我使用了一个旧代码示例(附后),以便从当前未连接的i2c外设读取值。 当然,我有nack和SW识别事件,但当它尝试发送停止条件时,BB位变为1,MST变为0。 下一个调用I2CA_ReadFromReg返回始终总线忙错误,无法在总线上执行其他操作。
此致
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.
e2e.ti.com/.../Texas_5F00_i2c.c
你(们)好
我不理解管理黑客事件的正确方式。 我使用了一个旧代码示例(附后),以便从当前未连接的i2c外设读取值。 当然,我有nack和SW识别事件,但当它尝试发送停止条件时,BB位变为1,MST变为0。 下一个调用I2CA_ReadFromReg返回始终总线忙错误,无法在总线上执行其他操作。
此致
您好,
要处理nack,您应执行以下步骤
这样,您就可以知道以前的I2C事务已完成,然后您就可以开始新的I2C事务了。
您是否看到在触发停止条件后MST位未清除?
此致
Siddharth
你好,Siddharth
第一个问题是由硬件导致的,它会使总线保持不可用...现在我可以与从属设备通信,但有时我会有奇怪的行为,i2c进入中断程序,但读取I2CIRC时,我得到 I2C_NO_ISRC!
随附相关代码,请查看...
/* =============================================================================
PROJECT NAME:
ITEM TYPE:
ITEM NAME:
ITEM REFERENCE:
CURRENT VERSION:
DATE:
ITEM DESCRIPTION:
DOC REFERENCES:
AUTHOR(S):
COPYRIGHT:
REVISION HISTORY:
============================================================================= */
#define I2CB_GLOBALS
#include "includes.h"
/* ============================================================================
FUNCTION NAME:
PURPOSE:
DESCRIPTION:
DOMAIN:
ACCURACY:
NOTES:
============================================================================ */
void SetUpI2CB(void)
{
GPIO_SetupPinMux(SCLB_GPIO, GPIO_MUX_CPU1, SCLB_PHER);
GPIO_SetupPinOptions(SCLB_GPIO, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
GPIO_SetupPinMux(SDAB_GPIO, GPIO_MUX_CPU1, SDAB_PHER);
GPIO_SetupPinOptions(SDAB_GPIO, GPIO_INPUT, GPIO_ASYNC | GPIO_PULLUP);
// Reset the module
I2cbRegs.I2CMDR.all = 0;
// 200MHz/(19+1) = 10MHz
I2cbRegs.I2CPSC.bit.IPSC = 19;
// Minimum low time for slave is 1.3us (program 1.5us)
I2cbRegs.I2CCLKL = 15;
// Minimum high time for slave is 0.6us (program 1us)
I2cbRegs.I2CCLKH = 10;
// Module stops in breakpoint
I2cbRegs.I2CMDR.bit.FREE = 1;
// Module operate as master
I2cbRegs.I2CMDR.bit.MST = 1;
// Enables interrupts
I2cbRegs.I2CIER.bit.ARDY = 1;
I2cbRegs.I2CIER.bit.NACK = 1;
I2cbRegs.I2CIER.bit.RRDY = 1;
I2cbRegs.I2CIER.bit.SCD = 1;
I2cbRegs.I2CIER.bit.XRDY = 1;
// Remove module from reset condition
// I2cbRegs.I2CMDR.bit.IRS = 1;
}
/* ============================================================================
FUNCTION NAME:
PURPOSE:
DESCRIPTION:
DOMAIN:
ACCURACY:
NOTES:
============================================================================ */
void i2cb_start_transfer(int16_t sadd, int16_t n_wr, int16_t n_rd, int16_t op)
{
union I2CMDR_REG cmdr;
i2cb.stop = false;
i2cb.nack = false;
i2cb.done = false;
i2cb.sar = sadd;
i2cb.n_writes = n_wr;
i2cb.n_reads = n_rd;
DELAY_US(10);
cmdr.all = 0;
cmdr.bit.IRS = 1;
cmdr.bit.MST = 1;
cmdr.bit.FREE = 1;
switch( op )
{
case I2C_WRITE:
i2cb.state = I2C_WRITING;
i2cb.trx_ptr = 0;
I2cbRegs.I2CSAR.bit.SAR = sadd;
I2cbRegs.I2CCNT = n_wr;
cmdr.bit.TRX = 1;
cmdr.bit.STP = 1;
cmdr.bit.STT = 1;
break;
case I2C_WRITE_READ:
i2cb.state = I2C_WRITING;
i2cb.trx_ptr = 0;
I2cbRegs.I2CSAR.bit.SAR = sadd;
I2cbRegs.I2CCNT = n_wr;
cmdr.bit.TRX = 1;
cmdr.bit.STP = 0;
cmdr.bit.STT = 1;
break;
case I2C_READ:
i2cb.state = I2C_READING;
i2cb.trx_ptr = 0;
I2cbRegs.I2CSAR.bit.SAR = sadd;
I2cbRegs.I2CCNT = n_rd;
cmdr.bit.TRX = 0;
cmdr.bit.STP = 1;
cmdr.bit.STT = 1;
break;
case I2C_POLLING:
i2cb.state = EEPROM_POLLING;
i2cb.trx_ptr = 0;
I2cbRegs.I2CSAR.bit.SAR = sadd;
I2cbRegs.I2CCNT = n_wr;
cmdr.bit.TRX = 1;
cmdr.bit.STP = 1;
cmdr.bit.STT = 1;
break;
default:
break;
}
I2cbRegs.I2CMDR.all = cmdr.all;
}
/* ============================================================================
FUNCTION NAME:
PURPOSE:
DESCRIPTION:
DOMAIN:
ACCURACY:
NOTES:
============================================================================ */
void i2cb_tx_rx(uint16_t sadd, int16_t n_writes, int16_t n_reads)
{
//bool esito;
if( n_reads == 0 )
{
// Start write only transfer
i2cb_start_transfer(sadd, n_writes, n_reads, I2C_WRITE);
}
else
{
if( n_writes == 0 )
{
// start read only transfer
i2cb_start_transfer(sadd, n_writes, n_reads, I2C_READ);
}
else
{
// start a read after write transfer
i2cb_start_transfer(sadd, n_writes, n_reads, I2C_WRITE_READ);
}
}
/* wait for end of operation
while( !(i2cb_d.done || i2cb_d.nack) );
if( i2cb_d.nack )
{
esito = false;
}
else
{
esito = true;
}
return ( esito );
*/
}
/* ============================================================================
FUNCTION NAME:
PURPOSE:
DESCRIPTION:
DOMAIN:
ACCURACY:
NOTES:
============================================================================ */
bool i2cb_ready(void)
{
return( i2cb.done || i2cb.nack );
}
/* ============================================================================
FUNCTION NAME:
PURPOSE:
DESCRIPTION:
DOMAIN:
ACCURACY:
NOTES:
============================================================================ */
interrupt void i2cb_isr(void)
{
// Set interrupt priority:
volatile uint16_t TempPIEIER = PieCtrlRegs.PIEIER8.all;
uint16_t tmp;
IER |= M_INT8;
IER &= MINT8;
PieCtrlRegs.PIEIER8.all &= MG8_3;
PieCtrlRegs.PIEACK.all = 0xFFFF;
asm(" NOP");
EINT;
// Insert ISR Code here.......
tmp = I2cbRegs.I2CISRC.all;
switch ( tmp )
{
case I2C_NO_ISRC:
i2cb.nack = true;
break;
case I2C_ARB_ISRC:
tmp = 0;
break;
case I2C_NACK_ISRC:
I2cbRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
I2cbRegs.I2CMDR.bit.STP = 1;
i2cb.nack = true;
break;
case I2C_ARDY_ISRC:
I2cbRegs.I2CSTR.bit.ARDY = 1;
if( (i2cb.state == EEPROM_POLLING) || i2cb.nack )
{
i2cb.done = true;
}
else
{
if( i2cb.state == I2C_WRITING )
{
i2cb_start_transfer(i2cb.sar, 0, i2cb.n_reads, I2C_READ);
}
}
break;
case I2C_RX_ISRC:
I2cbRegs.I2CSTR.bit.RRDY = 1;
i2cb.rx_buf[i2cb.trx_ptr++] = I2cbRegs.I2CDRR.bit.DATA;
break;
case I2C_TX_ISRC:
I2cbRegs.I2CSTR.bit.XRDY = 1;
I2cbRegs.I2CDXR.bit.DATA = i2cb.tx_buf[i2cb.trx_ptr++];
break;
case I2C_SCD_ISRC:
I2cbRegs.I2CSTR.bit.SCD = 1;
i2cb.state = I2C_NOP;
i2cb.stop = true;
i2cb.done = true;
break;
case I2C_AAS_ISRC:
tmp = 0;
break;
default:
tmp = 0;
break;
}
// Restore registers saved:
DINT;
PieCtrlRegs.PIEIER8.all = TempPIEIER;
}
尊敬的Siddharth
不,请不要关闭此标签,我与C2000 i2c战斗大约两年,我从未找到可靠的解决方案。 这不是延迟,但我认为这与我在中断过程中采取的措施有关。 例如,在nack的情况下,我首先在i2csrc寄存器中读取0x2,但在读取值后,寄存器更新为0x3,依此类推... 当我认为硬件已注册中断时,某些操作会将此寄存器清除为零。 有一些使用i2c正常中断的示例? 不是FIFO中断。 我想使用中断来避免等待i2c执行,但我想启动传输,只等待它发生。
此致
你好,Siddharth
随附示例代码。 我已经注意到,逐步解决I2CSRC =0的i2c中断问题不会出现,因此我输入了该行
while (!I2caRegs.I2CSTR.bit.scd);在I2C nack中断中,这似乎解决了问题。
此致
e2e.ti.com/.../test_5F00_i2c.zip
case I2C_NACK_ISRC:
I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
I2caRegs.I2CMDR.bit.STP = 1;
i2ca.nack = true;
while(!I2caRegs.I2CSTR.bit.SCD);
break;