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.
Hello. We are using the Hercules RM48L952 board with HalCoGen generated driver. When we ran off of the I2C example with interrupts enabled for loop back test of I2C. After 2 loops of sending, i2CSendByte generated by HalCoGen gets stuck in the endless loop in this HalCoGen function in i2c.c. Is there another step missing so that the while is not stuck in this infinite loop? What does it mean when it is in this infinite loop? Thank you
(HalCoGen function in i2c.c)
void i2cSendByte(i2cBASE_t *i2c, uint8 byte)
{
/* USER CODE BEGIN (15) */
/* USER CODE END */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
while ((i2c->STR & (uint32)I2C_TX_INT) == 0U)
{
} /* Wait */
i2c->DXR = (uint32)byte;
/* USER CODE BEGIN (16) */
/* USER CODE END */
}
Our test code based on TI sample code below
/** @fn void I2CInterruptDriverTest(void)
*
* This function tests I2C send and receive via Interrupt (loopback)
*/
void I2CInterruptDriverTest(void)
{
/* USER CODE BEGIN (3) */
uint32 buf_size = bsize;
uint8 *ti_buff = &TX_PACK[0];
uint8 *ri_buff = &RX_PACK[0];
uint8 i2cTest = PASS;
/* set i2c own address */
i2cSetOwnAdd(i2cREG1,own_add);
/* enable internal loopback */
i2cEnableLoopback(i2cREG1);
/* Initiate Receive data length & destination ptr */
i2cReceive(i2cREG1, 16, ri_buff);
/* Initiate Start condition for Transmission */
i2cSetStart(i2cREG1);
/* send data packets */
while(buf_size--)
{
2cSendByte(i2cREG1,*ti_buff++);
}
...
/* Clear Stop Condition detect flag */
i2cClearSCD(i2cREG1);
/* Disable RX ready Interrupt */
i2cDisableNotification(i2cREG1, I2C_RX_INT);
/* USER CODE END */
}
Hi Tammy,
I think Jan might be referring to the fact that the internal pullups are to weak to use for I2C. They're just strong enough to keep the pins from floating.
Definitely make sure to check out all the posts from Jan and Martin on I2C recently. They've been super about sharing their experiences and may likely have already run into the things you're running into ...
We actually discussed this on the private MVP forum and it just dawned on me that this isn't visible so I'll try to copy here (hoping the image comes out too:)
Hi Martin,
Do you mean on the I2C pins? Or just in general?
In general - some pins have pullups and some have pulldowns, and in most cases they are programmable.
(however, often the default pull state is important because during reset, it's the default state that is active and can prevent
things like a bus conflict.)
The datasheet will tell you which pins have pullups and which have pulldowns, for example:
But note that the pullup / down is pretty weak and not usually well controlled.
For example, we have mainly 20uA and 100uA 'class' pulls but the range on the 20uA is actually 5 to 40uA, and the range on the 100uA is 40 to 200uA.
5uA is probably too small to be useful for anything other than pulling up/down the pin when it's otherwise a NC. Most ICs have input leakage specs that are in the range of a microamp or two ...
Even for the 100uA nominal pull, the min value of 40uA is something like an 82K ohm resistor to 3.3V which is usually too high to be useful for something like an I2C bus. And if you're ok with 40uA then you have to consider that the max value could be 1/5 the 'resistance' which is a very large range.
So the internal pulls are really good for something not so timing critical, like making sure nRST eventually goes high, or leaving pins NC that would otherwise be a problem of floating inputs without the internal pull.
But if you need pretty good control of the resistance on a pin for functional reasons, you probably need to put the resistor on your board.
This is also why we err on the side of 'very weak' because you can override an 82K resistor with a 2K resistor and still be pretty close (1.9K) to 2K if that's what you need. But if we made the resistor on the chip a lower value, and you needed a higher one in your circuit, it would not be possible.
Yes, that was what I was refering to.
When I was trying the example that Tammy uses, I detected that it works perfectly when you do not assign thethe 2 i2C pins to I2C in the PINMUX tab.
When I assign them to I2C in the HALCoGen PINMUX tab, the example loops for me in exactly the same piece of code as for Tammy.
It's easy to replicate:
- (1) make the example exactly as HALCoGen instructions - without switching the 2 pins to I2C on PINMUX: works (but you don't get the i2c signal on the physical pins, everything stays on the silicon)
- (2) do same as (1), but set the pins to I2C in PINMUX tab: stuck in that loop
- (3) do same as (2), but put a pull-up resistor between the 2 I2C pins and +3.3v (as expected by I2C specs): works (and you get the physical i2c signal on the pins)
Tammy,
If you just want to have a successful run of the example, the only thing you need to do is: don't select i2c in the HALCoGen PINMUX tab.
The example will work, and nicely jump over that loop.
If you want to probe the i2c pins (with oscilloscope or logic analyzer), or if you want to connect an IC to the I2C pins,
then you have to enable i2c in the PINMUX tab. And you'll have to provide pull-up resistors.
What board are you using? ( I read Hercules RM48L952 board)
If it is the CPU control card with the DIMM-100 connector, then you'll have to put:
- 1 resistor between pin 95 and 3.3V, for the SCI signal
- 1 resistor between pin 45 and 3.3V, for the SDA signal
Regards, Jan
Hi Thank you. That is actually another TI open forum question, and we were informed there are no schematics for this board (we asked for them because what we got did not match the board). I have not gotten a reply from the TI engineer as to when he can get us schematics after he wrote he needed to update them. see link
e2e.ti.com/.../1404804
Since you are internal to TI also like QJ (since he is also working for TI), can you find out from QJ about when both you and us can get the schematics? Thank you again.
Thanks again Jan,
I am not sure why the results of (2) occur - will need to think that one over.
Tammy,
I admit I just skimmed the post w. QJ regarding the schematic, but it seems like you may have the latest schematic.
I would not worry about the part # difference between RM48L950 and RM48L952 at all. The 952 is just a premium / speed-bin of the 950.
And I'd probably just ignore the ADEVT pin name in the schematic. It's a good practice anyway to take the schematics for the dev. kits with some suspicion anyway and audit the symbol yourself against the datasheet terminal functions table... at least in my opinion. And that should resolve any question.
For the RTP and DMM (I think you meant DMM even though post was DIMM) these are J6 and J12 on the HDK and are of type 'Mictor' .. but the only tool that I'm aware of that will work with RTP and DMM is http://vector.com/vi_vx1000_functions_en.html?markierung=DMM
EDIT: Sorry strange the last sentences I typed got cut off...
I meant to add: for the RTP/DMM I'm guessing that you don't need them but if I'm wrong let me know.
For trace, there is an application report
That is helpful. Just make sure to not confuse the MIPI-60 header with the TI-60 header.
EDIT 2: Sunil never sleeps :) He noted that there is an option from ISystems as well mentioned here: Usage of DMM and RTP portson TMS570LS31x HDK - Arm-based microcontrollers forum - Arm-based microcontrollers...
(for RTP/DMM)
Tammy,
1) which loop exactly - this one ? while ((i2c->STR & (uint32)I2C_TX_INT) == 0U)
2) is the I2C Clock line stuck low as well?
EDIT:
3) if (1) is the correct loop then I think the issue might be that while the HDK has pullup resistors on the I2C lines, there is no slave connected. So if you don't have anything plugged into the expansion header, you are likely not getting an ACK back. It may be that the driver is expecting this.
So pls check the NACK bit in I2C-STR (or let us know the contents of I2C STR when you are stuck waiting on I2C_TX_INT).
If you are stuck because NACK is set and TXRDY is not, then you could try setting the IGNACK bit in the I2CEMDR register, for testing purposes when you have no slave attached to respond.